diff --git a/jscompile.c b/jscompile.c index c2e0357..805bb9b 100644 --- a/jscompile.c +++ b/jscompile.c @@ -115,7 +115,7 @@ static void emitnumber(JF, double num) 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 @@ static void carray(JF, js_Ast *list) 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 @@ static void cobject(JF, js_Ast *list) 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 @@ static void cassign(JF, js_Ast *lhs, js_Ast *rhs) 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 @@ static void cassignforin(JF, js_Ast *stm) 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 @@ static void cassignop1(JF, js_Ast *lhs, int dup) 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 @@ static void cassignop2(JF, js_Ast *lhs) 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 @@ static void cdelete(JF, js_Ast *exp) 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 @@ static void ccall(JF, js_Ast *fun, js_Ast *args) 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 @@ static void cexp(JF, js_Ast *exp) 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: diff --git a/jscompile.h b/jscompile.h index ee0e133..9174b6c 100644 --- a/jscompile.h +++ b/jscompile.h @@ -18,7 +18,7 @@ enum js_OpCode OP_NUMBER_0, /* -- 0 */ OP_NUMBER_1, /* -- 1 */ - OP_NUMBER_X, /* -K- K */ + OP_NUMBER_N, /* -K- K */ OP_NUMBER, /* -N- */ OP_STRING, /* -S- */ @@ -43,12 +43,16 @@ enum js_OpCode OP_IN, /* -- */ + OP_INITPROP, /* -- */ + OP_INITPROP_N, /* -- */ + OP_INITPROP_S, /* -- */ + OP_GETPROP, /* -- */ - OP_GETPROPS, /* -S- */ + OP_GETPROP_S, /* -S- */ OP_SETPROP, /* -- */ - OP_SETPROPS, /* -S- */ + OP_SETPROP_S, /* -S- */ OP_DELPROP, /* -- */ - OP_DELPROPS, /* -S- */ + OP_DELPROP_S, /* -S- */ OP_ITERATOR, /* -- */ OP_NEXTITER, /* -- true || false */ diff --git a/jsdump.c b/jsdump.c index 5f84715..c3a69cd 100644 --- a/jsdump.c +++ b/jsdump.c @@ -648,15 +648,17 @@ void jsC_dumpfunction(js_State *J, js_Function *F) 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: diff --git a/jsrun.c b/jsrun.c index cd732bc..beaa499 100644 --- a/jsrun.c +++ b/jsrun.c @@ -688,7 +688,7 @@ static void jsR_run(js_State *J, js_Function *F) 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 @@ static void jsR_run(js_State *J, js_Function *F) 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 @@ static void jsR_run(js_State *J, js_Function *F) 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 @@ static void jsR_run(js_State *J, js_Function *F) 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 @@ static void jsR_run(js_State *J, js_Function *F) 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);