- removed the longjmp based exception catch/rethrow mechanism and instead force-terminate in case a user exception is thrown while the VM is executing JITed code on a non-Windows system

On Windows none of this is needed, because we can generate a proper unwind frame for the JITed functions, but even on Linux, it would require manual additions to each single piece of native code that ever gets called from inside a JIT compiled function.
This is an utterly prohibitive proposition because it makes direct native calls a virtual impossibility
So, in order to get the thrown error properly presented both I_Error and ThrowAbortException will now forward to I_FatalError if it is called from inside a JIT context.
This commit is contained in:
Christoph Oelckers 2018-11-25 12:36:00 +01:00
commit 42b9a41421
6 changed files with 110 additions and 172 deletions

View file

@ -47,14 +47,7 @@ void JitCompiler::EmitIJMP()
static void ValidateCall(DObject *o, VMFunction *f, int b)
{
try
{
FScopeBarrier::ValidateCall(o->GetClass(), f, b - 1);
}
catch (...)
{
VMThrowException(std::current_exception());
}
FScopeBarrier::ValidateCall(o->GetClass(), f, b - 1);
}
void JitCompiler::EmitSCOPE()
@ -241,30 +234,22 @@ void JitCompiler::EmitRETI()
static DObject* CreateNew(PClass *cls, int c)
{
try
if (!cls->ConstructNative)
{
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'");
}
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'");
}
// [ZZ] validate readonly and between scope construction
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
return cls->CreateNew();
}
catch (...)
{
VMThrowException(std::current_exception());
return nullptr;
}
// [ZZ] validate readonly and between scope construction
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
return cls->CreateNew();
}
void JitCompiler::EmitNEW()
@ -280,39 +265,24 @@ void JitCompiler::EmitNEW()
static void ThrowNewK(PClass *cls, int c)
{
try
if (!cls->ConstructNative)
{
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'");
}
ThrowAbortException(X_OTHER, "Class %s requires native construction", cls->TypeName.GetChars());
}
catch (...)
else if (cls->bAbstract)
{
VMThrowException(std::current_exception());
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'");
}
}
static DObject *CreateNewK(PClass *cls, int c)
{
try
{
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
return cls->CreateNew();
}
catch (...)
{
VMThrowException(std::current_exception());
return nullptr;
}
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
return cls->CreateNew();
}
void JitCompiler::EmitNEW_K()
@ -393,19 +363,12 @@ void JitCompiler::EmitBOUND_R()
void JitCompiler::ThrowArrayOutOfBounds(VMScriptFunction *func, VMOP *line, int index, int size)
{
try
if (index >= size)
{
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);
}
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Max.index = %u, current index = %u\n", size, index);
}
catch (...)
else
{
VMThrowException(std::current_exception());
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Negative current index = %i\n", index);
}
}