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

📄 jsopcode.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
      case JSOP_SETLOCALPOP:        i = GET_UINT16(pc);        atom = NULL;        lval = NULL;        if (op == JSOP_SETARG)            atom = GetSlotAtom(jp, js_GetArgument, i);        else if (op == JSOP_SETVAR)            atom = GetSlotAtom(jp, js_GetLocalVariable, i);        else if (op == JSOP_SETGVAR)            atom = GET_ATOM(cx, jp->script, pc);        else            lval = GetLocal(ss, i);        if (atom)            lval = js_AtomToPrintableString(cx, atom);        LOCAL_ASSERT(lval);        todo = SprintCString(&ss->sprinter, lval);        if (op != JSOP_SETLOCALPOP) {            pc += oplen;            if (pc == endpc)                return pc;            LOAD_OP_DATA(pc);            if (op == JSOP_SETSP)                return pc;            LOCAL_ASSERT(op == JSOP_POP);        }        break;      default:        /*         * We may need to auto-parenthesize the left-most value decompiled         * here, so add back PAREN_SLOP temporarily.  Then decompile until the         * opcode that would reduce the stack depth to (ss->top-1), which we         * pass to Decompile encoded as -(ss->top-1) - 1 or just -ss->top for         * the nb parameter.         */        todo = ss->sprinter.offset;        ss->sprinter.offset = todo + PAREN_SLOP;        pc = Decompile(ss, pc, -ss->top);        if (!pc)            return NULL;        if (pc == endpc)            return pc;        LOAD_OP_DATA(pc);        LOCAL_ASSERT(op == JSOP_ENUMELEM || op == JSOP_ENUMCONSTELEM);        xval = PopStr(ss, JSOP_NOP);        lval = PopStr(ss, JSOP_GETPROP);        ss->sprinter.offset = todo;        if (*lval == '\0') {            /* lval is from JSOP_BINDNAME, so just print xval. */            todo = SprintCString(&ss->sprinter, xval);        } else if (*xval == '\0') {            /* xval is from JSOP_SETCALL or JSOP_BINDXMLNAME, print lval. */            todo = SprintCString(&ss->sprinter, lval);        } else {            todo = Sprint(&ss->sprinter,                          (js_CodeSpec[ss->opcodes[ss->top+1]].format                           & JOF_XMLNAME)                          ? "%s.%s"                          : "%s[%s]",                          lval, xval);        }        break;    }    if (todo < 0)        return NULL;    LOCAL_ASSERT(pc < endpc);    pc += oplen;    return pc;}/* * Starting with a SRC_DESTRUCT-annotated JSOP_DUP, decompile a destructuring * left-hand side object or array initialiser, including nested destructuring * initialisers.  On successful return, the decompilation will be pushed on ss * and the return value will point to the POP or GROUP bytecode following the * destructuring expression. * * At any point, if pc is equal to endpc and would otherwise advance, we stop * immediately and return endpc. */static jsbytecode *DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc){    ptrdiff_t head, todo;    JSContext *cx;    JSPrinter *jp;    JSOp op, saveop;    const JSCodeSpec *cs;    uintN oplen;    jsint i, lasti;    jsdouble d;    const char *lval;    jsbytecode *pc2;    jsatomid atomIndex;    JSAtom *atom;    jssrcnote *sn;    JSString *str;    JSBool hole;    LOCAL_ASSERT(*pc == JSOP_DUP);    pc += JSOP_DUP_LENGTH;    /*     * Set head so we can rewrite '[' to '{' as needed.  Back up PAREN_SLOP     * chars so the destructuring decompilation accumulates contiguously in     * ss->sprinter starting with "[".     */    head = SprintPut(&ss->sprinter, "[", 1);    if (head < 0 || !PushOff(ss, head, JSOP_NOP))        return NULL;    ss->sprinter.offset -= PAREN_SLOP;    LOCAL_ASSERT(head == ss->sprinter.offset - 1);    LOCAL_ASSERT(*OFF2STR(&ss->sprinter, head) == '[');    cx = ss->sprinter.context;    jp = ss->printer;    lasti = -1;    while (pc < endpc) {        LOAD_OP_DATA(pc);        saveop = op;        switch (op) {          case JSOP_POP:            pc += oplen;            goto out;          /* Handle the optimized number-pushing opcodes. */          case JSOP_ZERO:   d = i = 0; goto do_getelem;          case JSOP_ONE:    d = i = 1; goto do_getelem;          case JSOP_UINT16: d = i = GET_UINT16(pc); goto do_getelem;          case JSOP_UINT24: d = i = GET_UINT24(pc); goto do_getelem;          /* Handle the extended literal form of JSOP_NUMBER. */          case JSOP_LITOPX:            atomIndex = GET_LITERAL_INDEX(pc);            pc2 = pc + 1 + LITERAL_INDEX_LEN;            op = *pc2;            LOCAL_ASSERT(op == JSOP_NUMBER);            goto do_getatom;          case JSOP_NUMBER:            atomIndex = GET_ATOM_INDEX(pc);          do_getatom:            atom = js_GetAtom(cx, &jp->script->atomMap, atomIndex);            d = *ATOM_TO_DOUBLE(atom);            LOCAL_ASSERT(JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d));            i = (jsint)d;          do_getelem:            sn = js_GetSrcNote(jp->script, pc);            pc += oplen;            if (pc == endpc)                return pc;            LOAD_OP_DATA(pc);            LOCAL_ASSERT(op == JSOP_GETELEM);            /* Distinguish object from array by opcode or source note. */            if (saveop == JSOP_LITERAL ||                (sn && SN_TYPE(sn) == SRC_INITPROP)) {                *OFF2STR(&ss->sprinter, head) = '{';                if (Sprint(&ss->sprinter, "%g: ", d) < 0)                    return NULL;            } else {                /* Sanity check for the gnarly control flow above. */                LOCAL_ASSERT(i == d);                /* Fill in any holes (holes at the end don't matter). */                while (++lasti < i) {                    if (SprintPut(&ss->sprinter, ", ", 2) < 0)                        return NULL;                }            }            break;          case JSOP_LITERAL:            atomIndex = GET_LITERAL_INDEX(pc);            goto do_getatom;          case JSOP_GETPROP:            *OFF2STR(&ss->sprinter, head) = '{';            atom = GET_ATOM(cx, jp->script, pc);            str = ATOM_TO_STRING(atom);            if (!QuoteString(&ss->sprinter, str,                             js_IsIdentifier(str) ? 0 : (jschar)'\'')) {                return NULL;            }            if (SprintPut(&ss->sprinter, ": ", 2) < 0)                return NULL;            break;          default:            LOCAL_ASSERT(0);        }        pc += oplen;        if (pc == endpc)            return pc;        /*         * Decompile the left-hand side expression whose bytecode starts at pc         * and continues for a bounded number of bytecodes or stack operations         * (and which in any event stops before endpc).         */        pc = DecompileDestructuringLHS(ss, pc, endpc, &hole);        if (!pc)            return NULL;        if (pc == endpc || *pc != JSOP_DUP)            break;        /*         * Check for SRC_DESTRUCT on this JSOP_DUP, which would mean another         * destructuring initialiser abuts this one, and we should stop.  This         * happens with source of the form '[a] = [b] = c'.         */        sn = js_GetSrcNote(jp->script, pc);        if (sn && SN_TYPE(sn) == SRC_DESTRUCT)            break;        if (!hole && SprintPut(&ss->sprinter, ", ", 2) < 0)            return NULL;        pc += JSOP_DUP_LENGTH;    }out:    lval = OFF2STR(&ss->sprinter, head);    todo = SprintPut(&ss->sprinter, (*lval == '[') ? "]" : "}", 1);    if (todo < 0)        return NULL;    return pc;}static jsbytecode *DecompileGroupAssignment(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc,                         jssrcnote *sn, ptrdiff_t *todop){    JSOp op;    const JSCodeSpec *cs;    uintN oplen, start, end, i;    ptrdiff_t todo;    JSBool hole;    const char *rval;    LOAD_OP_DATA(pc);    LOCAL_ASSERT(op == JSOP_PUSH || op == JSOP_GETLOCAL);    todo = Sprint(&ss->sprinter, "%s[", VarPrefix(sn));    if (todo < 0 || !PushOff(ss, todo, JSOP_NOP))        return NULL;    ss->sprinter.offset -= PAREN_SLOP;    for (;;) {        pc += oplen;        if (pc == endpc)            return pc;        pc = DecompileDestructuringLHS(ss, pc, endpc, &hole);        if (!pc)            return NULL;        if (pc == endpc)            return pc;        LOAD_OP_DATA(pc);        if (op != JSOP_PUSH && op != JSOP_GETLOCAL)            break;        if (!hole && SprintPut(&ss->sprinter, ", ", 2) < 0)            return NULL;    }    LOCAL_ASSERT(op == JSOP_SETSP);    if (SprintPut(&ss->sprinter, "] = [", 5) < 0)        return NULL;    start = GET_UINT16(pc);    end = ss->top - 1;    for (i = start; i < end; i++) {        rval = GetStr(ss, i);        if (Sprint(&ss->sprinter, "%s%s",                   (i == start) ? "" : ", ",                   (i == end - 1 && *rval == '\0') ? ", " : rval) < 0) {            return NULL;        }    }    if (SprintPut(&ss->sprinter, "]", 1) < 0)        return NULL;    ss->sprinter.offset = ss->offsets[i];    ss->top = start;    *todop = todo;    return pc;}#undef LOCAL_ASSERT#undef LOAD_OP_DATA#endif /* JS_HAS_DESTRUCTURING *//* * If nb is non-negative, decompile nb bytecodes starting at pc.  Otherwise * the decompiler starts at pc and continues until it reaches an opcode for * which decompiling would result in the stack depth equaling -(nb + 1). */static jsbytecode *Decompile(SprintStack *ss, jsbytecode *pc, intN nb){    JSContext *cx;    JSPrinter *jp, *jp2;    jsbytecode *startpc, *endpc, *pc2, *done, *forelem_tail, *forelem_done;    ptrdiff_t tail, todo, len, oplen, cond, next;    JSOp op, lastop, saveop;    const JSCodeSpec *cs;    jssrcnote *sn, *sn2;    const char *lval, *rval, *xval, *fmt;    jsint i, argc;    char **argv;    jsatomid atomIndex;    JSAtom *atom;    JSObject *obj;    JSFunction *fun;    JSString *str;    JSBool ok;#if JS_HAS_XML_SUPPORT    JSBool foreach, inXML, quoteAttr;#else#define inXML JS_FALSE#endif    jsval val;    int stackDummy;    static const char exception_cookie[] = "/*EXCEPTION*/";    static const char retsub_pc_cookie[] = "/*RETSUB_PC*/";    static const char forelem_cookie[]   = "/*FORELEM*/";    static const char with_cookie[]      = "/*WITH*/";    static const char dot_format[]       = "%s.%s";    static const char index_format[]     = "%s[%s]";    static const char predot_format[]    = "%s%s.%s";    static const char postdot_format[]   = "%s.%s%s";    static const char preindex_format[]  = "%s%s[%s]";    static const char postindex_format[] = "%s[%s]%s";    static const char ss_format[]        = "%s%s";/* * Local macros */#define DECOMPILE_CODE(pc,nb)   if (!Decompile(ss, pc, nb)) return NULL#define POP_STR()               PopStr(ss, op)#define LOCAL_ASSERT(expr)      LOCAL_ASSERT_RV(expr, JS_FALSE)/* * Callers know that ATOM_IS_STRING(atom), and we leave it to the optimizer to * common ATOM_TO_STRING(atom) here and near the call sites. */#define ATOM_IS_IDENTIFIER(atom) js_IsIdentifier(ATOM_TO_STRING(atom))#define ATOM_IS_KEYWORD(atom)                                                 \            (js_CheckKeyword(JSSTRING_CHARS(ATOM_TO_STRING(atom)),            \                             JSSTRING_LENGTH(ATOM_TO_STRING(atom))) != TOK_EOF)/* * Given an atom already fetched from jp->script's atom map, quote/escape its * string appropriately into rval, and select fmt from the quoted and unquoted * alternatives. */#define GET_QUOTE_AND_FMT(qfmt, ufmt, rval)                                   \    JS_BEGIN_MACRO                                                            \        jschar quote_;                                                        \        if (!ATOM_IS_IDENTIFIER(atom)) {                                      \            quote_ = '\'';                                                    \            fmt = qfmt;                                                       \        } else {                                                              \            quote_ = 0;                                                       \            fmt = ufmt;                                                       \        }                                                                     \        rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), quote_);      \        if (!rval)                                                            \            return NULL;                                                      \    JS_END_MACRO/* * Get atom from jp->script's atom map, quote/escape its string appropriately * into rval, and select fmt from the quoted and unquoted alternatives. */#define GET_ATOM_QUOTE_AND_FMT(qfmt, ufmt, rval)                              \    JS_BEGIN_MACRO                                                            \        atom = GET_ATOM(cx, jp->script, pc);                                  \        GET_QUOTE_AND_FMT(qfmt, ufmt, rval);                                  \    JS_END_MACRO    cx = ss->sprinter.context;    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);        return NULL;    }    jp = ss->printer;    startpc = pc;    endpc = (nb < 0) ? jp->script->code + jp->script->length : pc + nb;    forelem_tail = forelem_done = NULL;    tail = -1;    todo = -2;                  /* NB: different from Sprint() error return. */

⌨️ 快捷键说明

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