mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 23:32:02 +00:00
- add first draft of abort exceptions
This commit is contained in:
parent
c89d8bb9bb
commit
6424190cbf
3 changed files with 72 additions and 2 deletions
|
@ -292,6 +292,57 @@ static int64_t ToMemAddress(const void *d)
|
||||||
return (int64_t)(ptrdiff_t)d;
|
return (int64_t)(ptrdiff_t)d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPCOnAbort(VMScriptFunction *sfunc, VMOP* pc) {
|
||||||
|
sfunc->pcOnJitAbort = pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void setCallArg(T call, int num, int64_t arg) {
|
||||||
|
call->setArg(num, asmjit::imm(arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCallArg(asmjit::CCFuncCall* call, int num, uint64_t arg) {
|
||||||
|
call->setArg(num, asmjit::imm_u(arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCallArg(asmjit::CCFuncCall* call, int num, const asmjit::Reg& arg) {
|
||||||
|
call->setArg(num, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Arg>
|
||||||
|
void setCallArg(asmjit::CCFuncCall* call, int num, Arg* arg) {
|
||||||
|
call->setArg(num, asmjit::imm_ptr(arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Arg>
|
||||||
|
void emitCallVariadicArgs(asmjit::CCFuncCall* call, int num, Arg arg) {
|
||||||
|
setCallArg(call, num, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Arg, typename... Args>
|
||||||
|
void emitCallVariadicArgs(asmjit::CCFuncCall* call, int num, Arg arg, Args... args) {
|
||||||
|
setCallArg(call, num, arg);
|
||||||
|
emitCallVariadicArgs(call, num + 1, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitCallVariadicArgs(asmjit::CCFuncCall*, int num) {}
|
||||||
|
|
||||||
|
template <typename... ArgTypes, typename... Args>
|
||||||
|
void emitAbortExceptionCall(asmjit::X86Compiler& cc, VMScriptFunction* sfunc, const VMOP* pc, EVMAbortException reason, const char* moreinfo, Args... args) {
|
||||||
|
using namespace asmjit;
|
||||||
|
|
||||||
|
auto ptr = cc.newIntPtr();
|
||||||
|
|
||||||
|
CCFuncCall* setPCCall = cc.call(imm_ptr((void*)setPCOnAbort), FuncSignature2<void, VMScriptFunction*, VMOP*>(CallConv::kIdHost));
|
||||||
|
setPCCall->setArg(0, imm_ptr(sfunc));
|
||||||
|
setPCCall->setArg(1, imm_ptr(pc));
|
||||||
|
|
||||||
|
CCFuncCall* throwAbortCall = cc.call(imm_ptr((void*)ThrowAbortException), FuncSignatureT<void, int, const char*, ArgTypes...>(CallConv::kIdHost));
|
||||||
|
throwAbortCall->setArg(0, imm(reason));
|
||||||
|
throwAbortCall->setArg(1, imm_ptr(moreinfo));
|
||||||
|
emitCallVariadicArgs(throwAbortCall, 2, args...);
|
||||||
|
}
|
||||||
|
|
||||||
static void CallSqrt(asmjit::X86Compiler& cc, const asmjit::X86Xmm &a, const asmjit::X86Xmm &b)
|
static void CallSqrt(asmjit::X86Compiler& cc, const asmjit::X86Xmm &a, const asmjit::X86Xmm &b)
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
@ -902,10 +953,18 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
||||||
{
|
{
|
||||||
auto tmp0 = cc.newInt32();
|
auto tmp0 = cc.newInt32();
|
||||||
auto tmp1 = cc.newInt32();
|
auto tmp1 = cc.newInt32();
|
||||||
|
auto label = cc.newLabel();
|
||||||
|
|
||||||
|
cc.test(regD[C], regD[C]);
|
||||||
|
cc.je(label);
|
||||||
|
|
||||||
cc.mov(tmp0, regD[B]);
|
cc.mov(tmp0, regD[B]);
|
||||||
cc.cdq(tmp1, tmp0);
|
cc.cdq(tmp1, tmp0);
|
||||||
cc.idiv(tmp1, tmp0, regD[C]);
|
cc.idiv(tmp1, tmp0, regD[C]);
|
||||||
cc.mov(regD[A], tmp0);
|
cc.mov(regD[A], tmp0);
|
||||||
|
|
||||||
|
cc.bind(label);
|
||||||
|
emitAbortExceptionCall(cc, sfunc, pc, X_DIVISION_BY_ZERO, nullptr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_DIV_RK:
|
case OP_DIV_RK:
|
||||||
|
|
|
@ -80,9 +80,19 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
||||||
sfunc->JitFunc = JitCompile(sfunc);
|
sfunc->JitFunc = JitCompile(sfunc);
|
||||||
sfunc->JitCompiled = true;
|
sfunc->JitCompiled = true;
|
||||||
}
|
}
|
||||||
if (sfunc->JitFunc)
|
if (sfunc->JitFunc) {
|
||||||
|
try {
|
||||||
return sfunc->JitFunc(stack, ®, ret, numret);
|
return sfunc->JitFunc(stack, ®, ret, numret);
|
||||||
}
|
}
|
||||||
|
catch (CVMAbortException &err)
|
||||||
|
{
|
||||||
|
err.MaybePrintMessage();
|
||||||
|
err.stacktrace.AppendFormat("Called from %s at %s, line %d\n", sfunc->PrintableName.GetChars(), sfunc->SourceFileName.GetChars(), sfunc->PCToLine(sfunc->pcOnJitAbort));
|
||||||
|
// PrintParameters(reg.param + f->NumParam - B, B);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
double fb, fc;
|
double fb, fc;
|
||||||
|
|
|
@ -471,6 +471,7 @@ public:
|
||||||
|
|
||||||
bool JitCompiled = false;
|
bool JitCompiled = false;
|
||||||
JitFuncPtr JitFunc = nullptr;
|
JitFuncPtr JitFunc = nullptr;
|
||||||
|
VMOP* pcOnJitAbort = nullptr;
|
||||||
|
|
||||||
void InitExtra(void *addr);
|
void InitExtra(void *addr);
|
||||||
void DestroyExtra(void *addr);
|
void DestroyExtra(void *addr);
|
||||||
|
|
Loading…
Reference in a new issue