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

📄 jsparse.c

📁 Swfdec still is development software, but has also followed a rigid no-crashes-allowed policy. I b
💻 C
📖 第 1 页 / 共 5 页
字号:
        pn->pn_right = pn2;        js_PopStatement(tc);        /* Record the absolute line number for source note emission. */        pn->pn_pos.end = pn2->pn_pos.end;        return pn;#if JS_HAS_EXCEPTIONS      case TOK_TRY: {        JSParseNode *catchtail = NULL;        /*         * try nodes are ternary.         * kid1 is the try Statement         * kid2 is the catch node         * kid3 is the finally Statement         *         * catch nodes are ternary.         * kid1 is the discriminant         * kid2 is the next catch node, or NULL         * kid3 is the catch block (on kid3 so that we can always append a         *                          new catch pn on catchtail->kid2)         *         * catch discriminant nodes are binary         * atom is the receptacle         * expr is the discriminant code         *         * finally nodes are unary (just the finally expression)         */        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);        pn->pn_op = JSOP_NOP;        MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY);        js_PushStatement(tc, &stmtInfo, STMT_TRY, -1);        pn->pn_kid1 = Statements(cx, ts, tc);        if (!pn->pn_kid1)            return NULL;        MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY);        js_PopStatement(tc);        catchtail = pn;        while (js_PeekToken(cx, ts) == TOK_CATCH) {            /* check for another catch after unconditional catch */            if (catchtail != pn && !catchtail->pn_kid1->pn_expr) {                js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                            JSMSG_CATCH_AFTER_GENERAL);                return NULL;            }            /*             * legal catch forms are:             * catch (v)             * catch (v if <boolean_expression>)             * (the latter is legal only #ifdef JS_HAS_CATCH_GUARD)             */            (void) js_GetToken(cx, ts); /* eat `catch' */            pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc);            if (!pn2)                return NULL;            /*             * We use a PN_NAME for the discriminant (catchguard) node             * with the actual discriminant code in the initializer spot             */            MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH);            MUST_MATCH_TOKEN(TOK_NAME, JSMSG_CATCH_IDENTIFIER);            pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc);            if (!pn3)                return NULL;            pn3->pn_atom = CURRENT_TOKEN(ts).t_atom;            pn3->pn_expr = NULL;#if JS_HAS_CATCH_GUARD            /*             * We use `catch (x if x === 5)' (not `catch (x : x === 5)') to             * avoid conflicting with the JS2/ECMA2 proposed catchguard syntax.             */            if (js_PeekToken(cx, ts) == TOK_IF) {                (void)js_GetToken(cx, ts); /* eat `if' */                pn3->pn_expr = Expr(cx, ts, tc);                if (!pn3->pn_expr)                    return NULL;            }#endif            pn2->pn_kid1 = pn3;            MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH);            MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH);            js_PushStatement(tc, &stmtInfo, STMT_CATCH, -1);            stmtInfo.label = pn3->pn_atom;            pn2->pn_kid3 = Statements(cx, ts, tc);            if (!pn2->pn_kid3)                return NULL;            MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_CATCH);            js_PopStatement(tc);            catchtail = catchtail->pn_kid2 = pn2;        }        catchtail->pn_kid2 = NULL;        if (js_MatchToken(cx, ts, TOK_FINALLY)) {            tc->tryCount++;            MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_FINALLY);            js_PushStatement(tc, &stmtInfo, STMT_FINALLY, -1);            pn->pn_kid3 = Statements(cx, ts, tc);            if (!pn->pn_kid3)                return NULL;            MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_FINALLY);            js_PopStatement(tc);        } else {            pn->pn_kid3 = NULL;        }        if (!pn->pn_kid2 && !pn->pn_kid3) {            js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                        JSMSG_CATCH_OR_FINALLY);            return NULL;        }        tc->tryCount++;        return pn;      }      case TOK_THROW:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);        if (!pn)            return NULL;        pn2 = Expr(cx, ts, tc);        if (!pn2)            return NULL;        pn->pn_pos.end = pn2->pn_pos.end;        pn->pn_op = JSOP_THROW;        pn->pn_kid = pn2;        break;      /* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */      case TOK_CATCH:        js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                    JSMSG_CATCH_WITHOUT_TRY);        return NULL;      case TOK_FINALLY:        js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                    JSMSG_FINALLY_WITHOUT_TRY);        return NULL;#endif /* JS_HAS_EXCEPTIONS */      case TOK_BREAK:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);        if (!pn)            return NULL;        if (!MatchLabel(cx, ts, pn))            return NULL;        stmt = tc->topStmt;        label = pn->pn_atom;        if (label) {            for (; ; stmt = stmt->down) {                if (!stmt) {                    js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                                JSMSG_LABEL_NOT_FOUND);                    return NULL;                }                if (stmt->type == STMT_LABEL && stmt->label == label)                    break;            }        } else {            for (; ; stmt = stmt->down) {                if (!stmt) {                    js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                                JSMSG_TOUGH_BREAK);                    return NULL;                }                if (STMT_IS_LOOP(stmt) || stmt->type == STMT_SWITCH)                    break;            }        }        if (label)            pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;        break;      case TOK_CONTINUE:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);        if (!pn)            return NULL;        if (!MatchLabel(cx, ts, pn))            return NULL;        stmt = tc->topStmt;        label = pn->pn_atom;        if (label) {            for (stmt2 = NULL; ; stmt = stmt->down) {                if (!stmt) {                    js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                                JSMSG_LABEL_NOT_FOUND);                    return NULL;                }                if (stmt->type == STMT_LABEL) {                    if (stmt->label == label) {                        if (!stmt2 || !STMT_IS_LOOP(stmt2)) {                            js_ReportCompileErrorNumber(cx, ts, NULL,                                                        JSREPORT_ERROR,                                                        JSMSG_BAD_CONTINUE);                            return NULL;                        }                        break;                    }                } else {                    stmt2 = stmt;                }            }        } else {            for (; ; stmt = stmt->down) {                if (!stmt) {                    js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                                JSMSG_BAD_CONTINUE);                    return NULL;                }                if (STMT_IS_LOOP(stmt))                    break;            }        }        if (label)            pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;        break;      case TOK_WITH:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc);        if (!pn)            return NULL;        MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);        pn2 = Expr(cx, ts, tc);        if (!pn2)            return NULL;        MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH);        pn->pn_left = pn2;        js_PushStatement(tc, &stmtInfo, STMT_WITH, -1);        pn2 = Statement(cx, ts, tc);        if (!pn2)            return NULL;        js_PopStatement(tc);        /* Deprecate after parsing, in case of WERROR option. */        if (!js_ReportCompileErrorNumber(cx, ts, NULL,                                         JSREPORT_WARNING | JSREPORT_STRICT,                                         JSMSG_DEPRECATED_USAGE,                                         js_with_statement_str)) {            return NULL;        }        pn->pn_pos.end = pn2->pn_pos.end;        pn->pn_right = pn2;        tc->flags |= TCF_FUN_HEAVYWEIGHT;        return pn;      case TOK_VAR:        pn = Variables(cx, ts, tc);        if (!pn)            return NULL;        /* Tell js_EmitTree to generate a final POP. */        pn->pn_extra |= PNX_POPVAR;        break;      case TOK_RETURN:        if (!(tc->flags & TCF_IN_FUNCTION)) {            js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                        JSMSG_BAD_RETURN);            return NULL;        }        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);        if (!pn)            return NULL;        /* This is ugly, but we don't want to require a semicolon. */        ts->flags |= TSF_REGEXP;        tt = js_PeekTokenSameLine(cx, ts);        ts->flags &= ~TSF_REGEXP;        if (tt == TOK_ERROR)            return NULL;        if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {            pn2 = Expr(cx, ts, tc);            if (!pn2)                return NULL;            tc->flags |= TCF_RETURN_EXPR;            pn->pn_pos.end = pn2->pn_pos.end;            pn->pn_kid = pn2;        } else {            tc->flags |= TCF_RETURN_VOID;            pn->pn_kid = NULL;        }        if (JS_HAS_STRICT_OPTION(cx) &&            (~tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == 0) {            /*             * We must be in a frame with a non-native function, because             * we're compiling one.             */            if (!ReportNoReturnValue(cx, ts))                return NULL;        }        break;      case TOK_LC:        js_PushStatement(tc, &stmtInfo, STMT_BLOCK, -1);        pn = Statements(cx, ts, tc);        if (!pn)            return NULL;        MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_COMPOUND);        js_PopStatement(tc);        return pn;      case TOK_EOL:      case TOK_SEMI:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);        if (!pn)            return NULL;        pn->pn_type = TOK_SEMI;        pn->pn_kid = NULL;        return pn;#if JS_HAS_DEBUGGER_KEYWORD      case TOK_DEBUGGER:        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc);        if (!pn)            return NULL;        pn->pn_type = TOK_DEBUGGER;        tc->flags |= TCF_FUN_HEAVYWEIGHT;        break;#endif /* JS_HAS_DEBUGGER_KEYWORD */      case TOK_ERROR:        return NULL;      default:        js_UngetToken(ts);        pn2 = Expr(cx, ts, tc);        if (!pn2)            return NULL;        if (js_PeekToken(cx, ts) == TOK_COLON) {            if (pn2->pn_type != TOK_NAME) {                js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                            JSMSG_BAD_LABEL);                return NULL;            }            label = pn2->pn_atom;            for (stmt = tc->topStmt; stmt; stmt = stmt->down) {                if (stmt->type == STMT_LABEL && stmt->label == label) {                    js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                                JSMSG_DUPLICATE_LABEL);                    return NULL;                }            }            (void) js_GetToken(cx, ts);            /* Push a label struct and parse the statement. */            js_PushStatement(tc, &stmtInfo, STMT_LABEL, -1);            stmtInfo.label = label;            pn = Statement(cx, ts, tc);            if (!pn)                return NULL;            /* Pop the label, set pn_expr, and return early. */            js_PopStatement(tc);            pn2->pn_type = TOK_COLON;            pn2->pn_pos.end = pn->pn_pos.end;            pn2->pn_expr = pn;            return pn2;        }        pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc);        if (!pn)            return NULL;        pn->pn_type = TOK_SEMI;        pn->pn_pos = pn2->pn_pos;        pn->pn_kid = pn2;        break;    }    /* Check termination of this primitive statement. */    if (ON_CURRENT_LINE(ts, pn->pn_pos)) {        tt = js_PeekTokenSameLine(cx, ts);        if (tt == TOK_ERROR)            return NULL;        if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {            js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,                                        JSMSG_SEMI_BEFORE_STMNT);            return NULL;        }    }    (v

⌨️ 快捷键说明

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