Add 'string' operand versions of get/set/del property opcodes.

This commit is contained in:
Tor Andersson
2014-01-23 17:08:59 +01:00
parent 6f4c2143e5
commit 40572172a5
4 changed files with 62 additions and 24 deletions
+21 -24
View File
@@ -197,15 +197,18 @@ static void cobject(JF, js_Ast *list)
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)
emitstring(J, F, OP_STRING, prop->string);
else if (prop->type == AST_NUMBER)
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);
} else if (prop->type == AST_NUMBER) {
emitnumber(J, F, prop->number);
else
cexp(J, F, kv->b);
emit(J, F, OP_SETPROP);
emit(J, F, OP_POP);
} else {
jsC_error(J, list, "illegal property name in object initializer");
cexp(J, F, kv->b);
emit(J, F, OP_SETPROP);
emit(J, F, OP_POP);
}
} else {
// TODO: set/get
jsC_error(J, kv, "property setters and getters are not implemented");
@@ -240,9 +243,8 @@ static void cassign(JF, js_Ast *lhs, js_Ast *rhs)
break;
case EXP_MEMBER:
cexp(J, F, lhs->a);
emitstring(J, F, OP_STRING, lhs->b->string);
cexp(J, F, rhs);
emit(J, F, OP_SETPROP);
emitstring(J, F, OP_SETPROPS, lhs->b->string);
break;
default:
jsC_error(J, lhs, "invalid l-value in assignment");
@@ -276,9 +278,8 @@ static void cassignforin(JF, js_Ast *stm)
break;
case EXP_MEMBER:
cexp(J, F, lhs->a);
emitstring(J, F, OP_STRING, lhs->b->string);
emit(J, F, OP_ROT3);
emit(J, F, OP_SETPROP);
emit(J, F, OP_ROT2);
emitstring(J, F, OP_SETPROPS, lhs->b->string);
emit(J, F, OP_POP);
break;
default:
@@ -303,10 +304,9 @@ static void cassignop1(JF, js_Ast *lhs, int dup)
break;
case EXP_MEMBER:
cexp(J, F, lhs->a);
emitstring(J, F, OP_STRING, lhs->b->string);
emit(J, F, OP_DUP2);
emit(J, F, OP_GETPROP);
if (dup) emit(J, F, OP_DUP1ROT4);
emit(J, F, OP_DUP);
emitstring(J, F, OP_GETPROPS, lhs->b->string);
if (dup) emit(J, F, OP_DUP1ROT3);
break;
default:
jsC_error(J, lhs, "invalid l-value in assignment");
@@ -321,9 +321,9 @@ static void cassignop2(JF, js_Ast *lhs)
emitstring(J, F, OP_SETVAR, lhs->string);
break;
case EXP_INDEX:
break;
case EXP_MEMBER:
case EXP_CALL:
emit(J, F, OP_SETPROP);
emitstring(J, F, OP_SETPROPS, lhs->b->string);
break;
default:
jsC_error(J, lhs, "invalid l-value in assignment");
@@ -352,8 +352,7 @@ static void cdelete(JF, js_Ast *exp)
break;
case EXP_MEMBER:
cexp(J, F, exp->a);
emitstring(J, F, OP_STRING, exp->b->string);
emit(J, F, OP_DELPROP);
emitstring(J, F, OP_DELPROPS, exp->b->string);
break;
default:
jsC_error(J, exp, "invalid l-value in delete expression");
@@ -375,8 +374,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_STRING, fun->b->string);
emit(J, F, OP_GETPROP);
emitstring(J, F, OP_GETPROPS, fun->b->string);
emit(J, F, OP_ROT2);
break;
default:
@@ -429,8 +427,7 @@ static void cexp(JF, js_Ast *exp)
case EXP_MEMBER:
cexp(J, F, exp->a);
emitstring(J, F, OP_STRING, exp->b->string);
emit(J, F, OP_GETPROP);
emitstring(J, F, OP_GETPROPS, exp->b->string);
break;
case EXP_CALL:
+5
View File
@@ -13,6 +13,7 @@ enum js_OpCode
OP_ROT3, /* A B C -- C A B */
OP_ROT2POP1, /* A B -- B */
OP_ROT3POP2, /* A B C -- C */
OP_DUP1ROT3, /* A B -- B A B */
OP_DUP1ROT4, /* A B C -- C A B C */
OP_NUMBER_0, /* -- 0 */
@@ -41,9 +42,13 @@ enum js_OpCode
OP_DELVAR, /* -S- <success> */
OP_IN, /* <name> <obj> -- <exists?> */
OP_GETPROP, /* <obj> <name> -- <value> */
OP_GETPROPS, /* <obj> -S- <value> */
OP_SETPROP, /* <obj> <name> <value> -- <value> */
OP_SETPROPS, /* <obj> <value> -S- <value> */
OP_DELPROP, /* <obj> <name> -- <success> */
OP_DELPROPS, /* <obj> -S- <success> */
OP_ITERATOR, /* <obj> -- <iobj> */
OP_NEXTITER, /* <iobj> -- <iobj> <name> true || false */
+3
View File
@@ -648,6 +648,9 @@ 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:
pc(' ');
ps(F->strtab[*p++]);
break;
+33
View File
@@ -215,6 +215,15 @@ void js_rot3pop2(js_State *J)
TOP -= 2;
}
void js_dup1rot3(js_State *J)
{
/* A B -> B A B */
STACK[TOP] = STACK[TOP-1]; /* A B B */
STACK[TOP-1] = STACK[TOP-2]; /* A A B */
STACK[TOP-2] = STACK[TOP]; /* B A B */
++TOP;
}
void js_dup1rot4(js_State *J)
{
/* A B C -> C A B C */
@@ -526,6 +535,7 @@ static void jsR_run(js_State *J, js_Function *F)
case OP_ROT3: js_rot3(J); break;
case OP_ROT2POP1: js_rot2pop1(J); break;
case OP_ROT3POP2: js_rot3pop2(J); break;
case OP_DUP1ROT3: js_dup1rot3(J); break;
case OP_DUP1ROT4: js_dup1rot4(J); break;
case OP_NUMBER_0: js_pushnumber(J, 0); break;
@@ -596,6 +606,19 @@ static void jsR_run(js_State *J, js_Function *F)
js_pushundefined(J);
break;
case OP_GETPROPS:
str = ST[*pc++];
js_getproperty(J, -1, str);
obj = js_toobject(J, -2);
ref = jsV_getproperty(J, obj, str);
js_pop(J, 2);
if (ref)
js_pushvalue(J, ref->value);
else
js_pushundefined(J);
break;
case OP_SETPROP:
obj = js_toobject(J, -3);
str = js_tostring(J, -2);
@@ -605,7 +628,17 @@ static void jsR_run(js_State *J, js_Function *F)
js_rot3pop2(J);
break;
case OP_SETPROPS:
str = ST[*pc++];
obj = js_toobject(J, -2);
ref = jsV_setproperty(J, obj, str);
if (ref)
ref->value = js_tovalue(J, -1);
js_rot2pop1(J);
break;
// OP_DELPROP
// OP_DELPROPS
case OP_ITERATOR:
obj = jsV_newiterator(J, js_toobject(J, -1));