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

📄 jsparse.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
    switch (pn->pn_op) {      case JSOP_GETPROP:        pn->pn_op = JSOP_IMPORTPROP;        break;      case JSOP_GETELEM:        pn->pn_op = JSOP_IMPORTELEM;        break;      case JSOP_IMPORTALL:        break;      default:        goto bad_import;    }    return pn;  bad_import:    js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, JSMSG_BAD_IMPORT);    return NULL;}#endif /* JS_HAS_EXPORT_IMPORT */extern const char js_with_statement_str[];static JSParseNode *Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc){    JSTokenType tt;    JSParseNode *pn, *pn1, *pn2, *pn3, *pn4;    JSStmtInfo stmtInfo, *stmt, *stmt2;    JSAtom *label;    CHECK_RECURSION();    ts->flags |= TSF_REGEXP;    tt = js_GetToken(cx, ts);    ts->flags &= ~TSF_REGEXP;#if JS_HAS_GETTER_SETTER    if (tt == TOK_NAME) {        tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION);        if (tt == TOK_ERROR)            return NULL;    }#endif    switch (tt) {#if JS_HAS_EXPORT_IMPORT      case TOK_EXPORT:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);        if (!pn)            return NULL;        PN_INIT_LIST(pn);        if (js_MatchToken(cx, ts, TOK_STAR)) {            pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);            if (!pn2)                return NULL;            PN_APPEND(pn, pn2);        } else {            do {                MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_EXPORT_NAME);                pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);                if (!pn2)                    return NULL;                pn2->pn_op = JSOP_NAME;                pn2->pn_atom = CURRENT_TOKEN(ts).t_atom;                pn2->pn_expr = NULL;                pn2->pn_slot = -1;                pn2->pn_attrs = 0;                PN_APPEND(pn, pn2);            } while (js_MatchToken(cx, ts, TOK_COMMA));        }        pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;        tc->flags |= TCF_FUN_HEAVYWEIGHT;        break;      case TOK_IMPORT:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);        if (!pn)            return NULL;        PN_INIT_LIST(pn);        do {            pn2 = ImportExpr(cx, ts, tc);            if (!pn2)                return NULL;            PN_APPEND(pn, pn2);        } while (js_MatchToken(cx, ts, TOK_COMMA));        pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;        tc->flags |= TCF_FUN_HEAVYWEIGHT;        break;#endif /* JS_HAS_EXPORT_IMPORT */      case TOK_FUNCTION:        return FunctionStmt(cx, ts, tc);      case TOK_IF:        /* An IF node has three kids: condition, then, and optional else. */        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);        if (!pn)            return NULL;        pn1 = Condition(cx, ts, tc);        if (!pn1)            return NULL;        js_PushStatement(tc, &stmtInfo, STMT_IF, -1);        pn2 = Statement(cx, ts, tc);        if (!pn2)            return NULL;        if (js_MatchToken(cx, ts, TOK_ELSE)) {            stmtInfo.type = STMT_ELSE;            pn3 = Statement(cx, ts, tc);            if (!pn3)                return NULL;            pn->pn_pos.end = pn3->pn_pos.end;        } else {            pn3 = NULL;            pn->pn_pos.end = pn2->pn_pos.end;        }        js_PopStatement(tc);        pn->pn_kid1 = pn1;        pn->pn_kid2 = pn2;        pn->pn_kid3 = pn3;        return pn;#if JS_HAS_SWITCH_STATEMENT      case TOK_SWITCH:      {        JSParseNode *pn5;        JSBool seenDefault = JS_FALSE;        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);        if (!pn)            return NULL;        MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);        /* pn1 points to the switch's discriminant. */        pn1 = Expr(cx, ts, tc);        if (!pn1)            return NULL;        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH);        MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH);        /* pn2 is a list of case nodes. The default case has pn_left == NULL */        pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);        if (!pn2)            return NULL;        PN_INIT_LIST(pn2);        js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1);        while ((tt = js_GetToken(cx, ts)) != TOK_RC) {            switch (tt) {              case TOK_DEFAULT:                if (seenDefault) {                    js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                                JSMSG_TOO_MANY_DEFAULTS);                    return NULL;                }                seenDefault = JS_TRUE;                /* fall through */              case TOK_CASE:                pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);                if (!pn3)                    return NULL;                if (tt == TOK_DEFAULT) {                    pn3->pn_left = NULL;                } else {                    pn3->pn_left = Expr(cx, ts, tc);                    if (!pn3->pn_left)                        return NULL;                }                PN_APPEND(pn2, pn3);                if (pn2->pn_count == JS_BIT(16)) {                    js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                                JSMSG_TOO_MANY_CASES);                    return NULL;                }                break;              case TOK_ERROR:                return NULL;              default:                js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                            JSMSG_BAD_SWITCH);                return NULL;            }            MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);            pn4 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc);            if (!pn4)                return NULL;            pn4->pn_type = TOK_LC;            PN_INIT_LIST(pn4);            while ((tt = js_PeekToken(cx, ts)) != TOK_RC &&                   tt != TOK_CASE && tt != TOK_DEFAULT) {                if (tt == TOK_ERROR)                    return NULL;                pn5 = Statement(cx, ts, tc);                if (!pn5)                    return NULL;                pn4->pn_pos.end = pn5->pn_pos.end;                PN_APPEND(pn4, pn5);            }            /* Fix the PN_LIST so it doesn't begin at the TOK_COLON. */            if (pn4->pn_head)                pn4->pn_pos.begin = pn4->pn_head->pn_pos.begin;            pn3->pn_pos.end = pn4->pn_pos.end;            pn3->pn_right = pn4;        }        js_PopStatement(tc);        pn->pn_pos.end = pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;        pn->pn_kid1 = pn1;        pn->pn_kid2 = pn2;        return pn;      }#endif /* JS_HAS_SWITCH_STATEMENT */      case TOK_WHILE:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);        if (!pn)            return NULL;        js_PushStatement(tc, &stmtInfo, STMT_WHILE_LOOP, -1);        pn2 = Condition(cx, ts, tc);        if (!pn2)            return NULL;        pn->pn_left = pn2;        pn2 = Statement(cx, ts, tc);        if (!pn2)            return NULL;        js_PopStatement(tc);        pn->pn_pos.end = pn2->pn_pos.end;        pn->pn_right = pn2;        return pn;#if JS_HAS_DO_WHILE_LOOP      case TOK_DO:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);        if (!pn)            return NULL;        js_PushStatement(tc, &stmtInfo, STMT_DO_LOOP, -1);        pn2 = Statement(cx, ts, tc);        if (!pn2)            return NULL;        pn->pn_left = pn2;        MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO);        pn2 = Condition(cx, ts, tc);        if (!pn2)            return NULL;        js_PopStatement(tc);        pn->pn_pos.end = pn2->pn_pos.end;        pn->pn_right = pn2;        if (cx->version != JSVERSION_ECMA_3) {            /*             * All legacy and extended versions must do automatic semicolon             * insertion after do-while.  See the testcase and discussion in             * http://bugzilla.mozilla.org/show_bug.cgi?id=238945.             */            (void) js_MatchToken(cx, ts, TOK_SEMI);            return pn;        }        break;#endif /* JS_HAS_DO_WHILE_LOOP */      case TOK_FOR:        /* A FOR node is binary, left is loop control and right is the body. */        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);        if (!pn)            return NULL;        js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1);        MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);        ts->flags |= TSF_REGEXP;        tt = js_PeekToken(cx, ts);        ts->flags &= ~TSF_REGEXP;        if (tt == TOK_SEMI) {            /* No initializer -- set first kid of left sub-node to null. */            pn1 = NULL;        } else {            /* Set pn1 to a var list or an initializing expression. */#if JS_HAS_IN_OPERATOR            /*             * Set the TCF_IN_FOR_INIT flag during parsing of the first clause             * of the for statement.  This flag will be used by the RelExpr             * production; if it is set, then the 'in' keyword will not be             * recognized as an operator, leaving it available to be parsed as             * part of a for/in loop.  A side effect of this restriction is             * that (unparenthesized) expressions involving an 'in' operator             * are illegal in the init clause of an ordinary for loop.             */            tc->flags |= TCF_IN_FOR_INIT;#endif /* JS_HAS_IN_OPERATOR */            if (tt == TOK_VAR) {                (void) js_GetToken(cx, ts);                pn1 = Variables(cx, ts, tc);            } else {                pn1 = Expr(cx, ts, tc);            }#if JS_HAS_IN_OPERATOR            tc->flags &= ~TCF_IN_FOR_INIT;#endif /* JS_HAS_IN_OPERATOR */            if (!pn1)                return NULL;        }        /*         * We can be sure that it's a for/in loop if there's still an 'in'         * keyword here, even if JavaScript recognizes 'in' as an operator,         * as we've excluded 'in' from being parsed in RelExpr by setting         * the TCF_IN_FOR_INIT flag in our JSTreeContext.         */        if (pn1 && js_MatchToken(cx, ts, TOK_IN)) {            stmtInfo.type = STMT_FOR_IN_LOOP;            /* Check that the left side of the 'in' is valid. */            if ((pn1->pn_type == TOK_VAR)                ? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST)                : (pn1->pn_type != TOK_NAME &&                   pn1->pn_type != TOK_DOT &&                   pn1->pn_type != TOK_LB)) {                js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                            JSMSG_BAD_FOR_LEFTSIDE);                return NULL;            }            if (pn1->pn_type == TOK_VAR) {                /* Tell js_EmitTree(TOK_VAR) that pn1 is part of a for/in. */                pn1->pn_extra |= PNX_FORINVAR;                /* Generate a final POP only if the var has an initializer. */                pn2 = pn1->pn_head;                if (pn2->pn_expr)                    pn1->pn_extra |= PNX_POPVAR;            } else {                pn2 = pn1;            }            /* Beware 'for (arguments in ...)' with or without a 'var'. */            if (pn2->pn_type == TOK_NAME &&                pn2->pn_atom == cx->runtime->atomState.argumentsAtom) {                tc->flags |= TCF_FUN_HEAVYWEIGHT;            }            /* Parse the object expression as the right operand of 'in'. */            pn2 = NewBinary(cx, TOK_IN, JSOP_NOP, pn1, Expr(cx, ts, tc), tc);            if (!pn2)                return NULL;            pn->pn_left = pn2;        } else {            /* Parse the loop condition or null into pn2. */            MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_INIT);            ts->flags |= TSF_REGEXP;            tt = js_PeekToken(cx, ts);            ts->flags &= ~TSF_REGEXP;            if (tt == TOK_SEMI) {                pn2 = NULL;            } else {                pn2 = Expr(cx, ts, tc);                if (!pn2)                    return NULL;            }            /* Parse the update expression or null into pn3. */            MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_COND);            ts->flags |= TSF_REGEXP;            tt = js_PeekToken(cx, ts);            ts->flags &= ~TSF_REGEXP;            if (tt == TOK_RP) {                pn3 = NULL;            } else {                pn3 = Expr(cx, ts, tc);                if (!pn3)                    return NULL;            }            /* Build the RESERVED node to use as the left kid of pn. */            pn4 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);            if (!pn4)                return NULL;            pn4->pn_type = TOK_RESERVED;            pn4->pn_op = JSOP_NOP;            pn4->pn_kid1 = pn1;            pn4->pn_kid2 = pn2;            pn4->pn_kid3 = pn3;            pn->pn_left = pn4;        }        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FOR_CTRL);        /* Parse the loop body into pn->pn_right. */        pn2 = Statement(cx, ts, tc);        if (!pn2)            return NULL;

⌨️ 快捷键说明

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