Wed, 31 Dec 2014 06:09:35 +0100
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 */