ref: 2b209d3f55fb75fc2e6ce50e5fe89b4507cdd67a
parent: 40572172a5acbbd86fe610d41b6d2195d7b81fb2
author: Tor Andersson <tor@ccxvii.net>
date: Thu Jan 23 12:07:04 EST 2014
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.
--- a/jscompile.c
+++ b/jscompile.c
@@ -666,8 +666,14 @@
}
/* 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 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,8 +720,7 @@
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 */
@@ -728,6 +727,7 @@
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 */
--- a/jscompile.h
+++ b/jscompile.h
@@ -89,8 +89,9 @@
OP_TRY, /* -ADDR- /jump/ or -ADDR- <exception> */
OP_ENDTRY,
- OP_CATCH, /* -ADDR,S- /jump/ or -ADDR,S- <exception> */
+ OP_CATCH, /* push scope chain with exception variable */
OP_ENDCATCH,
+
OP_WITH,
OP_ENDWITH,
--- a/jsdump.c
+++ b/jsdump.c
@@ -651,6 +651,7 @@
case OP_GETPROPS:
case OP_SETPROPS:
case OP_DELPROPS:
+ case OP_CATCH:
pc(' ');
ps(F->strtab[*p++]);
break;
@@ -664,11 +665,6 @@
case OP_TRY:
printf(" %d", *p++);
break;
- case OP_CATCH:
- printf(" %d", *p++);
- pc(' ');
- ps(F->strtab[*p++]);
- break;
}
nl();
@@ -713,6 +709,7 @@
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;
--- a/jsrun.c
+++ b/jsrun.c
@@ -822,23 +822,16 @@
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;