📄 jsopcode.c
字号:
* do_forinbody: code that uses on it to find the loop-closing * jump (whatever its format, normal or extended), in order to * bound the recursively decompiled loop body. */ sn = js_GetSrcNote(jp->script, pc); JS_ASSERT(!forelem_tail); forelem_tail = pc + js_GetSrcNoteOffset(sn, 0); /* * This gets a little wacky. Only the length of the for loop * 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -