js/src/frontend/Parser.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef frontend_Parser_h
     8 #define frontend_Parser_h
    10 /*
    11  * JS parser definitions.
    12  */
    14 #include "jspubtd.h"
    16 #include "frontend/BytecodeCompiler.h"
    17 #include "frontend/FullParseHandler.h"
    18 #include "frontend/ParseMaps.h"
    19 #include "frontend/ParseNode.h"
    20 #include "frontend/SharedContext.h"
    21 #include "frontend/SyntaxParseHandler.h"
    23 namespace js {
    24 namespace frontend {
    26 struct StmtInfoPC : public StmtInfoBase {
    27     StmtInfoPC      *down;          /* info for enclosing statement */
    28     StmtInfoPC      *downScope;     /* next enclosing lexical scope */
    30     uint32_t        blockid;        /* for simplified dominance computation */
    31     uint32_t        innerBlockScopeDepth; /* maximum depth of nested block scopes, in slots */
    33     StmtInfoPC(ExclusiveContext *cx) : StmtInfoBase(cx), innerBlockScopeDepth(0) {}
    34 };
    36 typedef HashSet<JSAtom *> FuncStmtSet;
    37 class SharedContext;
    39 typedef Vector<Definition *, 16> DeclVector;
    41 struct GenericParseContext
    42 {
    43     // Enclosing function or global context.
    44     GenericParseContext *parent;
    46     // Context shared between parsing and bytecode generation.
    47     SharedContext *sc;
    49     // The following flags are set when a particular code feature is detected
    50     // in a function.
    52     // Function has 'return <expr>;'
    53     bool funHasReturnExpr:1;
    55     // Function has 'return;'
    56     bool funHasReturnVoid:1;
    58     // The following flags are set when parsing enters a particular region of
    59     // source code, and cleared when that region is exited.
    61     // true while parsing init expr of for; exclude 'in'
    62     bool parsingForInit:1;
    64     // true while we are within a with-statement in the current ParseContext
    65     // chain (which stops at the top-level or an eval()
    66     bool parsingWith:1;
    68     GenericParseContext(GenericParseContext *parent, SharedContext *sc)
    69       : parent(parent),
    70         sc(sc),
    71         funHasReturnExpr(false),
    72         funHasReturnVoid(false),
    73         parsingForInit(false),
    74         parsingWith(parent ? parent->parsingWith : false)
    75     {}
    76 };
    78 template <typename ParseHandler>
    79 bool
    80 GenerateBlockId(TokenStream &ts, ParseContext<ParseHandler> *pc, uint32_t &blockid);
    82 /*
    83  * The struct ParseContext stores information about the current parsing context,
    84  * which is part of the parser state (see the field Parser::pc). The current
    85  * parsing context is either the global context, or the function currently being
    86  * parsed. When the parser encounters a function definition, it creates a new
    87  * ParseContext, makes it the new current context, and sets its parent to the
    88  * context in which it encountered the definition.
    89  */
    90 template <typename ParseHandler>
    91 struct ParseContext : public GenericParseContext
    92 {
    93     typedef StmtInfoPC StmtInfo;
    94     typedef typename ParseHandler::Node Node;
    95     typedef typename ParseHandler::DefinitionNode DefinitionNode;
    97     uint32_t        bodyid;         /* block number of program/function body */
    98     uint32_t        blockidGen;     /* preincremented block number generator */
   100     StmtInfoPC      *topStmt;       /* top of statement info stack */
   101     StmtInfoPC      *topScopeStmt;  /* top lexical scope statement */
   102     Rooted<NestedScopeObject *> staticScope;  /* compile time scope chain */
   103     Node            maybeFunction;  /* sc->isFunctionBox, the pn where pn->pn_funbox == sc */
   105     const unsigned  staticLevel;    /* static compilation unit nesting level */
   107     // lastYieldOffset stores the offset of the last yield that was parsed.
   108     // NoYieldOffset is its initial value.
   109     static const uint32_t NoYieldOffset = UINT32_MAX;
   110     uint32_t         lastYieldOffset;
   112     // Most functions start off being parsed as non-generators.
   113     // Non-generators transition to LegacyGenerator on parsing "yield" in JS 1.7.
   114     // An ES6 generator is marked as a "star generator" before its body is parsed.
   115     GeneratorKind generatorKind() const {
   116         return sc->isFunctionBox() ? sc->asFunctionBox()->generatorKind() : NotGenerator;
   117     }
   118     bool isGenerator() const { return generatorKind() != NotGenerator; }
   119     bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; }
   120     bool isStarGenerator() const { return generatorKind() == StarGenerator; }
   122     bool isArrowFunction() const {
   123         return sc->isFunctionBox() && sc->asFunctionBox()->function()->isArrow();
   124     }
   126     uint32_t        blockScopeDepth; /* maximum depth of nested block scopes, in slots */
   127     Node            blockNode;      /* parse node for a block with let declarations
   128                                        (block with its own lexical scope)  */
   129   private:
   130     AtomDecls<ParseHandler> decls_; /* function, const, and var declarations */
   131     DeclVector      args_;          /* argument definitions */
   132     DeclVector      vars_;          /* var/const definitions */
   134   public:
   135     const AtomDecls<ParseHandler> &decls() const {
   136         return decls_;
   137     }
   139     uint32_t numArgs() const {
   140         JS_ASSERT(sc->isFunctionBox());
   141         return args_.length();
   142     }
   144     /*
   145      * This function adds a definition to the lexical scope represented by this
   146      * ParseContext.
   147      *
   148      * Pre-conditions:
   149      *  + The caller must have already taken care of name collisions:
   150      *    - For non-let definitions, this means 'name' isn't in 'decls'.
   151      *    - For let definitions, this means 'name' isn't already a name in the
   152      *      current block.
   153      *  + The given 'pn' is either a placeholder (created by a previous unbound
   154      *    use) or an un-bound un-linked name node.
   155      *  + The given 'kind' is one of ARG, CONST, VAR, or LET. In particular,
   156      *    NAMED_LAMBDA is handled in an ad hoc special case manner (see
   157      *    LeaveFunction) that we should consider rewriting.
   158      *
   159      * Post-conditions:
   160      *  + pc->decls().lookupFirst(name) == pn
   161      *  + The given name 'pn' has been converted in-place into a
   162      *    non-placeholder definition.
   163      *  + If this is a function scope (sc->inFunction), 'pn' is bound to a
   164      *    particular local/argument slot.
   165      *  + PND_CONST is set for Definition::COSNT
   166      *  + Pre-existing uses of pre-existing placeholders have been linked to
   167      *    'pn' if they are in the scope of 'pn'.
   168      *  + Pre-existing placeholders in the scope of 'pn' have been removed.
   169      */
   170     bool define(TokenStream &ts, HandlePropertyName name, Node pn, Definition::Kind);
   172     /*
   173      * Let definitions may shadow same-named definitions in enclosing scopes.
   174      * To represesent this, 'decls' is not a plain map, but actually:
   175      *   decls :: name -> stack of definitions
   176      * New bindings are pushed onto the stack, name lookup always refers to the
   177      * top of the stack, and leaving a block scope calls popLetDecl for each
   178      * name in the block's scope.
   179      */
   180     void popLetDecl(JSAtom *atom);
   182     /* See the sad story in defineArg. */
   183     void prepareToAddDuplicateArg(HandlePropertyName name, DefinitionNode prevDecl);
   185     /* See the sad story in MakeDefIntoUse. */
   186     void updateDecl(JSAtom *atom, Node newDecl);
   188     /*
   189      * After a function body has been parsed, the parser generates the
   190      * function's "bindings". Bindings are a data-structure, ultimately stored
   191      * in the compiled JSScript, that serve three purposes:
   192      *  - After parsing, the ParseContext is destroyed and 'decls' along with
   193      *    it. Mostly, the emitter just uses the binding information stored in
   194      *    the use/def nodes, but the emitter occasionally needs 'bindings' for
   195      *    various scope-related queries.
   196      *  - Bindings provide the initial js::Shape to use when creating a dynamic
   197      *    scope object (js::CallObject) for the function. This shape is used
   198      *    during dynamic name lookup.
   199      *  - Sometimes a script's bindings are accessed at runtime to retrieve the
   200      *    contents of the lexical scope (e.g., from the debugger).
   201      */
   202     bool generateFunctionBindings(ExclusiveContext *cx, TokenStream &ts,
   203                                   LifoAlloc &alloc,
   204                                   InternalHandle<Bindings*> bindings) const;
   206   private:
   207     ParseContext    **parserPC;     /* this points to the Parser's active pc
   208                                        and holds either |this| or one of
   209                                        |this|'s descendents */
   211     // Value for parserPC to restore at the end. Use 'parent' instead for
   212     // information about the parse chain, this may be nullptr if
   213     // parent != nullptr.
   214     ParseContext<ParseHandler> *oldpc;
   216   public:
   217     OwnedAtomDefnMapPtr lexdeps;    /* unresolved lexical name dependencies */
   219     FuncStmtSet     *funcStmts;     /* Set of (non-top-level) function statements
   220                                        that will alias any top-level bindings with
   221                                        the same name. */
   223     // All inner functions in this context. Only filled in when parsing syntax.
   224     AutoFunctionVector innerFunctions;
   226     // In a function context, points to a Directive struct that can be updated
   227     // to reflect new directives encountered in the Directive Prologue that
   228     // require reparsing the function. In global/module/generator-tail contexts,
   229     // we don't need to reparse when encountering a DirectivePrologue so this
   230     // pointer may be nullptr.
   231     Directives *newDirectives;
   233     // Set when parsing a declaration-like destructuring pattern.  This flag
   234     // causes PrimaryExpr to create PN_NAME parse nodes for variable references
   235     // which are not hooked into any definition's use chain, added to any tree
   236     // context's AtomList, etc. etc.  CheckDestructuring will do that work
   237     // later.
   238     //
   239     // The comments atop CheckDestructuring explain the distinction between
   240     // assignment-like and declaration-like destructuring patterns, and why
   241     // they need to be treated differently.
   242     bool            inDeclDestructuring:1;
   244     ParseContext(Parser<ParseHandler> *prs, GenericParseContext *parent,
   245                  Node maybeFunction, SharedContext *sc,
   246                  Directives *newDirectives,
   247                  unsigned staticLevel, uint32_t bodyid, uint32_t blockScopeDepth)
   248       : GenericParseContext(parent, sc),
   249         bodyid(0),           // initialized in init()
   250         blockidGen(bodyid),  // used to set |bodyid| and subsequently incremented in init()
   251         topStmt(nullptr),
   252         topScopeStmt(nullptr),
   253         staticScope(prs->context),
   254         maybeFunction(maybeFunction),
   255         staticLevel(staticLevel),
   256         lastYieldOffset(NoYieldOffset),
   257         blockScopeDepth(blockScopeDepth),
   258         blockNode(ParseHandler::null()),
   259         decls_(prs->context, prs->alloc),
   260         args_(prs->context),
   261         vars_(prs->context),
   262         parserPC(&prs->pc),
   263         oldpc(prs->pc),
   264         lexdeps(prs->context),
   265         funcStmts(nullptr),
   266         innerFunctions(prs->context),
   267         newDirectives(newDirectives),
   268         inDeclDestructuring(false)
   269     {
   270         prs->pc = this;
   271     }
   273     ~ParseContext();
   275     bool init(TokenStream &ts);
   277     unsigned blockid() { return topStmt ? topStmt->blockid : bodyid; }
   279     // True if we are at the topmost level of a entire script or function body.
   280     // For example, while parsing this code we would encounter f1 and f2 at
   281     // body level, but we would not encounter f3 or f4 at body level:
   282     //
   283     //   function f1() { function f2() { } }
   284     //   if (cond) { function f3() { if (cond) { function f4() { } } } }
   285     //
   286     bool atBodyLevel() { return !topStmt; }
   288     // True if this is the ParseContext for the body of a function created by
   289     // the Function constructor.
   290     bool isFunctionConstructorBody() const {
   291         return sc->isFunctionBox() && staticLevel == 0;
   292     }
   294     inline bool useAsmOrInsideUseAsm() const {
   295         return sc->isFunctionBox() && sc->asFunctionBox()->useAsmOrInsideUseAsm();
   296     }
   297 };
   299 template <typename ParseHandler>
   300 inline
   301 Directives::Directives(ParseContext<ParseHandler> *parent)
   302   : strict_(parent->sc->strict),
   303     asmJS_(parent->useAsmOrInsideUseAsm())
   304 {}
   306 template <typename ParseHandler>
   307 struct BindData;
   309 class CompExprTransplanter;
   311 enum LetContext { LetExpresion, LetStatement };
   312 enum VarContext { HoistVars, DontHoistVars };
   313 enum FunctionType { Getter, Setter, Normal };
   315 template <typename ParseHandler>
   316 class Parser : private AutoGCRooter, public StrictModeGetter
   317 {
   318   public:
   319     ExclusiveContext *const context;
   320     LifoAlloc &alloc;
   322     TokenStream         tokenStream;
   323     LifoAlloc::Mark     tempPoolMark;
   325     /* list of parsed objects for GC tracing */
   326     ObjectBox *traceListHead;
   328     /* innermost parse context (stack-allocated) */
   329     ParseContext<ParseHandler> *pc;
   331     /* Compression token for aborting. */
   332     SourceCompressionTask *sct;
   334     ScriptSource        *ss;
   336     /* Root atoms and objects allocated for the parsed tree. */
   337     AutoKeepAtoms       keepAtoms;
   339     /* Perform constant-folding; must be true when interfacing with the emitter. */
   340     const bool          foldConstants:1;
   342   private:
   343     /*
   344      * Not all language constructs can be handled during syntax parsing. If it
   345      * is not known whether the parse succeeds or fails, this bit is set and
   346      * the parse will return false.
   347      */
   348     bool abortedSyntaxParse:1;
   350     /* Unexpected end of input, i.e. TOK_EOF not at top-level. */
   351     bool isUnexpectedEOF_:1;
   353     typedef typename ParseHandler::Node Node;
   354     typedef typename ParseHandler::DefinitionNode DefinitionNode;
   356   public:
   357     /* State specific to the kind of parse being performed. */
   358     ParseHandler handler;
   360   private:
   361     bool reportHelper(ParseReportKind kind, bool strict, uint32_t offset,
   362                       unsigned errorNumber, va_list args);
   363   public:
   364     bool report(ParseReportKind kind, bool strict, Node pn, unsigned errorNumber, ...);
   365     bool reportNoOffset(ParseReportKind kind, bool strict, unsigned errorNumber, ...);
   366     bool reportWithOffset(ParseReportKind kind, bool strict, uint32_t offset, unsigned errorNumber,
   367                           ...);
   369     Parser(ExclusiveContext *cx, LifoAlloc *alloc, const ReadOnlyCompileOptions &options,
   370            const jschar *chars, size_t length, bool foldConstants,
   371            Parser<SyntaxParseHandler> *syntaxParser,
   372            LazyScript *lazyOuterFunction);
   373     ~Parser();
   375     // A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
   376     // Parser's state. Note: clients must still take care that any ParseContext
   377     // that points into released ParseNodes is destroyed.
   378     class Mark
   379     {
   380         friend class Parser;
   381         LifoAlloc::Mark mark;
   382         ObjectBox *traceListHead;
   383     };
   384     Mark mark() const {
   385         Mark m;
   386         m.mark = alloc.mark();
   387         m.traceListHead = traceListHead;
   388         return m;
   389     }
   390     void release(Mark m) {
   391         alloc.release(m.mark);
   392         traceListHead = m.traceListHead;
   393     }
   395     friend void js::frontend::MarkParser(JSTracer *trc, AutoGCRooter *parser);
   397     const char *getFilename() const { return tokenStream.getFilename(); }
   398     JSVersion versionNumber() const { return tokenStream.versionNumber(); }
   400     /*
   401      * Parse a top-level JS script.
   402      */
   403     Node parse(JSObject *chain);
   405     /*
   406      * Allocate a new parsed object or function container from
   407      * cx->tempLifoAlloc.
   408      */
   409     ObjectBox *newObjectBox(JSObject *obj);
   410     FunctionBox *newFunctionBox(Node fn, JSFunction *fun, ParseContext<ParseHandler> *pc,
   411                                 Directives directives, GeneratorKind generatorKind);
   413     /*
   414      * Create a new function object given parse context (pc) and a name (which
   415      * is optional if this is a function expression).
   416      */
   417     JSFunction *newFunction(GenericParseContext *pc, HandleAtom atom, FunctionSyntaxKind kind,
   418                             JSObject *proto = nullptr);
   420     void trace(JSTracer *trc);
   422     bool hadAbortedSyntaxParse() {
   423         return abortedSyntaxParse;
   424     }
   425     void clearAbortedSyntaxParse() {
   426         abortedSyntaxParse = false;
   427     }
   429     bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
   431   private:
   432     Parser *thisForCtor() { return this; }
   434     Node stringLiteral();
   435     inline Node newName(PropertyName *name);
   437     inline bool abortIfSyntaxParser();
   439   public:
   441     /* Public entry points for parsing. */
   442     Node statement(bool canHaveDirectives = false);
   443     bool maybeParseDirective(Node list, Node pn, bool *cont);
   445     // Parse a function, given only its body. Used for the Function and
   446     // Generator constructors.
   447     Node standaloneFunctionBody(HandleFunction fun, const AutoNameVector &formals,
   448                                 GeneratorKind generatorKind,
   449                                 Directives inheritedDirectives, Directives *newDirectives);
   451     // Parse a function, given only its arguments and body. Used for lazily
   452     // parsed functions.
   453     Node standaloneLazyFunction(HandleFunction fun, unsigned staticLevel, bool strict,
   454                                 GeneratorKind generatorKind);
   456     /*
   457      * Parse a function body.  Pass StatementListBody if the body is a list of
   458      * statements; pass ExpressionBody if the body is a single expression.
   459      */
   460     enum FunctionBodyType { StatementListBody, ExpressionBody };
   461     Node functionBody(FunctionSyntaxKind kind, FunctionBodyType type);
   463     bool functionArgsAndBodyGeneric(Node pn, HandleFunction fun, FunctionType type,
   464                                     FunctionSyntaxKind kind, Directives *newDirectives);
   466     // Determine whether |yield| is a valid name in the current context, or
   467     // whether it's prohibited due to strictness, JS version, or occurrence
   468     // inside a star generator.
   469     bool checkYieldNameValidity();
   471     virtual bool strictMode() { return pc->sc->strict; }
   473     const ReadOnlyCompileOptions &options() const {
   474         return tokenStream.options();
   475     }
   477   private:
   478     /*
   479      * JS parsers, from lowest to highest precedence.
   480      *
   481      * Each parser must be called during the dynamic scope of a ParseContext
   482      * object, pointed to by this->pc.
   483      *
   484      * Each returns a parse node tree or null on error.
   485      *
   486      * Parsers whose name has a '1' suffix leave the TokenStream state
   487      * pointing to the token one past the end of the parsed fragment.  For a
   488      * number of the parsers this is convenient and avoids a lot of
   489      * unnecessary ungetting and regetting of tokens.
   490      *
   491      * Some parsers have two versions:  an always-inlined version (with an 'i'
   492      * suffix) and a never-inlined version (with an 'n' suffix).
   493      */
   494     Node functionStmt();
   495     Node functionExpr();
   496     Node statements();
   498     Node blockStatement();
   499     Node ifStatement();
   500     Node doWhileStatement();
   501     Node whileStatement();
   502     Node forStatement();
   503     Node switchStatement();
   504     Node continueStatement();
   505     Node breakStatement();
   506     Node returnStatement();
   507     Node withStatement();
   508     Node labeledStatement();
   509     Node throwStatement();
   510     Node tryStatement();
   511     Node debuggerStatement();
   513     Node letDeclaration();
   514     Node letStatement();
   515     Node importDeclaration();
   516     Node exportDeclaration();
   517     Node expressionStatement();
   518     Node variables(ParseNodeKind kind, bool *psimple = nullptr,
   519                    StaticBlockObject *blockObj = nullptr,
   520                    VarContext varContext = HoistVars);
   521     Node expr();
   522     Node assignExpr();
   523     Node assignExprWithoutYield(unsigned err);
   524     Node yieldExpression();
   525     Node condExpr1();
   526     Node orExpr1();
   527     Node unaryExpr();
   528     Node memberExpr(TokenKind tt, bool allowCallSyntax);
   529     Node primaryExpr(TokenKind tt);
   530     Node parenExprOrGeneratorComprehension();
   531     Node exprInParens();
   533     /*
   534      * Additional JS parsers.
   535      */
   536     bool functionArguments(FunctionSyntaxKind kind, Node *list, Node funcpn, bool *hasRest);
   538     Node functionDef(HandlePropertyName name, const TokenStream::Position &start,
   539                      FunctionType type, FunctionSyntaxKind kind, GeneratorKind generatorKind);
   540     bool functionArgsAndBody(Node pn, HandleFunction fun,
   541                              FunctionType type, FunctionSyntaxKind kind,
   542                              GeneratorKind generatorKind,
   543                              Directives inheritedDirectives, Directives *newDirectives);
   545     Node unaryOpExpr(ParseNodeKind kind, JSOp op, uint32_t begin);
   547     Node condition();
   549     Node generatorComprehensionLambda(GeneratorKind comprehensionKind, unsigned begin,
   550                                       Node innerStmt);
   552     Node legacyComprehensionTail(Node kid, unsigned blockid, GeneratorKind comprehensionKind,
   553                                  ParseContext<ParseHandler> *outerpc,
   554                                  unsigned innerBlockScopeDepth);
   555     Node legacyArrayComprehension(Node array);
   556     Node legacyGeneratorExpr(Node kid);
   558     Node comprehensionTail(GeneratorKind comprehensionKind);
   559     Node comprehensionIf(GeneratorKind comprehensionKind);
   560     Node comprehensionFor(GeneratorKind comprehensionKind);
   561     Node comprehension(GeneratorKind comprehensionKind);
   562     Node arrayComprehension(uint32_t begin);
   563     Node generatorComprehension(uint32_t begin);
   565     bool argumentList(Node listNode, bool *isSpread);
   566     Node letBlock(LetContext letContext);
   567     Node destructuringExpr(BindData<ParseHandler> *data, TokenKind tt);
   569     Node identifierName();
   571     bool matchLabel(MutableHandle<PropertyName*> label);
   573     bool allowsForEachIn() {
   574 #if !JS_HAS_FOR_EACH_IN
   575         return false;
   576 #else
   577         return versionNumber() >= JSVERSION_1_6;
   578 #endif
   579     }
   581     enum AssignmentFlavor {
   582         PlainAssignment,
   583         CompoundAssignment,
   584         KeyedDestructuringAssignment,
   585         IncDecAssignment
   586     };
   588     bool checkAndMarkAsAssignmentLhs(Node pn, AssignmentFlavor flavor);
   589     bool matchInOrOf(bool *isForOfp);
   591     bool checkFunctionArguments();
   592     bool makeDefIntoUse(Definition *dn, Node pn, JSAtom *atom);
   593     bool checkFunctionDefinition(HandlePropertyName funName, Node *pn, FunctionSyntaxKind kind,
   594                                  bool *pbodyProcessed);
   595     bool finishFunctionDefinition(Node pn, FunctionBox *funbox, Node prelude, Node body);
   596     bool addFreeVariablesFromLazyFunction(JSFunction *fun, ParseContext<ParseHandler> *pc);
   598     bool isValidForStatementLHS(Node pn1, JSVersion version, bool forDecl, bool forEach,
   599                                 ParseNodeKind headKind);
   600     bool checkAndMarkAsIncOperand(Node kid, TokenKind tt, bool preorder);
   601     bool checkStrictAssignment(Node lhs, AssignmentFlavor flavor);
   602     bool checkStrictBinding(PropertyName *name, Node pn);
   603     bool defineArg(Node funcpn, HandlePropertyName name,
   604                    bool disallowDuplicateArgs = false, Node *duplicatedArg = nullptr);
   605     Node pushLexicalScope(StmtInfoPC *stmt);
   606     Node pushLexicalScope(Handle<StaticBlockObject*> blockObj, StmtInfoPC *stmt);
   607     Node pushLetScope(Handle<StaticBlockObject*> blockObj, StmtInfoPC *stmt);
   608     bool noteNameUse(HandlePropertyName name, Node pn);
   609     Node objectLiteral();
   610     Node arrayInitializer();
   611     Node newRegExp();
   613     Node newBindingNode(PropertyName *name, bool functionScope, VarContext varContext = HoistVars);
   614     bool checkDestructuring(BindData<ParseHandler> *data, Node left, bool toplevel = true);
   615     bool bindDestructuringVar(BindData<ParseHandler> *data, Node pn);
   616     bool bindDestructuringLHS(Node pn);
   617     bool makeSetCall(Node pn, unsigned msg);
   618     Node cloneLeftHandSide(Node opn);
   619     Node cloneParseTree(Node opn);
   621     Node newNumber(const Token &tok) {
   622         return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
   623     }
   625     static bool
   626     bindDestructuringArg(BindData<ParseHandler> *data,
   627                          HandlePropertyName name, Parser<ParseHandler> *parser);
   629     static bool
   630     bindLet(BindData<ParseHandler> *data,
   631             HandlePropertyName name, Parser<ParseHandler> *parser);
   633     static bool
   634     bindVarOrConst(BindData<ParseHandler> *data,
   635                    HandlePropertyName name, Parser<ParseHandler> *parser);
   637     static Node null() { return ParseHandler::null(); }
   639     bool reportRedeclaration(Node pn, bool isConst, JSAtom *atom);
   640     bool reportBadReturn(Node pn, ParseReportKind kind, unsigned errnum, unsigned anonerrnum);
   641     bool checkFinalReturn(Node pn);
   642     DefinitionNode getOrCreateLexicalDependency(ParseContext<ParseHandler> *pc, JSAtom *atom);
   644     bool leaveFunction(Node fn, ParseContext<ParseHandler> *outerpc,
   645                        FunctionSyntaxKind kind = Expression);
   647     TokenPos pos() const { return tokenStream.currentToken().pos; }
   649     bool asmJS(Node list);
   651     friend class LegacyCompExprTransplanter;
   652     friend struct BindData<ParseHandler>;
   653 };
   655 /* Declare some required template specializations. */
   657 template <>
   658 bool
   659 Parser<FullParseHandler>::checkAndMarkAsAssignmentLhs(ParseNode *pn, AssignmentFlavor flavor);
   661 template <>
   662 bool
   663 Parser<SyntaxParseHandler>::checkAndMarkAsAssignmentLhs(Node pn, AssignmentFlavor flavor);
   665 } /* namespace frontend */
   666 } /* namespace js */
   668 /*
   669  * Convenience macro to access Parser.tokenStream as a pointer.
   670  */
   671 #define TS(p) (&(p)->tokenStream)
   673 #endif /* frontend_Parser_h */

mercurial