diff --git a/src/hx/cppia/CppiaFunction.cpp b/src/hx/cppia/CppiaFunction.cpp index 005977b36..c6e7b829d 100644 --- a/src/hx/cppia/CppiaFunction.cpp +++ b/src/hx/cppia/CppiaFunction.cpp @@ -508,10 +508,18 @@ void ScriptCallable::runFunction(CppiaCtx *ctx) #ifdef CPPIA_JIT if (compiled) { + { AutoFrame frame(ctx); //printf("Running compiled code...\n"); compiled(ctx); //printf("Done.\n"); + } + if (ctx->exception) + { + Dynamic caught = ctx->exception; + ctx->exception = nullptr; + HX_STACK_DO_THROW(caught); + } } else #endif @@ -543,10 +551,18 @@ void ScriptCallable::runFunctionClosure(CppiaCtx *ctx) #ifdef CPPIA_JIT if (compiled) { + { AutoFrame frame(ctx); //printf("Running compiled code...\n"); compiled(ctx); //printf("Done.\n"); + } + if (ctx->exception) + { + Dynamic caught = ctx->exception; + ctx->exception = nullptr; + HX_STACK_DO_THROW(caught); + } } else #endif @@ -747,7 +763,13 @@ class CppiaClosure : public hx::Object AutoFrame frame(ctx); function->compiled(ctx); } - if (!ctx->exception) + if (ctx->exception) + { + Dynamic caught = ctx->exception; + ctx->exception = nullptr; + HX_STACK_DO_THROW(caught); + } + { switch(function->returnType) { diff --git a/test/cppia/Client.hx b/test/cppia/Client.hx index 710373f4b..7a306efb6 100644 --- a/test/cppia/Client.hx +++ b/test/cppia/Client.hx @@ -14,6 +14,17 @@ class ClientFoo implements IFoo { } } +class ClientThrower { + + public static function boom():String { + throw "boom"; + } + + public static function fine():String { + return "still here"; + } +} + class Client { public static var clientBool0 = true; diff --git a/test/cppia/cases/TestCommon.hx b/test/cppia/cases/TestCommon.hx index eaacb5a76..bed28ab71 100644 --- a/test/cppia/cases/TestCommon.hx +++ b/test/cppia/cases/TestCommon.hx @@ -59,6 +59,25 @@ class TestCommon extends Test { Assert.equals(2, Common.callbackSet, 'Bad cppia closure'); } + @:depends(testStatus) + function testThrowReachesTheCaller() { + final cls = Type.resolveClass('ClientThrower'); + + if (Assert.notNull(cls, 'Unable to resolve ClientThrower')) { + var caught:String = null; + + try { + Reflect.callMethod(null, Reflect.field(cls, 'boom'), []); + } catch (e:Dynamic) { + caught = Std.string(e); + } + + Assert.equals('boom', caught, 'The throw did not reach the caller'); + Assert.equals('still here', Std.string(Reflect.callMethod(null, Reflect.field(cls, 'fine'), [])), + 'A later call answered null, so the exception was left on the context'); + } + } + @:depends(testStatus) function testInterfaceCalling() { final obj : IFoo = Type.createInstance(Type.resolveClass('ClientFoo'), []);