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

📄 jsparse.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
                OBJ_DROP_PROPERTY(cx, pobj, prop);                if (!ok)                    return NULL;                prop = NULL;            }            if (!js_AddNativeProperty(cx, fun->object, (jsid)argAtom,                                      js_GetArgument, js_SetArgument,                                      SPROP_INVALID_SLOT,                                      JSPROP_ENUMERATE | JSPROP_PERMANENT |                                      JSPROP_SHARED,                                      SPROP_HAS_SHORTID | dupflag,                                      fun->nargs)) {                return NULL;            }            fun->nargs++;        } while (js_MatchToken(cx, ts, TOK_COMMA));        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FORMAL);    }    MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_BODY);    pn->pn_pos.begin = CURRENT_TOKEN(ts).pos.begin;    TREE_CONTEXT_INIT(&funtc);    body = FunctionBody(cx, ts, fun, &funtc);    if (!body)        return NULL;    MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);    pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;#if JS_HAS_LEXICAL_CLOSURE    /*     * If we collected flags that indicate nested heavyweight functions, or     * this function contains heavyweight-making statements (references to     * __parent__ or __proto__; use of with, eval, import, or export; and     * assignment to arguments), flag the function as heavyweight (requiring     * a call object per invocation).     */    if (funtc.flags & TCF_FUN_HEAVYWEIGHT) {        fun->flags |= JSFUN_HEAVYWEIGHT;        tc->flags |= TCF_FUN_HEAVYWEIGHT;    } else {        /*         * If this function is a named statement function not at top-level         * (i.e. a JSOP_CLOSURE), or if it refers to unqualified names that         * are not local args or vars (TCF_FUN_USES_NONLOCALS), then our         * enclosing function, if any, must be heavyweight.         */        if ((!lambda && funAtom && tc->topStmt) ||            (funtc.flags & TCF_FUN_USES_NONLOCALS)) {            tc->flags |= TCF_FUN_HEAVYWEIGHT;        }    }#endif    /*     * Record names for function statements in tc->decls so we know when to     * avoid optimizing variable references that might name a function.     */    if (!lambda && funAtom) {        ATOM_LIST_SEARCH(ale, &tc->decls, funAtom);        if (ale) {            prevop = ALE_JSOP(ale);            if (JS_HAS_STRICT_OPTION(cx) || prevop == JSOP_DEFCONST) {                const char *name = js_AtomToPrintableString(cx, funAtom);                if (!name ||                    !js_ReportCompileErrorNumber(cx, ts, NULL,                                                 (prevop != JSOP_DEFCONST)                                                 ? JSREPORT_WARNING |                                                   JSREPORT_STRICT                                                 : JSREPORT_ERROR,                                                 JSMSG_REDECLARED_VAR,                                                 (prevop == JSOP_DEFFUN ||                                                  prevop == JSOP_CLOSURE)                                                 ? js_function_str                                                 : (prevop == JSOP_DEFCONST)                                                 ? js_const_str                                                 : js_var_str,                                                 name)) {                    return NULL;                }            }            if (tc->topStmt && prevop == JSOP_DEFVAR)                tc->flags |= TCF_FUN_CLOSURE_VS_VAR;        } else {            ale = js_IndexAtom(cx, funAtom, &tc->decls);            if (!ale)                return NULL;        }        ALE_SET_JSOP(ale, tc->topStmt ? JSOP_CLOSURE : JSOP_DEFFUN);#if JS_HAS_LEXICAL_CLOSURE        /*         * A function nested at top level inside another's body needs only a         * local variable to bind its name to its value, and not an activation         * object property (it might also need the activation property, if the         * outer function contains with statements, e.g., but the stack slot         * wins when jsemit.c's LookupArgOrVar can optimize a JSOP_NAME into a         * JSOP_GETVAR bytecode).         */        if (!tc->topStmt && (tc->flags & TCF_IN_FUNCTION)) {            JSStackFrame *fp;            JSObject *varobj;            /*             * Define a property on the outer function so that LookupArgOrVar             * can properly optimize accesses.             *             * XXX Here and in Variables, we use the function object's scope,             * XXX arguably polluting it, when we could use a compiler-private             * XXX scope structure.  Tradition!             */            fp = cx->fp;            varobj = fp->varobj;            JS_ASSERT(OBJ_GET_CLASS(cx, varobj) == &js_FunctionClass);            JS_ASSERT(fp->fun == (JSFunction *) JS_GetPrivate(cx, varobj));            if (!js_LookupProperty(cx, varobj, (jsid)funAtom, &pobj, &prop))                return NULL;            if (prop)                OBJ_DROP_PROPERTY(cx, pobj, prop);            if (!prop || pobj != varobj) {                if (!js_DefineNativeProperty(cx, varobj, (jsid)funAtom,                                             OBJECT_TO_JSVAL(fun->object),                                             js_GetLocalVariable,                                             js_SetLocalVariable,                                             JSPROP_ENUMERATE,                                             SPROP_HAS_SHORTID, fp->fun->nvars,                                             NULL)) {                    return NULL;                }                fp->fun->nvars++;            }        }#endif    }#if JS_HAS_LEXICAL_CLOSURE    if (lambda || !funAtom) {        /*         * ECMA ed. 3 standard: function expression, possibly anonymous (even         * if at top-level, an unnamed function is an expression statement, not         * a function declaration).         */        op = fun->atom ? JSOP_NAMEDFUNOBJ : JSOP_ANONFUNOBJ;    } else if (tc->topStmt) {        /*         * ECMA ed. 3 extension: a function expression statement not at the         * top level, e.g., in a compound statement such as the "then" part         * of an "if" statement, binds a closure only if control reaches that         * sub-statement.         */        op = JSOP_CLOSURE;    } else#endif        op = JSOP_NOP;    /*     * Pending a better automatic GC root management scheme (see Mozilla bug     * 40757, http://bugzilla.mozilla.org/show_bug.cgi?id=40757), we need to     * atomize here to protect against a GC activation.     */    pn->pn_funAtom = js_AtomizeObject(cx, fun->object, 0);    if (!pn->pn_funAtom)        return NULL;    pn->pn_op = op;    pn->pn_body = body;    pn->pn_flags = funtc.flags & TCF_FUN_FLAGS;    pn->pn_tryCount = funtc.tryCount;    TREE_CONTEXT_FINISH(&funtc);    return pn;}static JSParseNode *FunctionStmt(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc){    return FunctionDef(cx, ts, tc, JS_FALSE);}#if JS_HAS_LEXICAL_CLOSUREstatic JSParseNode *FunctionExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc){    return FunctionDef(cx, ts, tc, JS_TRUE);}#endif/* * Parse the statements in a block, creating a TOK_LC node that lists the * statements' trees.  If called from block-parsing code, the caller must * match { before and } after. */static JSParseNode *Statements(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc){    JSParseNode *pn, *pn2;    JSTokenType tt;    CHECK_RECURSION();    pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);    if (!pn)        return NULL;    PN_INIT_LIST(pn);    ts->flags |= TSF_REGEXP;    while ((tt = js_PeekToken(cx, ts)) > TOK_EOF && tt != TOK_RC) {        ts->flags &= ~TSF_REGEXP;        pn2 = Statement(cx, ts, tc);        if (!pn2)            return NULL;        ts->flags |= TSF_REGEXP;        /* If compiling top-level statements, emit as we go to save space. */        if (!tc->topStmt && (tc->flags & TCF_COMPILING)) {            if (cx->fp->fun &&                JS_HAS_STRICT_OPTION(cx) &&                (tc->flags & TCF_RETURN_EXPR)) {                /*                 * Check pn2 for lack of a final return statement if it is the                 * last statement in the block.                 */                tt = js_PeekToken(cx, ts);                if ((tt == TOK_EOF || tt == TOK_RC) &&                    !CheckFinalReturn(cx, ts, pn2)) {                    tt = TOK_ERROR;                    break;                }                /*                 * Clear TCF_RETURN_EXPR so FunctionBody doesn't try to                 * CheckFinalReturn again.                 */                tc->flags &= ~TCF_RETURN_EXPR;            }            if (!js_FoldConstants(cx, pn2, tc) ||                !js_AllocTryNotes(cx, (JSCodeGenerator *)tc) ||                !js_EmitTree(cx, (JSCodeGenerator *)tc, pn2)) {                tt = TOK_ERROR;                break;            }            RecycleTree(pn2, tc);        } else {            PN_APPEND(pn, pn2);        }    }    ts->flags &= ~TSF_REGEXP;    if (tt == TOK_ERROR)        return NULL;    pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;    return pn;}static JSParseNode *Condition(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc){    JSParseNode *pn, *pn2;    MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_COND);    pn = Expr(cx, ts, tc);    if (!pn)        return NULL;    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_COND);    /*     * Check for (a = b) and "correct" it to (a == b) iff b's operator has     * greater precedence than ==.     * XXX not ECMA, but documented in several books -- now a strict warning.     */    if (pn->pn_type == TOK_ASSIGN &&        pn->pn_op == JSOP_NOP &&        pn->pn_right->pn_type > TOK_EQOP)    {        JSBool rewrite = !JSVERSION_IS_ECMA(cx->version);        if (!js_ReportCompileErrorNumber(cx, ts, NULL,                                         JSREPORT_WARNING | JSREPORT_STRICT,                                         JSMSG_EQUAL_AS_ASSIGN,                                         rewrite                                         ? "\nAssuming equality test"                                         : "")) {            return NULL;        }        if (rewrite) {            pn->pn_type = TOK_EQOP;            pn->pn_op = (JSOp)cx->jsop_eq;            pn2 = pn->pn_left;            switch (pn2->pn_op) {              case JSOP_SETNAME:                pn2->pn_op = JSOP_NAME;                break;              case JSOP_SETPROP:                pn2->pn_op = JSOP_GETPROP;                break;              case JSOP_SETELEM:                pn2->pn_op = JSOP_GETELEM;                break;              default:                JS_ASSERT(0);            }        }    }    return pn;}static JSBoolMatchLabel(JSContext *cx, JSTokenStream *ts, JSParseNode *pn){    JSAtom *label;#if JS_HAS_LABEL_STATEMENT    JSTokenType tt;    tt = js_PeekTokenSameLine(cx, ts);    if (tt == TOK_ERROR)        return JS_FALSE;    if (tt == TOK_NAME) {        (void) js_GetToken(cx, ts);        label = CURRENT_TOKEN(ts).t_atom;    } else {        label = NULL;    }#else    label = NULL;#endif    pn->pn_atom = label;    return JS_TRUE;}#if JS_HAS_EXPORT_IMPORTstatic JSParseNode *ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc){    JSParseNode *pn, *pn2, *pn3;    JSTokenType tt;    MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);    pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);    if (!pn)        return NULL;    pn->pn_op = JSOP_NAME;    pn->pn_atom = CURRENT_TOKEN(ts).t_atom;    pn->pn_expr = NULL;    pn->pn_slot = -1;    pn->pn_attrs = 0;    ts->flags |= TSF_REGEXP;    while ((tt = js_GetToken(cx, ts)) == TOK_DOT || tt == TOK_LB) {        ts->flags &= ~TSF_REGEXP;        if (pn->pn_op == JSOP_IMPORTALL)            goto bad_import;        if (tt == TOK_DOT) {            pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);            if (!pn2)                return NULL;            if (js_MatchToken(cx, ts, TOK_STAR)) {                pn2->pn_op = JSOP_IMPORTALL;                pn2->pn_atom = NULL;            } else {                MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);                pn2->pn_op = JSOP_GETPROP;                pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;                pn2->pn_slot = -1;                pn2->pn_attrs = 0;            }            pn2->pn_expr = pn;            pn2->pn_pos.begin = pn->pn_pos.begin;            pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;        } else {            /* Make a TOK_LB node. */            pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);            if (!pn2)                return NULL;            pn3 = Expr(cx, ts, tc);            if (!pn3)                return NULL;            MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);            pn2->pn_pos.begin = pn->pn_pos.begin;            pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;            pn2->pn_op = JSOP_GETELEM;            pn2->pn_left = pn;            pn2->pn_right = pn3;        }        pn = pn2;        ts->flags |= TSF_REGEXP;    }    ts->flags &= ~TSF_REGEXP;    if (tt == TOK_ERROR)        return NULL;    js_UngetToken(ts);

⌨️ 快捷键说明

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