mirror of
https://github.com/ccxvii/mujs.git
synced 2026-09-22 15:13:35 +08:00
Add 'string' operand versions of get/set/del property opcodes.
This commit is contained in:
+21
-24
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user