Attachment #707407: Parser support for module declarations for bug #568953

View | Details | Raw Unified | Return to bug 568953
Collapse All | Expand All

(-)a/js/src/frontend/FoldConstants.cpp (-1 / +1 lines)
Line     Link Here 
 Lines 418-434   frontend::FoldConstants(JSContext *cx, P Link Here 
418
{
418
{
419
    ParseNode *pn = *pnp;
419
    ParseNode *pn = *pnp;
420
    ParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
420
    ParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
421
421
422
    JS_CHECK_RECURSION(cx, return false);
422
    JS_CHECK_RECURSION(cx, return false);
423
423
424
    switch (pn->getArity()) {
424
    switch (pn->getArity()) {
425
      case PN_MODULE:
425
      case PN_MODULE:
426
        if (!FoldConstants(cx, pn->pn_body, parser))
426
        if (!FoldConstants(cx, &pn->pn_body, parser))
427
            return false;
427
            return false;
428
        break;
428
        break;
429
429
430
      case PN_FUNC:
430
      case PN_FUNC:
431
        if (!FoldConstants(cx, &pn->pn_body, parser, pn->pn_funbox->inGenexpLambda))
431
        if (!FoldConstants(cx, &pn->pn_body, parser, pn->pn_funbox->inGenexpLambda))
432
            return false;
432
            return false;
433
        break;
433
        break;
434
434
(-)a/js/src/frontend/Parser.cpp (-1 / +45 lines)
Line     Link Here 
 Lines 406-422   FunctionBox::FunctionBox(JSContext *cx, Link Here 
406
        // eval(), so we have to look at |outerpc|'s scopeChain.
406
        // eval(), so we have to look at |outerpc|'s scopeChain.
407
        //
407
        //
408
        JSObject *scope = outerpc->sc->asGlobalSharedContext()->scopeChain();
408
        JSObject *scope = outerpc->sc->asGlobalSharedContext()->scopeChain();
409
        while (scope) {
409
        while (scope) {
410
            if (scope->isWith())
410
            if (scope->isWith())
411
                inWith = true;
411
                inWith = true;
412
            scope = scope->enclosingScope();
412
            scope = scope->enclosingScope();
413
        }
413
        }
414
    } else {
414
    } else if (outerpc->sc->isFunctionBox()) {
415
        // This is like the above case, but for more deeply nested functions.
415
        // This is like the above case, but for more deeply nested functions.
416
        // For example:
416
        // For example:
417
        //
417
        //
418
        //   with (o) { eval("(function() { (function() { g(); })(); })();"); } }
418
        //   with (o) { eval("(function() { (function() { g(); })(); })();"); } }
419
        //
419
        //
420
        // In this case, the inner anonymous function needs to inherit the
420
        // In this case, the inner anonymous function needs to inherit the
421
        // setting of |inWith| from the outer one.
421
        // setting of |inWith| from the outer one.
422
        FunctionBox *parent = outerpc->sc->asFunctionBox();
422
        FunctionBox *parent = outerpc->sc->asFunctionBox();
 Lines 1820-1835   Parser::functionArgsAndBody(ParseNode *p Link Here 
1820
1820
1821
    if (!LeaveFunction(pn, this, funName, kind))
1821
    if (!LeaveFunction(pn, this, funName, kind))
1822
        return false;
1822
        return false;
1823
1823
1824
    return true;
1824
    return true;
1825
}
1825
}
1826
1826
1827
ParseNode *
1827
ParseNode *
1828
Parser::moduleStmt()
1829
{
1830
    JS_ASSERT(versionNumber() == JSVERSION_ECMA_5);
1831
    JS_ASSERT(tokenStream.currentToken().name() == context->runtime->atomState.module);
1832
    if (!((pc->sc->isGlobalSharedContext() || pc->sc->isModuleBox()) && pc->atBodyLevel()))
1833
    {
1834
        reportError(NULL, JSMSG_MODULE_STATEMENT);
1835
        return NULL;
1836
    }
1837
1838
    ParseNode *pn = ModuleNode::create(PNK_MODULE, this);
1839
    if (!pn)
1840
        return NULL;
1841
    JS_ALWAYS_TRUE(tokenStream.matchToken(TOK_STRING));
1842
    Module *module = js_NewModule(context, tokenStream.currentToken().atom());
1843
    if (!module)
1844
        return NULL;
1845
    ModuleBox *modulebox = newModuleBox(module, pc);
1846
    if (!modulebox)
1847
        return NULL;
1848
    pn->pn_modulebox = modulebox;
1849
1850
    ParseContext modulepc(this, modulebox, pc->staticLevel + 1, pc->blockidGen);
1851
    if (!modulepc.init())
1852
        return NULL;
1853
    MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_MODULE);
1854
    pn->pn_body = statements();
1855
    if (!pn->pn_body)
1856
        return NULL;
1857
    MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_MODULE);
1858
1859
    return pn;
1860
}
1861
1862
ParseNode *
1828
Parser::functionStmt()
1863
Parser::functionStmt()
1829
{
1864
{
1830
    JS_ASSERT(tokenStream.currentToken().type == TOK_FUNCTION);
1865
    JS_ASSERT(tokenStream.currentToken().type == TOK_FUNCTION);
1831
    RootedPropertyName name(context);
1866
    RootedPropertyName name(context);
1832
    if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME) {
1867
    if (tokenStream.getToken(TSF_KEYWORD_IS_NAME) == TOK_NAME) {
1833
        name = tokenStream.currentToken().name();
1868
        name = tokenStream.currentToken().name();
1834
    } else {
1869
    } else {
1835
        /* Unnamed function expressions are forbidden in statement context. */
1870
        /* Unnamed function expressions are forbidden in statement context. */
 Lines 4070-4085   Parser::statement() Link Here 
4070
        pn->pn_kid = pn2;
4105
        pn->pn_kid = pn2;
4071
        break;
4106
        break;
4072
      }
4107
      }
4073
#endif
4108
#endif
4074
4109
4075
      case TOK_ERROR:
4110
      case TOK_ERROR:
4076
        return NULL;
4111
        return NULL;
4077
4112
4113
      case TOK_NAME:
4114
        if (versionNumber() == JSVERSION_ECMA_5 &&
4115
            tokenStream.currentToken().name() == context->names().module &&
4116
            tokenStream.peekTokenSameLine(TSF_OPERAND) == TOK_STRING)
4117
        {
4118
            return moduleStmt();
4119
        }
4120
4078
      default:
4121
      default:
4079
        return expressionStatement();
4122
        return expressionStatement();
4080
    }
4123
    }
4081
4124
4082
    /* Check termination of this primitive statement. */
4125
    /* Check termination of this primitive statement. */
4083
    return MatchOrInsertSemicolon(context, &tokenStream) ? pn : NULL;
4126
    return MatchOrInsertSemicolon(context, &tokenStream) ? pn : NULL;
4084
}
4127
}
4085
4128
 Lines 4944-4959   CompExprTransplanter::transplant(ParseNo Link Here 
4944
        }
4987
        }
4945
        break;
4988
        break;
4946
4989
4947
      case PN_UNARY:
4990
      case PN_UNARY:
4948
        if (!transplant(pn->pn_kid))
4991
        if (!transplant(pn->pn_kid))
4949
            return false;
4992
            return false;
4950
        break;
4993
        break;
4951
4994
4995
      case PN_MODULE:
4952
      case PN_FUNC:
4996
      case PN_FUNC:
4953
      case PN_NAME:
4997
      case PN_NAME:
4954
        if (!transplant(pn->maybeExpr()))
4998
        if (!transplant(pn->maybeExpr()))
4955
            return false;
4999
            return false;
4956
5000
4957
        if (pn->isDefn()) {
5001
        if (pn->isDefn()) {
4958
            if (genexp && !BumpStaticLevel(pn, pc))
5002
            if (genexp && !BumpStaticLevel(pn, pc))
4959
                return false;
5003
                return false;
(-)a/js/src/frontend/Parser.h (+1 lines)
Line     Link Here 
 Lines 373-388   struct Parser : private AutoGCRooter Link Here 
373
     * Parsers whose name has a '1' suffix leave the TokenStream state
373
     * Parsers whose name has a '1' suffix leave the TokenStream state
374
     * pointing to the token one past the end of the parsed fragment.  For a
374
     * pointing to the token one past the end of the parsed fragment.  For a
375
     * number of the parsers this is convenient and avoids a lot of
375
     * number of the parsers this is convenient and avoids a lot of
376
     * unnecessary ungetting and regetting of tokens.
376
     * unnecessary ungetting and regetting of tokens.
377
     *
377
     *
378
     * Some parsers have two versions:  an always-inlined version (with an 'i'
378
     * Some parsers have two versions:  an always-inlined version (with an 'i'
379
     * suffix) and a never-inlined version (with an 'n' suffix).
379
     * suffix) and a never-inlined version (with an 'n' suffix).
380
     */
380
     */
381
    ParseNode *moduleStmt();
381
    ParseNode *functionStmt();
382
    ParseNode *functionStmt();
382
    ParseNode *functionExpr();
383
    ParseNode *functionExpr();
383
    ParseNode *statements(bool *hasFunctionStmt = NULL);
384
    ParseNode *statements(bool *hasFunctionStmt = NULL);
384
385
385
    ParseNode *switchStatement();
386
    ParseNode *switchStatement();
386
    ParseNode *forStatement();
387
    ParseNode *forStatement();
387
    ParseNode *tryStatement();
388
    ParseNode *tryStatement();
388
    ParseNode *withStatement();
389
    ParseNode *withStatement();
(-)a/js/src/js.msg (+3 lines)
Line     Link Here 
 Lines 383-390   MSG_DEF(JSMSG_INVALID_LANGUAGE_TAG, 32 Link Here 
383
MSG_DEF(JSMSG_INVALID_LOCALE_MATCHER, 330, 1, JSEXN_RANGEERR, "invalid locale matcher in supportedLocalesOf(): {0}")
383
MSG_DEF(JSMSG_INVALID_LOCALE_MATCHER, 330, 1, JSEXN_RANGEERR, "invalid locale matcher in supportedLocalesOf(): {0}")
384
MSG_DEF(JSMSG_INVALID_OPTION_VALUE,   331, 2, JSEXN_RANGEERR, "invalid value {1} for option {0}")
384
MSG_DEF(JSMSG_INVALID_OPTION_VALUE,   331, 2, JSEXN_RANGEERR, "invalid value {1} for option {0}")
385
MSG_DEF(JSMSG_INVALID_DIGITS_VALUE,   332, 1, JSEXN_RANGEERR, "invalid digits value: {0}")
385
MSG_DEF(JSMSG_INVALID_DIGITS_VALUE,   332, 1, JSEXN_RANGEERR, "invalid digits value: {0}")
386
MSG_DEF(JSMSG_INTL_OBJECT_REINITED,   333, 0, JSEXN_TYPEERR, "can't initialize object twice as an object of an Intl constructor")
386
MSG_DEF(JSMSG_INTL_OBJECT_REINITED,   333, 0, JSEXN_TYPEERR, "can't initialize object twice as an object of an Intl constructor")
387
MSG_DEF(JSMSG_INVALID_CURRENCY_CODE,  334, 1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}")
387
MSG_DEF(JSMSG_INVALID_CURRENCY_CODE,  334, 1, JSEXN_RANGEERR, "invalid currency code in NumberFormat(): {0}")
388
MSG_DEF(JSMSG_UNDEFINED_CURRENCY,     335, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style")
388
MSG_DEF(JSMSG_UNDEFINED_CURRENCY,     335, 0, JSEXN_TYPEERR, "undefined currency in NumberFormat() with currency style")
389
MSG_DEF(JSMSG_INVALID_TIME_ZONE,      336, 1, JSEXN_RANGEERR, "invalid time zone in DateTimeFormat(): {0}")
389
MSG_DEF(JSMSG_INVALID_TIME_ZONE,      336, 1, JSEXN_RANGEERR, "invalid time zone in DateTimeFormat(): {0}")
390
MSG_DEF(JSMSG_DATE_NOT_FINITE,        337, 0, JSEXN_RANGEERR, "date value is not finite in DateTimeFormat.format()")
390
MSG_DEF(JSMSG_DATE_NOT_FINITE,        337, 0, JSEXN_RANGEERR, "date value is not finite in DateTimeFormat.format()")
391
MSG_DEF(JSMSG_MODULE_STATEMENT,       338, 0, JSEXN_SYNTAXERR, "module declarations may only appear at the top level of a program or module body")
392
MSG_DEF(JSMSG_CURLY_BEFORE_MODULE,    339, 0, JSEXN_SYNTAXERR, "missing { before module body")
393
MSG_DEF(JSMSG_CURLY_AFTER_MODULE,     340, 0, JSEXN_SYNTAXERR, "missing } after module body")
(-)a/js/src/vm/CommonPropertyNames.h (+1 lines)
Line     Link Here 
 Lines 100-115    Link Here 
100
    macro(lastIndex, lastIndex, "lastIndex") \
100
    macro(lastIndex, lastIndex, "lastIndex") \
101
    macro(length, length, "length") \
101
    macro(length, length, "length") \
102
    macro(line, line, "line") \
102
    macro(line, line, "line") \
103
    macro(lineNumber, lineNumber, "lineNumber") \
103
    macro(lineNumber, lineNumber, "lineNumber") \
104
    macro(loc, loc, "loc") \
104
    macro(loc, loc, "loc") \
105
    macro(lookupGetter, lookupGetter, "__lookupGetter__") \
105
    macro(lookupGetter, lookupGetter, "__lookupGetter__") \
106
    macro(lookupSetter, lookupSetter, "__lookupSetter__") \
106
    macro(lookupSetter, lookupSetter, "__lookupSetter__") \
107
    macro(message, message, "message") \
107
    macro(message, message, "message") \
108
    macro(module, module, "module") \
108
    macro(multiline, multiline, "multiline") \
109
    macro(multiline, multiline, "multiline") \
109
    macro(name, name, "name") \
110
    macro(name, name, "name") \
110
    macro(NaN, NaN, "NaN") \
111
    macro(NaN, NaN, "NaN") \
111
    macro(next, next, "next") \
112
    macro(next, next, "next") \
112
    macro(noSuchMethod, noSuchMethod, "__noSuchMethod__") \
113
    macro(noSuchMethod, noSuchMethod, "__noSuchMethod__") \
113
    macro(NumberFormat, NumberFormat, "NumberFormat") \
114
    macro(NumberFormat, NumberFormat, "NumberFormat") \
114
    macro(NumberFormatFormat, NumberFormatFormat, "Intl_NumberFormat_format") \
115
    macro(NumberFormatFormat, NumberFormatFormat, "Intl_NumberFormat_format") \
115
    macro(objectNull, objectNull, "[object Null]") \
116
    macro(objectNull, objectNull, "[object Null]") \

Return to bug 568953