]> git.saurik.com Git - apple/javascriptcore.git/blame - parser/Parser.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / parser / Parser.h
CommitLineData
b37bf2e1 1/*
b37bf2e1
A
2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
93a37866 4 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
b37bf2e1
A
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef Parser_h
24#define Parser_h
25
9dae56ea 26#include "Debugger.h"
14957cd0 27#include "ExceptionHelpers.h"
f9bf01c6
A
28#include "Executable.h"
29#include "JSGlobalObject.h"
30#include "Lexer.h"
9dae56ea 31#include "Nodes.h"
f9bf01c6 32#include "ParserArena.h"
93a37866 33#include "ParserError.h"
ed1e77d3 34#include "ParserFunctionInfo.h"
6fe7ccc8 35#include "ParserTokens.h"
ba379fdc 36#include "SourceProvider.h"
93a37866 37#include "SourceProviderCache.h"
6fe7ccc8 38#include "SourceProviderCacheItem.h"
b37bf2e1
A
39#include <wtf/Forward.h>
40#include <wtf/Noncopyable.h>
b37bf2e1 41#include <wtf/RefPtr.h>
6fe7ccc8
A
42namespace JSC {
43struct Scope;
44}
45
46namespace WTF {
47template <> struct VectorTraits<JSC::Scope> : SimpleClassVectorTraits {
48 static const bool canInitializeWithMemset = false; // Not all Scope data members initialize to 0.
49};
50}
b37bf2e1 51
9dae56ea 52namespace JSC {
b37bf2e1 53
6fe7ccc8
A
54class ExecState;
55class FunctionBodyNode;
56class FunctionParameters;
57class Identifier;
93a37866 58class VM;
6fe7ccc8
A
59class ProgramNode;
60class SourceCode;
93a37866
A
61
62// Macros to make the more common TreeBuilder types a little less verbose
6fe7ccc8
A
63#define TreeStatement typename TreeBuilder::Statement
64#define TreeExpression typename TreeBuilder::Expression
65#define TreeFormalParameterList typename TreeBuilder::FormalParameterList
66#define TreeSourceElements typename TreeBuilder::SourceElements
67#define TreeClause typename TreeBuilder::Clause
68#define TreeClauseList typename TreeBuilder::ClauseList
69#define TreeConstDeclList typename TreeBuilder::ConstDeclList
70#define TreeArguments typename TreeBuilder::Arguments
71#define TreeArgumentsList typename TreeBuilder::ArgumentsList
72#define TreeFunctionBody typename TreeBuilder::FunctionBody
ed1e77d3
A
73#if ENABLE(ES6_CLASS_SYNTAX)
74#define TreeClassExpression typename TreeBuilder::ClassExpression
75#endif
6fe7ccc8
A
76#define TreeProperty typename TreeBuilder::Property
77#define TreePropertyList typename TreeBuilder::PropertyList
ed1e77d3 78#define TreeDestructuringPattern typename TreeBuilder::DestructuringPattern
6fe7ccc8
A
79
80COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
81
82enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
ed1e77d3
A
83#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
84enum FunctionParseType { StandardFunctionParseType, ArrowFunctionParseType };
85#else
86enum FunctionParseType { StandardFunctionParseType};
87#endif
6fe7ccc8 88enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
ed1e77d3
A
89enum FunctionParseMode {
90 FunctionMode,
91 GetterMode,
92 SetterMode,
93 MethodMode,
94#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
95 ArrowFunctionMode
96#endif
97};
98enum DestructuringKind {
99 DestructureToVariables,
100 DestructureToParameters,
101 DestructureToExpressions
81345200 102};
6fe7ccc8
A
103
104template <typename T> inline bool isEvalNode() { return false; }
105template <> inline bool isEvalNode<EvalNode>() { return true; }
106
6fe7ccc8 107struct ScopeLabelInfo {
ed1e77d3
A
108 UniquedStringImpl* uid;
109 bool isLoop;
6fe7ccc8
A
110};
111
112struct Scope {
93a37866
A
113 Scope(const VM* vm, bool isFunction, bool strictMode)
114 : m_vm(vm)
6fe7ccc8
A
115 , m_shadowsArguments(false)
116 , m_usesEval(false)
117 , m_needsFullActivation(false)
ed1e77d3
A
118 , m_hasDirectSuper(false)
119 , m_needsSuperBinding(false)
6fe7ccc8
A
120 , m_allowsNewDecls(true)
121 , m_strictMode(strictMode)
122 , m_isFunction(isFunction)
123 , m_isFunctionBoundary(false)
124 , m_isValidStrictMode(true)
125 , m_loopDepth(0)
126 , m_switchDepth(0)
127 {
128 }
129
130 Scope(const Scope& rhs)
93a37866 131 : m_vm(rhs.m_vm)
6fe7ccc8
A
132 , m_shadowsArguments(rhs.m_shadowsArguments)
133 , m_usesEval(rhs.m_usesEval)
134 , m_needsFullActivation(rhs.m_needsFullActivation)
ed1e77d3
A
135 , m_hasDirectSuper(rhs.m_hasDirectSuper)
136 , m_needsSuperBinding(rhs.m_needsSuperBinding)
6fe7ccc8
A
137 , m_allowsNewDecls(rhs.m_allowsNewDecls)
138 , m_strictMode(rhs.m_strictMode)
139 , m_isFunction(rhs.m_isFunction)
140 , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
141 , m_isValidStrictMode(rhs.m_isValidStrictMode)
142 , m_loopDepth(rhs.m_loopDepth)
143 , m_switchDepth(rhs.m_switchDepth)
144 {
145 if (rhs.m_labels) {
ed1e77d3 146 m_labels = std::make_unique<LabelStack>();
6fe7ccc8
A
147
148 typedef LabelStack::const_iterator iterator;
149 iterator end = rhs.m_labels->end();
150 for (iterator it = rhs.m_labels->begin(); it != end; ++it)
ed1e77d3 151 m_labels->append(ScopeLabelInfo { it->uid, it->isLoop });
6fe7ccc8
A
152 }
153 }
154
155 void startSwitch() { m_switchDepth++; }
156 void endSwitch() { m_switchDepth--; }
157 void startLoop() { m_loopDepth++; }
158 void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
159 bool inLoop() { return !!m_loopDepth; }
160 bool breakIsValid() { return m_loopDepth || m_switchDepth; }
161 bool continueIsValid() { return m_loopDepth; }
162
163 void pushLabel(const Identifier* label, bool isLoop)
164 {
165 if (!m_labels)
ed1e77d3
A
166 m_labels = std::make_unique<LabelStack>();
167 m_labels->append(ScopeLabelInfo { label->impl(), isLoop });
6fe7ccc8
A
168 }
169
170 void popLabel()
171 {
172 ASSERT(m_labels);
173 ASSERT(m_labels->size());
174 m_labels->removeLast();
175 }
176
177 ScopeLabelInfo* getLabel(const Identifier* label)
178 {
179 if (!m_labels)
180 return 0;
181 for (int i = m_labels->size(); i > 0; i--) {
ed1e77d3 182 if (m_labels->at(i - 1).uid == label->impl())
6fe7ccc8
A
183 return &m_labels->at(i - 1);
184 }
185 return 0;
186 }
187
188 void setIsFunction()
189 {
190 m_isFunction = true;
191 m_isFunctionBoundary = true;
192 }
193 bool isFunction() { return m_isFunction; }
194 bool isFunctionBoundary() { return m_isFunctionBoundary; }
195
93a37866
A
196 void declareCallee(const Identifier* ident)
197 {
ed1e77d3 198 m_declaredVariables.add(ident->impl());
93a37866
A
199 }
200
6fe7ccc8
A
201 bool declareVariable(const Identifier* ident)
202 {
93a37866 203 bool isValidStrictMode = m_vm->propertyNames->eval != *ident && m_vm->propertyNames->arguments != *ident;
6fe7ccc8 204 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
ed1e77d3 205 m_declaredVariables.add(ident->impl());
6fe7ccc8
A
206 return isValidStrictMode;
207 }
208
81345200
A
209 bool hasDeclaredVariable(const Identifier& ident)
210 {
211 return m_declaredVariables.contains(ident.impl());
212 }
213
214 bool hasDeclaredParameter(const Identifier& ident)
215 {
216 return m_declaredParameters.contains(ident.impl()) || m_declaredVariables.contains(ident.impl());
217 }
218
6fe7ccc8
A
219 void declareWrite(const Identifier* ident)
220 {
221 ASSERT(m_strictMode);
222 m_writtenVariables.add(ident->impl());
223 }
224
225 void preventNewDecls() { m_allowsNewDecls = false; }
226 bool allowsNewDecls() const { return m_allowsNewDecls; }
227
228 bool declareParameter(const Identifier* ident)
229 {
93a37866 230 bool isArguments = m_vm->propertyNames->arguments == *ident;
ed1e77d3 231 bool isValidStrictMode = m_declaredVariables.add(ident->impl()).isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
6fe7ccc8 232 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
ed1e77d3 233 m_declaredParameters.add(ident->impl());
81345200 234
6fe7ccc8
A
235 if (isArguments)
236 m_shadowsArguments = true;
237 return isValidStrictMode;
238 }
81345200
A
239
240 enum BindingResult {
241 BindingFailed,
242 StrictBindingFailed,
243 BindingSucceeded
244 };
245 BindingResult declareBoundParameter(const Identifier* ident)
246 {
247 bool isArguments = m_vm->propertyNames->arguments == *ident;
ed1e77d3 248 bool newEntry = m_declaredVariables.add(ident->impl()).isNewEntry;
81345200
A
249 bool isValidStrictMode = newEntry && m_vm->propertyNames->eval != *ident && !isArguments;
250 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
251
252 if (isArguments)
253 m_shadowsArguments = true;
254 if (!newEntry)
255 return BindingFailed;
256 return isValidStrictMode ? BindingSucceeded : StrictBindingFailed;
257 }
258
259 void getUsedVariables(IdentifierSet& usedVariables)
260 {
261 usedVariables.swap(m_usedVariables);
262 }
6fe7ccc8
A
263
264 void useVariable(const Identifier* ident, bool isEval)
265 {
266 m_usesEval |= isEval;
ed1e77d3 267 m_usedVariables.add(ident->impl());
6fe7ccc8 268 }
b37bf2e1 269
6fe7ccc8 270 void setNeedsFullActivation() { m_needsFullActivation = true; }
b37bf2e1 271
ed1e77d3
A
272#if ENABLE(ES6_CLASS_SYNTAX)
273 bool hasDirectSuper() { return m_hasDirectSuper; }
274#else
275 bool hasDirectSuper() { return false; }
276#endif
277 void setHasDirectSuper() { m_hasDirectSuper = true; }
278
279#if ENABLE(ES6_CLASS_SYNTAX)
280 bool needsSuperBinding() { return m_needsSuperBinding; }
281#else
282 bool needsSuperBinding() { return false; }
283#endif
284 void setNeedsSuperBinding() { m_needsSuperBinding = true; }
285
6fe7ccc8
A
286 bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
287 {
288 if (nestedScope->m_usesEval)
289 m_usesEval = true;
290 IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
291 for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
292 if (nestedScope->m_declaredVariables.contains(*ptr))
293 continue;
294 m_usedVariables.add(*ptr);
295 if (shouldTrackClosedVariables)
296 m_closedVariables.add(*ptr);
297 }
298 if (nestedScope->m_writtenVariables.size()) {
299 IdentifierSet::iterator end = nestedScope->m_writtenVariables.end();
300 for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) {
301 if (nestedScope->m_declaredVariables.contains(*ptr))
302 continue;
303 m_writtenVariables.add(*ptr);
304 }
305 }
306
307 return true;
308 }
309
ed1e77d3 310 void getCapturedVariables(IdentifierSet& capturedVariables, bool& modifiedParameter, bool& modifiedArguments)
6fe7ccc8
A
311 {
312 if (m_needsFullActivation || m_usesEval) {
81345200 313 modifiedParameter = true;
ed1e77d3 314 capturedVariables = m_declaredVariables;
6fe7ccc8
A
315 return;
316 }
317 for (IdentifierSet::iterator ptr = m_closedVariables.begin(); ptr != m_closedVariables.end(); ++ptr) {
318 if (!m_declaredVariables.contains(*ptr))
319 continue;
320 capturedVariables.add(*ptr);
321 }
81345200 322 modifiedParameter = false;
ed1e77d3
A
323 if (shadowsArguments())
324 modifiedArguments = true;
81345200
A
325 if (m_declaredParameters.size()) {
326 IdentifierSet::iterator end = m_writtenVariables.end();
327 for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
ed1e77d3
A
328 if (*ptr == m_vm->propertyNames->arguments.impl())
329 modifiedArguments = true;
81345200
A
330 if (!m_declaredParameters.contains(*ptr))
331 continue;
332 modifiedParameter = true;
333 break;
334 }
335 }
6fe7ccc8
A
336 }
337 void setStrictMode() { m_strictMode = true; }
338 bool strictMode() const { return m_strictMode; }
339 bool isValidStrictMode() const { return m_isValidStrictMode; }
340 bool shadowsArguments() const { return m_shadowsArguments; }
341
ed1e77d3 342 void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<UniquedStringImpl>>& vector)
6fe7ccc8
A
343 {
344 IdentifierSet::iterator end = capturedVariables.end();
345 for (IdentifierSet::iterator it = capturedVariables.begin(); it != end; ++it) {
346 if (m_declaredVariables.contains(*it))
347 continue;
348 vector.append(*it);
349 }
6fe7ccc8
A
350 }
351
93a37866 352 void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters)
6fe7ccc8
A
353 {
354 ASSERT(m_isFunction);
93a37866
A
355 parameters.usesEval = m_usesEval;
356 parameters.strictMode = m_strictMode;
357 parameters.needsFullActivation = m_needsFullActivation;
358 copyCapturedVariablesToVector(m_writtenVariables, parameters.writtenVariables);
359 copyCapturedVariablesToVector(m_usedVariables, parameters.usedVariables);
6fe7ccc8
A
360 }
361
93a37866 362 void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
6fe7ccc8
A
363 {
364 ASSERT(m_isFunction);
365 m_usesEval = info->usesEval;
366 m_strictMode = info->strictMode;
367 m_needsFullActivation = info->needsFullActivation;
93a37866
A
368 for (unsigned i = 0; i < info->usedVariablesCount; ++i)
369 m_usedVariables.add(info->usedVariables()[i]);
370 for (unsigned i = 0; i < info->writtenVariablesCount; ++i)
371 m_writtenVariables.add(info->writtenVariables()[i]);
6fe7ccc8
A
372 }
373
374private:
93a37866 375 const VM* m_vm;
6fe7ccc8
A
376 bool m_shadowsArguments : 1;
377 bool m_usesEval : 1;
378 bool m_needsFullActivation : 1;
ed1e77d3
A
379 bool m_hasDirectSuper : 1;
380 bool m_needsSuperBinding : 1;
6fe7ccc8
A
381 bool m_allowsNewDecls : 1;
382 bool m_strictMode : 1;
383 bool m_isFunction : 1;
384 bool m_isFunctionBoundary : 1;
385 bool m_isValidStrictMode : 1;
386 int m_loopDepth;
387 int m_switchDepth;
388
389 typedef Vector<ScopeLabelInfo, 2> LabelStack;
ed1e77d3 390 std::unique_ptr<LabelStack> m_labels;
81345200 391 IdentifierSet m_declaredParameters;
6fe7ccc8
A
392 IdentifierSet m_declaredVariables;
393 IdentifierSet m_usedVariables;
394 IdentifierSet m_closedVariables;
395 IdentifierSet m_writtenVariables;
396};
397
398typedef Vector<Scope, 10> ScopeStack;
b37bf2e1 399
6fe7ccc8
A
400struct ScopeRef {
401 ScopeRef(ScopeStack* scopeStack, unsigned index)
402 : m_scopeStack(scopeStack)
403 , m_index(index)
404 {
405 }
406 Scope* operator->() { return &m_scopeStack->at(m_index); }
407 unsigned index() const { return m_index; }
408
409 bool hasContainingScope()
410 {
411 return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
412 }
413
414 ScopeRef containingScope()
415 {
416 ASSERT(hasContainingScope());
417 return ScopeRef(m_scopeStack, m_index - 1);
418 }
419
420private:
421 ScopeStack* m_scopeStack;
422 unsigned m_index;
423};
ba379fdc 424
6fe7ccc8
A
425template <typename LexerType>
426class Parser {
427 WTF_MAKE_NONCOPYABLE(Parser);
428 WTF_MAKE_FAST_ALLOCATED;
b5422865 429
6fe7ccc8 430public:
ed1e77d3
A
431 Parser(
432 VM*, const SourceCode&, FunctionParameters*, const Identifier&,
433 JSParserBuiltinMode, JSParserStrictMode, JSParserCodeType,
434 ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode = ThisTDZMode::CheckIfNeeded);
6fe7ccc8
A
435 ~Parser();
436
437 template <class ParsedNode>
ed1e77d3 438 std::unique_ptr<ParsedNode> parse(ParserError&);
81345200
A
439
440 JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
ed1e77d3
A
441 JSTokenLocation locationBeforeLastToken() const { return m_lexer->lastTokenLocation(); }
442 Vector<RefPtr<UniquedStringImpl>>&& closedVariables() { return WTF::move(m_closedVariables); }
6fe7ccc8
A
443
444private:
445 struct AllowInOverride {
446 AllowInOverride(Parser* parser)
447 : m_parser(parser)
448 , m_oldAllowsIn(parser->m_allowsIn)
449 {
450 parser->m_allowsIn = true;
451 }
452 ~AllowInOverride()
453 {
454 m_parser->m_allowsIn = m_oldAllowsIn;
455 }
456 Parser* m_parser;
457 bool m_oldAllowsIn;
458 };
459
460 struct AutoPopScopeRef : public ScopeRef {
461 AutoPopScopeRef(Parser* parser, ScopeRef scope)
462 : ScopeRef(scope)
463 , m_parser(parser)
464 {
465 }
466
467 ~AutoPopScopeRef()
468 {
469 if (m_parser)
470 m_parser->popScope(*this, false);
471 }
472
473 void setPopped()
474 {
475 m_parser = 0;
476 }
477
b37bf2e1 478 private:
6fe7ccc8 479 Parser* m_parser;
b37bf2e1 480 };
b37bf2e1 481
6fe7ccc8
A
482 ScopeRef currentScope()
483 {
484 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
485 }
486
487 ScopeRef pushScope()
488 {
489 bool isFunction = false;
490 bool isStrict = false;
491 if (!m_scopeStack.isEmpty()) {
492 isStrict = m_scopeStack.last().strictMode();
493 isFunction = m_scopeStack.last().isFunction();
494 }
93a37866 495 m_scopeStack.append(Scope(m_vm, isFunction, isStrict));
6fe7ccc8
A
496 return currentScope();
497 }
498
499 bool popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
500 {
501 ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
502 ASSERT(m_scopeStack.size() > 1);
503 bool result = m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
504 m_scopeStack.removeLast();
505 return result;
506 }
507
508 bool popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
509 {
510 return popScopeInternal(scope, shouldTrackClosedVariables);
511 }
512
513 bool popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
514 {
515 scope.setPopped();
516 return popScopeInternal(scope, shouldTrackClosedVariables);
517 }
518
519 bool declareVariable(const Identifier* ident)
520 {
521 unsigned i = m_scopeStack.size() - 1;
522 ASSERT(i < m_scopeStack.size());
523 while (!m_scopeStack[i].allowsNewDecls()) {
524 i--;
525 ASSERT(i < m_scopeStack.size());
526 }
527 return m_scopeStack[i].declareVariable(ident);
528 }
529
81345200
A
530 NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)
531 {
532 unsigned i = m_scopeStack.size() - 1;
533 ASSERT(i < m_scopeStack.size());
534 while (!m_scopeStack[i].allowsNewDecls()) {
535 i--;
536 ASSERT(i < m_scopeStack.size());
537 }
538 return m_scopeStack[i].hasDeclaredVariable(ident);
539 }
540
541 NEVER_INLINE bool hasDeclaredParameter(const Identifier& ident)
542 {
543 unsigned i = m_scopeStack.size() - 1;
544 ASSERT(i < m_scopeStack.size());
545 while (!m_scopeStack[i].allowsNewDecls()) {
546 i--;
547 ASSERT(i < m_scopeStack.size());
548 }
549 return m_scopeStack[i].hasDeclaredParameter(ident);
550 }
551
6fe7ccc8
A
552 void declareWrite(const Identifier* ident)
553 {
81345200 554 if (!m_syntaxAlreadyValidated || strictMode())
6fe7ccc8
A
555 m_scopeStack.last().declareWrite(ident);
556 }
557
558 ScopeStack m_scopeStack;
559
560 const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos)
561 {
562 return m_functionCache ? m_functionCache->get(openBracePos) : 0;
563 }
564
565 Parser();
93a37866 566 String parseInner();
6fe7ccc8 567
ed1e77d3
A
568 void didFinishParsing(SourceElements*, DeclarationStacks::VarStack&,
569 DeclarationStacks::FunctionStack&, CodeFeatures, int, IdentifierSet&, const Vector<RefPtr<UniquedStringImpl>>&&);
6fe7ccc8
A
570
571 // Used to determine type of error to report.
572 bool isFunctionBodyNode(ScopeNode*) { return false; }
573 bool isFunctionBodyNode(FunctionBodyNode*) { return true; }
574
6fe7ccc8
A
575 ALWAYS_INLINE void next(unsigned lexerFlags = 0)
576 {
81345200
A
577 int lastLine = m_token.m_location.line;
578 int lastTokenEnd = m_token.m_location.endOffset;
579 int lastTokenLineStart = m_token.m_location.lineStartOffset;
580 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
581 m_lexer->setLastLineNumber(lastLine);
582 m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode());
6fe7ccc8
A
583 }
584
585 ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
586 {
81345200
A
587 int lastLine = m_token.m_location.line;
588 int lastTokenEnd = m_token.m_location.endOffset;
589 int lastTokenLineStart = m_token.m_location.lineStartOffset;
590 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
591 m_lexer->setLastLineNumber(lastLine);
592 m_token.m_type = m_lexer->lexExpectIdentifier(&m_token, lexerFlags, strictMode());
6fe7ccc8
A
593 }
594
595 ALWAYS_INLINE bool nextTokenIsColon()
596 {
597 return m_lexer->nextTokenIsColon();
598 }
599
600 ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
601 {
602 bool result = m_token.m_type == expected;
603 if (result)
604 next(flags);
605 return result;
606 }
81345200
A
607
608 void printUnexpectedTokenText(WTF::PrintStream&);
93a37866 609 ALWAYS_INLINE String getToken() {
6fe7ccc8 610 SourceProvider* sourceProvider = m_source->provider();
81345200 611 return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset);
6fe7ccc8
A
612 }
613
614 ALWAYS_INLINE bool match(JSTokenType expected)
615 {
616 return m_token.m_type == expected;
617 }
618
81345200
A
619 ALWAYS_INLINE bool isofToken()
620 {
621 return m_token.m_type == IDENT && *m_token.m_data.ident == m_vm->propertyNames->of;
622 }
623
ed1e77d3
A
624#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
625 ALWAYS_INLINE bool isEndOfArrowFunction()
626 {
627 return match(SEMICOLON) || match(COMMA) || match(CLOSEPAREN) || match(CLOSEBRACE) || match(CLOSEBRACKET) || match(EOFTOK) || m_lexer->prevTerminator();
628 }
629
630 ALWAYS_INLINE bool isArrowFunctionParamters()
631 {
632 bool isArrowFunction = false;
633
634 if (match(EOFTOK))
635 return isArrowFunction;
636
637 SavePoint saveArrowFunctionPoint = createSavePoint();
638
639 if (consume(OPENPAREN)) {
640 bool isArrowFunctionParamters = true;
641
642 while (consume(IDENT)) {
643 if (consume(COMMA)) {
644 if (!match(IDENT)) {
645 isArrowFunctionParamters = false;
646 break;
647 }
648 } else
649 break;
650 }
651
652 if (isArrowFunctionParamters) {
653 if (consume(CLOSEPAREN) && match(ARROWFUNCTION))
654 isArrowFunction = true;
655 }
656 } else if (consume(IDENT) && match(ARROWFUNCTION))
657 isArrowFunction = true;
658
659 restoreSavePoint(saveArrowFunctionPoint);
660
661 return isArrowFunction;
662 }
663#endif
664
93a37866 665 ALWAYS_INLINE unsigned tokenStart()
6fe7ccc8 666 {
93a37866 667 return m_token.m_location.startOffset;
6fe7ccc8
A
668 }
669
81345200
A
670 ALWAYS_INLINE const JSTextPosition& tokenStartPosition()
671 {
672 return m_token.m_startPosition;
673 }
674
6fe7ccc8
A
675 ALWAYS_INLINE int tokenLine()
676 {
93a37866
A
677 return m_token.m_location.line;
678 }
679
680 ALWAYS_INLINE int tokenColumn()
681 {
682 return tokenStart() - tokenLineStart();
683 }
684
81345200 685 ALWAYS_INLINE const JSTextPosition& tokenEndPosition()
93a37866 686 {
81345200 687 return m_token.m_endPosition;
6fe7ccc8
A
688 }
689
93a37866 690 ALWAYS_INLINE unsigned tokenLineStart()
6fe7ccc8 691 {
93a37866 692 return m_token.m_location.lineStartOffset;
6fe7ccc8
A
693 }
694
93a37866
A
695 ALWAYS_INLINE const JSTokenLocation& tokenLocation()
696 {
697 return m_token.m_location;
698 }
699
ed1e77d3 700 void setErrorMessage(const String& message)
6fe7ccc8 701 {
ed1e77d3 702 m_errorMessage = message;
6fe7ccc8
A
703 }
704
81345200
A
705 NEVER_INLINE void logError(bool);
706 template <typename A> NEVER_INLINE void logError(bool, const A&);
707 template <typename A, typename B> NEVER_INLINE void logError(bool, const A&, const B&);
708 template <typename A, typename B, typename C> NEVER_INLINE void logError(bool, const A&, const B&, const C&);
709 template <typename A, typename B, typename C, typename D> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&);
710 template <typename A, typename B, typename C, typename D, typename E> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&, const E&);
711 template <typename A, typename B, typename C, typename D, typename E, typename F> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&, const E&, const F&);
712 template <typename A, typename B, typename C, typename D, typename E, typename F, typename G> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&, const E&, const F&, const G&);
6fe7ccc8 713
ed1e77d3 714 NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMessage, const String& name, const char* afterMessage)
6fe7ccc8 715 {
ed1e77d3 716 m_errorMessage = makeString(beforeMessage, " '", name, "' ", afterMessage);
6fe7ccc8
A
717 }
718
93a37866
A
719 NEVER_INLINE void updateErrorMessage(const char* msg)
720 {
721 ASSERT(msg);
722 m_errorMessage = String(msg);
723 ASSERT(!m_errorMessage.isNull());
6fe7ccc8
A
724 }
725
726 void startLoop() { currentScope()->startLoop(); }
727 void endLoop() { currentScope()->endLoop(); }
728 void startSwitch() { currentScope()->startSwitch(); }
729 void endSwitch() { currentScope()->endSwitch(); }
730 void setStrictMode() { currentScope()->setStrictMode(); }
731 bool strictMode() { return currentScope()->strictMode(); }
732 bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
733 bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
81345200 734 Scope::BindingResult declareBoundParameter(const Identifier* ident) { return currentScope()->declareBoundParameter(ident); }
6fe7ccc8
A
735 bool breakIsValid()
736 {
737 ScopeRef current = currentScope();
738 while (!current->breakIsValid()) {
739 if (!current.hasContainingScope())
740 return false;
741 current = current.containingScope();
742 }
743 return true;
744 }
745 bool continueIsValid()
746 {
747 ScopeRef current = currentScope();
748 while (!current->continueIsValid()) {
749 if (!current.hasContainingScope())
750 return false;
751 current = current.containingScope();
752 }
753 return true;
754 }
755 void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
756 void popLabel() { currentScope()->popLabel(); }
757 ScopeLabelInfo* getLabel(const Identifier* label)
758 {
759 ScopeRef current = currentScope();
760 ScopeLabelInfo* result = 0;
761 while (!(result = current->getLabel(label))) {
762 if (!current.hasContainingScope())
763 return 0;
764 current = current.containingScope();
765 }
766 return result;
767 }
ed1e77d3
A
768
769 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode, FunctionParseType);
770 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
6fe7ccc8 771 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
ed1e77d3
A
772#if ENABLE(ES6_CLASS_SYNTAX)
773 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&);
774#endif
6fe7ccc8
A
775 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
776 template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&);
777 template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
778 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
779 template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
780 template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
781 template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
782 template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
783 template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
784 template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
785 template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
786 template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
787 template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
788 template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
789 template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
790 template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
791 template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
792 template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&);
793 template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
81345200 794 template <class TreeBuilder> TreeStatement parseBlockStatement(TreeBuilder&);
6fe7ccc8
A
795 template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
796 template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
797 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
798 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
799 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
800 template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
801 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
802 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
803 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
81345200
A
804 template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
805 enum SpreadMode { AllowSpread, DontAllowSpread };
806 template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&, SpreadMode);
807 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
ed1e77d3
A
808 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName);
809 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind = ConstructorKind::None, SuperBinding = SuperBinding::NotNeeded);
810 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, FunctionParseType);
6fe7ccc8 811 template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
ed1e77d3
A
812 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
813 template <class TreeBuilder> TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext);
81345200
A
814 template <class TreeBuilder> NEVER_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder&);
815
ed1e77d3
A
816#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
817 template <class TreeBuilder> TreeStatement parseArrowFunctionSingleExpressionBody(TreeBuilder&, FunctionParseType);
818 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
819#endif
820
821 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, const Identifier&, int depth, JSToken);
822 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, int depth = 0);
823 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&);
824 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDestructuringPattern(TreeBuilder&);
825
826 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionParseType);
827
828 template <class TreeBuilder> NEVER_INLINE int parseFunctionParameters(TreeBuilder&, FunctionParseMode, ParserFunctionInfo<TreeBuilder>&);
829
830#if ENABLE(ES6_CLASS_SYNTAX)
831 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionRequirements, ParserClassInfo<TreeBuilder>&);
832#endif
833
834#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
835 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateString parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode, bool& elementIsTail);
836 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateLiteral parseTemplateLiteral(TreeBuilder&, typename LexerType::RawStringsBuildMode);
837#endif
838
839 template <class TreeBuilder> ALWAYS_INLINE bool shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder&, const TreeProperty&);
840
6fe7ccc8
A
841 ALWAYS_INLINE int isBinaryOperator(JSTokenType);
842 bool allowAutomaticSemicolon();
843
844 bool autoSemiColon()
845 {
846 if (m_token.m_type == SEMICOLON) {
847 next();
848 return true;
b37bf2e1 849 }
6fe7ccc8
A
850 return allowAutomaticSemicolon();
851 }
852
ed1e77d3
A
853
854#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
855 void setEndOfStatement()
856 {
857 m_lexer->setTokenPosition(&m_token);
858 }
859#endif
860
6fe7ccc8
A
861 bool canRecurse()
862 {
81345200 863 return m_vm->isSafeToRecurse();
6fe7ccc8
A
864 }
865
81345200 866 const JSTextPosition& lastTokenEndPosition() const
6fe7ccc8 867 {
81345200 868 return m_lastTokenEndPosition;
6fe7ccc8
A
869 }
870
81345200 871 bool hasError() const
93a37866 872 {
81345200 873 return !m_errorMessage.isNull();
93a37866
A
874 }
875
81345200
A
876 struct SavePoint {
877 int startOffset;
878 unsigned oldLineStartOffset;
879 unsigned oldLastLineNumber;
880 unsigned oldLineNumber;
881 };
882
883 ALWAYS_INLINE SavePoint createSavePoint()
884 {
885 ASSERT(!hasError());
886 SavePoint result;
887 result.startOffset = m_token.m_location.startOffset;
888 result.oldLineStartOffset = m_token.m_location.lineStartOffset;
889 result.oldLastLineNumber = m_lexer->lastLineNumber();
890 result.oldLineNumber = m_lexer->lineNumber();
891 return result;
892 }
893
894 ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
93a37866 895 {
81345200
A
896 m_errorMessage = String();
897 m_lexer->setOffset(savePoint.startOffset, savePoint.oldLineStartOffset);
898 next();
899 m_lexer->setLastLineNumber(savePoint.oldLastLineNumber);
900 m_lexer->setLineNumber(savePoint.oldLineNumber);
93a37866
A
901 }
902
81345200
A
903 struct ParserState {
904 int assignmentCount;
905 int nonLHSCount;
906 int nonTrivialExpressionCount;
907 };
908
909 ALWAYS_INLINE ParserState saveState()
93a37866 910 {
81345200
A
911 ParserState result;
912 result.assignmentCount = m_assignmentCount;
913 result.nonLHSCount = m_nonLHSCount;
914 result.nonTrivialExpressionCount = m_nonTrivialExpressionCount;
915 return result;
93a37866 916 }
81345200
A
917
918 ALWAYS_INLINE void restoreState(const ParserState& state)
919 {
920 m_assignmentCount = state.assignmentCount;
921 m_nonLHSCount = state.nonLHSCount;
922 m_nonTrivialExpressionCount = state.nonTrivialExpressionCount;
923
924 }
925
93a37866
A
926
927 VM* m_vm;
6fe7ccc8 928 const SourceCode* m_source;
ed1e77d3
A
929 ParserArena m_parserArena;
930 std::unique_ptr<LexerType> m_lexer;
6fe7ccc8 931
93a37866
A
932 bool m_hasStackOverflow;
933 String m_errorMessage;
6fe7ccc8
A
934 JSToken m_token;
935 bool m_allowsIn;
81345200 936 JSTextPosition m_lastTokenEndPosition;
6fe7ccc8
A
937 int m_assignmentCount;
938 int m_nonLHSCount;
939 bool m_syntaxAlreadyValidated;
940 int m_statementDepth;
941 int m_nonTrivialExpressionCount;
942 const Identifier* m_lastIdentifier;
81345200 943 const Identifier* m_lastFunctionName;
93a37866 944 RefPtr<SourceProviderCache> m_functionCache;
6fe7ccc8 945 SourceElements* m_sourceElements;
81345200 946 bool m_parsingBuiltin;
ed1e77d3
A
947 ConstructorKind m_defaultConstructorKind;
948 ThisTDZMode m_thisTDZMode;
949 DeclarationStacks::VarStack m_varDeclarations;
950 DeclarationStacks::FunctionStack m_funcDeclarations;
6fe7ccc8 951 IdentifierSet m_capturedVariables;
ed1e77d3 952 Vector<RefPtr<UniquedStringImpl>> m_closedVariables;
6fe7ccc8
A
953 CodeFeatures m_features;
954 int m_numConstants;
955
956 struct DepthManager {
957 DepthManager(int* depth)
958 : m_originalDepth(*depth)
959 , m_depth(depth)
960 {
961 }
962
963 ~DepthManager()
964 {
965 *m_depth = m_originalDepth;
966 }
967
968 private:
969 int m_originalDepth;
970 int* m_depth;
971 };
972};
973
93a37866 974
6fe7ccc8
A
975template <typename LexerType>
976template <class ParsedNode>
ed1e77d3 977std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
6fe7ccc8 978{
6fe7ccc8 979 int errLine;
93a37866 980 String errMsg;
6fe7ccc8 981
ed1e77d3 982 if (ParsedNode::scopeIsFunction)
6fe7ccc8
A
983 m_lexer->setIsReparsing();
984
985 m_sourceElements = 0;
b5422865 986
6fe7ccc8 987 errLine = -1;
93a37866
A
988 errMsg = String();
989
990 JSTokenLocation startLocation(tokenLocation());
81345200
A
991 ASSERT(m_source->startColumn() > 0);
992 unsigned startColumn = m_source->startColumn() - 1;
ba379fdc 993
93a37866 994 String parseError = parseInner();
6fe7ccc8
A
995
996 int lineNumber = m_lexer->lineNumber();
997 bool lexError = m_lexer->sawError();
93a37866 998 String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
6fe7ccc8
A
999 ASSERT(lexErrorMessage.isNull() != lexError);
1000 m_lexer->clear();
1001
1002 if (!parseError.isNull() || lexError) {
1003 errLine = lineNumber;
1004 errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
f9bf01c6 1005 m_sourceElements = 0;
6fe7ccc8 1006 }
9dae56ea 1007
ed1e77d3 1008 std::unique_ptr<ParsedNode> result;
6fe7ccc8 1009 if (m_sourceElements) {
93a37866 1010 JSTokenLocation endLocation;
81345200 1011 endLocation.line = m_lexer->lineNumber();
93a37866
A
1012 endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
1013 endLocation.startOffset = m_lexer->currentOffset();
81345200 1014 unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
ed1e77d3 1015 result = std::make_unique<ParsedNode>(m_parserArena,
93a37866
A
1016 startLocation,
1017 endLocation,
1018 startColumn,
81345200 1019 endColumn,
6fe7ccc8 1020 m_sourceElements,
ed1e77d3
A
1021 m_varDeclarations,
1022 m_funcDeclarations,
6fe7ccc8
A
1023 m_capturedVariables,
1024 *m_source,
1025 m_features,
1026 m_numConstants);
81345200 1027 result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
ed1e77d3 1028 result->setEndOffset(m_lexer->currentOffset());
93a37866 1029 } else {
6fe7ccc8
A
1030 // We can never see a syntax error when reparsing a function, since we should have
1031 // reported the error when parsing the containing program or eval code. So if we're
1032 // parsing a function body node, we assume that what actually happened here is that
1033 // we ran out of stack while parsing. If we see an error while parsing eval or program
1034 // code we assume that it was a syntax error since running out of stack is much less
1035 // likely, and we are currently unable to distinguish between the two cases.
93a37866
A
1036 if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
1037 error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
1038 else {
1039 ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
1040 if (m_token.m_type == EOFTOK)
1041 errorType = ParserError::SyntaxErrorRecoverable;
1042 else if (m_token.m_type & UnterminatedErrorTokenFlag)
1043 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
1044
1045 if (isEvalNode<ParsedNode>())
1046 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
1047 else
1048 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
1049 }
b37bf2e1
A
1050 }
1051
ed1e77d3 1052 return result;
6fe7ccc8
A
1053}
1054
1055template <class ParsedNode>
ed1e77d3
A
1056std::unique_ptr<ParsedNode> parse(
1057 VM* vm, const SourceCode& source, FunctionParameters* parameters,
1058 const Identifier& name, JSParserBuiltinMode builtinMode,
1059 JSParserStrictMode strictMode, JSParserCodeType codeType,
1060 ParserError& error, JSTextPosition* positionBeforeLastNewline = 0,
1061 ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded)
6fe7ccc8
A
1062{
1063 SamplingRegion samplingRegion("Parsing");
1064
93a37866
A
1065 ASSERT(!source.provider()->source().isNull());
1066 if (source.provider()->source().is8Bit()) {
ed1e77d3
A
1067 Parser<Lexer<LChar>> parser(vm, source, parameters, name, builtinMode, strictMode, codeType, defaultConstructorKind, thisTDZMode);
1068 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error);
81345200
A
1069 if (positionBeforeLastNewline)
1070 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
ed1e77d3 1071 if (builtinMode == JSParserBuiltinMode::Builtin) {
81345200 1072 if (!result)
ed1e77d3 1073 WTF::dataLog("Error compiling builtin: ", error.message(), "\n");
81345200
A
1074 RELEASE_ASSERT(result);
1075 result->setClosedVariables(parser.closedVariables());
1076 }
ed1e77d3 1077 return result;
6fe7ccc8 1078 }
ed1e77d3
A
1079 ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string");
1080 Parser<Lexer<UChar>> parser(vm, source, parameters, name, builtinMode, strictMode, codeType, defaultConstructorKind, thisTDZMode);
1081 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error);
81345200
A
1082 if (positionBeforeLastNewline)
1083 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
ed1e77d3 1084 return result;
6fe7ccc8 1085}
b37bf2e1 1086
93a37866 1087} // namespace
6fe7ccc8 1088#endif