From 2b209d3f55fb75fc2e6ce50e5fe89b4507cdd67a Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Thu, 23 Jan 2014 17:07:04 +0100 Subject: [PATCH] Omit needless setjmp guard over catch block in try/catch statement. Make the catch opcodes only set the scope chain, and add explicit try/endtry opcodes for the catch block in try/catch/finally statements. --- jscompile.c | 28 ++++++++++++++-------------- jscompile.h | 3 ++- jsdump.c | 7 ++----- jsrun.c | 19 ++++++------------- 4 files changed, 24 insertions(+), 33 deletions(-) diff --git a/jscompile.c b/jscompile.c index 5a18a27..9abdd9c 100644 --- a/jscompile.c +++ b/jscompile.c @@ -666,8 +666,14 @@ static void cexit(JF, js_AstType T, js_Ast *node, js_Ast *target) } /* came from catch block */ if (prev == node->c) { - emit(J, F, OP_ENDCATCH); - if (node->d) cstm(J, F, node->d); /* finally */ + /* ... with finally */ + if (node->d) { + emit(J, F, OP_ENDCATCH); + emit(J, F, OP_ENDTRY); + cstm(J, F, node->d); /* finally */ + } else { + emit(J, F, OP_ENDCATCH); + } } break; } @@ -693,25 +699,19 @@ static void ctryfinally(JF, js_Ast *trystm, js_Ast *finallystm) static void ctrycatch(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm) { - int L1, L2, L3; + int L1, L2; L1 = jump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the try block */ - L2 = jump(J, F, OP_CATCH); - emitraw(J, F, addstring(J, F, catchvar->string)); - { - /* if we get here, we have caught an exception in the catch block */ - emit(J, F, OP_THROW); /* rethrow exception */ - } - label(J, F, L2); + emitstring(J, F, OP_CATCH, catchvar->string); cstm(J, F, catchstm); emit(J, F, OP_ENDCATCH); - L3 = jump(J, F, OP_JUMP); /* skip past the try block */ + L2 = jump(J, F, OP_JUMP); /* skip past the try block */ } label(J, F, L1); cstm(J, F, trystm); emit(J, F, OP_ENDTRY); - label(J, F, L3); + label(J, F, L2); } static void ctrycatchfinally(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catchstm, js_Ast *finallystm) @@ -720,14 +720,14 @@ static void ctrycatchfinally(JF, js_Ast *trystm, js_Ast *catchvar, js_Ast *catch L1 = jump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the try block */ - L2 = jump(J, F, OP_CATCH); - emitraw(J, F, addstring(J, F, catchvar->string)); + L2 = jump(J, F, OP_TRY); { /* if we get here, we have caught an exception in the catch block */ cstm(J, F, finallystm); /* inline finally block */ emit(J, F, OP_THROW); /* rethrow exception */ } label(J, F, L2); + emitstring(J, F, OP_CATCH, catchvar->string); cstm(J, F, catchstm); emit(J, F, OP_ENDCATCH); L3 = jump(J, F, OP_JUMP); /* skip past the try block to the finally block */ diff --git a/jscompile.h b/jscompile.h index ea71eb5..4d5e9d6 100644 --- a/jscompile.h +++ b/jscompile.h @@ -89,8 +89,9 @@ enum js_OpCode OP_TRY, /* -ADDR- /jump/ or -ADDR- */ OP_ENDTRY, - OP_CATCH, /* -ADDR,S- /jump/ or -ADDR,S- */ + OP_CATCH, /* push scope chain with exception variable */ OP_ENDCATCH, + OP_WITH, OP_ENDWITH, diff --git a/jsdump.c b/jsdump.c index 0b8dafe..85f5aea 100644 --- a/jsdump.c +++ b/jsdump.c @@ -651,6 +651,7 @@ void jsC_dumpfunction(js_State *J, js_Function *F) case OP_GETPROPS: case OP_SETPROPS: case OP_DELPROPS: + case OP_CATCH: pc(' '); ps(F->strtab[*p++]); break; @@ -664,11 +665,6 @@ void jsC_dumpfunction(js_State *J, js_Function *F) case OP_TRY: printf(" %d", *p++); break; - case OP_CATCH: - printf(" %d", *p++); - pc(' '); - ps(F->strtab[*p++]); - break; } nl(); @@ -713,6 +709,7 @@ void js_dumpvalue(js_State *J, js_Value v) case JS_CNUMBER: printf("[Number %g]", v.u.object->u.number); break; case JS_CSTRING: printf("[String'%s']", v.u.object->u.string); break; case JS_CERROR: printf("[Error %s]", v.u.object->u.string); break; + case JS_CITERATOR: printf("[Iterator %p]", v.u.object); break; default: printf("[Object %p]", v.u.object); break; } break; diff --git a/jsrun.c b/jsrun.c index dc96825..04efd93 100644 --- a/jsrun.c +++ b/jsrun.c @@ -822,23 +822,16 @@ static void jsR_run(js_State *J, js_Function *F) break; case OP_CATCH: - offset = *pc++; str = ST[*pc++]; - if (js_trypc(J, pc)) { - pc = J->trybuf[J->trylen].pc; - } else { - obj = jsV_newobject(J, JS_COBJECT, NULL); - js_pushobject(J, obj); - js_rot2(J); - js_setproperty(J, -2, str); - J->E = jsR_newenvironment(J, obj, J->E); - js_pop(J, 1); - pc = pcstart + offset; - } + obj = jsV_newobject(J, JS_COBJECT, NULL); + js_pushobject(J, obj); + js_rot2(J); + js_setproperty(J, -2, str); + J->E = jsR_newenvironment(J, obj, J->E); + js_pop(J, 1); break; case OP_ENDCATCH: - js_endtry(J); J->E = J->E->outer; break;