Skip to content

Commit

Permalink
- catch and rethrow c++ exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
dpjudas committed Oct 7, 2018
1 parent 4748519 commit f321f64
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 39 deletions.
13 changes: 13 additions & 0 deletions src/scripting/vm/jit.cpp
Expand Up @@ -303,6 +303,19 @@ void JitCompiler::EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg
cc.ret(vReg);
}

void JitCompiler::EmitCheckForException()
{
auto noexception = cc.newLabel();
auto exceptResult = newTempInt32();
cc.mov(exceptResult, asmjit::x86::dword_ptr(exceptInfo, 0 * 4));
cc.cmp(exceptResult, (int)-1);
cc.je(noexception);
asmjit::X86Gp vReg = newTempInt32();
cc.mov(vReg, 0);
cc.ret(vReg);
cc.bind(noexception);
}

asmjit::X86Gp JitCompiler::CheckRegD(int r0, int r1)
{
if (r0 != r1)
Expand Down
12 changes: 2 additions & 10 deletions src/scripting/vm/jit_call.cpp
Expand Up @@ -180,15 +180,7 @@ void JitCompiler::EmitDoCall(asmjit::X86Gp ptr)
call->setArg(5, callReturns);
call->setArg(6, exceptInfo);

auto noexception = cc.newLabel();
auto exceptResult = newTempInt32();
cc.mov(exceptResult, x86::dword_ptr(exceptInfo, 0 * 4));
cc.cmp(exceptResult, (int)-1);
cc.je(noexception);
X86Gp vReg = newTempInt32();
cc.mov(vReg, 0);
cc.ret(vReg);
cc.bind(noexception);
EmitCheckForException();

LoadInOuts(B);
LoadReturns(pc + 1, C);
Expand Down Expand Up @@ -414,8 +406,8 @@ int JitCompiler::DoCall(VMFrameStack *stack, VMFunction *call, int b, int c, VMV
}
catch (...)
{
// To do: store full exception in exceptinfo
exceptinfo->reason = X_OTHER;
exceptinfo->cppException = std::current_exception();
return 0;
}
}
48 changes: 20 additions & 28 deletions src/scripting/vm/jit_flow.cpp
Expand Up @@ -79,30 +79,24 @@ void JitCompiler::EmitSCOPE()
auto f = newTempIntPtr();
cc.mov(f, asmjit::imm_ptr(konsta[C].v));

auto result = newResultInt32();
typedef int(*FuncPtr)(DObject*, VMFunction*, int);
auto call = CreateCall<int, DObject*, VMFunction*, int>([](DObject *o, VMFunction *f, int b) -> int {
auto call = CreateCall<void, DObject*, VMFunction*, int, JitExceptionInfo *>([](DObject *o, VMFunction *f, int b, JitExceptionInfo *exceptinfo) {
try
{
FScopeBarrier::ValidateCall(o->GetClass(), f, b - 1);
return 1;
}
catch (const CVMAbortException &)
catch (...)
{
// To do: pass along the exception info
return 0;
exceptinfo->reason = X_OTHER;
exceptinfo->cppException = std::current_exception();
}
});
call->setRet(0, result);
call->setArg(0, regA[A]);
call->setArg(1, f);
call->setArg(2, asmjit::Imm(B));
call->setArg(3, exceptInfo);

auto notzero = cc.newLabel();
cc.test(result, result);
cc.jnz(notzero);
EmitThrowException(X_OTHER);
cc.bind(notzero);
EmitCheckForException();
}

void JitCompiler::EmitRET()
Expand Down Expand Up @@ -259,7 +253,7 @@ void JitCompiler::EmitRETI()
void JitCompiler::EmitNEW()
{
auto result = newResultIntPtr();
auto call = CreateCall<DObject*, PClass*, int>([](PClass *cls, int c) -> DObject* {
auto call = CreateCall<DObject*, PClass*, int, JitExceptionInfo *>([](PClass *cls, int c, JitExceptionInfo *exceptinfo) -> DObject* {
try
{
if (!cls->ConstructNative)
Expand All @@ -279,21 +273,20 @@ void JitCompiler::EmitNEW()
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
return cls->CreateNew();
}
catch (const CVMAbortException &)
catch (...)
{
// To do: pass along the exception info
exceptinfo->reason = X_OTHER;
exceptinfo->cppException = std::current_exception();
return nullptr;
}
});
call->setRet(0, result);
call->setArg(0, regA[B]);
call->setArg(1, asmjit::Imm(C));
call->setArg(2, exceptInfo);

EmitCheckForException();

auto notnull = cc.newLabel();
cc.test(result, result);
cc.jnz(notnull);
EmitThrowException(X_OTHER);
cc.bind(notnull);
cc.mov(regA[A], result);
}

Expand All @@ -317,27 +310,26 @@ void JitCompiler::EmitNEW_K()
auto result = newResultIntPtr();
auto regcls = newTempIntPtr();
cc.mov(regcls, asmjit::imm_ptr(konsta[B].v));
auto call = CreateCall<DObject*, PClass*, int>([](PClass *cls, int c) -> DObject* {
auto call = CreateCall<DObject*, PClass*, int, JitExceptionInfo *>([](PClass *cls, int c, JitExceptionInfo *exceptinfo) -> DObject* {
try
{
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
return cls->CreateNew();
}
catch (const CVMAbortException &)
catch (...)
{
// To do: pass along the exception info
exceptinfo->reason = X_OTHER;
exceptinfo->cppException = std::current_exception();
return nullptr;
}
});
call->setRet(0, result);
call->setArg(0, regcls);
call->setArg(1, asmjit::Imm(C));
call->setArg(2, exceptInfo);

EmitCheckForException();

auto notnull = cc.newLabel();
cc.test(result, result);
cc.jnz(notnull);
EmitThrowException(X_OTHER);
cc.bind(notnull);
cc.mov(regA[A], result);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/scripting/vm/jitintern.h
Expand Up @@ -131,6 +131,7 @@ class JitCompiler
void EmitNullPointerThrow(int index, EVMAbortException reason);
void EmitThrowException(EVMAbortException reason);
void EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg1);
void EmitCheckForException();

asmjit::X86Gp CheckRegD(int r0, int r1);
asmjit::X86Xmm CheckRegF(int r0, int r1);
Expand Down
5 changes: 4 additions & 1 deletion src/scripting/vm/vmexec.h
Expand Up @@ -86,7 +86,10 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
int result = sfunc->JitFunc(stack, ret, numret, &exceptInfo);
if (exceptInfo.reason != -1)
{
ThrowAbortException(sfunc, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr);
if (exceptInfo.cppException)
std::rethrow_exception(exceptInfo.cppException);
else
ThrowAbortException(sfunc, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr);
}
return result;
}
Expand Down
1 change: 1 addition & 0 deletions src/scripting/vm/vmintern.h
Expand Up @@ -443,6 +443,7 @@ struct JitExceptionInfo
int32_t reason; // EVMAbortException
int32_t args[3];
VMOP* pcOnJitAbort;
std::exception_ptr cppException;
};

typedef int(*JitFuncPtr)(VMFrameStack *stack, VMReturn *ret, int numret, JitExceptionInfo *exceptInfo);
Expand Down

0 comments on commit f321f64

Please sign in to comment.