// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PARSER_H_
#define V8_PARSER_H_
-#include "allocation.h"
-#include "ast.h"
-#include "compiler.h" // For CachedDataMode
-#include "preparse-data-format.h"
-#include "preparse-data.h"
-#include "scopes.h"
-#include "preparser.h"
+#include "src/allocation.h"
+#include "src/ast.h"
+#include "src/compiler.h" // For CachedDataMode
+#include "src/preparse-data.h"
+#include "src/preparse-data-format.h"
+#include "src/preparser.h"
+#include "src/scopes.h"
namespace v8 {
class ScriptCompiler;
int literal_count() { return backing_[kLiteralCountIndex]; }
int property_count() { return backing_[kPropertyCountIndex]; }
StrictMode strict_mode() {
- ASSERT(backing_[kStrictModeIndex] == SLOPPY ||
+ DCHECK(backing_[kStrictModeIndex] == SLOPPY ||
backing_[kStrictModeIndex] == STRICT);
return static_cast<StrictMode>(backing_[kStrictModeIndex]);
}
};
-class ScriptDataImpl : public ScriptData {
+// Wrapper around ScriptData to provide parser-specific functionality.
+class ParseData {
public:
- explicit ScriptDataImpl(Vector<unsigned> store)
- : store_(store),
- owns_store_(true) { }
-
- // Create an empty ScriptDataImpl that is guaranteed to not satisfy
- // a SanityCheck.
- ScriptDataImpl() : owns_store_(false) { }
-
- virtual ~ScriptDataImpl();
- virtual int Length();
- virtual const char* Data();
- virtual bool HasError();
-
+ explicit ParseData(ScriptData* script_data) : script_data_(script_data) {
+ CHECK(IsAligned(script_data->length(), sizeof(unsigned)));
+ CHECK(IsSane());
+ }
void Initialize();
- void ReadNextSymbolPosition();
-
FunctionEntry GetFunctionEntry(int start);
- int GetSymbolIdentifier();
- bool SanityCheck();
+ int FunctionCount();
- Scanner::Location MessageLocation();
- const char* BuildMessage();
- Vector<const char*> BuildArgs();
+ bool HasError();
- int symbol_count() {
- return (store_.length() > PreparseDataConstants::kHeaderSize)
- ? store_[PreparseDataConstants::kSymbolCountOffset]
- : 0;
+ unsigned* Data() { // Writable data as unsigned int array.
+ return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
}
- // The following functions should only be called if SanityCheck has
- // returned true.
- bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
- unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
- unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
private:
- friend class v8::ScriptCompiler;
- Vector<unsigned> store_;
- unsigned char* symbol_data_;
- unsigned char* symbol_data_end_;
- int function_index_;
- bool owns_store_;
-
- unsigned Read(int position);
- unsigned* ReadAddress(int position);
- // Reads a number from the current symbols
- int ReadNumber(byte** source);
-
- ScriptDataImpl(const char* backing_store, int length)
- : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
- length / static_cast<int>(sizeof(unsigned))),
- owns_store_(false) {
- ASSERT_EQ(0, static_cast<int>(
- reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
+ bool IsSane();
+ unsigned Magic();
+ unsigned Version();
+ int FunctionsSize();
+ int Length() const {
+ // Script data length is already checked to be a multiple of unsigned size.
+ return script_data_->length() / sizeof(unsigned);
}
- // Read strings written by ParserRecorder::WriteString.
- static const char* ReadString(unsigned* start, int* chars);
-
- friend class ScriptData;
-};
-
+ ScriptData* script_data_;
+ int function_index_;
-class PreParserApi {
- public:
- // Pre-parse a character stream and return full preparse data.
- //
- // This interface is here instead of in preparser.h because it instantiates a
- // preparser recorder object that is suited to the parser's purposes. Also,
- // the preparser doesn't know about ScriptDataImpl.
- static ScriptDataImpl* PreParse(Isolate* isolate,
- Utf16CharacterStream* source);
+ DISALLOW_COPY_AND_ASSIGN(ParseData);
};
-
// ----------------------------------------------------------------------------
// REGEXP PARSING
}
T* last() {
- ASSERT(last_ != NULL);
+ DCHECK(last_ != NULL);
return last_;
}
T* RemoveLast() {
- ASSERT(last_ != NULL);
+ DCHECK(last_ != NULL);
T* result = last_;
if ((list_ != NULL) && (list_->length() > 0))
last_ = list_->RemoveLast();
}
T* Get(int i) {
- ASSERT((0 <= i) && (i < length()));
+ DCHECK((0 <= i) && (i < length()));
if (list_ == NULL) {
- ASSERT_EQ(0, i);
+ DCHECK_EQ(0, i);
return last_;
} else {
if (i == list_->length()) {
- ASSERT(last_ != NULL);
+ DCHECK(last_ != NULL);
return last_;
} else {
return list_->at(i);
// Used by FunctionState and BlockState.
typedef v8::internal::Scope Scope;
+ typedef v8::internal::Scope* ScopePtr;
+ inline static Scope* ptr_to_scope(ScopePtr scope) { return scope; }
+
typedef Variable GeneratorVariable;
typedef v8::internal::Zone Zone;
+ typedef v8::internal::AstProperties AstProperties;
+ typedef Vector<VariableProxy*> ParameterIdentifierVector;
+
// Return types for traversing functions.
- typedef Handle<String> Identifier;
+ typedef const AstRawString* Identifier;
typedef v8::internal::Expression* Expression;
typedef Yield* YieldExpression;
typedef v8::internal::FunctionLiteral* FunctionLiteral;
+ typedef v8::internal::ClassLiteral* ClassLiteral;
typedef v8::internal::Literal* Literal;
typedef ObjectLiteral::Property* ObjectLiteralProperty;
typedef ZoneList<v8::internal::Expression*>* ExpressionList;
typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
+ typedef ZoneList<v8::internal::Statement*>* StatementList;
// For constructing objects returned by the traversing functions.
typedef AstNodeFactory<AstConstructionVisitor> Factory;
explicit ParserTraits(Parser* parser) : parser_(parser) {}
- // Custom operations executed when FunctionStates are created and destructed.
- template<typename FunctionState>
- static void SetUpFunctionState(FunctionState* function_state, Zone* zone) {
- Isolate* isolate = zone->isolate();
- function_state->isolate_ = isolate;
- function_state->saved_ast_node_id_ = isolate->ast_node_id();
- isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
- }
-
- template<typename FunctionState>
- static void TearDownFunctionState(FunctionState* function_state) {
- if (function_state->outer_function_state_ != NULL) {
- function_state->isolate_->set_ast_node_id(
- function_state->saved_ast_node_id_);
- }
- }
-
// Helper functions for recursive descent.
- bool IsEvalOrArguments(Handle<String> identifier) const;
+ bool IsEvalOrArguments(const AstRawString* identifier) const;
+ V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
// Returns true if the expression is of type "this.foo".
static bool IsThisProperty(Expression* expression);
static bool IsIdentifier(Expression* expression);
+ bool IsPrototype(const AstRawString* identifier) const;
+
+ bool IsConstructor(const AstRawString* identifier) const;
+
+ static const AstRawString* AsIdentifier(Expression* expression) {
+ DCHECK(IsIdentifier(expression));
+ return expression->AsVariableProxy()->raw_name();
+ }
+
static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
return ObjectLiteral::IsBoilerplateProperty(property);
}
- static bool IsArrayIndex(Handle<String> string, uint32_t* index) {
- return !string.is_null() && string->AsArrayIndex(index);
+ static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
+ return string->AsArrayIndex(index);
+ }
+
+ bool IsConstructorProperty(ObjectLiteral::Property* property) {
+ return property->key()->raw_value()->EqualsString(
+ ast_value_factory()->constructor_string());
+ }
+
+ static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
+ return property->value();
}
// Functions for encapsulating the differences between parsing and preparsing;
// operations interleaved with the recursive descent.
- static void PushLiteralName(FuncNameInferrer* fni, Handle<String> id) {
+ static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
fni->PushLiteralName(id);
}
void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
+ static void InferFunctionName(FuncNameInferrer* fni,
+ FunctionLiteral* func_to_infer) {
+ fni->AddFunction(func_to_infer);
+ }
static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
- Scope* scope, Expression* value, bool* has_function) {
+ Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
+ Expression* value = property->value();
if (scope->DeclarationScope()->is_global_scope() &&
value->AsFunctionLiteral() != NULL) {
*has_function = true;
void CheckPossibleEvalCall(Expression* expression, Scope* scope);
// Determine if the expression is a variable proxy and mark it as being used
- // in an assignment or with a increment/decrement operator. This is currently
- // used on for the statically checking assignments to harmony const bindings.
- static Expression* MarkExpressionAsLValue(Expression* expression);
-
- // Checks LHS expression for assignment and prefix/postfix increment/decrement
- // in strict mode.
- void CheckStrictModeLValue(Expression* expression, bool* ok);
+ // in an assignment or with a increment/decrement operator.
+ static Expression* MarkExpressionAsAssigned(Expression* expression);
// Returns true if we have a binary expression between two numeric
// literals. In that case, *x will be changed to an expression which is the
Expression** x, Expression* y, Token::Value op, int pos,
AstNodeFactory<AstConstructionVisitor>* factory);
+ // If we find a SIMD load or store call with array types
+ // and offset as arguments, we will return an expression
+ // calling array types load or store with offset as argument.
+ // Otherwise, returns NULL.
+ bool BuildSIMD128LoadStoreExpression(
+ Expression** expression, ZoneList<Expression*>* arguments, int pos,
+ AstNodeFactory<AstConstructionVisitor>* factory);
+
// Rewrites the following types of unary expressions:
// not <literal> -> true / false
// + <numeric literal> -> <numeric literal>
Expression* expression, Token::Value op, int pos,
AstNodeFactory<AstConstructionVisitor>* factory);
+ // Generate AST node that throws a ReferenceError with the given type.
+ Expression* NewThrowReferenceError(const char* type, int pos);
+
+ // Generate AST node that throws a SyntaxError with the given
+ // type. The first argument may be null (in the handle sense) in
+ // which case no arguments are passed to the constructor.
+ Expression* NewThrowSyntaxError(
+ const char* type, const AstRawString* arg, int pos);
+
+ // Generate AST node that throws a TypeError with the given
+ // type. Both arguments must be non-null (in the handle sense).
+ Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
+ int pos);
+
+ // Generic AST generator for throwing errors from compiled code.
+ Expression* NewThrowError(
+ const AstRawString* constructor, const char* type,
+ const AstRawString* arg, int pos);
+
// Reporting errors.
void ReportMessageAt(Scanner::Location source_location,
const char* message,
- Vector<const char*> args,
+ const char* arg = NULL,
bool is_reference_error = false);
void ReportMessage(const char* message,
- Vector<Handle<String> > args,
+ const char* arg = NULL,
+ bool is_reference_error = false);
+ void ReportMessage(const char* message,
+ const AstRawString* arg,
bool is_reference_error = false);
void ReportMessageAt(Scanner::Location source_location,
const char* message,
- Vector<Handle<String> > args,
+ const AstRawString* arg,
bool is_reference_error = false);
// "null" return type creators.
- static Handle<String> EmptyIdentifier() {
- return Handle<String>();
+ static const AstRawString* EmptyIdentifier() {
+ return NULL;
}
static Expression* EmptyExpression() {
return NULL;
}
+ static Expression* EmptyArrowParamList() { return NULL; }
static Literal* EmptyLiteral() {
return NULL;
}
+ static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
+ static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
+
// Used in error return values.
static ZoneList<Expression*>* NullExpressionList() {
return NULL;
}
+ // Non-NULL empty string.
+ V8_INLINE const AstRawString* EmptyIdentifierString();
+
// Odd-ball literal creators.
Literal* GetLiteralTheHole(int position,
AstNodeFactory<AstConstructionVisitor>* factory);
// Producing data during the recursive descent.
- Handle<String> GetSymbol(Scanner* scanner = NULL);
- Handle<String> NextLiteralString(Scanner* scanner,
- PretenureFlag tenured);
+ const AstRawString* GetSymbol(Scanner* scanner);
+ const AstRawString* GetNextSymbol(Scanner* scanner);
+ const AstRawString* GetNumberAsSymbol(Scanner* scanner);
+
Expression* ThisExpression(Scope* scope,
- AstNodeFactory<AstConstructionVisitor>* factory);
+ AstNodeFactory<AstConstructionVisitor>* factory,
+ int pos = RelocInfo::kNoPosition);
+ Expression* SuperReference(Scope* scope,
+ AstNodeFactory<AstConstructionVisitor>* factory,
+ int pos = RelocInfo::kNoPosition);
+ Expression* ClassExpression(const AstRawString* name, Expression* extends,
+ Expression* constructor,
+ ZoneList<ObjectLiteral::Property*>* properties,
+ int start_position, int end_position,
+ AstNodeFactory<AstConstructionVisitor>* factory);
+
Literal* ExpressionFromLiteral(
Token::Value token, int pos, Scanner* scanner,
AstNodeFactory<AstConstructionVisitor>* factory);
Expression* ExpressionFromIdentifier(
- Handle<String> name, int pos, Scope* scope,
+ const AstRawString* name, int pos, Scope* scope,
AstNodeFactory<AstConstructionVisitor>* factory);
Expression* ExpressionFromString(
int pos, Scanner* scanner,
AstNodeFactory<AstConstructionVisitor>* factory);
+ Expression* GetIterator(Expression* iterable,
+ AstNodeFactory<AstConstructionVisitor>* factory);
ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
}
ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
}
+ ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
+ return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
+ }
+ V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type);
+
+ // Utility functions
+ int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
+ Scanner::Location* dupe_loc,
+ bool* ok);
+ V8_INLINE AstValueFactory* ast_value_factory();
// Temporary glue; these functions will move to ParserBase.
Expression* ParseV8Intrinsic(bool* ok);
FunctionLiteral* ParseFunctionLiteral(
- Handle<String> name,
- Scanner::Location function_name_location,
- bool name_is_strict_reserved,
- bool is_generator,
- int function_token_position,
- FunctionLiteral::FunctionType type,
- bool* ok);
+ const AstRawString* name, Scanner::Location function_name_location,
+ bool name_is_strict_reserved, FunctionKind kind,
+ int function_token_position, FunctionLiteral::FunctionType type,
+ FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
+ V8_INLINE void SkipLazyFunctionBody(const AstRawString* name,
+ int* materialized_literal_count,
+ int* expected_property_count, bool* ok);
+ V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
+ const AstRawString* name, int pos, Variable* fvar,
+ Token::Value fvar_init_op, bool is_generator, bool* ok);
+ V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
+ bool* ok);
private:
Parser* parser_;
class Parser : public ParserBase<ParserTraits> {
public:
- explicit Parser(CompilationInfo* info);
+ // Note that the hash seed in ParseInfo must be the hash seed from the
+ // Isolate's heap, otherwise the heap will be in an inconsistent state once
+ // the strings created by the Parser are internalized.
+ struct ParseInfo {
+ uintptr_t stack_limit;
+ uint32_t hash_seed;
+ UnicodeCache* unicode_cache;
+ };
+
+ Parser(CompilationInfo* info, ParseInfo* parse_info);
~Parser() {
delete reusable_preparser_;
reusable_preparser_ = NULL;
+ delete cached_parse_data_;
+ cached_parse_data_ = NULL;
}
// Parses the source code represented by the compilation info and sets its
// nodes) if parsing failed.
static bool Parse(CompilationInfo* info,
bool allow_lazy = false) {
- Parser parser(info);
+ ParseInfo parse_info = {info->isolate()->stack_guard()->real_climit(),
+ info->isolate()->heap()->HashSeed(),
+ info->isolate()->unicode_cache()};
+ Parser parser(info, &parse_info);
parser.set_allow_lazy(allow_lazy);
- return parser.Parse();
+ if (parser.Parse()) {
+ info->SetStrictMode(info->function()->strict_mode());
+ return true;
+ }
+ return false;
}
bool Parse();
+ void ParseOnBackground();
+
+ // Handle errors detected during parsing, move statistics to Isolate,
+ // internalize strings (move them to the heap).
+ void Internalize();
private:
friend class ParserTraits;
FunctionLiteral* ParseLazy();
FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
- Isolate* isolate() { return isolate_; }
+ Isolate* isolate() { return info_->isolate(); }
CompilationInfo* info() const { return info_; }
+ Handle<Script> script() const { return info_->script(); }
+ AstValueFactory* ast_value_factory() const {
+ return info_->ast_value_factory();
+ }
// Called by ParseProgram after setting up the scanner.
- FunctionLiteral* DoParseProgram(CompilationInfo* info,
- Handle<String> source);
-
- // Report syntax error
- void ReportInvalidPreparseData(Handle<String> name, bool* ok);
+ FunctionLiteral* DoParseProgram(CompilationInfo* info, Scope** scope,
+ Scope** ad_hoc_eval_scope);
- void SetCachedData(ScriptDataImpl** data,
- CachedDataMode cached_data_mode) {
- cached_data_mode_ = cached_data_mode;
- if (cached_data_mode == NO_CACHED_DATA) {
- cached_data_ = NULL;
- } else {
- ASSERT(data != NULL);
- cached_data_ = data;
- symbol_cache_.Initialize(*data ? (*data)->symbol_count() : 0, zone());
- }
- }
+ void SetCachedData();
bool inside_with() const { return scope_->inside_with(); }
- ScriptDataImpl** cached_data() const { return cached_data_; }
- CachedDataMode cached_data_mode() const { return cached_data_mode_; }
+ ScriptCompiler::CompileOptions compile_options() const {
+ return info_->compile_options();
+ }
Scope* DeclarationScope(VariableMode mode) {
return IsLexicalVariableMode(mode)
? scope_ : scope_->DeclarationScope();
// By making the 'exception handling' explicit, we are forced to check
// for failure at the call sites.
void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
- bool is_eval, bool is_global, bool* ok);
- Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
- Statement* ParseModuleDeclaration(ZoneStringList* names, bool* ok);
+ bool is_eval, bool is_global,
+ Scope** ad_hoc_eval_scope, bool* ok);
+ Statement* ParseModuleElement(ZoneList<const AstRawString*>* labels,
+ bool* ok);
+ Statement* ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
+ bool* ok);
Module* ParseModule(bool* ok);
Module* ParseModuleLiteral(bool* ok);
Module* ParseModulePath(bool* ok);
Module* ParseModuleSpecifier(bool* ok);
Block* ParseImportDeclaration(bool* ok);
Statement* ParseExportDeclaration(bool* ok);
- Statement* ParseBlockElement(ZoneStringList* labels, bool* ok);
- Statement* ParseStatement(ZoneStringList* labels, bool* ok);
- Statement* ParseFunctionDeclaration(ZoneStringList* names, bool* ok);
+ Statement* ParseBlockElement(ZoneList<const AstRawString*>* labels, bool* ok);
+ Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
+ Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
+ bool* ok);
+ Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
+ bool* ok);
Statement* ParseNativeDeclaration(bool* ok);
- Block* ParseBlock(ZoneStringList* labels, bool* ok);
+ Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
Block* ParseVariableStatement(VariableDeclarationContext var_context,
- ZoneStringList* names,
+ ZoneList<const AstRawString*>* names,
bool* ok);
Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
VariableDeclarationProperties* decl_props,
- ZoneStringList* names,
- Handle<String>* out,
+ ZoneList<const AstRawString*>* names,
+ const AstRawString** out,
bool* ok);
- Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
- bool* ok);
- IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
+ Statement* ParseExpressionOrLabelledStatement(
+ ZoneList<const AstRawString*>* labels, bool* ok);
+ IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
+ bool* ok);
Statement* ParseContinueStatement(bool* ok);
- Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
+ Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
+ bool* ok);
Statement* ParseReturnStatement(bool* ok);
- Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
+ Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
+ bool* ok);
CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
- SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
- DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
- WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
- Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
+ SwitchStatement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
+ bool* ok);
+ DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
+ bool* ok);
+ WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
+ bool* ok);
+ Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
Statement* ParseThrowStatement(bool* ok);
Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
TryStatement* ParseTryStatement(bool* ok);
DebuggerStatement* ParseDebuggerStatement(bool* ok);
// Support for hamony block scoped bindings.
- Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);
+ Block* ParseScopedBlock(ZoneList<const AstRawString*>* labels, bool* ok);
// Initialize the components of a for-in / for-of statement.
void InitializeForEachStatement(ForEachStatement* stmt,
Expression* each,
Expression* subject,
Statement* body);
+ Statement* DesugarLetBindingsInForStatement(
+ Scope* inner_scope, ZoneList<const AstRawString*>* names,
+ ForStatement* loop, Statement* init, Expression* cond, Statement* next,
+ Statement* body, bool* ok);
FunctionLiteral* ParseFunctionLiteral(
- Handle<String> name,
- Scanner::Location function_name_location,
- bool name_is_strict_reserved,
- bool is_generator,
- int function_token_position,
- FunctionLiteral::FunctionType type,
- bool* ok);
+ const AstRawString* name, Scanner::Location function_name_location,
+ bool name_is_strict_reserved, FunctionKind kind,
+ int function_token_position, FunctionLiteral::FunctionType type,
+ FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
// Magical syntax support.
Expression* ParseV8Intrinsic(bool* ok);
void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
// Parser support
- VariableProxy* NewUnresolved(Handle<String> name,
+ VariableProxy* NewUnresolved(const AstRawString* name,
VariableMode mode,
Interface* interface);
void Declare(Declaration* declaration, bool resolve, bool* ok);
- bool TargetStackContainsLabel(Handle<String> label);
- BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
- IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
+ bool TargetStackContainsLabel(const AstRawString* label);
+ BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
+ IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
void RegisterTargetUse(Label* target, Target* stop);
Scope* NewScope(Scope* parent, ScopeType type);
- Handle<String> LookupCachedSymbol(int symbol_id);
+ // Skip over a lazy function, either using cached data if we have it, or
+ // by parsing the function with PreParser. Consumes the ending }.
+ void SkipLazyFunctionBody(const AstRawString* function_name,
+ int* materialized_literal_count,
+ int* expected_property_count,
+ bool* ok);
- // Generate AST node that throw a ReferenceError with the given type.
- Expression* NewThrowReferenceError(Handle<String> type);
+ PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
+ SingletonLogger* logger);
- // Generate AST node that throw a SyntaxError with the given
- // type. The first argument may be null (in the handle sense) in
- // which case no arguments are passed to the constructor.
- Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
-
- // Generate AST node that throw a TypeError with the given
- // type. Both arguments must be non-null (in the handle sense).
- Expression* NewThrowTypeError(Handle<String> type,
- Handle<Object> first,
- Handle<Object> second);
+ // Consumes the ending }.
+ ZoneList<Statement*>* ParseEagerFunctionBody(
+ const AstRawString* function_name, int pos, Variable* fvar,
+ Token::Value fvar_init_op, bool is_generator, bool* ok);
- // Generic AST generator for throwing errors from compiled code.
- Expression* NewThrowError(Handle<String> constructor,
- Handle<String> type,
- Vector< Handle<Object> > arguments);
+ void HandleSourceURLComments();
- PreParser::PreParseResult LazyParseFunctionLiteral(
- SingletonLogger* logger);
+ void ThrowPendingError();
- Isolate* isolate_;
- ZoneList<Handle<String> > symbol_cache_;
-
- Handle<Script> script_;
Scanner scanner_;
PreParser* reusable_preparser_;
Scope* original_scope_; // for ES5 function declarations in sloppy eval
Target* target_stack_; // for break, continue statements
- ScriptDataImpl** cached_data_;
- CachedDataMode cached_data_mode_;
+ ParseData* cached_parse_data_;
CompilationInfo* info_;
+
+ // Pending errors.
+ bool has_pending_error_;
+ Scanner::Location pending_error_location_;
+ const char* pending_error_message_;
+ const AstRawString* pending_error_arg_;
+ const char* pending_error_char_arg_;
+ bool pending_error_is_reference_error_;
+
+ // Other information which will be stored in Parser and moved to Isolate after
+ // parsing.
+ int use_counts_[v8::Isolate::kUseCounterFeatureCount];
+ int total_preparse_skipped_;
+ HistogramTimer* pre_parse_timer_;
+
+ // Temporary; for debugging. See Parser::SkipLazyFunctionBody. TODO(marja):
+ // remove this once done.
+ ScriptCompiler::CompileOptions debug_saved_compile_options_;
};
+bool ParserTraits::IsFutureStrictReserved(
+ const AstRawString* identifier) const {
+ return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
+}
+
+
+Scope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type) {
+ return parser_->NewScope(parent_scope, scope_type);
+}
+
+
+const AstRawString* ParserTraits::EmptyIdentifierString() {
+ return parser_->ast_value_factory()->empty_string();
+}
+
+
+void ParserTraits::SkipLazyFunctionBody(const AstRawString* function_name,
+ int* materialized_literal_count,
+ int* expected_property_count,
+ bool* ok) {
+ return parser_->SkipLazyFunctionBody(
+ function_name, materialized_literal_count, expected_property_count, ok);
+}
+
+
+ZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
+ const AstRawString* name, int pos, Variable* fvar,
+ Token::Value fvar_init_op, bool is_generator, bool* ok) {
+ return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op,
+ is_generator, ok);
+}
+
+void ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
+ bool* ok) {
+ parser_->CheckConflictingVarDeclarations(scope, ok);
+}
+
+
+AstValueFactory* ParserTraits::ast_value_factory() {
+ return parser_->ast_value_factory();
+}
+
+
// Support for handling complex values (array and object literals) that
// can be fully handled at compile time.
class CompileTimeValue: public AllStatic {