From 173fe947368e8eb37e289c41bdc0f3a693951319 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 10 Nov 2018 19:52:41 +0100 Subject: [PATCH] - fix the throw messages --- src/scripting/vm/jit.cpp | 29 ++++----- src/scripting/vm/jit_flow.cpp | 115 ++++++++++++++++++++++------------ src/scripting/vm/jitintern.h | 4 +- 3 files changed, 92 insertions(+), 56 deletions(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index aa599ab60..767423585 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -685,29 +685,26 @@ void JitCompiler::EmitNullPointerThrow(int index, EVMAbortException reason) cc.bind(label); } +void JitCompiler::ThrowException(VMScriptFunction *func, VMOP *line, int reason) +{ + try + { + ThrowAbortException(func, line, (EVMAbortException)reason, nullptr); + } + catch (...) + { + VMThrowException(std::current_exception()); + } +} + void JitCompiler::EmitThrowException(EVMAbortException reason) { - auto call = CreateCall([](VMScriptFunction *func, VMOP *line, int r) { - try - { - ThrowAbortException(func, line, (EVMAbortException)r, nullptr); - } - catch (...) - { - VMThrowException(std::current_exception()); - } - }); + auto call = CreateCall(&JitCompiler::ThrowException); call->setArg(0, asmjit::imm_ptr(sfunc)); call->setArg(1, asmjit::imm_ptr(pc)); call->setArg(2, asmjit::imm(reason)); } -void JitCompiler::EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg1) -{ - // To do: fix throw message and use arg1 - EmitThrowException(reason); -} - asmjit::X86Gp JitCompiler::CheckRegD(int r0, int r1) { if (r0 != r1) diff --git a/src/scripting/vm/jit_flow.cpp b/src/scripting/vm/jit_flow.cpp index 15177b57d..6371be6c3 100644 --- a/src/scripting/vm/jit_flow.cpp +++ b/src/scripting/vm/jit_flow.cpp @@ -297,23 +297,37 @@ void JitCompiler::EmitNEW() void JitCompiler::EmitNEW_K() { PClass *cls = (PClass*)konsta[B].v; - if (!cls->ConstructNative) + auto regcls = newTempIntPtr(); + cc.mov(regcls, asmjit::imm_ptr(cls)); + + if (!cls->ConstructNative || cls->bAbstract || cls->IsDescendantOf(NAME_Actor)) { - EmitThrowException(X_OTHER); // "Class %s requires native construction", cls->TypeName.GetChars() - } - else if (cls->bAbstract) - { - EmitThrowException(X_OTHER); // "Cannot instantiate abstract class %s", cls->TypeName.GetChars() - } - else if (cls->IsDescendantOf(NAME_Actor)) // Creating actors here must be outright prohibited - { - EmitThrowException(X_OTHER); // "Cannot create actors with 'new'" + auto call = CreateCall([](PClass *cls, int c) { + try + { + if (!cls->ConstructNative) + { + ThrowAbortException(X_OTHER, "Class %s requires native construction", cls->TypeName.GetChars()); + } + else if (cls->bAbstract) + { + ThrowAbortException(X_OTHER, "Cannot instantiate abstract class %s", cls->TypeName.GetChars()); + } + else // if (cls->IsDescendantOf(NAME_Actor)) // Creating actors here must be outright prohibited + { + ThrowAbortException(X_OTHER, "Cannot create actors with 'new'"); + } + } + catch (...) + { + VMThrowException(std::current_exception()); + } + }); + call->setArg(0, regcls); } else { auto result = newResultIntPtr(); - auto regcls = newTempIntPtr(); - cc.mov(regcls, asmjit::imm_ptr(konsta[B].v)); auto call = CreateCall([](PClass *cls, int c) -> DObject* { try { @@ -341,42 +355,65 @@ void JitCompiler::EmitTHROW() void JitCompiler::EmitBOUND() { - auto label1 = cc.newLabel(); - auto label2 = cc.newLabel(); + auto label = cc.newLabel(); + cc.cmp(regD[A], (int)BC); - cc.jl(label1); - EmitThrowException(X_ARRAY_OUT_OF_BOUNDS); // "Max.index = %u, current index = %u\n", BC, reg.d[A] - cc.bind(label1); - cc.cmp(regD[A], (int)0); - cc.jge(label2); - EmitThrowException(X_ARRAY_OUT_OF_BOUNDS); // "Negative current index = %i\n", reg.d[A] - cc.bind(label2); + cc.jb(label); + + auto call = CreateCall(&JitCompiler::ThrowArrayOutOfBounds); + call->setArg(0, asmjit::imm_ptr(sfunc)); + call->setArg(1, asmjit::imm_ptr(pc)); + call->setArg(2, regD[A]); + call->setArg(3, asmjit::imm(BC)); + + cc.bind(label); } void JitCompiler::EmitBOUND_K() { - auto label1 = cc.newLabel(); - auto label2 = cc.newLabel(); + auto label = cc.newLabel(); cc.cmp(regD[A], (int)konstd[BC]); - cc.jl(label1); - EmitThrowException(X_ARRAY_OUT_OF_BOUNDS); // "Max.index = %u, current index = %u\n", konstd[BC], reg.d[A] - cc.bind(label1); - cc.cmp(regD[A], (int)0); - cc.jge(label2); - EmitThrowException(X_ARRAY_OUT_OF_BOUNDS); // "Negative current index = %i\n", reg.d[A] - cc.bind(label2); + cc.jb(label); + + auto call = CreateCall(&JitCompiler::ThrowArrayOutOfBounds); + call->setArg(0, asmjit::imm_ptr(sfunc)); + call->setArg(1, asmjit::imm_ptr(pc)); + call->setArg(2, regD[A]); + call->setArg(3, asmjit::imm(konstd[BC])); + + cc.bind(label); } void JitCompiler::EmitBOUND_R() { - auto label1 = cc.newLabel(); - auto label2 = cc.newLabel(); + auto label = cc.newLabel(); cc.cmp(regD[A], regD[B]); - cc.jl(label1); - EmitThrowException(X_ARRAY_OUT_OF_BOUNDS); // "Max.index = %u, current index = %u\n", reg.d[B], reg.d[A] - cc.bind(label1); - cc.cmp(regD[A], (int)0); - cc.jge(label2); - EmitThrowException(X_ARRAY_OUT_OF_BOUNDS); // "Negative current index = %i\n", reg.d[A] - cc.bind(label2); + cc.jb(label); + + auto call = CreateCall(&JitCompiler::ThrowArrayOutOfBounds); + call->setArg(0, asmjit::imm_ptr(sfunc)); + call->setArg(1, asmjit::imm_ptr(pc)); + call->setArg(2, regD[A]); + call->setArg(3, regD[B]); + + cc.bind(label); +} + +void JitCompiler::ThrowArrayOutOfBounds(VMScriptFunction *func, VMOP *line, int index, int size) +{ + try + { + if (index > size) + { + ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Max.index = %u, current index = %u\n", size, index); + } + else + { + ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Negative current index = %i\n", index); + } + } + catch (...) + { + VMThrowException(std::current_exception()); + } } diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index 0f47ceb1a..f19c202bf 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -146,7 +146,9 @@ private: void EmitNullPointerThrow(int index, EVMAbortException reason); void EmitThrowException(EVMAbortException reason); - void EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg1); + + static void ThrowArrayOutOfBounds(VMScriptFunction *func, VMOP *line, int index, int size); + static void ThrowException(VMScriptFunction *func, VMOP *line, int reason); asmjit::X86Gp CheckRegD(int r0, int r1); asmjit::X86Xmm CheckRegF(int r0, int r1);