ref: 46f726843cdc443b93cba6facecf6909b8ec78cb
parent: d948459f4459eacc01edba9d62f4e0108fc85306
author: Tor Andersson <tor@ccxvii.net>
date: Thu Jan 23 20:27:44 EST 2014
Leave last evaluated expression on the stack for script code. Pop before evaluating an expression statement, rather than after. Keep track of the stack when looping and exiting a for-in statement (which keeps the iterator on the stack between statements). This involves a few more stack gyrations during for-in statements, so the code is predicated on compiling script code.
--- a/jscompile.c
+++ b/jscompile.c
@@ -654,10 +654,17 @@
case STM_FOR_IN:
case STM_FOR_IN_VAR:
/* pop the iterator if leaving the loop */
- if (T == STM_RETURN)
- emit(J, F, OP_ROT2POP1); /* save the return value */
- if (T == STM_BREAK)
- emit(J, F, OP_POP);
+ if (F->script) {
+ if (T == STM_RETURN || T == STM_BREAK || (T == STM_CONTINUE && target != node))
+ emit(J, F, OP_ROT2POP1); /* pop the iterator, save the return or exp value */
+ if (T == STM_CONTINUE)
+ emit(J, F, OP_ROT2); /* put the iterator back on top */
+ } else {
+ if (T == STM_RETURN)
+ emit(J, F, OP_ROT2POP1); /* pop the iterator, save the return value */
+ if (T == STM_BREAK || (T == STM_CONTINUE && target != node))
+ emit(J, F, OP_POP); /* pop the iterator */
+ }
break;
case STM_TRY:
/* came from try block */
@@ -810,6 +817,10 @@
break;
case STM_EMPTY:
+ if (F->script) {
+ emit(J, F, OP_POP);
+ emit(J, F, OP_UNDEF);
+ }
break;
case STM_VAR:
@@ -887,7 +898,13 @@
emit(J, F, OP_NEXTITER);
end = jump(J, F, OP_JFALSE);
cassignforin(J, F, stm);
- cstm(J, F, stm->c);
+ if (F->script) {
+ emit(J, F, OP_ROT2);
+ cstm(J, F, stm->c);
+ emit(J, F, OP_ROT2);
+ } else {
+ cstm(J, F, stm->c);
+ }
jumpto(J, F, OP_JUMP, loop);
}
label(J, F, end);
@@ -977,8 +994,13 @@
break;
default:
- cexp(J, F, stm);
- emit(J, F, OP_POP);
+ if (F->script) {
+ emit(J, F, OP_POP);
+ cexp(J, F, stm);
+ } else {
+ cexp(J, F, stm);
+ emit(J, F, OP_POP);
+ }
break;
}
}
@@ -1047,6 +1069,9 @@
cparams(J, F, params);
+ if (F->script)
+ emit(J, F, OP_UNDEF);
+
if (body) {
cfundecs(J, F, body);
cvardecs(J, F, body);
@@ -1053,8 +1078,12 @@
cstmlist(J, F, body);
}
- emit(J, F, OP_UNDEF);
- emit(J, F, OP_RETURN);
+ if (F->script) {
+ emit(J, F, OP_RETURN);
+ } else {
+ emit(J, F, OP_UNDEF);
+ emit(J, F, OP_RETURN);
+ }
}
js_Function *jsC_compile(js_State *J, js_Ast *prog)