📄 jsopcode.c
字号:
* body PLUS the element-indexing expression is known here, so
* we pass the after-loop pc to the JSOP_ENUMELEM case, which
* is immediately below, to decompile that helper bytecode via
* the 'forelem_done' local.
*
* Since a for..in loop can't nest in the head of another for
* loop, we can use forelem_{tail,done} singletons to remember
* state from JSOP_FORELEM to JSOP_ENUMELEM, thence (via goto)
* to label do_forinbody.
*/
JS_ASSERT(!forelem_done);
forelem_done = pc + GetJumpOffset(pc, pc);
break;
case JSOP_ENUMELEM:
/*
* The stack has the object under the (top) index expression.
* The "rval" property id is underneath those two on the stack.
* The for loop body net and gross lengths can now be adjusted
* to account for the length of the indexing expression that
* came after JSOP_FORELEM and before JSOP_ENUMELEM.
*/
atom = NULL;
xval = POP_STR();
lval = POP_STR();
rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
JS_ASSERT(forelem_tail > pc);
tail = forelem_tail - pc;
forelem_tail = NULL;
JS_ASSERT(forelem_done > pc);
len = forelem_done - pc;
forelem_done = NULL;
goto do_forinbody;
case JSOP_DUP2:
rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-2]);
todo = SprintPut(&ss->sprinter, rval, strlen(rval));
if (todo < 0 || !PushOff(ss, todo, ss->opcodes[ss->top-2]))
return JS_FALSE;
/* FALL THROUGH */
case JSOP_DUP:
rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]);
op = ss->opcodes[ss->top-1];
todo = SprintPut(&ss->sprinter, rval, strlen(rval));
break;
case JSOP_SETARG:
atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
LOCAL_ASSERT(atom);
goto do_setname;
case JSOP_SETVAR:
atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
LOCAL_ASSERT(atom);
goto do_setname;
case JSOP_SETCONST:
case JSOP_SETNAME:
atom = GET_ATOM(cx, jp->script, pc);
do_setname:
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
if (!lval)
return JS_FALSE;
rval = POP_STR();
if (op == JSOP_SETNAME)
(void) PopOff(ss, op);
do_setlval:
sn = js_GetSrcNote(jp->script, pc - 1);
if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
todo = Sprint(&ss->sprinter, "%s %s= %s",
lval, js_CodeSpec[lastop].token, rval);
} else {
sn = js_GetSrcNote(jp->script, pc);
todo = Sprint(&ss->sprinter, "%s%s = %s",
VarPrefix(sn), lval, rval);
}
break;
case JSOP_NEW:
case JSOP_CALL:
case JSOP_EVAL:
#if JS_HAS_LVALUE_RETURN
case JSOP_SETCALL:
#endif
saveop = op;
op = JSOP_NOP; /* turn off parens */
argc = GET_ARGC(pc);
argv = (char **)
JS_malloc(cx, (size_t)(argc + 1) * sizeof *argv);
if (!argv)
return JS_FALSE;
ok = JS_TRUE;
for (i = argc; i > 0; i--) {
argv[i] = JS_strdup(cx, POP_STR());
if (!argv[i]) {
ok = JS_FALSE;
break;
}
}
/* Skip the JSOP_PUSHOBJ-created empty string. */
LOCAL_ASSERT(ss->top >= 2);
(void) PopOff(ss, op);
/* Get the callee's decompiled image in argv[0]. */
argv[0] = JS_strdup(cx, POP_STR());
if (!argv[i])
ok = JS_FALSE;
lval = "(", rval = ")";
if (saveop == JSOP_NEW) {
todo = Sprint(&ss->sprinter, "%s %s%s",
js_new_str, argv[0], lval);
} else {
todo = Sprint(&ss->sprinter, "%s%s",
argv[0], lval);
}
if (todo < 0)
ok = JS_FALSE;
for (i = 1; i <= argc; i++) {
if (!argv[i] ||
Sprint(&ss->sprinter, "%s%s",
argv[i], (i < argc) ? ", " : "") < 0) {
ok = JS_FALSE;
break;
}
}
if (Sprint(&ss->sprinter, rval) < 0)
ok = JS_FALSE;
for (i = 0; i <= argc; i++) {
if (argv[i])
JS_free(cx, argv[i]);
}
JS_free(cx, argv);
if (!ok)
return JS_FALSE;
op = saveop;
#if JS_HAS_LVALUE_RETURN
if (op == JSOP_SETCALL) {
if (!PushOff(ss, todo, op))
return JS_FALSE;
todo = Sprint(&ss->sprinter, "");
}
#endif
break;
case JSOP_DELNAME:
atom = GET_ATOM(cx, jp->script, pc);
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
if (!lval)
return JS_FALSE;
RETRACT(&ss->sprinter, lval);
todo = Sprint(&ss->sprinter, "%s %s", js_delete_str, lval);
break;
case JSOP_DELPROP:
GET_ATOM_QUOTE_AND_FMT("%s %s[%s]", "%s %s.%s", rval);
lval = POP_STR();
todo = Sprint(&ss->sprinter, fmt, js_delete_str, lval, rval);
break;
case JSOP_DELELEM:
xval = POP_STR();
lval = POP_STR();
todo = Sprint(&ss->sprinter, "%s %s[%s]",
js_delete_str, lval, xval);
break;
case JSOP_TYPEOF:
case JSOP_VOID:
rval = POP_STR();
todo = Sprint(&ss->sprinter, "%s %s", cs->name, rval);
break;
case JSOP_INCARG:
case JSOP_DECARG:
atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
LOCAL_ASSERT(atom);
goto do_incatom;
case JSOP_INCVAR:
case JSOP_DECVAR:
atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
LOCAL_ASSERT(atom);
goto do_incatom;
case JSOP_INCNAME:
case JSOP_DECNAME:
atom = GET_ATOM(cx, jp->script, pc);
do_incatom:
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
if (!lval)
return JS_FALSE;
RETRACT(&ss->sprinter, lval);
todo = Sprint(&ss->sprinter, "%s%s",
js_incop_str[!(cs->format & JOF_INC)], lval);
break;
case JSOP_INCPROP:
case JSOP_DECPROP:
GET_ATOM_QUOTE_AND_FMT("%s%s[%s]", "%s%s.%s", rval);
lval = POP_STR();
todo = Sprint(&ss->sprinter, fmt,
js_incop_str[!(cs->format & JOF_INC)],
lval, rval);
break;
case JSOP_INCELEM:
case JSOP_DECELEM:
xval = POP_STR();
lval = POP_STR();
todo = Sprint(&ss->sprinter, "%s%s[%s]",
js_incop_str[!(cs->format & JOF_INC)],
lval, xval);
break;
case JSOP_ARGINC:
case JSOP_ARGDEC:
atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
LOCAL_ASSERT(atom);
goto do_atominc;
case JSOP_VARINC:
case JSOP_VARDEC:
atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
LOCAL_ASSERT(atom);
goto do_atominc;
case JSOP_NAMEINC:
case JSOP_NAMEDEC:
atom = GET_ATOM(cx, jp->script, pc);
do_atominc:
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
if (!lval)
return JS_FALSE;
todo = STR2OFF(&ss->sprinter, lval);
SprintPut(&ss->sprinter,
js_incop_str[!(cs->format & JOF_INC)],
2);
break;
case JSOP_PROPINC:
case JSOP_PROPDEC:
GET_ATOM_QUOTE_AND_FMT("%s[%s]%s", "%s.%s%s", rval);
lval = POP_STR();
todo = Sprint(&ss->sprinter, fmt, lval, rval,
js_incop_str[!(cs->format & JOF_INC)]);
break;
case JSOP_ELEMINC:
case JSOP_ELEMDEC:
xval = POP_STR();
lval = POP_STR();
todo = Sprint(&ss->sprinter, "%s[%s]%s",
lval, xval,
js_incop_str[!(cs->format & JOF_INC)]);
break;
case JSOP_GETPROP2:
op = JSOP_GETPROP;
(void) PopOff(ss, lastop);
/* FALL THROUGH */
case JSOP_GETPROP:
GET_ATOM_QUOTE_AND_FMT("%s[%s]", "%s.%s", rval);
lval = POP_STR();
todo = Sprint(&ss->sprinter, fmt, lval, rval);
break;
case JSOP_SETPROP:
GET_ATOM_QUOTE_AND_FMT("%s[%s] %s= %s", "%s.%s %s= %s", xval);
rval = POP_STR();
lval = POP_STR();
sn = js_GetSrcNote(jp->script, pc - 1);
todo = Sprint(&ss->sprinter, fmt, lval, xval,
(sn && SN_TYPE(sn) == SRC_ASSIGNOP)
? js_CodeSpec[lastop].token
: "",
rval);
break;
case JSOP_GETELEM2:
op = JSOP_GETELEM;
(void) PopOff(ss, lastop);
/* FALL THROUGH */
case JSOP_GETELEM:
op = JSOP_NOP; /* turn off parens */
xval = POP_STR();
op = JSOP_GETELEM;
lval = POP_STR();
if (*xval == '\0')
todo = Sprint(&ss->sprinter, "%s", lval);
else
todo = Sprint(&ss->sprinter, "%s[%s]", lval, xval);
break;
case JSOP_SETELEM:
op = JSOP_NOP; /* turn off parens */
rval = POP_STR();
xval = POP_STR();
op = JSOP_SETELEM;
lval = POP_STR();
if (*xval == '\0')
goto do_setlval;
sn = js_GetSrcNote(jp->script, pc - 1);
todo = Sprint(&ss->sprinter, "%s[%s] %s= %s",
lval, xval,
(sn && SN_TYPE(sn) == SRC_ASSIGNOP)
? js_CodeSpec[lastop].token
: "",
rval);
break;
case JSOP_ARGSUB:
i = (jsint) GET_ATOM_INDEX(pc);
todo = Sprint(&ss->sprinter, "%s[%d]",
js_arguments_str, (int) i);
break;
case JSOP_ARGCNT:
todo = Sprint(&ss->sprinter, "%s.%s",
js_arguments_str, js_length_str);
break;
case JSOP_GETARG:
atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc));
LOCAL_ASSERT(atom);
goto do_name;
case JSOP_GETVAR:
atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc));
LOCAL_ASSERT(atom);
goto do_name;
case JSOP_NAME:
atom = GET_ATOM(cx, jp->script, pc);
do_name:
sn = js_GetSrcNote(jp->script, pc);
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
if (!rval)
return JS_FALSE;
RETRACT(&ss->sprinter, rval);
todo = Sprint(&ss->sprinter, "%s%s", VarPrefix(sn), rval);
break;
case JSOP_UINT16:
i = (jsint) GET_ATOM_INDEX(pc);
todo = Sprint(&ss->sprinter, "%u", (unsigned) i);
break;
case JSOP_NUMBER:
atom = GET_ATOM(cx, jp->script, pc);
val = ATOM_KEY(atom);
if (JSVAL_IS_INT(val)) {
long ival = (long)JSVAL_TO_INT(val);
todo = Sprint(&ss->sprinter, "%ld", ival);
} else {
char buf[DTOSTR_STANDARD_BUFFER_SIZE];
char *numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD,
0, *JSVAL_TO_DOUBLE(val));
if (!numStr) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
todo = Sprint(&ss->sprinter, numStr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -