Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index 51065568bac7855a841c4fc724ba1d60d5e633a1..3bd7e46e9abefba85c793b03c7231f12d935f8e2 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -326,7 +326,9 @@ unsigned* ScriptData::ReadAddress(int position) const { |
| Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
| - Scope* result = new(zone()) Scope(parent, scope_type, zone()); |
| + ASSERT(ast_value_factory_); |
| + Scope* result = |
| + new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); |
| result->Initialize(); |
| return result; |
| } |
| @@ -399,10 +401,9 @@ 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(const AstString* identifier) const { |
| + return identifier == parser_->ast_value_factory_->eval_string() || |
| + identifier == parser_->ast_value_factory_->arguments_string(); |
| } |
| @@ -424,10 +425,10 @@ 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()); |
| + parser_->ast_value_factory_->anonymous_function_string()); |
| } |
| } |
| @@ -446,7 +447,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_->ast_value_factory_->eval_string()) { |
| scope->DeclarationScope()->RecordEvalCall(); |
| } |
| } |
| @@ -464,10 +465,10 @@ 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(); |
| + if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() && |
| + y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) { |
| + double x_val = (*x)->AsLiteral()->raw_value()->AsNumber(); |
| + double y_val = y->AsLiteral()->raw_value()->AsNumber(); |
| switch (op) { |
| case Token::ADD: |
| *x = factory->NewNumberLiteral(x_val + y_val, pos); |
| @@ -526,16 +527,14 @@ Expression* ParserTraits::BuildUnaryExpression( |
| AstNodeFactory<AstConstructionVisitor>* factory) { |
| ASSERT(expression != NULL); |
| if (expression->IsLiteral()) { |
| - Handle<Object> literal = expression->AsLiteral()->value(); |
| + const AstValue* literal = expression->AsLiteral()->raw_value(); |
| if (op == Token::NOT) { |
| // Convert the literal to a boolean condition and negate it. |
| bool condition = literal->BooleanValue(); |
| - Handle<Object> result = |
| - parser_->isolate()->factory()->ToBoolean(!condition); |
| - return factory->NewLiteral(result, pos); |
| + return factory->NewBooleanLiteral(!condition, pos); |
| } else if (literal->IsNumber()) { |
| // Compute some expressions involving only number literals. |
| - double value = literal->Number(); |
| + double value = literal->AsNumber(); |
| switch (op) { |
| case Token::ADD: |
| return expression; |
| @@ -569,51 +568,41 @@ Expression* ParserTraits::BuildUnaryExpression( |
| Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
| return NewThrowError( |
| - parser_->isolate()->factory()->MakeReferenceError_string(), |
| - message, HandleVector<Object>(NULL, 0), pos); |
| + parser_->ast_value_factory_->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, const AstString* arg, int pos) { |
| + return NewThrowError(parser_->ast_value_factory_->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, const AstString* arg, int pos) { |
| + return NewThrowError(parser_->ast_value_factory_->make_type_error_string(), |
| + message, arg, pos); |
| } |
| Expression* ParserTraits::NewThrowError( |
| - Handle<String> constructor, const char* message, |
| - Vector<Handle<Object> > arguments, int pos) { |
| + const AstString* constructor, const char* message, |
| + const AstString* 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); |
| - args->Add(parser_->factory()->NewLiteral(type, pos), zone); |
| - args->Add(parser_->factory()->NewLiteral(array, pos), zone); |
| + int argc = arg != NULL ? 1 : 0; |
| + const AstString* type = |
| + parser_->ast_value_factory_->GetOneByteString(Vector<const uint8_t>( |
| + reinterpret_cast<const uint8_t*>(message), StrLength(message))); |
| + ZoneList<const AstString*>* array = |
| + new (zone) ZoneList<const AstString*>(argc, zone); |
| + if (arg != NULL) { |
| + array->Add(arg, zone); |
| + } |
| + ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone); |
| + args->Add(parser_->factory()->NewStringLiteral(type, pos), zone); |
| + args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone); |
| CallRuntime* call_constructor = |
| parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); |
| return parser_->factory()->NewThrow(call_constructor, pos); |
| @@ -634,13 +623,21 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| parser_->pending_error_location_ = source_location; |
| parser_->pending_error_message_ = message; |
| parser_->pending_error_char_arg_ = arg; |
| - parser_->pending_error_arg_ = Handle<String>(); |
| + parser_->pending_error_arg_ = NULL; |
| parser_->pending_error_is_reference_error_ = is_reference_error; |
| } |
| void ParserTraits::ReportMessage(const char* message, |
| - MaybeHandle<String> arg, |
| + const char* arg, |
| + bool is_reference_error) { |
| + Scanner::Location source_location = parser_->scanner()->location(); |
| + ReportMessageAt(source_location, message, arg, is_reference_error); |
| +} |
| + |
| + |
| +void ParserTraits::ReportMessage(const char* message, |
| + const AstString* arg, |
| bool is_reference_error) { |
| Scanner::Location source_location = parser_->scanner()->location(); |
| ReportMessageAt(source_location, message, arg, is_reference_error); |
| @@ -649,7 +646,7 @@ void ParserTraits::ReportMessage(const char* message, |
| void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| const char* message, |
| - MaybeHandle<String> arg, |
| + const AstString* arg, |
| bool is_reference_error) { |
| if (parser_->stack_overflow()) { |
| // Suppress the error message (syntax error or such) in the presence of a |
| @@ -666,17 +663,16 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| } |
| -Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { |
| - Handle<String> result = |
| - parser_->scanner()->AllocateInternalizedString(parser_->isolate()); |
| - ASSERT(!result.is_null()); |
| +const AstString* ParserTraits::GetSymbol(Scanner* scanner) { |
| + const AstString* result = |
| + parser_->scanner()->CurrentSymbol(parser_->ast_value_factory_); |
| + ASSERT(result != NULL); |
| return result; |
| } |
| -Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, |
| - PretenureFlag tenured) { |
| - return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); |
| +const AstString* ParserTraits::GetNextSymbol(Scanner* scanner) { |
| + return parser_->scanner()->NextSymbol(parser_->ast_value_factory_); |
| } |
| @@ -691,14 +687,14 @@ Literal* ParserTraits::ExpressionFromLiteral( |
| Token::Value token, int pos, |
| Scanner* scanner, |
| AstNodeFactory<AstConstructionVisitor>* factory) { |
| - Factory* isolate_factory = parser_->isolate()->factory(); |
| switch (token) { |
| case Token::NULL_LITERAL: |
| - return factory->NewLiteral(isolate_factory->null_value(), pos); |
| + return factory->NewSpecialLiteral( |
|
rossberg
2014/06/12 12:20:28
Nit: just for symmetry, I would wrap this up into
marja
2014/06/12 12:35:03
Done.
|
| + parser_->ast_value_factory_->NewNull(), pos); |
| case Token::TRUE_LITERAL: |
| - return factory->NewLiteral(isolate_factory->true_value(), pos); |
| + return factory->NewBooleanLiteral(true, pos); |
| case Token::FALSE_LITERAL: |
| - return factory->NewLiteral(isolate_factory->false_value(), pos); |
| + return factory->NewBooleanLiteral(false, pos); |
| case Token::NUMBER: { |
| double value = scanner->DoubleValue(); |
| return factory->NewNumberLiteral(value, pos); |
| @@ -711,13 +707,13 @@ Literal* ParserTraits::ExpressionFromLiteral( |
| Expression* ParserTraits::ExpressionFromIdentifier( |
| - Handle<String> name, int pos, Scope* scope, |
| + const AstString* name, int pos, Scope* scope, |
| AstNodeFactory<AstConstructionVisitor>* factory) { |
| 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()); |
| + PrintF("# Variable %.*s ", name->length(), name->raw_data()); |
| #endif |
| Interface* interface = Interface::NewUnknown(parser_->zone()); |
| return scope->NewUnresolved(factory, name, interface, pos); |
| @@ -727,16 +723,16 @@ Expression* ParserTraits::ExpressionFromIdentifier( |
| Expression* ParserTraits::ExpressionFromString( |
| int pos, Scanner* scanner, |
| AstNodeFactory<AstConstructionVisitor>* factory) { |
| - Handle<String> symbol = GetSymbol(scanner); |
| + const AstString* symbol = GetSymbol(scanner); |
| if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
| - return factory->NewLiteral(symbol, pos); |
| + return factory->NewStringLiteral(symbol, pos); |
| } |
| Literal* ParserTraits::GetLiteralTheHole( |
| int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
| - return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), |
| - RelocInfo::kNoPosition); |
| + return factory->NewSpecialLiteral( |
|
rossberg
2014/06/12 12:20:28
...and similarly here.
marja
2014/06/12 12:35:03
Done.
|
| + parser_->ast_value_factory_->NewTheHole(), RelocInfo::kNoPosition); |
| } |
| @@ -746,7 +742,7 @@ Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
| FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
| - Handle<String> name, |
| + const AstString* name, |
| Scanner::Location function_name_location, |
| bool name_is_strict_reserved, |
| bool is_generator, |
| @@ -774,9 +770,11 @@ Parser::Parser(CompilationInfo* info) |
| target_stack_(NULL), |
| cached_data_(NULL), |
| cached_data_mode_(NO_CACHED_DATA), |
| + ast_value_factory_(NULL), |
| info_(info), |
| has_pending_error_(false), |
| pending_error_message_(NULL), |
| + pending_error_arg_(NULL), |
| pending_error_char_arg_(NULL) { |
| ASSERT(!script_.is_null()); |
| isolate_->set_ast_node_id(0); |
| @@ -800,7 +798,7 @@ FunctionLiteral* Parser::ParseProgram() { |
| if (FLAG_trace_parse) { |
| timer.Start(); |
| } |
| - fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| + fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
| // Initialize parser state. |
| CompleteParserRecorder recorder; |
| @@ -855,13 +853,16 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| ASSERT(scope_ == NULL); |
| ASSERT(target_stack_ == NULL); |
| - Handle<String> no_name = isolate()->factory()->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()); |
| + // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
| + // means the Parser cannot operate independent of the V8 heap. Tell the |
| + // string table to internalize strings and values right after they're |
| + // created. |
| + ast_value_factory_->Internalize(isolate()); |
| } |
| original_scope_ = scope; |
| if (info->is_eval()) { |
| @@ -884,7 +885,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| ParsingModeScope parsing_mode(this, mode); |
| // Enters 'scope'. |
| - FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| + FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| + ast_value_factory_); |
| scope_->SetStrictMode(info->strict_mode()); |
| ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| @@ -911,7 +913,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| if (ok) { |
| result = factory()->NewFunctionLiteral( |
| - no_name, |
| + ast_value_factory_->empty_string(), |
| + ast_value_factory_, |
| scope_, |
| body, |
| function_state.materialized_literal_count(), |
| @@ -983,8 +986,10 @@ 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); |
| + ASSERT(ast_value_factory_); |
| + fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
| + const AstString* raw_name = ast_value_factory_->GetString(name); |
| + fni_->PushEnclosingName(raw_name); |
| ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| @@ -1000,7 +1005,8 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
| zone()); |
| } |
| original_scope_ = scope; |
| - FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| + FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| + ast_value_factory_); |
| ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); |
| ASSERT(info()->strict_mode() == shared_info->strict_mode()); |
| scope->SetStrictMode(shared_info->strict_mode()); |
| @@ -1010,7 +1016,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(), |
| @@ -1079,15 +1085,12 @@ 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->raw_value()->IsString()) { |
| // 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->raw_value()->AsString() == |
| + ast_value_factory_->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 |
| @@ -1118,7 +1121,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| } |
| -Statement* Parser::ParseModuleElement(ZoneStringList* labels, |
| +Statement* Parser::ParseModuleElement(ZoneList<const AstString*>* labels, |
| bool* ok) { |
| // (Ecma 262 5th Edition, clause 14): |
| // SourceElement: |
| @@ -1152,10 +1155,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() == |
| + ast_value_factory_->module_string() && |
| !scanner()->literal_contains_escapes()) { |
| return ParseModuleDeclaration(NULL, ok); |
| } |
| @@ -1166,16 +1168,17 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels, |
| } |
| -Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| +Statement* Parser::ParseModuleDeclaration(ZoneList<const AstString*>* names, |
| + bool* ok) { |
| // ModuleDeclaration: |
| // 'module' Identifier Module |
| int pos = peek_position(); |
| - Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| + const AstString* name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| #ifdef DEBUG |
| if (FLAG_print_interface_details) |
| - PrintF("# Module %s...\n", name->ToAsciiArray()); |
| + PrintF("# Module %.*s ", name->length(), name->raw_data()); |
| #endif |
| Module* module = ParseModule(CHECK_OK); |
| @@ -1186,10 +1189,9 @@ Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| #ifdef DEBUG |
| if (FLAG_print_interface_details) |
| - PrintF("# Module %s.\n", name->ToAsciiArray()); |
| - |
| + PrintF("# Module %.*s ", name->length(), name->raw_data()); |
| if (FLAG_print_interfaces) { |
| - PrintF("module %s : ", name->ToAsciiArray()); |
| + PrintF("module %.*s: ", name->length(), name->raw_data()); |
| module->interface()->Print(); |
| } |
| #endif |
| @@ -1290,17 +1292,17 @@ Module* Parser::ParseModulePath(bool* ok) { |
| int pos = peek_position(); |
| Module* result = ParseModuleVariable(CHECK_OK); |
| while (Check(Token::PERIOD)) { |
| - Handle<String> name = ParseIdentifierName(CHECK_OK); |
| + const AstString* name = ParseIdentifierName(CHECK_OK); |
| #ifdef DEBUG |
| if (FLAG_print_interface_details) |
| - PrintF("# Path .%s ", name->ToAsciiArray()); |
| + PrintF("# Path .%.*s ", name->length(), name->raw_data()); |
| #endif |
| 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->length(), name->raw_data()); |
| PrintF("result: "); |
| result->interface()->Print(); |
| PrintF("member: "); |
| @@ -1322,10 +1324,10 @@ Module* Parser::ParseModuleVariable(bool* ok) { |
| // Identifier |
| int pos = peek_position(); |
| - Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| + const AstString* name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| #ifdef DEBUG |
| if (FLAG_print_interface_details) |
| - PrintF("# Module variable %s ", name->ToAsciiArray()); |
| + PrintF("# Module variable %.*s ", name->length(), name->raw_data()); |
| #endif |
| VariableProxy* proxy = scope_->NewUnresolved( |
| factory(), name, Interface::NewModule(zone()), |
| @@ -1341,7 +1343,7 @@ Module* Parser::ParseModuleUrl(bool* ok) { |
| int pos = peek_position(); |
| Expect(Token::STRING, CHECK_OK); |
| - Handle<String> symbol = GetSymbol(); |
| + const AstString* symbol = GetSymbol(scanner()); |
| // TODO(ES6): Request JS resource from environment... |
| @@ -1385,9 +1387,9 @@ Block* Parser::ParseImportDeclaration(bool* ok) { |
| int pos = peek_position(); |
| Expect(Token::IMPORT, CHECK_OK); |
| - ZoneStringList names(1, zone()); |
| + ZoneList<const AstString*> names(1, zone()); |
| - Handle<String> name = ParseIdentifierName(CHECK_OK); |
| + const AstString* name = ParseIdentifierName(CHECK_OK); |
| names.Add(name, zone()); |
| while (peek() == Token::COMMA) { |
| Consume(Token::COMMA); |
| @@ -1405,14 +1407,15 @@ Block* Parser::ParseImportDeclaration(bool* ok) { |
| for (int i = 0; i < names.length(); ++i) { |
| #ifdef DEBUG |
| if (FLAG_print_interface_details) |
| - PrintF("# Import %s ", names[i]->ToAsciiArray()); |
| + PrintF("# Import %.*s ", name->length(), name->raw_data()); |
| #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->length(), |
| + name->raw_data()); |
| PrintF("module: "); |
| module->interface()->Print(); |
| } |
| @@ -1443,14 +1446,14 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { |
| Expect(Token::EXPORT, CHECK_OK); |
| Statement* result = NULL; |
| - ZoneStringList names(1, zone()); |
| + ZoneList<const AstString*> names(1, zone()); |
| switch (peek()) { |
| case Token::IDENTIFIER: { |
| int pos = position(); |
| - Handle<String> name = |
| + const AstString* name = |
| ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| // Handle 'module' as a context-sensitive keyword. |
| - if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
| + if (name != ast_value_factory_->module_string()) { |
| names.Add(name, zone()); |
| while (peek() == Token::COMMA) { |
| Consume(Token::COMMA); |
| @@ -1486,7 +1489,7 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { |
| for (int i = 0; i < names.length(); ++i) { |
| #ifdef DEBUG |
| if (FLAG_print_interface_details) |
| - PrintF("# Export %s ", names[i]->ToAsciiArray()); |
| + PrintF("# Export %.*s ", names[i]->length(), names[i]->raw_data()); |
| #endif |
| Interface* inner = Interface::NewUnknown(zone()); |
| interface->Add(names[i], inner, zone(), CHECK_OK); |
| @@ -1506,7 +1509,7 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { |
| } |
| -Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
| +Statement* Parser::ParseBlockElement(ZoneList<const AstString*>* labels, |
| bool* ok) { |
| // (Ecma 262 5th Edition, clause 14): |
| // SourceElement: |
| @@ -1531,7 +1534,8 @@ Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
| } |
| -Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
| +Statement* Parser::ParseStatement(ZoneList<const AstString*>* labels, |
| + bool* ok) { |
| // Statement :: |
| // Block |
| // VariableStatement |
| @@ -1641,8 +1645,8 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
| } |
| -VariableProxy* Parser::NewUnresolved( |
| - Handle<String> name, VariableMode mode, Interface* interface) { |
| +VariableProxy* Parser::NewUnresolved(const AstString* 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. |
| @@ -1655,7 +1659,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); |
| + const AstString* name = proxy->raw_name(); |
| VariableMode mode = declaration->mode(); |
| Scope* declaration_scope = DeclarationScope(mode); |
| Variable* var = NULL; |
| @@ -1783,8 +1788,10 @@ 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) { |
| + PrintF("# Declare %.*s ", var->raw_name()->length(), |
| + var->raw_name()->raw_data()); |
| + } |
| #endif |
| proxy->interface()->Unify(var->interface(), zone(), &ok); |
| if (!ok) { |
| @@ -1812,7 +1819,7 @@ 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); |
| + const AstString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| Expect(Token::LPAREN, CHECK_OK); |
| bool done = (peek() == Token::RPAREN); |
| while (!done) { |
| @@ -1847,7 +1854,8 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| } |
| -Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
| +Statement* Parser::ParseFunctionDeclaration(ZoneList<const AstString*>* names, |
| + bool* ok) { |
| // FunctionDeclaration :: |
| // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| // GeneratorDeclaration :: |
| @@ -1857,7 +1865,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( |
| + const AstString* name = ParseIdentifierOrStrictReservedWord( |
| &is_strict_reserved, CHECK_OK); |
| FunctionLiteral* fun = ParseFunctionLiteral(name, |
| scanner()->location(), |
| @@ -1883,7 +1891,7 @@ Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
| } |
| -Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| +Block* Parser::ParseBlock(ZoneList<const AstString*>* labels, bool* ok) { |
| if (allow_harmony_scoping() && strict_mode() == STRICT) { |
| return ParseScopedBlock(labels, ok); |
| } |
| @@ -1910,7 +1918,7 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| } |
| -Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| +Block* Parser::ParseScopedBlock(ZoneList<const AstString*>* labels, bool* ok) { |
| // The harmony mode uses block elements instead of statements. |
| // |
| // Block :: |
| @@ -1945,12 +1953,12 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| - ZoneStringList* names, |
| + ZoneList<const AstString*>* names, |
| bool* ok) { |
| // VariableStatement :: |
| // VariableDeclarations ';' |
| - Handle<String> ignore; |
| + const AstString* ignore; |
| Block* result = |
| ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
| ExpectSemicolon(CHECK_OK); |
| @@ -1966,8 +1974,8 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| Block* Parser::ParseVariableDeclarations( |
| VariableDeclarationContext var_context, |
| VariableDeclarationProperties* decl_props, |
| - ZoneStringList* names, |
| - Handle<String>* out, |
| + ZoneList<const AstString*>* names, |
| + const AstString** out, |
| bool* ok) { |
| // VariableDeclarations :: |
| // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
| @@ -2075,7 +2083,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; |
| + const AstString* name = NULL; |
| do { |
| if (fni_ != NULL) fni_->Enter(); |
| @@ -2194,7 +2202,7 @@ Block* Parser::ParseVariableDeclarations( |
| ZoneList<Expression*>* arguments = |
| new(zone()) ZoneList<Expression*>(3, zone()); |
| // We have at least 1 parameter. |
| - arguments->Add(factory()->NewLiteral(name, pos), zone()); |
| + arguments->Add(factory()->NewStringLiteral(name, pos), zone()); |
| CallRuntime* initialize; |
| if (is_const) { |
| @@ -2206,7 +2214,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(), |
| + ast_value_factory_->initialize_const_global_string(), |
| Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), |
| arguments, pos); |
| } else { |
| @@ -2229,7 +2237,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(), |
| + ast_value_factory_->initialize_var_global_string(), |
| Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| arguments, pos); |
| } |
| @@ -2285,11 +2293,12 @@ Block* Parser::ParseVariableDeclarations( |
| } |
| -static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { |
| - ASSERT(!label.is_null()); |
| +static bool ContainsLabel(ZoneList<const AstString*>* labels, |
| + const AstString* 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; |
| } |
| } |
| @@ -2298,8 +2307,8 @@ static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { |
| } |
| -Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
| - bool* ok) { |
| +Statement* Parser::ParseExpressionOrLabelledStatement( |
| + ZoneList<const AstString*>* labels, bool* ok) { |
| // ExpressionStatement | LabelledStatement :: |
| // Expression ';' |
| // Identifier ':' Statement |
| @@ -2312,7 +2321,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(); |
| + const AstString* 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 |
| @@ -2324,7 +2333,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
| return NULL; |
| } |
| if (labels == NULL) { |
| - labels = new(zone()) ZoneStringList(4, zone()); |
| + labels = new(zone()) ZoneList<const AstString*>(4, zone()); |
| } |
| labels->Add(label, zone()); |
| // Remove the "ghost" variable that turned out to be a label |
| @@ -2343,8 +2352,8 @@ 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() == |
| + ast_value_factory_->native_string() && |
| !scanner()->literal_contains_escapes()) { |
| return ParseNativeDeclaration(ok); |
| } |
| @@ -2355,8 +2364,8 @@ 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() != |
| + ast_value_factory_->module_string() || |
| scanner()->literal_contains_escapes()) { |
| ExpectSemicolon(CHECK_OK); |
| } |
| @@ -2364,7 +2373,8 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
| } |
| -IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
| +IfStatement* Parser::ParseIfStatement(ZoneList<const AstString*>* labels, |
| + bool* ok) { |
| // IfStatement :: |
| // 'if' '(' Expression ')' Statement ('else' Statement)? |
| @@ -2392,19 +2402,18 @@ Statement* Parser::ParseContinueStatement(bool* ok) { |
| int pos = peek_position(); |
| Expect(Token::CONTINUE, CHECK_OK); |
| - Handle<String> label = Handle<String>::null(); |
| + const AstString* 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()) { |
| + if (label != NULL) { |
| message = "unknown_label"; |
| } |
| ParserTraits::ReportMessage(message, label); |
| @@ -2416,13 +2425,14 @@ Statement* Parser::ParseContinueStatement(bool* ok) { |
| } |
| -Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| +Statement* Parser::ParseBreakStatement(ZoneList<const AstString*>* labels, |
| + bool* ok) { |
| // BreakStatement :: |
| // 'break' Identifier? ';' |
| int pos = peek_position(); |
| Expect(Token::BREAK, CHECK_OK); |
| - Handle<String> label; |
| + const AstString* label = NULL; |
| Token::Value tok = peek(); |
| if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| @@ -2431,7 +2441,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); |
| } |
| @@ -2440,7 +2450,7 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| if (target == NULL) { |
| // Illegal break statement. |
| const char* message = "illegal_break"; |
| - if (!label.is_null()) { |
| + if (label != NULL) { |
| message = "unknown_label"; |
| } |
| ParserTraits::ReportMessage(message, label); |
| @@ -2494,7 +2504,8 @@ Statement* Parser::ParseReturnStatement(bool* ok) { |
| } |
| -Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| +Statement* Parser::ParseWithStatement(ZoneList<const AstString*>* labels, |
| + bool* ok) { |
| // WithStatement :: |
| // 'with' '(' Expression ')' Statement |
| @@ -2556,8 +2567,8 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| } |
| -SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
| - bool* ok) { |
| +SwitchStatement* Parser::ParseSwitchStatement( |
| + ZoneList<const AstString*>* labels, bool* ok) { |
| // SwitchStatement :: |
| // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| @@ -2640,7 +2651,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
| Scope* catch_scope = NULL; |
| Variable* catch_variable = NULL; |
| Block* catch_block = NULL; |
| - Handle<String> name; |
| + const AstString* name = NULL; |
| if (tok == Token::CATCH) { |
| Consume(Token::CATCH); |
| @@ -2710,8 +2721,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
| } |
| -DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| - bool* ok) { |
| +DoWhileStatement* Parser::ParseDoWhileStatement( |
| + ZoneList<const AstString*>* labels, bool* ok) { |
| // DoStatement :: |
| // 'do' Statement 'while' '(' Expression ')' ';' |
| @@ -2738,7 +2749,8 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| } |
| -WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| +WhileStatement* Parser::ParseWhileStatement(ZoneList<const AstString*>* labels, |
| + bool* ok) { |
| // WhileStatement :: |
| // 'while' '(' Expression ')' Statement |
| @@ -2777,11 +2789,10 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| ForOfStatement* for_of = stmt->AsForOfStatement(); |
| if (for_of != NULL) { |
| - Factory* heap_factory = isolate()->factory(); |
| Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
| - heap_factory->dot_iterator_string()); |
| + ast_value_factory_->dot_iterator_string()); |
| Variable* result = scope_->DeclarationScope()->NewTemporary( |
| - heap_factory->dot_result_string()); |
| + ast_value_factory_->dot_result_string()); |
| Expression* assign_iterator; |
| Expression* next_result; |
| @@ -2798,8 +2809,8 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| // var result = iterator.next(); |
| { |
| Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| - Expression* next_literal = factory()->NewLiteral( |
| - heap_factory->next_string(), RelocInfo::kNoPosition); |
| + Expression* next_literal = factory()->NewStringLiteral( |
| + ast_value_factory_->next_string(), RelocInfo::kNoPosition); |
| Expression* next_property = factory()->NewProperty( |
| iterator_proxy, next_literal, RelocInfo::kNoPosition); |
| ZoneList<Expression*>* next_arguments = |
| @@ -2813,8 +2824,8 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| // result.done |
| { |
| - Expression* done_literal = factory()->NewLiteral( |
| - heap_factory->done_string(), RelocInfo::kNoPosition); |
| + Expression* done_literal = factory()->NewStringLiteral( |
| + ast_value_factory_->done_string(), RelocInfo::kNoPosition); |
| Expression* result_proxy = factory()->NewVariableProxy(result); |
| result_done = factory()->NewProperty( |
| result_proxy, done_literal, RelocInfo::kNoPosition); |
| @@ -2822,8 +2833,8 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| // each = result.value |
| { |
| - Expression* value_literal = factory()->NewLiteral( |
| - heap_factory->value_string(), RelocInfo::kNoPosition); |
| + Expression* value_literal = factory()->NewStringLiteral( |
| + ast_value_factory_->value_string(), RelocInfo::kNoPosition); |
| Expression* result_proxy = factory()->NewVariableProxy(result); |
| Expression* result_value = factory()->NewProperty( |
| result_proxy, value_literal, RelocInfo::kNoPosition); |
| @@ -2840,9 +2851,9 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| Statement* Parser::DesugarLetBindingsInForStatement( |
| - Scope* inner_scope, ZoneStringList* names, ForStatement* loop, |
| - Statement* init, Expression* cond, Statement* next, Statement* body, |
| - bool* ok) { |
| + Scope* inner_scope, ZoneList<const AstString*>* names, |
| + ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
| + Statement* body, bool* ok) { |
| // ES6 13.6.3.4 specifies that on each loop iteration the let variables are |
| // copied into a new environment. After copying, the "next" statement of the |
| // loop is executed to update the loop variables. The loop condition is |
| @@ -2883,10 +2894,7 @@ Statement* Parser::DesugarLetBindingsInForStatement( |
| RelocInfo::kNoPosition); |
| outer_block->AddStatement(init, zone()); |
| - Handle<String> temp_name = isolate()->factory()->dot_for_string(); |
| - Handle<Smi> smi0 = handle(Smi::FromInt(0), isolate()); |
| - Handle<Smi> smi1 = handle(Smi::FromInt(1), isolate()); |
| - |
| + const AstString* temp_name = ast_value_factory_->dot_for_string(); |
| // For each let variable x: |
| // make statement: temp_x = x. |
| @@ -2907,7 +2915,7 @@ Statement* Parser::DesugarLetBindingsInForStatement( |
| // Make statement: flag = 1. |
| { |
| VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| - Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); |
| + Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
| Assignment* assignment = factory()->NewAssignment( |
| Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition); |
| Statement* assignment_statement = factory()->NewExpressionStatement( |
| @@ -2947,7 +2955,7 @@ Statement* Parser::DesugarLetBindingsInForStatement( |
| Expression* compare = NULL; |
| // Make compare expresion: flag == 1. |
| { |
| - Expression* const1 = factory()->NewLiteral(smi1, RelocInfo::kNoPosition); |
| + Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); |
| VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| compare = factory()->NewCompareOperation( |
| Token::EQ, flag_proxy, const1, pos); |
| @@ -2956,7 +2964,7 @@ Statement* Parser::DesugarLetBindingsInForStatement( |
| // Make statement: flag = 0. |
| { |
| VariableProxy* flag_proxy = factory()->NewVariableProxy(flag); |
| - Expression* const0 = factory()->NewLiteral(smi0, RelocInfo::kNoPosition); |
| + Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition); |
| Assignment* assignment = factory()->NewAssignment( |
| Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition); |
| clear_flag = factory()->NewExpressionStatement(assignment, pos); |
| @@ -2970,7 +2978,7 @@ Statement* Parser::DesugarLetBindingsInForStatement( |
| // Make statement: if (cond) { } else { break; }. |
| { |
| Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| - BreakableStatement* t = LookupBreakTarget(Handle<String>(), CHECK_OK); |
| + BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK); |
| Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition); |
| Statement* if_not_cond_break = factory()->NewIfStatement( |
| cond, empty, stop, cond->position()); |
| @@ -3001,13 +3009,14 @@ Statement* Parser::DesugarLetBindingsInForStatement( |
| } |
| -Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| +Statement* Parser::ParseForStatement(ZoneList<const AstString*>* labels, |
| + bool* ok) { |
| // ForStatement :: |
| // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| int pos = peek_position(); |
| Statement* init = NULL; |
| - ZoneStringList let_bindings(1, zone()); |
| + ZoneList<const AstString*> let_bindings(1, zone()); |
| // Create an in-between scope for let-bound iteration variables. |
| Scope* saved_scope = scope_; |
| @@ -3020,7 +3029,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; |
| + const AstString* name = NULL; |
| VariableDeclarationProperties decl_props = kHasNoInitializers; |
| Block* variable_statement = |
| ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| @@ -3028,7 +3037,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 = |
| @@ -3056,12 +3065,12 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| init = variable_statement; |
| } |
| } else if (peek() == Token::LET) { |
| - Handle<String> name; |
| + const AstString* name = NULL; |
| VariableDeclarationProperties decl_props = kHasNoInitializers; |
| Block* variable_statement = |
| - ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
| - &name, CHECK_OK); |
| - bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
| + ParseVariableDeclarations(kForStatement, &decl_props, &let_bindings, |
| + &name, CHECK_OK); |
| + bool accept_IN = name != NULL && decl_props != kHasInitializers; |
| bool accept_OF = decl_props == kHasNoInitializers; |
| ForEachStatement::VisitMode mode; |
| @@ -3081,14 +3090,8 @@ 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); |
| + Variable* temp = scope_->DeclarationScope()->NewTemporary( |
| + ast_value_factory_->dot_for_string()); |
| VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| ForEachStatement* loop = |
| factory()->NewForEachStatement(mode, labels, pos); |
| @@ -3219,7 +3222,7 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
| } |
| -void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { |
| +void Parser::ReportInvalidCachedData(const AstString* name, bool* ok) { |
| ParserTraits::ReportMessage("invalid_cached_data_function", name); |
| *ok = false; |
| } |
| @@ -3269,7 +3272,7 @@ Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
| FunctionLiteral* Parser::ParseFunctionLiteral( |
| - Handle<String> function_name, |
| + const AstString* function_name, |
| Scanner::Location function_name_location, |
| bool name_is_strict_reserved, |
| bool is_generator, |
| @@ -3285,11 +3288,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 = ast_value_factory_->empty_string(); |
| } |
| int num_parameters = 0; |
| @@ -3341,7 +3344,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| AstProperties ast_properties; |
| BailoutReason dont_optimize_reason = kNoReason; |
| // Parse function body. |
| - { FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| + { |
| + FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| + ast_value_factory_); |
| scope_->SetScopeName(function_name); |
| if (is_generator) { |
| @@ -3354,7 +3359,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| // 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()); |
| + ast_value_factory_->dot_generator_object_string()); |
| function_state.set_generator_object_variable(temp); |
| } |
| @@ -3373,7 +3378,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| bool done = (peek() == Token::RPAREN); |
| while (!done) { |
| bool is_strict_reserved = false; |
| - Handle<String> param_name = |
| + const AstString* param_name = |
| ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| // Store locations for possible future error reports. |
| @@ -3417,6 +3422,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| VariableMode fvar_mode = |
| allow_harmony_scoping() && strict_mode() == STRICT ? CONST |
| : CONST_LEGACY; |
| + ASSERT(function_name != NULL); |
| fvar = new(zone()) Variable(scope_, |
| function_name, fvar_mode, true /* is valid LHS */, |
| Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| @@ -3520,6 +3526,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| : FunctionLiteral::kNotGenerator; |
| FunctionLiteral* function_literal = |
| factory()->NewFunctionLiteral(function_name, |
| + ast_value_factory_, |
| scope, |
| body, |
| materialized_literal_count, |
| @@ -3541,7 +3548,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| } |
| -void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
| +void Parser::SkipLazyFunctionBody(const AstString* function_name, |
| int* materialized_literal_count, |
| int* expected_property_count, |
| bool* ok) { |
| @@ -3620,7 +3627,7 @@ void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
| ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| - Handle<String> function_name, int pos, Variable* fvar, |
| + const AstString* 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). |
| @@ -3643,7 +3650,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| ZoneList<Expression*>* arguments = |
| new(zone()) ZoneList<Expression*>(0, zone()); |
| CallRuntime* allocation = factory()->NewCallRuntime( |
| - isolate()->factory()->empty_string(), |
| + ast_value_factory_->empty_string(), |
| Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), |
| arguments, pos); |
| VariableProxy* init_proxy = factory()->NewVariableProxy( |
| @@ -3663,10 +3670,10 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| if (is_generator) { |
| VariableProxy* get_proxy = factory()->NewVariableProxy( |
| function_state_->generator_object_variable()); |
| - Expression *undefined = factory()->NewLiteral( |
| - isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); |
| - Yield* yield = factory()->NewYield( |
| - get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
| + Expression* undefined = factory()->NewSpecialLiteral( |
|
rossberg
2014/06/12 12:20:28
...and here.
marja
2014/06/12 12:35:04
Done.
|
| + ast_value_factory_->NewUndefined(), RelocInfo::kNoPosition); |
| + Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::FINAL, |
| + RelocInfo::kNoPosition); |
| body->Add(factory()->NewExpressionStatement( |
| yield, RelocInfo::kNoPosition), zone()); |
| } |
| @@ -3710,7 +3717,7 @@ 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); |
| + const AstString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| if (extension_ != NULL) { |
| @@ -3719,7 +3726,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 && |
| @@ -3747,7 +3754,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->FirstCharacter() == '_') { |
| ParserTraits::ReportMessage("not_defined", name); |
| *ok = false; |
| return NULL; |
| @@ -3759,8 +3766,8 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| Literal* Parser::GetLiteralUndefined(int position) { |
| - return factory()->NewLiteral( |
| - isolate()->factory()->undefined_value(), position); |
| + return factory()->NewSpecialLiteral(ast_value_factory_->NewUndefined(), |
|
rossberg
2014/06/12 12:20:28
...and here.
marja
2014/06/12 12:35:04
Done.
|
| + position); |
| } |
| @@ -3769,7 +3776,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(); |
| + const AstString* name = decl->proxy()->raw_name(); |
| int position = decl->proxy()->position(); |
| Scanner::Location location = position == RelocInfo::kNoPosition |
| ? Scanner::Location::invalid() |
| @@ -3784,7 +3791,7 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| // Parser support |
| -bool Parser::TargetStackContainsLabel(Handle<String> label) { |
| +bool Parser::TargetStackContainsLabel(const AstString* label) { |
| for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| if (stat != NULL && ContainsLabel(stat->labels(), label)) |
| @@ -3794,8 +3801,9 @@ bool Parser::TargetStackContainsLabel(Handle<String> label) { |
| } |
| -BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { |
| - bool anonymous = label.is_null(); |
| +BreakableStatement* Parser::LookupBreakTarget(const AstString* 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; |
| @@ -3809,9 +3817,9 @@ BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { |
| } |
| -IterationStatement* Parser::LookupContinueTarget(Handle<String> label, |
| +IterationStatement* Parser::LookupContinueTarget(const AstString* label, |
| bool* ok) { |
| - bool anonymous = label.is_null(); |
| + bool anonymous = label == NULL; |
| for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| IterationStatement* stat = t->node()->AsIterationStatement(); |
| if (stat == NULL) continue; |
| @@ -3844,10 +3852,11 @@ void Parser::ThrowPendingError() { |
| pending_error_location_.end_pos); |
| Factory* factory = isolate()->factory(); |
| bool has_arg = |
| - !pending_error_arg_.is_null() || pending_error_char_arg_ != NULL; |
| + pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; |
| Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); |
| - if (!pending_error_arg_.is_null()) { |
| - elements->set(0, *(pending_error_arg_.ToHandleChecked())); |
| + if (pending_error_arg_ != NULL) { |
| + Handle<String> arg_string = pending_error_arg_->string(); |
| + elements->set(0, *arg_string); |
| } else if (pending_error_char_arg_ != NULL) { |
| Handle<String> arg_string = |
| factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) |
| @@ -4760,7 +4769,16 @@ bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| bool Parser::Parse() { |
| ASSERT(info()->function() == NULL); |
| + ASSERT(info()->ast_value_factory() == NULL); |
| FunctionLiteral* result = NULL; |
| + ast_value_factory_ = new AstValueFactory(zone()); |
| + if (allow_natives_syntax() || extension_ != NULL) { |
| + // If intrinsics are allowed, the Parser cannot operate independent of the |
| + // V8 heap because of Rumtime. Tell the string table to internalize strings |
| + // and values right after they're created. |
| + ast_value_factory_->Internalize(isolate()); |
| + } |
| + |
| if (info()->is_lazy()) { |
| ASSERT(!info()->is_eval()); |
| if (info()->shared_info()->is_function()) { |
| @@ -4786,6 +4804,10 @@ bool Parser::Parse() { |
| } |
| } |
| info()->SetFunction(result); |
| + ast_value_factory_->Internalize(isolate()); |
| + // info takes ownership of ast_value_factory_. |
| + info()->SetAstValueFactory(ast_value_factory_); |
| + ast_value_factory_ = NULL; |
| return (result != NULL); |
| } |