diff --git a/src/hx/cppia/Cppia.cpp b/src/hx/cppia/Cppia.cpp index ad37f40d8..6f1a09a17 100644 --- a/src/hx/cppia/Cppia.cpp +++ b/src/hx/cppia/Cppia.cpp @@ -1744,6 +1744,7 @@ struct CallHaxe : public CppiaExpr { unsigned char *pointer = ctx->pointer; ctx->pushObject(isStatic ? 0: thisExpr ? thisExpr->runObject(ctx) : ctx->getThis(false)); + BCR_VCHECK; const char *s = function.signature+1; for(int a=0;apushObject( arg->runObject(ctx) ); break; default: ;// huh? } + BCR_VCHECK; } AutoStack a(ctx,pointer); @@ -2148,8 +2150,9 @@ struct CallMemberVTable : public CppiaExpr ExprType getType() { return returnType; } // ScriptCallable **vtable = (ScriptCallable **)thisVal->__GetScriptVTable(); - #define CALL_VTABLE_SETUP \ + #define CALL_VTABLE_SETUP(errorValue) \ hx::Object *thisVal = thisExpr ? thisExpr->runObject(ctx) : ctx->getThis(); \ + BCR_CHECK_RET(errorValue); \ CPPIA_CHECK(thisVal); \ ScriptCallable **vtable = (!isInterfaceCall ? (*(ScriptCallable ***)((char *)thisVal +scriptVTableOffset)) : (ScriptCallable **) thisVal->__GetScriptVTable()); \ unsigned char *pointer = ctx->pointer; \ @@ -2160,29 +2163,29 @@ struct CallMemberVTable : public CppiaExpr void runVoid(CppiaCtx *ctx) { - CALL_VTABLE_SETUP + CALL_VTABLE_SETUP() ctx->runVoid(func); } int runInt(CppiaCtx *ctx) { - CALL_VTABLE_SETUP - return runContextConvertInt(ctx, checkInterfaceReturnType ? func->getReturnType() : returnType, func); + CALL_VTABLE_SETUP(BCRReturn()) + return runContextConvertInt(ctx, checkInterfaceReturnType ? func->getReturnType() : returnType, func); } - + Float runFloat(CppiaCtx *ctx) { - CALL_VTABLE_SETUP - return runContextConvertFloat(ctx, checkInterfaceReturnType ? func->getReturnType() : returnType, func); + CALL_VTABLE_SETUP(BCRReturn()) + return runContextConvertFloat(ctx, checkInterfaceReturnType ? func->getReturnType() : returnType, func); } String runString(CppiaCtx *ctx) { - CALL_VTABLE_SETUP - return runContextConvertString(ctx, checkInterfaceReturnType ? func->getReturnType() : returnType, func); + CALL_VTABLE_SETUP(BCRReturn()) + return runContextConvertString(ctx, checkInterfaceReturnType ? func->getReturnType() : returnType, func); } hx::Object *runObject(CppiaCtx *ctx) { - CALL_VTABLE_SETUP - return runContextConvertObject(ctx, checkInterfaceReturnType ? func->getReturnType() : returnType, func); + CALL_VTABLE_SETUP(BCRReturn()) + return runContextConvertObject(ctx, checkInterfaceReturnType ? func->getReturnType() : returnType, func); } bool isBoolInt() { return boolResult; } @@ -3088,6 +3091,8 @@ struct Call : public CppiaDynamicExpr hx::Object *runObject(CppiaCtx *ctx) { hx::Object *funcVal = func->runObject(ctx); + BCR_CHECK; + CPPIA_CHECK_FUNC(funcVal); int size = args.size(); switch(size) diff --git a/src/hx/cppia/Cppia.h b/src/hx/cppia/Cppia.h index b8361537c..f8d862a07 100644 --- a/src/hx/cppia/Cppia.h +++ b/src/hx/cppia/Cppia.h @@ -835,7 +835,7 @@ struct BCRReturn #define BCR_CHECK if (ctx->breakContReturn || ctx->exception) return BCRReturn(); -#define BCR_CHECK_RET(x) if (ctx->breakContReturn) return x; +#define BCR_CHECK_RET(x) if (ctx->breakContReturn || ctx->exception) return x; #define BCR_VCHECK if (ctx->breakContReturn || ctx->exception) return; diff --git a/test/cppia/Client.hx b/test/cppia/Client.hx index 67842a75a..2b3feb1b2 100644 --- a/test/cppia/Client.hx +++ b/test/cppia/Client.hx @@ -189,6 +189,27 @@ class Client default: } + switch LocalFunctionExceptions.testObjMethodOnReturn() { + case Error(message): + Common.status = 'Failed test for running object method on returned value: ' + message; + return; + default: + } + + switch LocalFunctionExceptions.testClassMethodOnReturn() { + case Error(message): + Common.status = 'Failed test for running class method on returned value: ' + message; + return; + default: + } + + switch LocalFunctionExceptions.testHostClassMethodOnHostReturn() { + case Error(message): + Common.status = 'Failed test for running host class method on returned value: ' + message; + return; + default: + } + final extending = new ClientExtendedExtendedRoot(); extending.addValue(); diff --git a/test/cppia/Common.hx b/test/cppia/Common.hx index 99f80f815..e547881b6 100644 --- a/test/cppia/Common.hx +++ b/test/cppia/Common.hx @@ -8,4 +8,5 @@ class Common public static var callbackSet:Int = 0; public static var callback: Void->Void; + public function dummyMethod() {} } diff --git a/test/cppia/LocalFunctionExceptions.hx b/test/cppia/LocalFunctionExceptions.hx index 3caae76bc..7395daeb6 100644 --- a/test/cppia/LocalFunctionExceptions.hx +++ b/test/cppia/LocalFunctionExceptions.hx @@ -3,8 +3,12 @@ enum Status { Error(message:String); } +class DummyClass { + public function run() {} +} + class LocalFunctionExceptions { - static function staticFunction() { + static function staticFunction():Dynamic { throw 'Thrown from static'; } @@ -65,4 +69,58 @@ class LocalFunctionExceptions { return Error("No exception caught"); } + + public static function testObjMethodOnReturn():Status { + function localFunction() { + (staticFunction() : Dynamic).run(); + } + + try { + localFunction(); + } catch (e:Dynamic) { + if (e == 'Thrown from static') { + return Ok; + } else { + return Error("Incorrect exception caught from local function call: " + e); + } + } + + return Error("No exception caught"); + } + + public static function testClassMethodOnReturn():Status { + function localFunction() { + (staticFunction() : DummyClass).run(); + } + + try { + localFunction(); + } catch (e:Dynamic) { + if (e == 'Thrown from static') { + return Ok; + } else { + return Error("Incorrect exception caught from local function call: " + e); + } + } + + return Error("No exception caught"); + } + + public static function testHostClassMethodOnHostReturn():Status { + function localFunction() { + (staticFunction() : Common).dummyMethod(); + } + + try { + localFunction(); + } catch (e:Dynamic) { + if (e == 'Thrown from static') { + return Ok; + } else { + return Error("Incorrect exception caught from local function call: " + e); + } + } + + return Error("No exception caught"); + } } diff --git a/test/cppia/compile-host.hxml b/test/cppia/compile-host.hxml index efe8bdf09..218812e3f 100644 --- a/test/cppia/compile-host.hxml +++ b/test/cppia/compile-host.hxml @@ -3,4 +3,5 @@ -D dll_export=host_classes.info -L utest --dce no ---cpp bin \ No newline at end of file +--cpp bin +-D HXCPP_CATCH_SEGV