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

📄 jsemit.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
    ptrdiff_t jmp;    jsbytecode *pc;    extend = off < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < off;    if (extend && !cg->spanDeps && !BuildSpanDepTable(cx, cg))        return JS_FALSE;    jmp = js_Emit3(cx, cg, op, JUMP_OFFSET_HI(off), JUMP_OFFSET_LO(off));    if (jmp >= 0 && (extend || cg->spanDeps)) {        pc = CG_CODE(cg, jmp);        if (!AddSpanDep(cx, cg, pc, pc, off))            return JS_FALSE;    }    return jmp;}static ptrdiff_tGetJumpOffset(JSCodeGenerator *cg, jsbytecode *pc){    JSSpanDep *sd;    JSJumpTarget *jt;    ptrdiff_t top;    if (!cg->spanDeps)        return GET_JUMP_OFFSET(pc);    sd = GetSpanDep(cg, pc);    jt = sd->target;    if (!JT_HAS_TAG(jt))        return JT_TO_BPDELTA(jt);    top = sd->top;    while (--sd >= cg->spanDeps && sd->top == top)        continue;    sd++;    return JT_CLR_TAG(jt)->offset - sd->offset;}JSBooljs_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,                 ptrdiff_t off){    if (!cg->spanDeps) {        if (JUMP_OFFSET_MIN <= off && off <= JUMP_OFFSET_MAX) {            SET_JUMP_OFFSET(pc, off);            return JS_TRUE;        }        if (!BuildSpanDepTable(cx, cg))            return JS_FALSE;    }    return SetSpanDepTarget(cx, cg, GetSpanDep(cg, pc), off);}JSBooljs_InStatement(JSTreeContext *tc, JSStmtType type){    JSStmtInfo *stmt;    for (stmt = tc->topStmt; stmt; stmt = stmt->down) {        if (stmt->type == type)            return JS_TRUE;    }    return JS_FALSE;}JSBooljs_IsGlobalReference(JSTreeContext *tc, JSAtom *atom, JSBool *loopyp){    JSStmtInfo *stmt;    JSObject *obj;    JSScope *scope;    *loopyp = JS_FALSE;    for (stmt = tc->topStmt; stmt; stmt = stmt->down) {        if (stmt->type == STMT_WITH)            return JS_FALSE;        if (STMT_IS_LOOP(stmt)) {            *loopyp = JS_TRUE;            continue;        }        if (stmt->flags & SIF_SCOPE) {            obj = ATOM_TO_OBJECT(stmt->atom);            JS_ASSERT(LOCKED_OBJ_GET_CLASS(obj) == &js_BlockClass);            scope = OBJ_SCOPE(obj);            if (SCOPE_GET_PROPERTY(scope, ATOM_TO_JSID(atom)))                return JS_FALSE;        }    }    return JS_TRUE;}voidjs_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type,                 ptrdiff_t top){    stmt->type = type;    stmt->flags = 0;    SET_STATEMENT_TOP(stmt, top);    stmt->atom = NULL;    stmt->down = tc->topStmt;    tc->topStmt = stmt;    if (STMT_LINKS_SCOPE(stmt)) {        stmt->downScope = tc->topScopeStmt;        tc->topScopeStmt = stmt;    } else {        stmt->downScope = NULL;    }}voidjs_PushBlockScope(JSTreeContext *tc, JSStmtInfo *stmt, JSAtom *blockAtom,                  ptrdiff_t top){    JSObject *blockObj;    js_PushStatement(tc, stmt, STMT_BLOCK, top);    stmt->flags |= SIF_SCOPE;    blockObj = ATOM_TO_OBJECT(blockAtom);    blockObj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(tc->blockChain);    stmt->downScope = tc->topScopeStmt;    tc->topScopeStmt = stmt;    tc->blockChain = blockObj;    stmt->atom = blockAtom;}/* * Emit a backpatch op with offset pointing to the previous jump of this type, * so that we can walk back up the chain fixing up the op and jump offset. */static ptrdiff_tEmitBackPatchOp(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t *lastp){    ptrdiff_t offset, delta;    offset = CG_OFFSET(cg);    delta = offset - *lastp;    *lastp = offset;    JS_ASSERT(delta > 0);    return EmitJump(cx, cg, op, delta);}/* * Macro to emit a bytecode followed by a uint16 immediate operand stored in * big-endian order, used for arg and var numbers as well as for atomIndexes. * NB: We use cx and cg from our caller's lexical environment, and return * false on error. */#define EMIT_UINT16_IMM_OP(op, i)                                             \    JS_BEGIN_MACRO                                                            \        if (js_Emit3(cx, cg, op, UINT16_HI(i), UINT16_LO(i)) < 0)             \            return JS_FALSE;                                                  \    JS_END_MACRO/* Emit additional bytecode(s) for non-local jumps. */static JSBoolEmitNonLocalJumpFixup(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt,                      JSOp *returnop){    intN depth;    JSStmtInfo *stmt;    ptrdiff_t jmp;    /*     * Return from within a try block that has a finally clause must be split     * into two ops: JSOP_SETRVAL, to pop the r.v. and store it in fp->rval;     * and JSOP_RETRVAL, which makes control flow go back to the caller, who     * picks up fp->rval as usual.  Otherwise, the stack will be unbalanced     * when executing the finally clause.     *     * We mutate *returnop once only if we find an enclosing try-block (viz,     * STMT_FINALLY) to ensure that we emit just one JSOP_SETRVAL before one     * or more JSOP_GOSUBs and other fixup opcodes emitted by this function.     * Our caller (the TOK_RETURN case of js_EmitTree) then emits *returnop.     * The fixup opcodes and gosubs must interleave in the proper order, from     * inner statement to outer, so that finally clauses run at the correct     * stack depth.     */    if (returnop) {        JS_ASSERT(*returnop == JSOP_RETURN);        for (stmt = cg->treeContext.topStmt; stmt != toStmt;             stmt = stmt->down) {            if (stmt->type == STMT_FINALLY ||                ((cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT) &&                 STMT_MAYBE_SCOPE(stmt))) {                if (js_Emit1(cx, cg, JSOP_SETRVAL) < 0)                    return JS_FALSE;                *returnop = JSOP_RETRVAL;                break;            }        }        /*         * If there are no try-with-finally blocks open around this return         * statement, we can generate a return forthwith and skip generating         * any fixup code.         */        if (*returnop == JSOP_RETURN)            return JS_TRUE;    }    /*     * The non-local jump fixup we emit will unbalance cg->stackDepth, because     * the fixup replicates balanced code such as JSOP_LEAVEWITH emitted at the     * end of a with statement, so we save cg->stackDepth here and restore it     * just before a successful return.     */    depth = cg->stackDepth;    for (stmt = cg->treeContext.topStmt; stmt != toStmt; stmt = stmt->down) {        switch (stmt->type) {          case STMT_FINALLY:            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)                return JS_FALSE;            jmp = EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, &GOSUBS(*stmt));            if (jmp < 0)                return JS_FALSE;            break;          case STMT_WITH:            /* There's a With object on the stack that we need to pop. */            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)                return JS_FALSE;            if (js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0)                return JS_FALSE;            break;          case STMT_FOR_IN_LOOP:            /*             * The iterator and the object being iterated need to be popped.             */            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)                return JS_FALSE;            if (js_Emit1(cx, cg, JSOP_ENDITER) < 0)                return JS_FALSE;            break;          case STMT_SUBROUTINE:            /*             * There's a [exception or hole, retsub pc-index] pair on the             * stack that we need to pop.             */            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)                return JS_FALSE;            if (js_Emit1(cx, cg, JSOP_POP2) < 0)                return JS_FALSE;            break;          default:;        }        if (stmt->flags & SIF_SCOPE) {            uintN i;            /* There is a Block object with locals on the stack to pop. */            if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0)                return JS_FALSE;            i = OBJ_BLOCK_COUNT(cx, ATOM_TO_OBJECT(stmt->atom));            EMIT_UINT16_IMM_OP(JSOP_LEAVEBLOCK, i);        }    }    cg->stackDepth = depth;    return JS_TRUE;}static ptrdiff_tEmitGoto(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt,         ptrdiff_t *lastp, JSAtomListElement *label, JSSrcNoteType noteType){    intN index;    if (!EmitNonLocalJumpFixup(cx, cg, toStmt, NULL))        return -1;    if (label)        index = js_NewSrcNote2(cx, cg, noteType, (ptrdiff_t) ALE_INDEX(label));    else if (noteType != SRC_NULL)        index = js_NewSrcNote(cx, cg, noteType);    else        index = 0;    if (index < 0)        return -1;    return EmitBackPatchOp(cx, cg, JSOP_BACKPATCH, lastp);}static JSBoolBackPatch(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t last,          jsbytecode *target, jsbytecode op){    jsbytecode *pc, *stop;    ptrdiff_t delta, span;    pc = CG_CODE(cg, last);    stop = CG_CODE(cg, -1);    while (pc != stop) {        delta = GetJumpOffset(cg, pc);        span = PTRDIFF(target, pc, jsbytecode);        CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, span);        /*         * Set *pc after jump offset in case bpdelta didn't overflow, but span         * does (if so, CHECK_AND_SET_JUMP_OFFSET might call BuildSpanDepTable         * and need to see the JSOP_BACKPATCH* op at *pc).         */        *pc = op;        pc -= delta;    }    return JS_TRUE;}voidjs_PopStatement(JSTreeContext *tc){    JSStmtInfo *stmt;    JSObject *blockObj;    stmt = tc->topStmt;    tc->topStmt = stmt->down;    if (STMT_LINKS_SCOPE(stmt)) {        tc->topScopeStmt = stmt->downScope;        if (stmt->flags & SIF_SCOPE) {            blockObj = ATOM_TO_OBJECT(stmt->atom);            tc->blockChain = JSVAL_TO_OBJECT(blockObj->slots[JSSLOT_PARENT]);        }    }}JSBooljs_PopStatementCG(JSContext *cx, JSCodeGenerator *cg){    JSStmtInfo *stmt;    stmt = cg->treeContext.topStmt;    if (!STMT_IS_TRYING(stmt) &&        (!BackPatch(cx, cg, stmt->breaks, CG_NEXT(cg), JSOP_GOTO) ||         !BackPatch(cx, cg, stmt->continues, CG_CODE(cg, stmt->update),                    JSOP_GOTO))) {        return JS_FALSE;    }    js_PopStatement(&cg->treeContext);    return JS_TRUE;}JSBooljs_DefineCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,                             JSParseNode *pn){    jsdouble dval;    jsint ival;    JSAtom *valueAtom;    JSAtomListElement *ale;    /* XXX just do numbers for now */    if (pn->pn_type == TOK_NUMBER) {        dval = pn->pn_dval;        valueAtom = (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival))                    ? js_AtomizeInt(cx, ival, 0)                    : js_AtomizeDouble(cx, dval, 0);        if (!valueAtom)            return JS_FALSE;        ale = js_IndexAtom(cx, atom, &cg->constList);        if (!ale)            return JS_FALSE;        ALE_SET_VALUE(ale, ATOM_KEY(valueAtom));    }    return JS_TRUE;}JSStmtInfo *js_LexicalLookup(JSTreeContext *tc, JSAtom *atom, jsint *slotp, JSBool letdecl){    JSStmtInfo *stmt;    JSObject *obj;    JSScope *scope;    JSScopeProperty *sprop;    jsval v;    for (stmt = tc->topScopeStmt; stmt; stmt = stmt->downScope) {        if (stmt->type == STMT_WITH) {

⌨️ 快捷键说明

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