Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 35 additions & 19 deletions src/hx/cppia/Cppia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ struct BlockExpr : public CppiaExpr
return;
CppiaExpr **e = &expressions[0];
CppiaExpr **end = e+expressions.size();
for(;e<end && !ctx->breakContReturn;e++)
for(;e<end && !ctx->breakContReturn && !ctx->exception;e++)
{
CPPIA_STACK_LINE((*e));
(*e)->runVoid(ctx);
Expand Down Expand Up @@ -800,8 +800,7 @@ struct CallFunExpr : public CppiaExpr
{
unsigned char *pointer = ctx->pointer;
function->pushArgs(ctx,thisExpr?thisExpr->runObject(ctx):ctx->getThis(false),args);
if (ctx->breakContReturn)
return;
BCR_VCHECK;

AutoStack save(ctx,pointer);
ctx->runVoid(function);
Expand Down Expand Up @@ -5948,7 +5947,7 @@ struct TVars : public CppiaVoidExpr
{
CppiaExpr **v = &vars[0];
CppiaExpr **end = v + vars.size();
for(;v<end && !ctx->breakContReturn;v++)
for(;v<end && !ctx->breakContReturn && !ctx->exception;v++)
(*v)->runVoid(ctx);
}

Expand Down Expand Up @@ -5998,8 +5997,14 @@ struct ForExpr : public CppiaVoidExpr

while(hasNext())
{
if (ctx->exception)
return;
var.set(ctx,getNext());
if (ctx->exception)
return;
loop->runVoid(ctx);
if (ctx->exception)
return;

if (ctx->breakContReturn)
{
Expand Down Expand Up @@ -6045,6 +6050,9 @@ struct WhileExpr : public CppiaVoidExpr
{
loop->runVoid(ctx);

if (ctx->exception)
break;

if (ctx->breakContReturn)
{
if (ctx->breakContReturn & (bcrBreak|bcrReturn))
Expand All @@ -6053,7 +6061,7 @@ struct WhileExpr : public CppiaVoidExpr
ctx->breakContReturn = 0;
}

if (!condition->runInt(ctx) || ctx->breakContReturn)
if (!condition->runInt(ctx) || ctx->breakContReturn || ctx->exception)
break;
}
ctx->breakContReturn &= ~bcrLoop;
Expand Down Expand Up @@ -6338,30 +6346,38 @@ struct TryExpr : public CppiaVoidExpr
}
return this;
}

void handleException(CppiaCtx* ctx, Dynamic caught) {
//Class cls = caught.mPtr ? caught->__GetClass() : 0;
for(int i=0;i<catchCount;i++)
{
Catch &c = catches[i];
if ( c.type->isClassOf(caught) )
{
ctx->exception = nullptr;
HX_STACK_BEGIN_CATCH
c.var.set(ctx,caught);
c.body->runVoid(ctx);
return;
}
}
HX_STACK_DO_THROW(caught);
}

// TODO - return types...
void runVoid(CppiaCtx *ctx)
{
try
{
body->runVoid(ctx);
BCR_VCHECK;
}
catch(Dynamic caught)
{
//Class cls = caught.mPtr ? caught->__GetClass() : 0;
for(int i=0;i<catchCount;i++)
{
Catch &c = catches[i];
if ( c.type->isClassOf(caught) )
{
HX_STACK_BEGIN_CATCH
c.var.set(ctx,caught);
c.body->runVoid(ctx);
return;
}
}
HX_STACK_DO_THROW(caught);
handleException(ctx,caught);
return;
}
if (ctx->exception)
handleException(ctx,ctx->exception);
}

#ifdef CPPIA_JIT
Expand Down
4 changes: 2 additions & 2 deletions src/hx/cppia/Cppia.h
Original file line number Diff line number Diff line change
Expand Up @@ -834,9 +834,9 @@ struct BCRReturn
};


#define BCR_CHECK if (ctx->breakContReturn) return BCRReturn();
#define BCR_CHECK if (ctx->breakContReturn || ctx->exception) return BCRReturn();
#define BCR_CHECK_RET(x) if (ctx->breakContReturn) return x;
#define BCR_VCHECK if (ctx->breakContReturn) return;
#define BCR_VCHECK if (ctx->breakContReturn || ctx->exception) return;



Expand Down
20 changes: 20 additions & 0 deletions test/cppia/Client.hx
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,26 @@ class Client
return;
}

switch LocalFunctionExceptions.testLocalCallingStatic() {
case Error(message):
Common.status = 'Failed test for throw in static called by local: ' + message;
return;
default:
}

switch LocalFunctionExceptions.testCatchWithinLocal() {
case Error(message):
Common.status = 'Failed test for catch in local function: ' + message;
return;
default:
}

switch LocalFunctionExceptions.testCatchFromLocal() {
case Error(message):
Common.status = 'Failed test for catching exception from local function: ' + message;
return;
default:
}

final extending = new ClientExtendedExtendedRoot();

Expand Down
68 changes: 68 additions & 0 deletions test/cppia/LocalFunctionExceptions.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
enum Status {
Ok;
Error(message:String);
}

class LocalFunctionExceptions {
static function staticFunction() {
throw 'Thrown from static';
}

public static function testLocalCallingStatic():Status {
function localFunction() {
staticFunction();
throw 'Thrown from local';
}

try {
localFunction();
} catch (e:String) {
if (e == 'Thrown from static') {
return Ok;
} else {
return Error("Incorrect exception caught from local function call");
}
}

return Error("No exception caught");
}

public static function testCatchWithinLocal():Status {
function localFunction() {
try {
staticFunction();
} catch (e:String) {
if (e == 'Thrown from static') {
return Ok;
} else {
return Error("Incorrect exception caught from local function call");
}
}
return Error("Exception from static function not caught");
}

return try {
localFunction();
} catch (e) {
Error('Exception leaked from local function: $e');
};
}

public static function testCatchFromLocal():Status {
function localFunction() {
throw 'Thrown from local';
}

try {
localFunction();
} catch (e:String) {
if (e == 'Thrown from local') {
return Ok;
} else {
return Error("Incorrect exception caught from local function call");
}
}

return Error("No exception caught");
}
}