- fix the throw messages

This commit is contained in:
Magnus Norddahl 2018-11-10 19:52:41 +01:00
parent fb7345e470
commit 173fe94736
3 changed files with 92 additions and 56 deletions

View file

@ -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<void, VMScriptFunction *, VMOP *, int>([](VMScriptFunction *func, VMOP *line, int r) {
try
{
ThrowAbortException(func, line, (EVMAbortException)r, nullptr);
}
catch (...)
{
VMThrowException(std::current_exception());
}
});
auto call = CreateCall<void, VMScriptFunction *, VMOP *, int>(&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)

View file

@ -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<void, PClass*, int>([](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<DObject*, PClass*, int>([](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<void, VMScriptFunction *, VMOP *, int, int>(&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<void, VMScriptFunction *, VMOP *, int, int>(&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<void, VMScriptFunction *, VMOP *, int, int>(&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());
}
}

View file

@ -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);