ref: 34b9fda6f8778c7dbfae55c2480f09ffb6f0d952
parent: ff6f94236518e06e6274fe50c2a660ed45ec776d
author: Tor Andersson <tor@ccxvii.net>
date: Fri Jan 24 19:58:14 EST 2014
Create special initializer opcodes for brevity. Pop the key and value, don't pop the object.
--- a/jscompile.c
+++ b/jscompile.c
@@ -115,7 +115,7 @@
else if (num == 1)
emit(J, F, OP_NUMBER_1);
else if (num == (short)num) {
- emit(J, F, OP_NUMBER_X);
+ emit(J, F, OP_NUMBER_N);
emitraw(J, F, (short)num);
} else {
emit(J, F, OP_NUMBER);
@@ -178,12 +178,9 @@
int i = 0;
while (list) {
if (list->a->type != EXP_UNDEF) {
- emit(J, F, OP_DUP);
- emit(J, F, OP_NUMBER_X);
- emitraw(J, F, i++);
cexp(J, F, list->a);
- emit(J, F, OP_SETPROP);
- emit(J, F, OP_POP);
+ emit(J, F, OP_INITPROP_N);
+ emitraw(J, F, i++);
} else {
++i;
}
@@ -197,16 +194,19 @@
js_Ast *kv = list->a;
if (kv->type == EXP_PROP_VAL) {
js_Ast *prop = kv->a;
- emit(J, F, OP_DUP);
if (prop->type == AST_IDENTIFIER || prop->type == AST_STRING) {
cexp(J, F, kv->b);
- emitstring(J, F, OP_SETPROPS, prop->string);
- emit(J, F, OP_POP);
+ emitstring(J, F, OP_INITPROP_S, prop->string);
} else if (prop->type == AST_NUMBER) {
- emitnumber(J, F, prop->number);
- cexp(J, F, kv->b);
- emit(J, F, OP_SETPROP);
- emit(J, F, OP_POP);
+ if (prop->number == (short)prop->number) {
+ cexp(J, F, kv->b);
+ emit(J, F, OP_INITPROP_N);
+ emitraw(J, F, (short)prop->number);
+ } else {
+ emitnumber(J, F, prop->number);
+ cexp(J, F, kv->b);
+ emit(J, F, OP_INITPROP);
+ }
} else {
jsC_error(J, list, "illegal property name in object initializer");
}
@@ -245,7 +245,7 @@
case EXP_MEMBER:
cexp(J, F, lhs->a);
cexp(J, F, rhs);
- emitstring(J, F, OP_SETPROPS, lhs->b->string);
+ emitstring(J, F, OP_SETPROP_S, lhs->b->string);
break;
default:
jsC_error(J, lhs, "invalid l-value in assignment");
@@ -280,7 +280,7 @@
case EXP_MEMBER:
cexp(J, F, lhs->a);
emit(J, F, OP_ROT2);
- emitstring(J, F, OP_SETPROPS, lhs->b->string);
+ emitstring(J, F, OP_SETPROP_S, lhs->b->string);
emit(J, F, OP_POP);
break;
default:
@@ -306,7 +306,7 @@
case EXP_MEMBER:
cexp(J, F, lhs->a);
emit(J, F, OP_DUP);
- emitstring(J, F, OP_GETPROPS, lhs->b->string);
+ emitstring(J, F, OP_GETPROP_S, lhs->b->string);
if (dup) emit(J, F, OP_DUP1ROT3);
break;
default:
@@ -324,7 +324,7 @@
case EXP_INDEX:
break;
case EXP_MEMBER:
- emitstring(J, F, OP_SETPROPS, lhs->b->string);
+ emitstring(J, F, OP_SETPROP_S, lhs->b->string);
break;
default:
jsC_error(J, lhs, "invalid l-value in assignment");
@@ -353,7 +353,7 @@
break;
case EXP_MEMBER:
cexp(J, F, exp->a);
- emitstring(J, F, OP_DELPROPS, exp->b->string);
+ emitstring(J, F, OP_DELPROP_S, exp->b->string);
break;
default:
jsC_error(J, exp, "invalid l-value in delete expression");
@@ -375,7 +375,7 @@
case EXP_MEMBER:
cexp(J, F, fun->a);
emit(J, F, OP_DUP);
- emitstring(J, F, OP_GETPROPS, fun->b->string);
+ emitstring(J, F, OP_GETPROP_S, fun->b->string);
emit(J, F, OP_ROT2);
break;
default:
@@ -428,7 +428,7 @@
case EXP_MEMBER:
cexp(J, F, exp->a);
- emitstring(J, F, OP_GETPROPS, exp->b->string);
+ emitstring(J, F, OP_GETPROP_S, exp->b->string);
break;
case EXP_CALL:
--- a/jscompile.h
+++ b/jscompile.h
@@ -18,7 +18,7 @@
OP_NUMBER_0, /* -- 0 */
OP_NUMBER_1, /* -- 1 */
- OP_NUMBER_X, /* -K- K */
+ OP_NUMBER_N, /* -K- K */
OP_NUMBER, /* -N- <number> */
OP_STRING, /* -S- <string> */
@@ -43,12 +43,16 @@
OP_IN, /* <name> <obj> -- <exists?> */
+ OP_INITPROP, /* <obj> <key> <val> -- <obj> */
+ OP_INITPROP_N, /* <obj> <val> -- <obj> */
+ OP_INITPROP_S, /* <obj> <val> -- <obj> */
+
OP_GETPROP, /* <obj> <name> -- <value> */
- OP_GETPROPS, /* <obj> -S- <value> */
+ OP_GETPROP_S, /* <obj> -S- <value> */
OP_SETPROP, /* <obj> <name> <value> -- <value> */
- OP_SETPROPS, /* <obj> <value> -S- <value> */
+ OP_SETPROP_S, /* <obj> <value> -S- <value> */
OP_DELPROP, /* <obj> <name> -- <success> */
- OP_DELPROPS, /* <obj> -S- <success> */
+ OP_DELPROP_S, /* <obj> -S- <success> */
OP_ITERATOR, /* <obj> -- <iobj> */
OP_NEXTITER, /* <iobj> -- <iobj> <name> true || false */
--- a/jsdump.c
+++ b/jsdump.c
@@ -648,15 +648,17 @@
case OP_GETVAR:
case OP_SETVAR:
case OP_DELVAR:
- case OP_GETPROPS:
- case OP_SETPROPS:
- case OP_DELPROPS:
+ case OP_GETPROP_S:
+ case OP_SETPROP_S:
+ case OP_DELPROP_S:
+ case OP_INITPROP_S:
case OP_CATCH:
pc(' ');
ps(F->strtab[*p++]);
break;
- case OP_NUMBER_X:
+ case OP_NUMBER_N:
+ case OP_INITPROP_N:
case OP_CALL:
case OP_NEW:
case OP_JUMP:
--- a/jsrun.c
+++ b/jsrun.c
@@ -688,7 +688,7 @@
case OP_NUMBER_0: js_pushnumber(J, 0); break;
case OP_NUMBER_1: js_pushnumber(J, 1); break;
- case OP_NUMBER_X: js_pushnumber(J, *pc++); break;
+ case OP_NUMBER_N: js_pushnumber(J, *pc++); break;
case OP_NUMBER: js_pushnumber(J, NT[*pc++]); break;
case OP_STRING: js_pushliteral(J, ST[*pc++]); break;
@@ -733,6 +733,28 @@
js_pushboolean(J, b);
break;
+ case OP_INITPROP:
+ str = js_tostring(J, -2);
+ obj = js_toobject(J, -3);
+ jsR_setproperty(J, obj, str, -1);
+ js_pop(J, 2);
+ break;
+
+ case OP_INITPROP_S:
+ str = ST[*pc++];
+ obj = js_toobject(J, -2);
+ jsR_setproperty(J, obj, str, -1);
+ js_pop(J, 1);
+ break;
+
+ case OP_INITPROP_N:
+ js_pushnumber(J, *pc++);
+ str = js_tostring(J, -2);
+ obj = js_toobject(J, -3);
+ jsR_setproperty(J, obj, str, -1);
+ js_pop(J, 2);
+ break;
+
case OP_GETPROP:
str = js_tostring(J, -1);
obj = js_toobject(J, -2);
@@ -740,7 +762,7 @@
js_rot3pop2(J);
break;
- case OP_GETPROPS:
+ case OP_GETPROP_S:
str = ST[*pc++];
obj = js_toobject(J, -1);
jsR_getproperty(J, obj, str);
@@ -748,13 +770,13 @@
break;
case OP_SETPROP:
- obj = js_toobject(J, -3);
str = js_tostring(J, -2);
+ obj = js_toobject(J, -3);
jsR_setproperty(J, obj, str, -1);
js_rot3pop2(J);
break;
- case OP_SETPROPS:
+ case OP_SETPROP_S:
str = ST[*pc++];
obj = js_toobject(J, -2);
jsR_setproperty(J, obj, str, -1);
@@ -762,13 +784,13 @@
break;
case OP_DELPROP:
- obj = js_toobject(J, -2);
str = js_tostring(J, -1);
+ obj = js_toobject(J, -2);
jsR_delproperty(J, obj, str);
js_pop(J, 2);
break;
- case OP_DELPROPS:
+ case OP_DELPROP_S:
str = ST[*pc++];
obj = js_toobject(J, -1);
jsR_delproperty(J, obj, str);