⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsopcode.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    saveop = JSOP_NOP;    sn = NULL;    rval = NULL;#if JS_HAS_XML_SUPPORT    foreach = inXML = quoteAttr = JS_FALSE;#endif    while (nb < 0 || pc < endpc) {        /*         * Move saveop to lastop so prefixed bytecodes can take special action         * while sharing maximal code.  Set op and saveop to the new bytecode,         * use op in POP_STR to trigger automatic parenthesization, but push         * saveop at the bottom of the loop if this op pushes.  Thus op may be         * set to nop or otherwise mutated to suppress auto-parens.         */        lastop = saveop;        op = saveop = (JSOp) *pc;        cs = &js_CodeSpec[saveop];        len = oplen = cs->length;        if (nb < 0 && -(nb + 1) == (intN)ss->top - cs->nuses + cs->ndefs)            return pc;        if (pc + oplen == jp->dvgfence) {            JSStackFrame *fp;            uint32 format, mode, type;            /*             * Rewrite non-get ops to their "get" format if the error is in             * the bytecode at pc, so we don't decompile more than the error             * expression.             */            for (fp = cx->fp; fp && !fp->script; fp = fp->down)                continue;            format = cs->format;            if (((fp && pc == fp->pc) ||                 (pc == startpc && cs->nuses != 0)) &&                format & (JOF_SET|JOF_DEL|JOF_INCDEC|JOF_IMPORT|JOF_FOR)) {                mode = (format & JOF_MODEMASK);                if (mode == JOF_NAME) {                    /*                     * JOF_NAME does not imply JOF_CONST, so we must check for                     * the QARG and QVAR format types, and translate those to                     * JSOP_GETARG or JSOP_GETVAR appropriately, instead of to                     * JSOP_NAME.                     */                    type = format & JOF_TYPEMASK;                    op = (type == JOF_QARG)                         ? JSOP_GETARG                         : (type == JOF_QVAR)                         ? JSOP_GETVAR                         : (type == JOF_LOCAL)                         ? JSOP_GETLOCAL                         : JSOP_NAME;                    i = cs->nuses - js_CodeSpec[op].nuses;                    while (--i >= 0)                        PopOff(ss, JSOP_NOP);                } else {                    /*                     * We must replace the faulting pc's bytecode with a                     * corresponding JSOP_GET* code.  For JSOP_SET{PROP,ELEM},                     * we must use the "2nd" form of JSOP_GET{PROP,ELEM}, to                     * throw away the assignment op's right-hand operand and                     * decompile it as if it were a GET of its left-hand                     * operand.                     */                    if (mode == JOF_PROP) {                        op = (format & JOF_SET) ? JSOP_GETPROP2 : JSOP_GETPROP;                    } else if (mode == JOF_ELEM) {                        op = (format & JOF_SET) ? JSOP_GETELEM2 : JSOP_GETELEM;                    } else {                        /*                         * Zero mode means precisely that op is uncategorized                         * for our purposes, so we must write per-op special                         * case code here.                         */                        switch (op) {                          case JSOP_ENUMELEM:                          case JSOP_ENUMCONSTELEM:                            op = JSOP_GETELEM;                            break;#if JS_HAS_LVALUE_RETURN                          case JSOP_SETCALL:                            op = JSOP_CALL;                            break;#endif                          default:                            LOCAL_ASSERT(0);                        }                    }                }            }            saveop = op;            if (op >= JSOP_LIMIT) {                switch (op) {                  case JSOP_GETPROP2:                    saveop = JSOP_GETPROP;                    break;                  case JSOP_GETELEM2:                    saveop = JSOP_GETELEM;                    break;                  default:;                }            }            LOCAL_ASSERT(js_CodeSpec[saveop].length == oplen);            jp->dvgfence = NULL;        }        if (cs->token) {            switch (cs->nuses) {              case 2:                sn = js_GetSrcNote(jp->script, pc);                if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {                    /*                     * Avoid over-parenthesizing y in x op= y based on its                     * expansion: x = x op y (replace y by z = w to see the                     * problem).                     */                    op = pc[oplen];                    LOCAL_ASSERT(op != saveop);                }                rval = POP_STR();                lval = POP_STR();                if (op != saveop) {                    /* Print only the right operand of the assignment-op. */                    todo = SprintCString(&ss->sprinter, rval);                    op = saveop;                } else if (!inXML) {                    todo = Sprint(&ss->sprinter, "%s %s %s",                                  lval, cs->token, rval);                } else {                    /* In XML, just concatenate the two operands. */                    LOCAL_ASSERT(op == JSOP_ADD);                    todo = Sprint(&ss->sprinter, ss_format, lval, rval);                }                break;              case 1:                rval = POP_STR();                todo = Sprint(&ss->sprinter, ss_format, cs->token, rval);                break;              case 0:                todo = SprintCString(&ss->sprinter, cs->token);                break;              default:                todo = -2;                break;            }        } else {            switch (op) {#define BEGIN_LITOPX_CASE(OP)                                                 \              case OP:                                                        \                atomIndex = GET_ATOM_INDEX(pc);                               \              do_##OP:                                                        \                atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);#define END_LITOPX_CASE                                                       \                break;              case JSOP_NOP:                /*                 * Check for a do-while loop, a for-loop with an empty                 * initializer part, a labeled statement, a function                 * definition, or try/finally.                 */                sn = js_GetSrcNote(jp->script, pc);                todo = -2;                switch (sn ? SN_TYPE(sn) : SRC_NULL) {                  case SRC_WHILE:                    js_printf(SET_MAYBE_BRACE(jp), "\tdo {\n");                    jp->indent += 4;                    break;                  case SRC_FOR:                    rval = "";                  do_forloop:                    /* Skip the JSOP_NOP or JSOP_POP bytecode. */                    pc++;                    /* Get the cond, next, and loop-closing tail offsets. */                    cond = js_GetSrcNoteOffset(sn, 0);                    next = js_GetSrcNoteOffset(sn, 1);                    tail = js_GetSrcNoteOffset(sn, 2);                    LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);                    /* Print the keyword and the possibly empty init-part. */                    js_printf(jp, "\tfor (%s;", rval);                    if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) {                        /* Decompile the loop condition. */                        DECOMPILE_CODE(pc, cond);                        js_printf(jp, " %s", POP_STR());                    }                    /* Need a semicolon whether or not there was a cond. */                    js_puts(jp, ";");                    if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) {                        /* Decompile the loop updater. */                        DECOMPILE_CODE(pc + next, tail - next - 1);                        js_printf(jp, " %s", POP_STR());                    }                    /* Do the loop body. */                    js_printf(SET_MAYBE_BRACE(jp), ") {\n");                    jp->indent += 4;                    oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;                    DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);                    jp->indent -= 4;                    js_printf(jp, "\t}\n");                    /* Set len so pc skips over the entire loop. */                    len = tail + js_CodeSpec[pc[tail]].length;                    break;                  case SRC_LABEL:                    atom = js_GetAtom(cx, &jp->script->atomMap,                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));                    jp->indent -= 4;                    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);                    if (!rval)                        return NULL;                    RETRACT(&ss->sprinter, rval);                    js_printf(CLEAR_MAYBE_BRACE(jp), "\t%s:\n", rval);                    jp->indent += 4;                    break;                  case SRC_LABELBRACE:                    atom = js_GetAtom(cx, &jp->script->atomMap,                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));                    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);                    if (!rval)                        return NULL;                    RETRACT(&ss->sprinter, rval);                    js_printf(CLEAR_MAYBE_BRACE(jp), "\t%s: {\n", rval);                    jp->indent += 4;                    break;                  case SRC_ENDBRACE:                    jp->indent -= 4;                    js_printf(jp, "\t}\n");                    break;                  case SRC_FUNCDEF:                    atom = js_GetAtom(cx, &jp->script->atomMap,                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));                    LOCAL_ASSERT(ATOM_IS_OBJECT(atom));                  do_function:                    obj = ATOM_TO_OBJECT(atom);                    fun = (JSFunction *) JS_GetPrivate(cx, obj);                    jp2 = js_NewPrinter(cx, JS_GetFunctionName(fun),                                        jp->indent, jp->pretty);                    if (!jp2)                        return NULL;                    jp2->scope = jp->scope;                    js_puts(jp2, "\n");                    ok = js_DecompileFunction(jp2, fun);                    if (ok) {                        js_puts(jp2, "\n");                        str = js_GetPrinterOutput(jp2);                        if (str)                            js_printf(jp, "%s\n", JS_GetStringBytes(str));                        else                            ok = JS_FALSE;                    }                    js_DestroyPrinter(jp2);                    if (!ok)                        return NULL;                    break;                  case SRC_BRACE:                    js_printf(CLEAR_MAYBE_BRACE(jp), "\t{\n");                    jp->indent += 4;                    len = js_GetSrcNoteOffset(sn, 0);                    DECOMPILE_CODE(pc + oplen, len - oplen);                    jp->indent -= 4;                    js_printf(jp, "\t}\n");                    break;                  default:;                }                break;              case JSOP_GROUP:                cs = &js_CodeSpec[lastop];                if ((cs->prec != 0 &&                     cs->prec == js_CodeSpec[pc[JSOP_GROUP_LENGTH]].prec) ||                    pc[JSOP_GROUP_LENGTH] == JSOP_PUSHOBJ ||                    pc[JSOP_GROUP_LENGTH] == JSOP_DUP) {                    /*                     * Force parens if this JSOP_GROUP forced re-association                     * against precedence, or if this is a call or constructor                     * expression, or if it is destructured (JSOP_DUP).                     *                     * This is necessary to handle the operator new grammar,                     * by which new x(y).z means (new x(y))).z.  For example                     * new (x(y).z) must decompile with the constructor                     * parenthesized, but normal precedence has JSOP_GETPROP                     * (for the final .z) higher than JSOP_NEW.  In general,                     * if the call or constructor expression is parenthesized,                     * we preserve parens.                     */                    op = JSOP_NAME;                    rval = POP_STR();                    todo = SprintCString(&ss->sprinter, rval);                } else {                    /*                     * Don't explicitly parenthesize -- just fix the top                     * opcode so that the auto-parens magic in PopOff can do                     * its thing.                     */                    LOCAL_ASSERT(ss->top != 0);                    ss->opcodes[ss->top-1] = saveop = lastop;                    todo = -2;                }                break;              case JSOP_STARTITER:                todo = -2;                break;              case JSOP_PUSH:#if JS_HAS_DESTRUCTURING                sn = js_GetSrcNote(jp->script, pc);                if (sn && SN_TYPE(sn) == SRC_GROUPASSIGN) {                    pc = DecompileGroupAssignment(ss, pc, endpc, sn, &todo);                    if (!pc)                        return NULL;                    LOCAL_ASSERT(*pc == JSOP_SETSP);                    len = oplen = JSOP_SETSP_LENGTH;                    goto end_groupassignment;                }#endif                /* FALL THROUGH */              case JSOP_PUSHOBJ:              case JSOP_BINDNAME:              do_JSOP_BINDNAME:                todo = Sprint(&ss->sprinter, "");                break;              case JSOP_TRY:                js_printf(CLEAR_MAYBE_BRACE(jp), "\ttry {\n");                jp->indent += 4;                todo = -2;                break;              case JSOP_FINALLY:                jp->indent -= 4;                js_printf(CLEAR_MAYBE_BRACE(jp), "\t} finally {\n");                jp->indent += 4;                /*                 * We must push an empty string placeholder for gosub's return                 * address, popped by JSOP_RETSUB and counted by script->depth                 * but not by ss->top (see JSOP_SETSP, below).                 */                todo = Sprint(&ss->sprinter, exception_cookie);                if (todo < 0 || !PushOff(ss, todo, op))                    return NULL;                todo = Sprint(&ss->sprinter, retsub_pc_cookie);                break;              case JSOP_RETSUB:                rval = POP_STR();                LOCAL_ASSERT(strcmp(rval, retsub_pc_cookie) == 0);                lval = POP_STR();                LOCAL_ASSERT(strcmp(lval, exception_cookie) == 0);                todo = -2;                break;              case JSOP_SWAP:                /*                 * We don't generate this opcode currently, and previously we                 * did not need to decompile it.  If old, serialized bytecode                 * uses it still, we should fall through and set todo = -2.                 */                /* FALL THROUGH */              case JSOP_GOSUB:              case JSOP_GOSUBX:                /*                 * JSOP_GOSUB and GOSUBX have no effect on the decompiler's                 * string stack because the next op in bytecode order finds                 * the stack balanced by a JSOP_RETSUB executed elsewhere.                 */                todo = -2;                break;              case JSOP_SETSP:           

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -