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

📄 jsopcode.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
                    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, "\tdefault:\n");                jp->indent += 2;            }            if (!Decompile(ss, pc + off, off2 - off))                return JS_FALSE;            jp->indent -= 4;        }    }    if (defaultOffset == switchLength) {        jp->indent += 2;        js_printf(jp, "\tdefault:;\n");        jp->indent -= 2;    }    js_printf(jp, "\t}\n");    return JS_TRUE;}#endifstatic 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(!JSVAL_IS_INT(sprop->id));            if ((uintN) sprop->shortid == slot)                return (JSAtom *) 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;}static const char *VarPrefix(jssrcnote *sn){    const char *kw;    static char buf[8];    kw = NULL;    if (sn) {        if (SN_TYPE(sn) == SRC_VAR)            kw = js_var_str;        else if (SN_TYPE(sn) == SRC_CONST)            kw = js_const_str;    }    if (!kw)        return "";    JS_snprintf(buf, sizeof buf, "%s ", kw);    return buf;}static JSBoolDecompile(SprintStack *ss, jsbytecode *pc, intN nb){    JSContext *cx;    JSPrinter *jp, *jp2;    jsbytecode *endpc, *done, *forelem_tail, *forelem_done;    ptrdiff_t len, todo, oplen, cond, next, tail;    JSOp op, lastop, saveop;    const JSCodeSpec *cs, *topcs;    jssrcnote *sn, *sn2;    const char *lval, *rval, *xval, *fmt;    jsint i, argc;    char **argv;    JSAtom *atom;    JSObject *obj;    JSFunction *fun;    JSString *str;    JSBool ok;    jsval val;    static const char catch_cookie[] = "/*CATCH*/";    static const char with_cookie[] = "/*WITH*/";/* * Local macros */#define DECOMPILE_CODE(pc,nb)	if (!Decompile(ss, pc, nb)) return JS_FALSE#define POP_STR()		OFF2STR(&ss->sprinter, PopOff(ss, op))#define LOCAL_ASSERT(expr)	JS_ASSERT(expr); if (!(expr)) return 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)                                              \    (!ATOM_KEYWORD(atom) && js_IsIdentifier(ATOM_TO_STRING(atom)))/* * Get atom from 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                                                            \        jschar quote_;                                                        \        atom = GET_ATOM(cx, jp->script, pc);                                  \        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 JS_FALSE;                                                  \    JS_END_MACRO    cx = ss->sprinter.context;    jp = ss->printer;    endpc = pc + nb;    forelem_tail = forelem_done = NULL;    todo = -2;			/* NB: different from Sprint() error return. */    tail = -1;    op = JSOP_NOP;    sn = NULL;    rval = NULL;    while (pc < endpc) {        lastop = op;        op = saveop = (JSOp) *pc;        if (op >= JSOP_LIMIT) {            switch (op) {              case JSOP_GETPROP2:                saveop = JSOP_GETPROP;                break;              case JSOP_GETELEM2:                saveop = JSOP_GETELEM;                break;              default:;            }        }        cs = &js_CodeSpec[saveop];        len = oplen = cs->length;        if (cs->token) {            switch (cs->nuses) {              case 2:                rval = POP_STR();                lval = POP_STR();                sn = js_GetSrcNote(jp->script, pc);                if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {                    /* Print only the right operand of the assignment-op. */                    todo = SprintPut(&ss->sprinter, rval, strlen(rval));                } else {                    todo = Sprint(&ss->sprinter, "%s %s %s",                                  lval, cs->token, rval);                }                break;              case 1:                rval = POP_STR();                todo = Sprint(&ss->sprinter, "%s%s", cs->token, rval);                break;              case 0:#if JS_HAS_GETTER_SETTER                if (op == JSOP_GETTER || op == JSOP_SETTER) {                    todo = -2;                    break;                }#endif                todo = SprintPut(&ss->sprinter, cs->token, strlen(cs->token));                break;              default:                todo = -2;                break;            }        } else {            switch (op) {              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) {#if JS_HAS_DO_WHILE_LOOP                  case SRC_WHILE:                    js_printf(jp, "\tdo {\n");                    jp->indent += 4;                    break;#endif /* JS_HAS_DO_WHILE_LOOP */                  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(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 JS_FALSE;                    RETRACT(&ss->sprinter, rval);                    js_printf(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 JS_FALSE;                    RETRACT(&ss->sprinter, rval);                    js_printf(jp, "\t%s: {\n", rval);                    jp->indent += 4;                    break;                  case SRC_ENDBRACE:                    jp->indent -= 4;                    js_printf(jp, "\t}\n");                    break;                  case SRC_CATCH:                    jp->indent -= 4;                    sn = js_GetSrcNote(jp->script, pc);                    pc += oplen;                    js_printf(jp, "\t} catch (");                    LOCAL_ASSERT(*pc == JSOP_NAME);                    pc += js_CodeSpec[JSOP_NAME].length;                    LOCAL_ASSERT(*pc == JSOP_PUSHOBJ);                    pc += js_CodeSpec[JSOP_PUSHOBJ].length;                    LOCAL_ASSERT(*pc == JSOP_NEWINIT);                    pc += js_CodeSpec[JSOP_NEWINIT].length;                    LOCAL_ASSERT(*pc == JSOP_EXCEPTION);                    pc += js_CodeSpec[JSOP_EXCEPTION].length;                    LOCAL_ASSERT(*pc == JSOP_INITCATCHVAR);                    atom = GET_ATOM(cx, jp->script, pc);                    rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);                    if (!rval)                        return JS_FALSE;                    RETRACT(&ss->sprinter, rval);                    js_printf(jp, "%s", rval);                    pc += js_CodeSpec[JSOP_INITCATCHVAR].length;                    LOCAL_ASSERT(*pc == JSOP_ENTERWITH);                    pc += js_CodeSpec[JSOP_ENTERWITH].length;                    len = js_GetSrcNoteOffset(sn, 0);                    if (len) {                        js_printf(jp, " if ");                        DECOMPILE_CODE(pc, len);                        js_printf(jp, "%s", POP_STR());                        pc += len;                        LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX);                        pc += js_CodeSpec[*pc].length;                    }                    js_printf(jp, ") {\n");                    jp->indent += 4;                    todo = Sprint(&ss->sprinter, catch_cookie);                    len = 0;                    break;                  case SRC_FUNCDEF:                    atom = js_GetAtom(cx, &jp->script->atomMap,                                      (jsatomid) js_GetSrcNoteOffset(sn, 0));                    JS_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 JS_FALSE;                    jp2->scope = jp->scope;                    if (js_DecompileFunction(jp2, fun)) {                        str = js_GetPrinterOutput(jp2);                        if (str)                            js_printf(jp, "%s\n", JS_GetStringBytes(str));                    }                    js_DestroyPrinter(jp2);                    break;                  default:;                }              case JSOP_RETRVAL:                break;              case JSOP_GROUP:                /* Use last real op so PopOff adds parens if needed. */                todo = PopOff(ss, lastop);                /* Now add user-supplied parens only if PopOff did not. */                cs    = &js_CodeSpec[lastop];                topcs = &js_CodeSpec[ss->opcodes[ss->top]];                if (topcs->prec >= cs->prec) {                    todo = Sprint(&ss->sprinter, "(%s)",                                  OFF2STR(&ss->sprinter, todo));                }                break;              case JSOP_PUSH:              case JSOP_PUSHOBJ:              case JSOP_BINDNAME:                todo = Sprint(&ss->sprinter, "");                break;#if JS_HAS_EXCEPTIONS              case JSOP_TRY:                js_printf(jp, "\ttry {\n");                jp->indent += 4;                todo = -2;                break;            {              static const char finally_cookie[] = "/*FINALLY*/";

⌨️ 快捷键说明

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