| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index 94d657504e8392ce3e456217fd02c9260bc72477..8a2eca7cc97f2ec63856302a6000ae6a9fdf1fa0 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -326,7 +326,8 @@ unsigned* ScriptData::ReadAddress(int position) const {
|
|
|
|
|
| Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) {
|
| - Scope* result = new(zone()) Scope(parent, scope_type, zone());
|
| + ASSERT(symbol_table_);
|
| + Scope* result = new(zone()) Scope(parent, scope_type, symbol_table_, zone());
|
| result->Initialize();
|
| return result;
|
| }
|
| @@ -399,10 +400,10 @@ class TargetScope BASE_EMBEDDED {
|
| // ----------------------------------------------------------------------------
|
| // Implementation of Parser
|
|
|
| -bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const {
|
| - Factory* factory = parser_->isolate()->factory();
|
| - return identifier.is_identical_to(factory->eval_string())
|
| - || identifier.is_identical_to(factory->arguments_string());
|
| +bool ParserTraits::IsEvalOrArguments(
|
| + ParserSymbolTable::Symbol* identifier) const {
|
| + return identifier == parser_->symbol_table_->eval_string() ||
|
| + identifier == parser_->symbol_table_->arguments_string();
|
| }
|
|
|
|
|
| @@ -424,10 +425,9 @@ bool ParserTraits::IsIdentifier(Expression* expression) {
|
| void ParserTraits::PushPropertyName(FuncNameInferrer* fni,
|
| Expression* expression) {
|
| if (expression->IsPropertyName()) {
|
| - fni->PushLiteralName(expression->AsLiteral()->AsPropertyName());
|
| + fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName());
|
| } else {
|
| - fni->PushLiteralName(
|
| - parser_->isolate()->factory()->anonymous_function_string());
|
| + fni->PushLiteralName(parser_->symbol_table_->anonymous_function_string());
|
| }
|
| }
|
|
|
| @@ -446,7 +446,7 @@ void ParserTraits::CheckPossibleEvalCall(Expression* expression,
|
| Scope* scope) {
|
| VariableProxy* callee = expression->AsVariableProxy();
|
| if (callee != NULL &&
|
| - callee->IsVariable(parser_->isolate()->factory()->eval_string())) {
|
| + callee->raw_name() == parser_->symbol_table_->eval_string()) {
|
| scope->DeclarationScope()->RecordEvalCall();
|
| }
|
| }
|
| @@ -464,10 +464,13 @@ Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) {
|
| bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
|
| Expression** x, Expression* y, Token::Value op, int pos,
|
| AstNodeFactory<AstConstructionVisitor>* factory) {
|
| - if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() &&
|
| - y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) {
|
| - double x_val = (*x)->AsLiteral()->value()->Number();
|
| - double y_val = y->AsLiteral()->value()->Number();
|
| + // FIXME: this needs to change when it cannot use handles.
|
| + if ((*x)->AsLiteral() && !(*x)->AsLiteral()->valueIfNotString().is_null() &&
|
| + (*x)->AsLiteral()->valueIfNotString()->IsNumber() && y->AsLiteral() &&
|
| + !y->AsLiteral()->valueIfNotString().is_null() &&
|
| + y->AsLiteral()->valueIfNotString()->IsNumber()) {
|
| + double x_val = (*x)->AsLiteral()->valueIfNotString()->Number();
|
| + double y_val = y->AsLiteral()->valueIfNotString()->Number();
|
| switch (op) {
|
| case Token::ADD:
|
| *x = factory->NewNumberLiteral(x_val + y_val, pos);
|
| @@ -525,8 +528,12 @@ Expression* ParserTraits::BuildUnaryExpression(
|
| Expression* expression, Token::Value op, int pos,
|
| AstNodeFactory<AstConstructionVisitor>* factory) {
|
| ASSERT(expression != NULL);
|
| - if (expression->AsLiteral() != NULL) {
|
| - Handle<Object> literal = expression->AsLiteral()->value();
|
| + // FIXME: This needs to change when numbers and booleans are no longer
|
| + // handles.
|
| + // FIXME: The !"foo" shortcut doesn't work atm.
|
| + if (expression->AsLiteral() != NULL &&
|
| + !expression->AsLiteral()->valueIfNotString().is_null()) {
|
| + Handle<Object> literal = expression->AsLiteral()->valueIfNotString();
|
| if (op == Token::NOT) {
|
| // Convert the literal to a boolean condition and negate it.
|
| bool condition = literal->BooleanValue();
|
| @@ -568,52 +575,40 @@ Expression* ParserTraits::BuildUnaryExpression(
|
|
|
|
|
| Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
|
| - return NewThrowError(
|
| - parser_->isolate()->factory()->MakeReferenceError_string(),
|
| - message, HandleVector<Object>(NULL, 0), pos);
|
| + return NewThrowError(parser_->symbol_table_->make_reference_error_string(),
|
| + message, NULL, pos);
|
| }
|
|
|
|
|
| Expression* ParserTraits::NewThrowSyntaxError(
|
| - const char* message, Handle<Object> arg, int pos) {
|
| - int argc = arg.is_null() ? 0 : 1;
|
| - Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc);
|
| - return NewThrowError(
|
| - parser_->isolate()->factory()->MakeSyntaxError_string(),
|
| - message, arguments, pos);
|
| + const char* message, ParserSymbolTable::Symbol* arg, int pos) {
|
| + return NewThrowError(parser_->symbol_table_->make_syntax_error_string(),
|
| + message, arg, pos);
|
| }
|
|
|
|
|
| Expression* ParserTraits::NewThrowTypeError(
|
| - const char* message, Handle<Object> arg, int pos) {
|
| - int argc = arg.is_null() ? 0 : 1;
|
| - Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc);
|
| - return NewThrowError(
|
| - parser_->isolate()->factory()->MakeTypeError_string(),
|
| - message, arguments, pos);
|
| + const char* message, ParserSymbolTable::Symbol* arg, int pos) {
|
| + return NewThrowError(parser_->symbol_table_->make_type_error_string(),
|
| + message, arg, pos);
|
| }
|
|
|
|
|
| Expression* ParserTraits::NewThrowError(
|
| - Handle<String> constructor, const char* message,
|
| - Vector<Handle<Object> > arguments, int pos) {
|
| + ParserSymbolTable::Symbol* constructor, const char* message,
|
| + ParserSymbolTable::Symbol* arg, int pos) {
|
| Zone* zone = parser_->zone();
|
| - Factory* factory = parser_->isolate()->factory();
|
| - int argc = arguments.length();
|
| - Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED);
|
| - for (int i = 0; i < argc; i++) {
|
| - Handle<Object> element = arguments[i];
|
| - if (!element.is_null()) {
|
| - elements->set(i, *element);
|
| - }
|
| - }
|
| - Handle<JSArray> array =
|
| - factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED);
|
| -
|
| - ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone);
|
| - Handle<String> type = factory->InternalizeUtf8String(message);
|
| + ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(arg != NULL ? 2 : 1, zone);
|
| + ParserSymbolTable::Symbol* type =
|
| + parser_->symbol_table_->GetOneByteSymbol(Vector<const uint8_t>(
|
| + reinterpret_cast<const uint8_t*>(message), StrLength(message)));
|
| args->Add(parser_->factory()->NewLiteral(type, pos), zone);
|
| - args->Add(parser_->factory()->NewLiteral(array, pos), zone);
|
| + if (arg != NULL) {
|
| + ZoneList<ParserSymbolTable::Symbol*>* array =
|
| + new (zone) ZoneList<ParserSymbolTable::Symbol*>(1, zone);
|
| + array->Add(arg, zone);
|
| + args->Add(parser_->factory()->NewLiteral(array, pos), zone);
|
| + }
|
| CallRuntime* call_constructor =
|
| parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
|
| return parser_->factory()->NewThrow(call_constructor, pos);
|
| @@ -622,7 +617,7 @@ Expression* ParserTraits::NewThrowError(
|
|
|
| void ParserTraits::ReportMessageAt(Scanner::Location source_location,
|
| const char* message,
|
| - const char* arg,
|
| + const char* char_arg,
|
| bool is_reference_error) {
|
| if (parser_->stack_overflow()) {
|
| // Suppress the error message (syntax error or such) in the presence of a
|
| @@ -630,35 +625,18 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
|
| // and we want to report the stack overflow later.
|
| return;
|
| }
|
| - MessageLocation location(parser_->script_,
|
| - source_location.beg_pos,
|
| - source_location.end_pos);
|
| - Factory* factory = parser_->isolate()->factory();
|
| - Handle<FixedArray> elements = factory->NewFixedArray(arg == NULL ? 0 : 1);
|
| - if (arg != NULL) {
|
| - Handle<String> arg_string =
|
| - factory->NewStringFromUtf8(CStrVector(arg)).ToHandleChecked();
|
| - elements->set(0, *arg_string);
|
| - }
|
| - Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
|
| - Handle<Object> result = is_reference_error
|
| - ? factory->NewReferenceError(message, array)
|
| - : factory->NewSyntaxError(message, array);
|
| - parser_->isolate()->Throw(*result, &location);
|
| -}
|
| -
|
| -
|
| -void ParserTraits::ReportMessage(const char* message,
|
| - MaybeHandle<String> arg,
|
| - bool is_reference_error) {
|
| - Scanner::Location source_location = parser_->scanner()->location();
|
| - ReportMessageAt(source_location, message, arg, is_reference_error);
|
| + parser_->has_pending_error_ = true;
|
| + parser_->pending_location_ = source_location;
|
| + parser_->pending_message_ = message;
|
| + parser_->pending_char_arg_ = char_arg;
|
| + parser_->pending_arg_ = NULL;
|
| + parser_->pending_is_reference_error_ = is_reference_error;
|
| }
|
|
|
|
|
| void ParserTraits::ReportMessageAt(Scanner::Location source_location,
|
| const char* message,
|
| - MaybeHandle<String> arg,
|
| + ParserSymbolTable::Symbol* arg,
|
| bool is_reference_error) {
|
| if (parser_->stack_overflow()) {
|
| // Suppress the error message (syntax error or such) in the presence of a
|
| @@ -666,33 +644,38 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
|
| // and we want to report the stack overflow later.
|
| return;
|
| }
|
| - MessageLocation location(parser_->script_,
|
| - source_location.beg_pos,
|
| - source_location.end_pos);
|
| - Factory* factory = parser_->isolate()->factory();
|
| - Handle<FixedArray> elements = factory->NewFixedArray(arg.is_null() ? 0 : 1);
|
| - if (!arg.is_null()) {
|
| - elements->set(0, *(arg.ToHandleChecked()));
|
| - }
|
| - Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
|
| - Handle<Object> result = is_reference_error
|
| - ? factory->NewReferenceError(message, array)
|
| - : factory->NewSyntaxError(message, array);
|
| - parser_->isolate()->Throw(*result, &location);
|
| + parser_->has_pending_error_ = true;
|
| + parser_->pending_location_ = source_location;
|
| + parser_->pending_message_ = message;
|
| + parser_->pending_char_arg_ = NULL;
|
| + parser_->pending_arg_ = arg;
|
| + parser_->pending_is_reference_error_ = is_reference_error;
|
| }
|
|
|
|
|
| -Handle<String> ParserTraits::GetSymbol(Scanner* scanner) {
|
| - Handle<String> result =
|
| - parser_->scanner()->AllocateInternalizedString(parser_->isolate());
|
| - ASSERT(!result.is_null());
|
| - return result;
|
| +void ParserTraits::ReportMessage(const char* message,
|
| + const char* char_arg,
|
| + bool is_reference_error) {
|
| + Scanner::Location source_location = parser_->scanner()->location();
|
| + ReportMessageAt(source_location, message, char_arg, is_reference_error);
|
| +}
|
| +
|
| +
|
| +void ParserTraits::ReportMessage(const char* message,
|
| + ParserSymbolTable::Symbol* arg,
|
| + bool is_reference_error) {
|
| + Scanner::Location source_location = parser_->scanner()->location();
|
| + ReportMessageAt(source_location, message, arg, is_reference_error);
|
| +}
|
| +
|
| +
|
| +ParserSymbolTable::Symbol* ParserTraits::GetSymbol(Scanner* scanner) {
|
| + return parser_->scanner()->CurrentString(parser_->symbol_table_);
|
| }
|
|
|
|
|
| -Handle<String> ParserTraits::NextLiteralString(Scanner* scanner,
|
| - PretenureFlag tenured) {
|
| - return scanner->AllocateNextLiteralString(parser_->isolate(), tenured);
|
| +ParserSymbolTable::Symbol* ParserTraits::GetNextSymbol(Scanner* scanner) {
|
| + return parser_->scanner()->NextString(parser_->symbol_table_);
|
| }
|
|
|
|
|
| @@ -727,13 +710,17 @@ Literal* ParserTraits::ExpressionFromLiteral(
|
|
|
|
|
| Expression* ParserTraits::ExpressionFromIdentifier(
|
| - Handle<String> name, int pos, Scope* scope,
|
| + ParserSymbolTable::Symbol* name, int pos, Scope* scope,
|
| AstNodeFactory<AstConstructionVisitor>* factory) {
|
| - if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
|
| + if (parser_->fni_ != NULL) {
|
| + parser_->fni_->PushVariableName(name);
|
| + }
|
| // The name may refer to a module instance object, so its type is unknown.
|
| #ifdef DEBUG
|
| - if (FLAG_print_interface_details)
|
| - PrintF("# Variable %s ", name->ToAsciiArray());
|
| + if (FLAG_print_interface_details) {
|
| + PrintF("# Variable %.*s ", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| + }
|
| #endif
|
| Interface* interface = Interface::NewUnknown(parser_->zone());
|
| return scope->NewUnresolved(factory, name, interface, pos);
|
| @@ -743,7 +730,7 @@ Expression* ParserTraits::ExpressionFromIdentifier(
|
| Expression* ParserTraits::ExpressionFromString(
|
| int pos, Scanner* scanner,
|
| AstNodeFactory<AstConstructionVisitor>* factory) {
|
| - Handle<String> symbol = GetSymbol(scanner);
|
| + ParserSymbolTable::Symbol* symbol = GetSymbol(scanner);
|
| if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
|
| return factory->NewLiteral(symbol, pos);
|
| }
|
| @@ -762,7 +749,7 @@ Expression* ParserTraits::ParseV8Intrinsic(bool* ok) {
|
|
|
|
|
| FunctionLiteral* ParserTraits::ParseFunctionLiteral(
|
| - Handle<String> name,
|
| + ParserSymbolTable::Symbol* name,
|
| Scanner::Location function_name_location,
|
| bool name_is_strict_reserved,
|
| bool is_generator,
|
| @@ -790,7 +777,12 @@ Parser::Parser(CompilationInfo* info)
|
| target_stack_(NULL),
|
| cached_data_(NULL),
|
| cached_data_mode_(NO_CACHED_DATA),
|
| - info_(info) {
|
| + symbol_table_(NULL),
|
| + info_(info),
|
| + has_pending_error_(false),
|
| + pending_message_(NULL),
|
| + pending_arg_(NULL),
|
| + pending_char_arg_(NULL) {
|
| ASSERT(!script_.is_null());
|
| isolate_->set_ast_node_id(0);
|
| set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
|
| @@ -813,7 +805,7 @@ FunctionLiteral* Parser::ParseProgram() {
|
| if (FLAG_trace_parse) {
|
| timer.Start();
|
| }
|
| - fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
|
| + fni_ = new(zone()) FuncNameInferrer(symbol_table_, zone());
|
|
|
| // Initialize parser state.
|
| CompleteParserRecorder recorder;
|
| @@ -868,13 +860,14 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
|
| ASSERT(scope_ == NULL);
|
| ASSERT(target_stack_ == NULL);
|
|
|
| - Handle<String> no_name = isolate()->factory()->empty_string();
|
| + ParserSymbolTable::Symbol* no_name = symbol_table_->empty_string();
|
|
|
| FunctionLiteral* result = NULL;
|
| { Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
|
| info->SetGlobalScope(scope);
|
| if (!info->context().is_null()) {
|
| scope = Scope::DeserializeScopeChain(*info->context(), scope, zone());
|
| + symbol_table_->AlwaysInternalize(isolate());
|
| }
|
| original_scope_ = scope;
|
| if (info->is_eval()) {
|
| @@ -922,6 +915,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
|
| }
|
| }
|
|
|
| + symbol_table_->Internalize(isolate());
|
| +
|
| if (ok) {
|
| result = factory()->NewFunctionLiteral(
|
| no_name,
|
| @@ -940,8 +935,11 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
|
| result->set_ast_properties(factory()->visitor()->ast_properties());
|
| result->set_dont_optimize_reason(
|
| factory()->visitor()->dont_optimize_reason());
|
| +
|
| } else if (stack_overflow()) {
|
| isolate()->StackOverflow();
|
| + } else {
|
| + CheckPendingError();
|
| }
|
| }
|
|
|
| @@ -994,8 +992,9 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
|
| ASSERT(target_stack_ == NULL);
|
|
|
| Handle<String> name(String::cast(shared_info->name()));
|
| - fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
|
| - fni_->PushEnclosingName(name);
|
| + fni_ = new(zone()) FuncNameInferrer(symbol_table_, zone());
|
| + ParserSymbolTable::Symbol* raw_name = symbol_table_->GetSymbol(name);
|
| + fni_->PushEnclosingName(raw_name);
|
|
|
| ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
|
|
|
| @@ -1021,7 +1020,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
|
| : FunctionLiteral::NAMED_EXPRESSION)
|
| : FunctionLiteral::DECLARATION;
|
| bool ok = true;
|
| - result = ParseFunctionLiteral(name,
|
| + result = ParseFunctionLiteral(raw_name,
|
| Scanner::Location::invalid(),
|
| false, // Strict mode name already checked.
|
| shared_info->is_generator(),
|
| @@ -1030,13 +1029,20 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) {
|
| &ok);
|
| // Make sure the results agree.
|
| ASSERT(ok == (result != NULL));
|
| +
|
| + // Start using the heap (before scope goes out of scope).
|
| + symbol_table_->Internalize(isolate());
|
| }
|
|
|
| // Make sure the target stack is empty.
|
| ASSERT(target_stack_ == NULL);
|
|
|
| if (result == NULL) {
|
| - if (stack_overflow()) isolate()->StackOverflow();
|
| + if (stack_overflow()) {
|
| + isolate()->StackOverflow();
|
| + } else {
|
| + CheckPendingError();
|
| + }
|
| } else {
|
| Handle<String> inferred_name(shared_info->inferred_name());
|
| result->set_inferred_name(inferred_name);
|
| @@ -1086,15 +1092,11 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
|
| // Still processing directive prologue?
|
| if ((e_stat = stat->AsExpressionStatement()) != NULL &&
|
| (literal = e_stat->expression()->AsLiteral()) != NULL &&
|
| - literal->value()->IsString()) {
|
| - Handle<String> directive = Handle<String>::cast(literal->value());
|
| -
|
| + literal->string() != NULL) {
|
| // Check "use strict" directive (ES5 14.1).
|
| if (strict_mode() == SLOPPY &&
|
| - String::Equals(isolate()->factory()->use_strict_string(),
|
| - directive) &&
|
| - token_loc.end_pos - token_loc.beg_pos ==
|
| - isolate()->heap()->use_strict_string()->length() + 2) {
|
| + literal->string() == symbol_table_->use_strict_string() &&
|
| + token_loc.end_pos - token_loc.beg_pos == 12) {
|
| // TODO(mstarzinger): Global strict eval calls, need their own scope
|
| // as specified in ES5 10.4.2(3). The correct fix would be to always
|
| // add this scope in DoParseProgram(), but that requires adaptations
|
| @@ -1125,8 +1127,8 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
|
| }
|
|
|
|
|
| -Statement* Parser::ParseModuleElement(ZoneStringList* labels,
|
| - bool* ok) {
|
| +Statement* Parser::ParseModuleElement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // (Ecma 262 5th Edition, clause 14):
|
| // SourceElement:
|
| // Statement
|
| @@ -1159,10 +1161,9 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels,
|
| !scanner()->HasAnyLineTerminatorBeforeNext() &&
|
| stmt != NULL) {
|
| ExpressionStatement* estmt = stmt->AsExpressionStatement();
|
| - if (estmt != NULL &&
|
| - estmt->expression()->AsVariableProxy() != NULL &&
|
| - String::Equals(isolate()->factory()->module_string(),
|
| - estmt->expression()->AsVariableProxy()->name()) &&
|
| + if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL &&
|
| + estmt->expression()->AsVariableProxy()->raw_name() ==
|
| + symbol_table_->module_string() &&
|
| !scanner()->literal_contains_escapes()) {
|
| return ParseModuleDeclaration(NULL, ok);
|
| }
|
| @@ -1173,16 +1174,20 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels,
|
| }
|
|
|
|
|
| -Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
|
| +Statement* Parser::ParseModuleDeclaration(
|
| + ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) {
|
| // ModuleDeclaration:
|
| // 'module' Identifier Module
|
|
|
| int pos = peek_position();
|
| - Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
|
| + ParserSymbolTable::Symbol* name =
|
| + ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
|
|
|
| #ifdef DEBUG
|
| - if (FLAG_print_interface_details)
|
| - PrintF("# Module %s...\n", name->ToAsciiArray());
|
| + if (FLAG_print_interface_details) {
|
| + PrintF("# Module %.*s ", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| + }
|
| #endif
|
|
|
| Module* module = ParseModule(CHECK_OK);
|
| @@ -1192,11 +1197,13 @@ Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
|
| Declare(declaration, true, CHECK_OK);
|
|
|
| #ifdef DEBUG
|
| - if (FLAG_print_interface_details)
|
| - PrintF("# Module %s.\n", name->ToAsciiArray());
|
| -
|
| + if (FLAG_print_interface_details) {
|
| + PrintF("# Module %.*s ", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| + }
|
| if (FLAG_print_interfaces) {
|
| - PrintF("module %s : ", name->ToAsciiArray());
|
| + PrintF("module %.*s: ", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| module->interface()->Print();
|
| }
|
| #endif
|
| @@ -1297,17 +1304,21 @@ Module* Parser::ParseModulePath(bool* ok) {
|
| int pos = peek_position();
|
| Module* result = ParseModuleVariable(CHECK_OK);
|
| while (Check(Token::PERIOD)) {
|
| - Handle<String> name = ParseIdentifierName(CHECK_OK);
|
| + ParserSymbolTable::Symbol* name = ParseIdentifierName(CHECK_OK);
|
| #ifdef DEBUG
|
| - if (FLAG_print_interface_details)
|
| - PrintF("# Path .%s ", name->ToAsciiArray());
|
| + if (FLAG_print_interface_details) {
|
| + PrintF("# Path .%.*s ", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| + }
|
| #endif
|
| - Module* member = factory()->NewModulePath(result, name, pos);
|
| + Module* member =
|
| + factory()->NewModulePath(result, name, pos);
|
| result->interface()->Add(name, member->interface(), zone(), ok);
|
| if (!*ok) {
|
| #ifdef DEBUG
|
| if (FLAG_print_interfaces) {
|
| - PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
|
| + PrintF("PATH TYPE ERROR at '%.*s'\n", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| PrintF("result: ");
|
| result->interface()->Print();
|
| PrintF("member: ");
|
| @@ -1329,10 +1340,13 @@ Module* Parser::ParseModuleVariable(bool* ok) {
|
| // Identifier
|
|
|
| int pos = peek_position();
|
| - Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
|
| + ParserSymbolTable::Symbol* name =
|
| + ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
|
| #ifdef DEBUG
|
| - if (FLAG_print_interface_details)
|
| - PrintF("# Module variable %s ", name->ToAsciiArray());
|
| + if (FLAG_print_interface_details) {
|
| + PrintF("# Module variable %.*s ", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| + }
|
| #endif
|
| VariableProxy* proxy = scope_->NewUnresolved(
|
| factory(), name, Interface::NewModule(zone()),
|
| @@ -1348,7 +1362,7 @@ Module* Parser::ParseModuleUrl(bool* ok) {
|
|
|
| int pos = peek_position();
|
| Expect(Token::STRING, CHECK_OK);
|
| - Handle<String> symbol = GetSymbol();
|
| + ParserSymbolTable::Symbol* symbol = GetSymbol(scanner());
|
|
|
| // TODO(ES6): Request JS resource from environment...
|
|
|
| @@ -1392,9 +1406,9 @@ Block* Parser::ParseImportDeclaration(bool* ok) {
|
|
|
| int pos = peek_position();
|
| Expect(Token::IMPORT, CHECK_OK);
|
| - ZoneStringList names(1, zone());
|
| + ZoneList<ParserSymbolTable::Symbol*> names(1, zone());
|
|
|
| - Handle<String> name = ParseIdentifierName(CHECK_OK);
|
| + ParserSymbolTable::Symbol* name = ParseIdentifierName(CHECK_OK);
|
| names.Add(name, zone());
|
| while (peek() == Token::COMMA) {
|
| Consume(Token::COMMA);
|
| @@ -1411,15 +1425,18 @@ Block* Parser::ParseImportDeclaration(bool* ok) {
|
| Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
|
| for (int i = 0; i < names.length(); ++i) {
|
| #ifdef DEBUG
|
| - if (FLAG_print_interface_details)
|
| - PrintF("# Import %s ", names[i]->ToAsciiArray());
|
| + if (FLAG_print_interface_details) {
|
| + PrintF("# Import %.*s ", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| + }
|
| #endif
|
| Interface* interface = Interface::NewUnknown(zone());
|
| module->interface()->Add(names[i], interface, zone(), ok);
|
| if (!*ok) {
|
| #ifdef DEBUG
|
| if (FLAG_print_interfaces) {
|
| - PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
|
| + PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->literal_bytes.length(),
|
| + name->literal_bytes.start());
|
| PrintF("module: ");
|
| module->interface()->Print();
|
| }
|
| @@ -1450,14 +1467,14 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
|
| Expect(Token::EXPORT, CHECK_OK);
|
|
|
| Statement* result = NULL;
|
| - ZoneStringList names(1, zone());
|
| + ZoneList<ParserSymbolTable::Symbol*> names(1, zone());
|
| switch (peek()) {
|
| case Token::IDENTIFIER: {
|
| int pos = position();
|
| - Handle<String> name =
|
| + ParserSymbolTable::Symbol* name =
|
| ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
|
| // Handle 'module' as a context-sensitive keyword.
|
| - if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) {
|
| + if (name != symbol_table_->module_string()) {
|
| names.Add(name, zone());
|
| while (peek() == Token::COMMA) {
|
| Consume(Token::COMMA);
|
| @@ -1492,8 +1509,10 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
|
| Interface* interface = scope_->interface();
|
| for (int i = 0; i < names.length(); ++i) {
|
| #ifdef DEBUG
|
| - if (FLAG_print_interface_details)
|
| - PrintF("# Export %s ", names[i]->ToAsciiArray());
|
| + if (FLAG_print_interface_details) {
|
| + PrintF("# Export %.*s ", names[i]->literal_bytes.length(),
|
| + names[i]->literal_bytes.start());
|
| + }
|
| #endif
|
| Interface* inner = Interface::NewUnknown(zone());
|
| interface->Add(names[i], inner, zone(), CHECK_OK);
|
| @@ -1513,8 +1532,8 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
|
| }
|
|
|
|
|
| -Statement* Parser::ParseBlockElement(ZoneStringList* labels,
|
| - bool* ok) {
|
| +Statement* Parser::ParseBlockElement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // (Ecma 262 5th Edition, clause 14):
|
| // SourceElement:
|
| // Statement
|
| @@ -1538,7 +1557,8 @@ Statement* Parser::ParseBlockElement(ZoneStringList* labels,
|
| }
|
|
|
|
|
| -Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
| +Statement* Parser::ParseStatement(ZoneList<ParserSymbolTable::Symbol*>* labels,
|
| + bool* ok) {
|
| // Statement ::
|
| // Block
|
| // VariableStatement
|
| @@ -1632,7 +1652,8 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
| // Statement:
|
| // GeneratorDeclaration
|
| if (strict_mode() == STRICT) {
|
| - ReportMessageAt(scanner()->peek_location(), "strict_function");
|
| + ParserTraits::ReportMessageAt(scanner()->peek_location(),
|
| + "strict_function");
|
| *ok = false;
|
| return NULL;
|
| }
|
| @@ -1648,8 +1669,9 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
|
| }
|
|
|
|
|
| +template<typename SymbolType>
|
| VariableProxy* Parser::NewUnresolved(
|
| - Handle<String> name, VariableMode mode, Interface* interface) {
|
| + SymbolType name, VariableMode mode, Interface* interface) {
|
| // If we are inside a function, a declaration of a var/const variable is a
|
| // truly local variable, and the scope of the variable is always the function
|
| // scope.
|
| @@ -1662,7 +1684,8 @@ VariableProxy* Parser::NewUnresolved(
|
|
|
| void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
|
| VariableProxy* proxy = declaration->proxy();
|
| - Handle<String> name = proxy->name();
|
| + ASSERT(proxy->raw_name() != NULL);
|
| + ParserSymbolTable::Symbol* name = proxy->raw_name();
|
| VariableMode mode = declaration->mode();
|
| Scope* declaration_scope = DeclarationScope(mode);
|
| Variable* var = NULL;
|
| @@ -1790,8 +1813,15 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
|
| if (FLAG_harmony_modules) {
|
| bool ok;
|
| #ifdef DEBUG
|
| - if (FLAG_print_interface_details)
|
| - PrintF("# Declare %s\n", var->name()->ToAsciiArray());
|
| + if (FLAG_print_interface_details) {
|
| + if (!var->name().is_null()) {
|
| + PrintF("# Declare %s\n", var->name()->ToAsciiArray());
|
| + } else {
|
| + ASSERT(var->raw_name() != NULL);
|
| + PrintF("# Declare %.*s ", var->raw_name()->literal_bytes.length(),
|
| + var->raw_name()->literal_bytes.start());
|
| + }
|
| + }
|
| #endif
|
| proxy->interface()->Unify(var->interface(), zone(), &ok);
|
| if (!ok) {
|
| @@ -1819,7 +1849,8 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
| int pos = peek_position();
|
| Expect(Token::FUNCTION, CHECK_OK);
|
| // Allow "eval" or "arguments" for backward compatibility.
|
| - Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
|
| + ParserSymbolTable::Symbol* name =
|
| + ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
|
| Expect(Token::LPAREN, CHECK_OK);
|
| bool done = (peek() == Token::RPAREN);
|
| while (!done) {
|
| @@ -1854,7 +1885,8 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
| }
|
|
|
|
|
| -Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
|
| +Statement* Parser::ParseFunctionDeclaration(
|
| + ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) {
|
| // FunctionDeclaration ::
|
| // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
|
| // GeneratorDeclaration ::
|
| @@ -1864,7 +1896,7 @@ Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
|
| int pos = position();
|
| bool is_generator = allow_generators() && Check(Token::MUL);
|
| bool is_strict_reserved = false;
|
| - Handle<String> name = ParseIdentifierOrStrictReservedWord(
|
| + ParserSymbolTable::Symbol* name = ParseIdentifierOrStrictReservedWord(
|
| &is_strict_reserved, CHECK_OK);
|
| FunctionLiteral* fun = ParseFunctionLiteral(name,
|
| scanner()->location(),
|
| @@ -1890,7 +1922,7 @@ Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) {
|
| }
|
|
|
|
|
| -Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
|
| +Block* Parser::ParseBlock(ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| if (allow_harmony_scoping() && strict_mode() == STRICT) {
|
| return ParseScopedBlock(labels, ok);
|
| }
|
| @@ -1917,7 +1949,7 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
|
| }
|
|
|
|
|
| -Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
|
| +Block* Parser::ParseScopedBlock(ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // The harmony mode uses block elements instead of statements.
|
| //
|
| // Block ::
|
| @@ -1951,13 +1983,13 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) {
|
| }
|
|
|
|
|
| -Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
|
| - ZoneStringList* names,
|
| - bool* ok) {
|
| +Block* Parser::ParseVariableStatement(
|
| + VariableDeclarationContext var_context,
|
| + ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) {
|
| // VariableStatement ::
|
| // VariableDeclarations ';'
|
|
|
| - Handle<String> ignore;
|
| + ParserSymbolTable::Symbol* ignore;
|
| Block* result =
|
| ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK);
|
| ExpectSemicolon(CHECK_OK);
|
| @@ -1973,8 +2005,8 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
|
| Block* Parser::ParseVariableDeclarations(
|
| VariableDeclarationContext var_context,
|
| VariableDeclarationProperties* decl_props,
|
| - ZoneStringList* names,
|
| - Handle<String>* out,
|
| + ZoneList<ParserSymbolTable::Symbol*>* names,
|
| + ParserSymbolTable::Symbol** out,
|
| bool* ok) {
|
| // VariableDeclarations ::
|
| // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
|
| @@ -2082,7 +2114,7 @@ Block* Parser::ParseVariableDeclarations(
|
| // Create new block with one expected declaration.
|
| Block* block = factory()->NewBlock(NULL, 1, true, pos);
|
| int nvars = 0; // the number of variables declared
|
| - Handle<String> name;
|
| + ParserSymbolTable::Symbol* name = NULL;
|
| do {
|
| if (fni_ != NULL) fni_->Enter();
|
|
|
| @@ -2114,7 +2146,7 @@ Block* Parser::ParseVariableDeclarations(
|
| Declare(declaration, mode != VAR, CHECK_OK);
|
| nvars++;
|
| if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
|
| - ReportMessageAt(scanner()->location(), "too_many_variables");
|
| + ReportMessage("too_many_variables");
|
| *ok = false;
|
| return NULL;
|
| }
|
| @@ -2213,7 +2245,7 @@ Block* Parser::ParseVariableDeclarations(
|
| // Note that the function does different things depending on
|
| // the number of arguments (1 or 2).
|
| initialize = factory()->NewCallRuntime(
|
| - isolate()->factory()->InitializeConstGlobal_string(),
|
| + symbol_table_->initialize_const_global_string(),
|
| Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal),
|
| arguments, pos);
|
| } else {
|
| @@ -2236,7 +2268,7 @@ Block* Parser::ParseVariableDeclarations(
|
| // Note that the function does different things depending on
|
| // the number of arguments (2 or 3).
|
| initialize = factory()->NewCallRuntime(
|
| - isolate()->factory()->InitializeVarGlobal_string(),
|
| + symbol_table_->initialize_var_global_string(),
|
| Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
|
| arguments, pos);
|
| }
|
| @@ -2292,19 +2324,20 @@ Block* Parser::ParseVariableDeclarations(
|
| }
|
|
|
|
|
| -static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) {
|
| - ASSERT(!label.is_null());
|
| +static bool ContainsLabel(ZoneList<ParserSymbolTable::Symbol*>* labels,
|
| + ParserSymbolTable::Symbol* label) {
|
| + ASSERT(label != NULL);
|
| if (labels != NULL)
|
| for (int i = labels->length(); i-- > 0; )
|
| - if (labels->at(i).is_identical_to(label))
|
| + if (labels->at(i) == label)
|
| return true;
|
|
|
| return false;
|
| }
|
|
|
|
|
| -Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
| - bool* ok) {
|
| +Statement* Parser::ParseExpressionOrLabelledStatement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // ExpressionStatement | LabelledStatement ::
|
| // Expression ';'
|
| // Identifier ':' Statement
|
| @@ -2317,7 +2350,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
| // Expression is a single identifier, and not, e.g., a parenthesized
|
| // identifier.
|
| VariableProxy* var = expr->AsVariableProxy();
|
| - Handle<String> label = var->name();
|
| + ParserSymbolTable::Symbol* label = var->raw_name();
|
| // TODO(1240780): We don't check for redeclaration of labels
|
| // during preparsing since keeping track of the set of active
|
| // labels requires nontrivial changes to the way scopes are
|
| @@ -2329,7 +2362,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
| return NULL;
|
| }
|
| if (labels == NULL) {
|
| - labels = new(zone()) ZoneStringList(4, zone());
|
| + labels = new(zone()) ZoneList<ParserSymbolTable::Symbol*>(4, zone());
|
| }
|
| labels->Add(label, zone());
|
| // Remove the "ghost" variable that turned out to be a label
|
| @@ -2348,8 +2381,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
| !scanner()->HasAnyLineTerminatorBeforeNext() &&
|
| expr != NULL &&
|
| expr->AsVariableProxy() != NULL &&
|
| - String::Equals(isolate()->factory()->native_string(),
|
| - expr->AsVariableProxy()->name()) &&
|
| + expr->AsVariableProxy()->raw_name() == symbol_table_->native_string() &&
|
| !scanner()->literal_contains_escapes()) {
|
| return ParseNativeDeclaration(ok);
|
| }
|
| @@ -2360,8 +2392,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
| peek() != Token::IDENTIFIER ||
|
| scanner()->HasAnyLineTerminatorBeforeNext() ||
|
| expr->AsVariableProxy() == NULL ||
|
| - !String::Equals(isolate()->factory()->module_string(),
|
| - expr->AsVariableProxy()->name()) ||
|
| + expr->AsVariableProxy()->raw_name() != symbol_table_->module_string() ||
|
| scanner()->literal_contains_escapes()) {
|
| ExpectSemicolon(CHECK_OK);
|
| }
|
| @@ -2369,7 +2400,8 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
|
| }
|
|
|
|
|
| -IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
|
| +IfStatement* Parser::ParseIfStatement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // IfStatement ::
|
| // 'if' '(' Expression ')' Statement ('else' Statement)?
|
|
|
| @@ -2397,22 +2429,22 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
|
|
|
| int pos = peek_position();
|
| Expect(Token::CONTINUE, CHECK_OK);
|
| - Handle<String> label = Handle<String>::null();
|
| + ParserSymbolTable::Symbol* label = NULL;
|
| Token::Value tok = peek();
|
| if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
| tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
|
| // ECMA allows "eval" or "arguments" as labels even in strict mode.
|
| label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
|
| }
|
| - IterationStatement* target = NULL;
|
| - target = LookupContinueTarget(label, CHECK_OK);
|
| + IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
|
| if (target == NULL) {
|
| // Illegal continue statement.
|
| - const char* message = "illegal_continue";
|
| - if (!label.is_null()) {
|
| - message = "unknown_label";
|
| + if (label != NULL) {
|
| + ParserTraits::ReportMessageAt(scanner()->location(), "unknown_label",
|
| + label);
|
| + } else {
|
| + ParserTraits::ReportMessageAt(scanner()->location(), "illegal_continue");
|
| }
|
| - ParserTraits::ReportMessageAt(scanner()->location(), message, label);
|
| *ok = false;
|
| return NULL;
|
| }
|
| @@ -2421,13 +2453,14 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
|
| }
|
|
|
|
|
| -Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
|
| +Statement* Parser::ParseBreakStatement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // BreakStatement ::
|
| // 'break' Identifier? ';'
|
|
|
| int pos = peek_position();
|
| Expect(Token::BREAK, CHECK_OK);
|
| - Handle<String> label;
|
| + ParserSymbolTable::Symbol* label = NULL;
|
| Token::Value tok = peek();
|
| if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
|
| tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
|
| @@ -2436,7 +2469,7 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
|
| }
|
| // Parse labeled break statements that target themselves into
|
| // empty statements, e.g. 'l1: l2: l3: break l2;'
|
| - if (!label.is_null() && ContainsLabel(labels, label)) {
|
| + if (label != NULL && ContainsLabel(labels, label)) {
|
| ExpectSemicolon(CHECK_OK);
|
| return factory()->NewEmptyStatement(pos);
|
| }
|
| @@ -2444,11 +2477,11 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
|
| target = LookupBreakTarget(label, CHECK_OK);
|
| if (target == NULL) {
|
| // Illegal break statement.
|
| - const char* message = "illegal_break";
|
| - if (!label.is_null()) {
|
| - message = "unknown_label";
|
| + if (label != NULL) {
|
| + ParserTraits::ReportMessage("unknown_label", label);
|
| + } else {
|
| + ParserTraits::ReportMessage("illegal_break");
|
| }
|
| - ParserTraits::ReportMessageAt(scanner()->location(), message, label);
|
| *ok = false;
|
| return NULL;
|
| }
|
| @@ -2491,7 +2524,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
|
|
| Scope* decl_scope = scope_->DeclarationScope();
|
| if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) {
|
| - ReportMessageAt(loc, "illegal_return");
|
| + ParserTraits::ReportMessageAt(loc, "illegal_return");
|
| *ok = false;
|
| return NULL;
|
| }
|
| @@ -2499,7 +2532,8 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
| }
|
|
|
|
|
| -Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
|
| +Statement* Parser::ParseWithStatement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // WithStatement ::
|
| // 'with' '(' Expression ')' Statement
|
|
|
| @@ -2561,8 +2595,8 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
|
| }
|
|
|
|
|
| -SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
|
| - bool* ok) {
|
| +SwitchStatement* Parser::ParseSwitchStatement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // SwitchStatement ::
|
| // 'switch' '(' Expression ')' '{' CaseClause* '}'
|
|
|
| @@ -2645,7 +2679,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
|
| Scope* catch_scope = NULL;
|
| Variable* catch_variable = NULL;
|
| Block* catch_block = NULL;
|
| - Handle<String> name;
|
| + ParserSymbolTable::Symbol* name = NULL;
|
| if (tok == Token::CATCH) {
|
| Consume(Token::CATCH);
|
|
|
| @@ -2715,8 +2749,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
|
| }
|
|
|
|
|
| -DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
|
| - bool* ok) {
|
| +DoWhileStatement* Parser::ParseDoWhileStatement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // DoStatement ::
|
| // 'do' Statement 'while' '(' Expression ')' ';'
|
|
|
| @@ -2743,7 +2777,8 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
|
| }
|
|
|
|
|
| -WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
|
| +WhileStatement* Parser::ParseWhileStatement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // WhileStatement ::
|
| // 'while' '(' Expression ')' Statement
|
|
|
| @@ -2784,9 +2819,9 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt,
|
| if (for_of != NULL) {
|
| Factory* heap_factory = isolate()->factory();
|
| Variable* iterator = scope_->DeclarationScope()->NewTemporary(
|
| - heap_factory->dot_iterator_string());
|
| + symbol_table_->dot_iterator_string());
|
| Variable* result = scope_->DeclarationScope()->NewTemporary(
|
| - heap_factory->dot_result_string());
|
| + symbol_table_->dot_result_string());
|
|
|
| Expression* assign_iterator;
|
| Expression* next_result;
|
| @@ -2844,7 +2879,8 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt,
|
| }
|
|
|
|
|
| -Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
| +Statement* Parser::ParseForStatement(
|
| + ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) {
|
| // ForStatement ::
|
| // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
|
|
|
| @@ -2862,7 +2898,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
| if (peek() != Token::SEMICOLON) {
|
| if (peek() == Token::VAR || peek() == Token::CONST) {
|
| bool is_const = peek() == Token::CONST;
|
| - Handle<String> name;
|
| + ParserSymbolTable::Symbol* name = NULL;
|
| VariableDeclarationProperties decl_props = kHasNoInitializers;
|
| Block* variable_statement =
|
| ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
|
| @@ -2870,7 +2906,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
| bool accept_OF = decl_props == kHasNoInitializers;
|
| ForEachStatement::VisitMode mode;
|
|
|
| - if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) {
|
| + if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
|
| Interface* interface =
|
| is_const ? Interface::NewConst() : Interface::NewValue();
|
| ForEachStatement* loop =
|
| @@ -2898,12 +2934,12 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
| init = variable_statement;
|
| }
|
| } else if (peek() == Token::LET) {
|
| - Handle<String> name;
|
| + ParserSymbolTable::Symbol* name = NULL;
|
| VariableDeclarationProperties decl_props = kHasNoInitializers;
|
| Block* variable_statement =
|
| ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
|
| CHECK_OK);
|
| - bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
|
| + bool accept_IN = name != NULL && decl_props != kHasInitializers;
|
| bool accept_OF = decl_props == kHasNoInitializers;
|
| ForEachStatement::VisitMode mode;
|
|
|
| @@ -2923,14 +2959,14 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
|
|
|
| // TODO(keuchel): Move the temporary variable to the block scope, after
|
| // implementing stack allocated block scoped variables.
|
| - Factory* heap_factory = isolate()->factory();
|
| - Handle<String> tempstr;
|
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| - isolate(), tempstr,
|
| - heap_factory->NewConsString(heap_factory->dot_for_string(), name),
|
| - 0);
|
| - Handle<String> tempname = heap_factory->InternalizeString(tempstr);
|
| - Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname);
|
| + // Factory* heap_factory = isolate()->factory();
|
| + // FIXME: do this somehow independent of the heap.
|
| + // ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
| + // isolate(), tempstr,
|
| + // heap_factory->NewConsString(heap_factory->dot_for_string(), name),
|
| + // 0);
|
| + Variable* temp = scope_->DeclarationScope()->NewTemporary(
|
| + symbol_table_->dot_for_string());
|
| VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
|
| ForEachStatement* loop =
|
| factory()->NewForEachStatement(mode, labels, pos);
|
| @@ -3061,7 +3097,8 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
|
| }
|
|
|
|
|
| -void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) {
|
| +void Parser::ReportInvalidCachedData(ParserSymbolTable::Symbol* name,
|
| + bool* ok) {
|
| ParserTraits::ReportMessage("invalid_cached_data_function", name);
|
| *ok = false;
|
| }
|
| @@ -3111,7 +3148,7 @@ Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) {
|
|
|
|
|
| FunctionLiteral* Parser::ParseFunctionLiteral(
|
| - Handle<String> function_name,
|
| + ParserSymbolTable::Symbol* function_name,
|
| Scanner::Location function_name_location,
|
| bool name_is_strict_reserved,
|
| bool is_generator,
|
| @@ -3127,11 +3164,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| // Anonymous functions were passed either the empty symbol or a null
|
| // handle as the function name. Remember if we were passed a non-empty
|
| // handle to decide whether to invoke function name inference.
|
| - bool should_infer_name = function_name.is_null();
|
| + bool should_infer_name = function_name == NULL;
|
|
|
| // We want a non-null handle as the function name.
|
| if (should_infer_name) {
|
| - function_name = isolate()->factory()->empty_string();
|
| + function_name = symbol_table_->empty_string();
|
| }
|
|
|
| int num_parameters = 0;
|
| @@ -3195,8 +3232,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| // Calling a generator returns a generator object. That object is stored
|
| // in a temporary variable, a definition that is used by "yield"
|
| // expressions. This also marks the FunctionState as a generator.
|
| - Variable* temp = scope_->DeclarationScope()->NewTemporary(
|
| - isolate()->factory()->dot_generator_object_string());
|
| + ParserSymbolTable::Symbol* generator_name =
|
| + symbol_table_->GetOneByteSymbol(Vector<const uint8_t>(
|
| + reinterpret_cast<const unsigned char*>(".generator"), 10));
|
| + Variable* temp = scope_->DeclarationScope()->NewTemporary(generator_name);
|
| function_state.set_generator_object_variable(temp);
|
| }
|
|
|
| @@ -3215,7 +3254,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| bool done = (peek() == Token::RPAREN);
|
| while (!done) {
|
| bool is_strict_reserved = false;
|
| - Handle<String> param_name =
|
| + ParserSymbolTable::Symbol* param_name =
|
| ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
|
|
|
| // Store locations for possible future error reports.
|
| @@ -3233,7 +3272,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| scope_->DeclareParameter(param_name, VAR);
|
| num_parameters++;
|
| if (num_parameters > Code::kMaxArguments) {
|
| - ReportMessageAt(scanner()->location(), "too_many_parameters");
|
| + ReportMessage("too_many_parameters");
|
| *ok = false;
|
| return NULL;
|
| }
|
| @@ -3253,6 +3292,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| Variable* fvar = NULL;
|
| Token::Value fvar_init_op = Token::INIT_CONST_LEGACY;
|
| if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
|
| + ASSERT(function_name != NULL);
|
| if (allow_harmony_scoping() && strict_mode() == STRICT) {
|
| fvar_init_op = Token::INIT_CONST;
|
| }
|
| @@ -3383,7 +3423,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| }
|
|
|
|
|
| -void Parser::SkipLazyFunctionBody(Handle<String> function_name,
|
| +void Parser::SkipLazyFunctionBody(ParserSymbolTable::Symbol* function_name,
|
| int* materialized_literal_count,
|
| int* expected_property_count,
|
| bool* ok) {
|
| @@ -3462,7 +3502,7 @@ void Parser::SkipLazyFunctionBody(Handle<String> function_name,
|
|
|
|
|
| ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
|
| - Handle<String> function_name, int pos, Variable* fvar,
|
| + ParserSymbolTable::Symbol* function_name, int pos, Variable* fvar,
|
| Token::Value fvar_init_op, bool is_generator, bool* ok) {
|
| // Everything inside an eagerly parsed function will be parsed eagerly
|
| // (see comment above).
|
| @@ -3485,7 +3525,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
|
| ZoneList<Expression*>* arguments =
|
| new(zone()) ZoneList<Expression*>(0, zone());
|
| CallRuntime* allocation = factory()->NewCallRuntime(
|
| - isolate()->factory()->empty_string(),
|
| + symbol_table_->empty_string(),
|
| Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject),
|
| arguments, pos);
|
| VariableProxy* init_proxy = factory()->NewVariableProxy(
|
| @@ -3545,6 +3585,33 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
|
| }
|
|
|
|
|
| +void Parser::CheckPendingError() {
|
| + if (has_pending_error_) {
|
| + MessageLocation location(script_,
|
| + pending_location_.beg_pos,
|
| + pending_location_.end_pos);
|
| + Factory* factory = isolate()->factory();
|
| + bool has_arg = pending_arg_ != NULL || pending_char_arg_ != NULL;
|
| + Handle<FixedArray> elements =
|
| + factory->NewFixedArray(has_arg ? 1 : 0);
|
| + if (pending_arg_ != NULL) {
|
| + Handle<String> arg_string = pending_arg_->string();
|
| + elements->set(0, *arg_string);
|
| + } else if (pending_char_arg_ != NULL) {
|
| + Handle<String> arg_string =
|
| + factory->NewStringFromUtf8(CStrVector(pending_char_arg_))
|
| + .ToHandleChecked();
|
| + elements->set(0, *arg_string);
|
| + }
|
| + Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
|
| + Handle<Object> result = pending_is_reference_error_
|
| + ? factory->NewReferenceError(pending_message_, array)
|
| + : factory->NewSyntaxError(pending_message_, array);
|
| + isolate()->Throw(*result, &location);
|
| + }
|
| +}
|
| +
|
| +
|
| Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
| // CallRuntime ::
|
| // '%' Identifier Arguments
|
| @@ -3552,7 +3619,8 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
| int pos = peek_position();
|
| Expect(Token::MOD, CHECK_OK);
|
| // Allow "eval" or "arguments" for backward compatibility.
|
| - Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
|
| + ParserSymbolTable::Symbol* name =
|
| + ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
|
| ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
|
|
|
| if (extension_ != NULL) {
|
| @@ -3561,7 +3629,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
| scope_->DeclarationScope()->ForceEagerCompilation();
|
| }
|
|
|
| - const Runtime::Function* function = Runtime::FunctionForName(name);
|
| + const Runtime::Function* function = Runtime::FunctionForName(name->string());
|
|
|
| // Check for built-in IS_VAR macro.
|
| if (function != NULL &&
|
| @@ -3589,7 +3657,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
| }
|
|
|
| // Check that the function is defined if it's an inline runtime call.
|
| - if (function == NULL && name->Get(0) == '_') {
|
| + if (function == NULL && name->literal_bytes.at(0) == '_') {
|
| ParserTraits::ReportMessage("not_defined", name);
|
| *ok = false;
|
| return NULL;
|
| @@ -3611,7 +3679,7 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
|
| if (decl != NULL) {
|
| // In harmony mode we treat conflicting variable bindinds as early
|
| // errors. See ES5 16 for a definition of early errors.
|
| - Handle<String> name = decl->proxy()->name();
|
| + ParserSymbolTable::Symbol* name = decl->proxy()->raw_name();
|
| int position = decl->proxy()->position();
|
| Scanner::Location location = position == RelocInfo::kNoPosition
|
| ? Scanner::Location::invalid()
|
| @@ -3626,7 +3694,7 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
|
| // Parser support
|
|
|
|
|
| -bool Parser::TargetStackContainsLabel(Handle<String> label) {
|
| +bool Parser::TargetStackContainsLabel(ParserSymbolTable::Symbol* label) {
|
| for (Target* t = target_stack_; t != NULL; t = t->previous()) {
|
| BreakableStatement* stat = t->node()->AsBreakableStatement();
|
| if (stat != NULL && ContainsLabel(stat->labels(), label))
|
| @@ -3636,8 +3704,9 @@ bool Parser::TargetStackContainsLabel(Handle<String> label) {
|
| }
|
|
|
|
|
| -BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
|
| - bool anonymous = label.is_null();
|
| +BreakableStatement* Parser::LookupBreakTarget(ParserSymbolTable::Symbol* label,
|
| + bool* ok) {
|
| + bool anonymous = label == NULL;
|
| for (Target* t = target_stack_; t != NULL; t = t->previous()) {
|
| BreakableStatement* stat = t->node()->AsBreakableStatement();
|
| if (stat == NULL) continue;
|
| @@ -3651,9 +3720,9 @@ BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
|
| }
|
|
|
|
|
| -IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
|
| - bool* ok) {
|
| - bool anonymous = label.is_null();
|
| +IterationStatement* Parser::LookupContinueTarget(
|
| + ParserSymbolTable::Symbol* label, bool* ok) {
|
| + bool anonymous = label == NULL;
|
| for (Target* t = target_stack_; t != NULL; t = t->previous()) {
|
| IterationStatement* stat = t->node()->AsIterationStatement();
|
| if (stat == NULL) continue;
|
| @@ -4576,7 +4645,13 @@ bool RegExpParser::ParseRegExp(FlatStringReader* input,
|
|
|
| bool Parser::Parse() {
|
| ASSERT(info()->function() == NULL);
|
| + ASSERT(info()->symbol_table() == NULL);
|
| FunctionLiteral* result = NULL;
|
| + symbol_table_ = new ParserSymbolTable();
|
| + if (allow_natives_syntax() || extension_ != NULL) {
|
| + symbol_table_->AlwaysInternalize(isolate());
|
| + }
|
| +
|
| if (info()->is_lazy()) {
|
| ASSERT(!info()->is_eval());
|
| if (info()->shared_info()->is_function()) {
|
| @@ -4602,6 +4677,9 @@ bool Parser::Parse() {
|
| }
|
| }
|
| info()->SetFunction(result);
|
| + // info takes ownership of symbol_table_.
|
| + info()->SetSymbolTable(symbol_table_);
|
| + symbol_table_ = NULL;
|
| return (result != NULL);
|
| }
|
|
|
|
|