mirror of
https://github.com/ccxvii/mujs.git
synced 2026-02-06 09:51:41 +08:00
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.
This commit is contained in:
28
jscompile.c
28
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 */
|
||||
|
||||
@@ -89,8 +89,9 @@ enum js_OpCode
|
||||
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,
|
||||
|
||||
|
||||
7
jsdump.c
7
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;
|
||||
|
||||
19
jsrun.c
19
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user