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

📄 jsopcode.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
        }        str = js_DecompileValueGenerator(ss->sprinter.context, off,                                         JSVAL_NULL, NULL);        if (!str)            return 0;        off = SprintCString(&ss->sprinter, JS_GetStringBytes(str));        if (off < 0)            off = 0;        ss->offsets[i] = off;    }    return off;}static const char *GetStr(SprintStack *ss, uintN i){    ptrdiff_t off;    /*     * Must call GetOff before using ss->sprinter.base, since it may be null     * until bootstrapped by GetOff.     */    off = GetOff(ss, i);    return OFF2STR(&ss->sprinter, off);}/* Gap between stacked strings to allow for insertion of parens and commas. */#define PAREN_SLOP      (2 + 1)/* * These pseudo-ops help js_DecompileValueGenerator decompile JSOP_SETNAME, * JSOP_SETPROP, and JSOP_SETELEM, respectively.  They are never stored in * bytecode, so they don't preempt valid opcodes. */#define JSOP_GETPROP2   256#define JSOP_GETELEM2   257static JSBoolPushOff(SprintStack *ss, ptrdiff_t off, JSOp op){    uintN top;    if (!SprintAlloc(&ss->sprinter, PAREN_SLOP))        return JS_FALSE;    /* ss->top points to the next free slot; be paranoid about overflow. */    top = ss->top;    JS_ASSERT(top < ss->printer->script->depth);    if (top >= ss->printer->script->depth) {        JS_ReportOutOfMemory(ss->sprinter.context);        return JS_FALSE;    }    /* The opcodes stack must contain real bytecodes that index js_CodeSpec. */    ss->offsets[top] = off;    ss->opcodes[top] = (op == JSOP_GETPROP2) ? JSOP_GETPROP                     : (op == JSOP_GETELEM2) ? JSOP_GETELEM                     : (jsbytecode) op;    ss->top = ++top;    memset(OFF2STR(&ss->sprinter, ss->sprinter.offset), 0, PAREN_SLOP);    ss->sprinter.offset += PAREN_SLOP;    return JS_TRUE;}static ptrdiff_tPopOff(SprintStack *ss, JSOp op){    uintN top;    const JSCodeSpec *cs, *topcs;    ptrdiff_t off;    /* ss->top points to the next free slot; be paranoid about underflow. */    top = ss->top;    JS_ASSERT(top != 0);    if (top == 0)        return 0;    ss->top = --top;    off = GetOff(ss, top);    topcs = &js_CodeSpec[ss->opcodes[top]];    cs = &js_CodeSpec[op];    if (topcs->prec != 0 && topcs->prec < cs->prec) {        ss->sprinter.offset = ss->offsets[top] = off - 2;        off = Sprint(&ss->sprinter, "(%s)", OFF2STR(&ss->sprinter, off));    } else {        ss->sprinter.offset = off;    }    return off;}static const char *PopStr(SprintStack *ss, JSOp op){    ptrdiff_t off;    off = PopOff(ss, op);    return OFF2STR(&ss->sprinter, off);}typedef struct TableEntry {    jsval       key;    ptrdiff_t   offset;    JSAtom      *label;    jsint       order;          /* source order for stable tableswitch sort */} TableEntry;static JSBoolCompareOffsets(void *arg, const void *v1, const void *v2, int *result){    ptrdiff_t offset_diff;    const TableEntry *te1 = (const TableEntry *) v1,                     *te2 = (const TableEntry *) v2;    offset_diff = te1->offset - te2->offset;    *result = (offset_diff == 0 ? te1->order - te2->order               : offset_diff < 0 ? -1               : 1);    return JS_TRUE;}static jsbytecode *Decompile(SprintStack *ss, jsbytecode *pc, intN nb);static JSBoolDecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,                jsbytecode *pc, ptrdiff_t switchLength,                ptrdiff_t defaultOffset, JSBool isCondSwitch){    JSContext *cx;    JSPrinter *jp;    ptrdiff_t off, off2, diff, caseExprOff;    char *lval, *rval;    uintN i;    jsval key;    JSString *str;    cx = ss->sprinter.context;    jp = ss->printer;    /* JSOP_CONDSWITCH doesn't pop, unlike JSOP_{LOOKUP,TABLE}SWITCH. */    off = isCondSwitch ? GetOff(ss, ss->top-1) : PopOff(ss, JSOP_NOP);    lval = OFF2STR(&ss->sprinter, off);    js_printf(CLEAR_MAYBE_BRACE(jp), "\tswitch (%s) {\n", lval);    if (tableLength) {        diff = table[0].offset - defaultOffset;        if (diff > 0) {            jp->indent += 2;            js_printf(jp, "\t%s:\n", js_default_str);            jp->indent += 2;            if (!Decompile(ss, pc + defaultOffset, diff))                return JS_FALSE;            jp->indent -= 4;        }        caseExprOff = isCondSwitch ? JSOP_CONDSWITCH_LENGTH : 0;        for (i = 0; i < tableLength; i++) {            off = table[i].offset;            off2 = (i + 1 < tableLength) ? table[i + 1].offset : switchLength;            key = table[i].key;            if (isCondSwitch) {                ptrdiff_t nextCaseExprOff;                /*                 * key encodes the JSOP_CASE bytecode's offset from switchtop.                 * The next case expression follows immediately, unless we are                 * at the last case.                 */                nextCaseExprOff = (ptrdiff_t)JSVAL_TO_INT(key);                nextCaseExprOff += js_CodeSpec[pc[nextCaseExprOff]].length;                jp->indent += 2;                if (!Decompile(ss, pc + caseExprOff,                               nextCaseExprOff - caseExprOff)) {                    return JS_FALSE;                }                caseExprOff = nextCaseExprOff;                /* Balance the stack as if this JSOP_CASE matched. */                --ss->top;            } else {                /*                 * key comes from an atom, not the decompiler, so we need to                 * quote it if it's a string literal.  But if table[i].label                 * is non-null, key was constant-propagated and label is the                 * name of the const we should show as the case label.  We set                 * key to undefined so this identifier is escaped, if required                 * by non-ASCII characters, but not quoted, by QuoteString.                 */                if (table[i].label) {                    str = ATOM_TO_STRING(table[i].label);                    key = JSVAL_VOID;                } else {                    str = js_ValueToString(cx, key);                    if (!str)                        return JS_FALSE;                }                rval = QuoteString(&ss->sprinter, str,                                   (jschar)(JSVAL_IS_STRING(key) ? '"' : 0));                if (!rval)                    return JS_FALSE;                RETRACT(&ss->sprinter, rval);                jp->indent += 2;                js_printf(jp, "\tcase %s:\n", rval);            }            jp->indent += 2;            if (off <= defaultOffset && defaultOffset < off2) {                diff = defaultOffset - off;                if (diff != 0) {                    if (!Decompile(ss, pc + off, diff))                        return JS_FALSE;                    off = defaultOffset;                }                jp->indent -= 2;                js_printf(jp, "\t%s:\n", js_default_str);                jp->indent += 2;            }            if (!Decompile(ss, pc + off, off2 - off))                return JS_FALSE;            jp->indent -= 4;            /* Re-balance as if last JSOP_CASE or JSOP_DEFAULT mismatched. */            if (isCondSwitch)                ++ss->top;        }    }    if (defaultOffset == switchLength) {        jp->indent += 2;        js_printf(jp, "\t%s:;\n", js_default_str);        jp->indent -= 2;    }    js_printf(jp, "\t}\n");    /* By the end of a JSOP_CONDSWITCH, the discriminant has been popped. */    if (isCondSwitch)        --ss->top;    return JS_TRUE;}static JSAtom *GetSlotAtom(JSPrinter *jp, JSPropertyOp getter, uintN slot){    JSScope *scope;    JSScopeProperty *sprop;    JSObject *obj, *proto;    scope = jp->scope;    while (scope) {        for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) {            if (sprop->getter != getter)                continue;            JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID);            JS_ASSERT(JSID_IS_ATOM(sprop->id));            if ((uintN) sprop->shortid == slot)                return JSID_TO_ATOM(sprop->id);        }        obj = scope->object;        if (!obj)            break;        proto = OBJ_GET_PROTO(jp->sprinter.context, obj);        if (!proto)            break;        scope = OBJ_SCOPE(proto);    }    return NULL;}/* * NB: Indexed by SRC_DECL_* defines from jsemit.h. */static const char * const var_prefix[] = {"var ", "const ", "let "};static const char *VarPrefix(jssrcnote *sn){    if (sn && (SN_TYPE(sn) == SRC_DECL || SN_TYPE(sn) == SRC_GROUPASSIGN)) {        ptrdiff_t type = js_GetSrcNoteOffset(sn, 0);        if ((uintN)type <= SRC_DECL_LET)            return var_prefix[type];    }    return "";}#define LOCAL_ASSERT_RV(expr, rv)                                             \    JS_BEGIN_MACRO                                                            \        JS_ASSERT(expr);                                                      \        if (!(expr)) return (rv);                                             \    JS_END_MACROconst char *GetLocal(SprintStack *ss, jsint i){    ptrdiff_t off;    JSContext *cx;    JSScript *script;    jsatomid j, n;    JSAtom *atom;    JSObject *obj;    jsint depth, count;    JSScopeProperty *sprop;    const char *rval;#define LOCAL_ASSERT(expr)      LOCAL_ASSERT_RV(expr, "")    off = ss->offsets[i];    if (off >= 0)        return OFF2STR(&ss->sprinter, off);    /*     * We must be called from js_DecompileValueGenerator (via Decompile) when     * dereferencing a local that's undefined or null.  Search script->atomMap     * for the block containing this local by its stack index, i.     */    cx = ss->sprinter.context;    script = ss->printer->script;    for (j = 0, n = script->atomMap.length; j < n; j++) {        atom = script->atomMap.vector[j];        if (ATOM_IS_OBJECT(atom)) {            obj = ATOM_TO_OBJECT(atom);            if (OBJ_GET_CLASS(cx, obj) == &js_BlockClass) {                depth = OBJ_BLOCK_DEPTH(cx, obj);                count = OBJ_BLOCK_COUNT(cx, obj);                if ((jsuint)(i - depth) < (jsuint)count)                    break;            }        }    }    LOCAL_ASSERT(j < n);    i -= depth;    for (sprop = OBJ_SCOPE(obj)->lastProp; sprop; sprop = sprop->parent) {        if (sprop->shortid == i)            break;    }    LOCAL_ASSERT(sprop && JSID_IS_ATOM(sprop->id));    atom = JSID_TO_ATOM(sprop->id);    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);    if (!rval)        return NULL;    RETRACT(&ss->sprinter, rval);    return rval;#undef LOCAL_ASSERT}#if JS_HAS_DESTRUCTURING#define LOCAL_ASSERT(expr)  LOCAL_ASSERT_RV(expr, NULL)#define LOAD_OP_DATA(pc)    (oplen = (cs = &js_CodeSpec[op = *pc])->length)static jsbytecode *DecompileDestructuring(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc);static jsbytecode *DecompileDestructuringLHS(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc,                          JSBool *hole){    JSContext *cx;    JSPrinter *jp;    JSOp op;    const JSCodeSpec *cs;    uintN oplen, i;    const char *lval, *xval;    ptrdiff_t todo;    JSAtom *atom;    *hole = JS_FALSE;    cx = ss->sprinter.context;    jp = ss->printer;    LOAD_OP_DATA(pc);    switch (op) {      case JSOP_POP:        *hole = JS_TRUE;        todo = SprintPut(&ss->sprinter, ", ", 2);        break;      case JSOP_DUP:        pc = DecompileDestructuring(ss, pc, endpc);        if (!pc)            return NULL;        if (pc == endpc)            return pc;        LOAD_OP_DATA(pc);        lval = PopStr(ss, JSOP_NOP);        todo = SprintCString(&ss->sprinter, lval);        if (op == JSOP_SETSP)            return pc;        LOCAL_ASSERT(*pc == JSOP_POP);        break;      case JSOP_SETARG:      case JSOP_SETVAR:      case JSOP_SETGVAR:      case JSOP_SETLOCAL:        LOCAL_ASSERT(pc[oplen] == JSOP_POP || pc[oplen] == JSOP_SETSP);        /* FALL THROUGH */

⌨️ 快捷键说明

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