Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 49e9a81db0ce63f42a4225f0538c00ed6ba9274a..dd91b1a45e47100feb0b9c3d9d19001b5b5eb812 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 AstRawString* 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 AstRawString* 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 AstRawString* 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 AstRawString* constructor, const char* message, |
+ const AstRawString* 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 AstRawString* type = |
+ parser_->ast_value_factory_->GetOneByteString(Vector<const uint8_t>( |
+ reinterpret_cast<const uint8_t*>(message), StrLength(message))); |
+ ZoneList<const AstRawString*>* array = |
+ new (zone) ZoneList<const AstRawString*>(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 AstRawString* 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 AstRawString* 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 AstRawString* ParserTraits::GetSymbol(Scanner* scanner) { |
+ const AstRawString* 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 AstRawString* ParserTraits::GetNextSymbol(Scanner* scanner) { |
+ return parser_->scanner()->NextSymbol(parser_->ast_value_factory_); |
} |
@@ -691,14 +687,13 @@ 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->NewNullLiteral(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 +706,13 @@ Literal* ParserTraits::ExpressionFromLiteral( |
Expression* ParserTraits::ExpressionFromIdentifier( |
- Handle<String> name, int pos, Scope* scope, |
+ const AstRawString* 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 +722,15 @@ Expression* ParserTraits::ExpressionFromIdentifier( |
Expression* ParserTraits::ExpressionFromString( |
int pos, Scanner* scanner, |
AstNodeFactory<AstConstructionVisitor>* factory) { |
- Handle<String> symbol = GetSymbol(scanner); |
+ const AstRawString* 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->NewTheHoleLiteral(RelocInfo::kNoPosition); |
} |
@@ -746,7 +740,7 @@ Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
- Handle<String> name, |
+ const AstRawString* name, |
Scanner::Location function_name_location, |
bool name_is_strict_reserved, |
bool is_generator, |
@@ -776,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); |
@@ -802,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; |
@@ -857,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()) { |
@@ -886,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,9 +911,11 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
} |
} |
+ ast_value_factory_->Internalize(isolate()); |
if (ok) { |
result = factory()->NewFunctionLiteral( |
- no_name, |
+ ast_value_factory_->empty_string(), |
+ ast_value_factory_, |
scope_, |
body, |
function_state.materialized_literal_count(), |
@@ -985,8 +987,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 AstRawString* raw_name = ast_value_factory_->GetString(name); |
+ fni_->PushEnclosingName(raw_name); |
ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
@@ -1002,7 +1006,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()); |
@@ -1012,7 +1017,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(), |
@@ -1027,6 +1032,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
// Make sure the target stack is empty. |
ASSERT(target_stack_ == NULL); |
+ ast_value_factory_->Internalize(isolate()); |
if (result == NULL) { |
if (stack_overflow()) { |
isolate()->StackOverflow(); |
@@ -1082,15 +1088,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 |
@@ -1121,7 +1124,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
} |
-Statement* Parser::ParseModuleElement(ZoneStringList* labels, |
+Statement* Parser::ParseModuleElement(ZoneList<const AstRawString*>* labels, |
bool* ok) { |
// (Ecma 262 5th Edition, clause 14): |
// SourceElement: |
@@ -1155,10 +1158,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); |
} |
@@ -1169,16 +1171,18 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels, |
} |
-Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
+Statement* Parser::ParseModuleDeclaration(ZoneList<const AstRawString*>* names, |
+ bool* ok) { |
// ModuleDeclaration: |
// 'module' Identifier Module |
int pos = peek_position(); |
- Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
+ const AstRawString* 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); |
@@ -1189,10 +1193,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 |
@@ -1293,17 +1296,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 AstRawString* 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: "); |
@@ -1325,10 +1328,11 @@ Module* Parser::ParseModuleVariable(bool* ok) { |
// Identifier |
int pos = peek_position(); |
- Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
+ const AstRawString* 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()), |
@@ -1344,7 +1348,7 @@ Module* Parser::ParseModuleUrl(bool* ok) { |
int pos = peek_position(); |
Expect(Token::STRING, CHECK_OK); |
- Handle<String> symbol = GetSymbol(); |
+ const AstRawString* symbol = GetSymbol(scanner()); |
// TODO(ES6): Request JS resource from environment... |
@@ -1388,9 +1392,9 @@ Block* Parser::ParseImportDeclaration(bool* ok) { |
int pos = peek_position(); |
Expect(Token::IMPORT, CHECK_OK); |
- ZoneStringList names(1, zone()); |
+ ZoneList<const AstRawString*> names(1, zone()); |
- Handle<String> name = ParseIdentifierName(CHECK_OK); |
+ const AstRawString* name = ParseIdentifierName(CHECK_OK); |
names.Add(name, zone()); |
while (peek() == Token::COMMA) { |
Consume(Token::COMMA); |
@@ -1408,14 +1412,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(); |
} |
@@ -1446,14 +1451,14 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { |
Expect(Token::EXPORT, CHECK_OK); |
Statement* result = NULL; |
- ZoneStringList names(1, zone()); |
+ ZoneList<const AstRawString*> names(1, zone()); |
switch (peek()) { |
case Token::IDENTIFIER: { |
int pos = position(); |
- Handle<String> name = |
+ const AstRawString* 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); |
@@ -1489,7 +1494,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); |
@@ -1509,7 +1514,7 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { |
} |
-Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
+Statement* Parser::ParseBlockElement(ZoneList<const AstRawString*>* labels, |
bool* ok) { |
// (Ecma 262 5th Edition, clause 14): |
// SourceElement: |
@@ -1534,7 +1539,8 @@ Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
} |
-Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
+Statement* Parser::ParseStatement(ZoneList<const AstRawString*>* labels, |
+ bool* ok) { |
// Statement :: |
// Block |
// VariableStatement |
@@ -1644,8 +1650,8 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
} |
-VariableProxy* Parser::NewUnresolved( |
- Handle<String> name, VariableMode mode, Interface* interface) { |
+VariableProxy* Parser::NewUnresolved(const AstRawString* 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. |
@@ -1658,7 +1664,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 AstRawString* name = proxy->raw_name(); |
VariableMode mode = declaration->mode(); |
Scope* declaration_scope = DeclarationScope(mode); |
Variable* var = NULL; |
@@ -1786,8 +1793,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) { |
@@ -1815,7 +1824,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 AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
Expect(Token::LPAREN, CHECK_OK); |
bool done = (peek() == Token::RPAREN); |
while (!done) { |
@@ -1850,7 +1859,8 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { |
} |
-Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
+Statement* Parser::ParseFunctionDeclaration( |
+ ZoneList<const AstRawString*>* names, bool* ok) { |
// FunctionDeclaration :: |
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
// GeneratorDeclaration :: |
@@ -1860,7 +1870,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 AstRawString* name = ParseIdentifierOrStrictReservedWord( |
&is_strict_reserved, CHECK_OK); |
FunctionLiteral* fun = ParseFunctionLiteral(name, |
scanner()->location(), |
@@ -1887,7 +1897,7 @@ Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
} |
-Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
+Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { |
if (allow_harmony_scoping() && strict_mode() == STRICT) { |
return ParseScopedBlock(labels, ok); |
} |
@@ -1914,7 +1924,8 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
} |
-Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
+Block* Parser::ParseScopedBlock(ZoneList<const AstRawString*>* labels, |
+ bool* ok) { |
// The harmony mode uses block elements instead of statements. |
// |
// Block :: |
@@ -1949,12 +1960,12 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
- ZoneStringList* names, |
+ ZoneList<const AstRawString*>* names, |
bool* ok) { |
// VariableStatement :: |
// VariableDeclarations ';' |
- Handle<String> ignore; |
+ const AstRawString* ignore; |
Block* result = |
ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
ExpectSemicolon(CHECK_OK); |
@@ -1970,8 +1981,8 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
Block* Parser::ParseVariableDeclarations( |
VariableDeclarationContext var_context, |
VariableDeclarationProperties* decl_props, |
- ZoneStringList* names, |
- Handle<String>* out, |
+ ZoneList<const AstRawString*>* names, |
+ const AstRawString** out, |
bool* ok) { |
// VariableDeclarations :: |
// ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
@@ -2079,7 +2090,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 AstRawString* name = NULL; |
do { |
if (fni_ != NULL) fni_->Enter(); |
@@ -2198,7 +2209,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) { |
@@ -2210,7 +2221,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 { |
@@ -2233,7 +2244,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); |
} |
@@ -2289,11 +2300,12 @@ Block* Parser::ParseVariableDeclarations( |
} |
-static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { |
- ASSERT(!label.is_null()); |
+static bool ContainsLabel(ZoneList<const AstRawString*>* labels, |
+ const AstRawString* 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; |
} |
} |
@@ -2302,8 +2314,8 @@ static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { |
} |
-Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
- bool* ok) { |
+Statement* Parser::ParseExpressionOrLabelledStatement( |
+ ZoneList<const AstRawString*>* labels, bool* ok) { |
// ExpressionStatement | LabelledStatement :: |
// Expression ';' |
// Identifier ':' Statement |
@@ -2316,7 +2328,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 AstRawString* 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 |
@@ -2328,7 +2340,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
return NULL; |
} |
if (labels == NULL) { |
- labels = new(zone()) ZoneStringList(4, zone()); |
+ labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); |
} |
labels->Add(label, zone()); |
// Remove the "ghost" variable that turned out to be a label |
@@ -2347,8 +2359,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); |
} |
@@ -2359,8 +2371,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); |
} |
@@ -2368,7 +2380,8 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
} |
-IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
+IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, |
+ bool* ok) { |
// IfStatement :: |
// 'if' '(' Expression ')' Statement ('else' Statement)? |
@@ -2396,19 +2409,18 @@ Statement* Parser::ParseContinueStatement(bool* ok) { |
int pos = peek_position(); |
Expect(Token::CONTINUE, CHECK_OK); |
- Handle<String> label = Handle<String>::null(); |
+ const AstRawString* 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); |
@@ -2420,13 +2432,14 @@ Statement* Parser::ParseContinueStatement(bool* ok) { |
} |
-Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
+Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels, |
+ bool* ok) { |
// BreakStatement :: |
// 'break' Identifier? ';' |
int pos = peek_position(); |
Expect(Token::BREAK, CHECK_OK); |
- Handle<String> label; |
+ const AstRawString* label = NULL; |
Token::Value tok = peek(); |
if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
@@ -2435,7 +2448,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,7 +2457,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); |
@@ -2498,7 +2511,8 @@ Statement* Parser::ParseReturnStatement(bool* ok) { |
} |
-Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
+Statement* Parser::ParseWithStatement(ZoneList<const AstRawString*>* labels, |
+ bool* ok) { |
// WithStatement :: |
// 'with' '(' Expression ')' Statement |
@@ -2560,8 +2574,8 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
} |
-SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
- bool* ok) { |
+SwitchStatement* Parser::ParseSwitchStatement( |
+ ZoneList<const AstRawString*>* labels, bool* ok) { |
// SwitchStatement :: |
// 'switch' '(' Expression ')' '{' CaseClause* '}' |
@@ -2644,7 +2658,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
Scope* catch_scope = NULL; |
Variable* catch_variable = NULL; |
Block* catch_block = NULL; |
- Handle<String> name; |
+ const AstRawString* name = NULL; |
if (tok == Token::CATCH) { |
Consume(Token::CATCH); |
@@ -2714,8 +2728,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
} |
-DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
- bool* ok) { |
+DoWhileStatement* Parser::ParseDoWhileStatement( |
+ ZoneList<const AstRawString*>* labels, bool* ok) { |
// DoStatement :: |
// 'do' Statement 'while' '(' Expression ')' ';' |
@@ -2742,7 +2756,8 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
} |
-WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
+WhileStatement* Parser::ParseWhileStatement( |
+ ZoneList<const AstRawString*>* labels, bool* ok) { |
// WhileStatement :: |
// 'while' '(' Expression ')' Statement |
@@ -2781,13 +2796,12 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
ForOfStatement* for_of = stmt->AsForOfStatement(); |
if (for_of != NULL) { |
- Factory* heap_factory = isolate()->factory(); |
Variable* iterable = scope_->DeclarationScope()->NewTemporary( |
- heap_factory->dot_iterable_string()); |
+ ast_value_factory_->dot_iterable_string()); |
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_iterable; |
Expression* assign_iterator; |
@@ -2805,10 +2819,8 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
// var iterator = iterable[Symbol.iterator](); |
{ |
Expression* iterable_proxy = factory()->NewVariableProxy(iterable); |
- Handle<Symbol> iterator_symbol( |
- isolate()->native_context()->iterator_symbol(), isolate()); |
- Expression* iterator_symbol_literal = factory()->NewLiteral( |
- iterator_symbol, RelocInfo::kNoPosition); |
+ Expression* iterator_symbol_literal = |
+ factory()->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition); |
// FIXME(wingo): Unhappily, it will be a common error that the RHS of a |
// for-of doesn't have a Symbol.iterator property. We should do better |
// than informing the user that "undefined is not a function". |
@@ -2827,8 +2839,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 = |
@@ -2842,8 +2854,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); |
@@ -2851,8 +2863,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); |
@@ -2873,9 +2885,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 AstRawString*>* 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 |
@@ -2916,10 +2928,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 AstRawString* temp_name = ast_value_factory_->dot_for_string(); |
// For each let variable x: |
// make statement: temp_x = x. |
@@ -2940,7 +2949,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( |
@@ -2980,7 +2989,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); |
@@ -2989,7 +2998,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); |
@@ -3003,7 +3012,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()); |
@@ -3034,13 +3043,14 @@ Statement* Parser::DesugarLetBindingsInForStatement( |
} |
-Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
+Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels, |
+ bool* ok) { |
// ForStatement :: |
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
int pos = peek_position(); |
Statement* init = NULL; |
- ZoneStringList let_bindings(1, zone()); |
+ ZoneList<const AstRawString*> let_bindings(1, zone()); |
// Create an in-between scope for let-bound iteration variables. |
Scope* saved_scope = scope_; |
@@ -3053,7 +3063,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 AstRawString* name = NULL; |
VariableDeclarationProperties decl_props = kHasNoInitializers; |
Block* variable_statement = |
ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
@@ -3061,7 +3071,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 = |
@@ -3089,12 +3099,12 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
init = variable_statement; |
} |
} else if (peek() == Token::LET) { |
- Handle<String> name; |
+ const AstRawString* 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; |
@@ -3114,14 +3124,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); |
@@ -3252,7 +3256,7 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
} |
-void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { |
+void Parser::ReportInvalidCachedData(const AstRawString* name, bool* ok) { |
ParserTraits::ReportMessage("invalid_cached_data_function", name); |
*ok = false; |
} |
@@ -3302,7 +3306,7 @@ Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
FunctionLiteral* Parser::ParseFunctionLiteral( |
- Handle<String> function_name, |
+ const AstRawString* function_name, |
Scanner::Location function_name_location, |
bool name_is_strict_reserved, |
bool is_generator, |
@@ -3325,11 +3329,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; |
@@ -3381,7 +3385,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) { |
@@ -3394,7 +3400,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); |
} |
@@ -3415,7 +3421,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
arity_restriction != FunctionLiteral::SETTER_ARITY); |
while (!done) { |
bool is_strict_reserved = false; |
- Handle<String> param_name = |
+ const AstRawString* param_name = |
ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
// Store locations for possible future error reports. |
@@ -3460,6 +3466,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()); |
@@ -3544,6 +3551,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
: FunctionLiteral::kNotGenerator; |
FunctionLiteral* function_literal = |
factory()->NewFunctionLiteral(function_name, |
+ ast_value_factory_, |
scope, |
body, |
materialized_literal_count, |
@@ -3565,7 +3573,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
} |
-void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
+void Parser::SkipLazyFunctionBody(const AstRawString* function_name, |
int* materialized_literal_count, |
int* expected_property_count, |
bool* ok) { |
@@ -3644,7 +3652,7 @@ void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
- Handle<String> function_name, int pos, Variable* fvar, |
+ const AstRawString* 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). |
@@ -3667,7 +3675,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( |
@@ -3687,10 +3695,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()->NewUndefinedLiteral(RelocInfo::kNoPosition); |
+ Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::FINAL, |
+ RelocInfo::kNoPosition); |
body->Add(factory()->NewExpressionStatement( |
yield, RelocInfo::kNoPosition), zone()); |
} |
@@ -3734,7 +3742,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 AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
if (extension_ != NULL) { |
@@ -3743,7 +3751,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 && |
@@ -3771,7 +3779,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; |
@@ -3783,8 +3791,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { |
Literal* Parser::GetLiteralUndefined(int position) { |
- return factory()->NewLiteral( |
- isolate()->factory()->undefined_value(), position); |
+ return factory()->NewUndefinedLiteral(position); |
} |
@@ -3793,7 +3800,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 AstRawString* name = decl->proxy()->raw_name(); |
int position = decl->proxy()->position(); |
Scanner::Location location = position == RelocInfo::kNoPosition |
? Scanner::Location::invalid() |
@@ -3808,7 +3815,7 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
// Parser support |
-bool Parser::TargetStackContainsLabel(Handle<String> label) { |
+bool Parser::TargetStackContainsLabel(const AstRawString* label) { |
for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
BreakableStatement* stat = t->node()->AsBreakableStatement(); |
if (stat != NULL && ContainsLabel(stat->labels(), label)) |
@@ -3818,8 +3825,9 @@ bool Parser::TargetStackContainsLabel(Handle<String> label) { |
} |
-BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { |
- bool anonymous = label.is_null(); |
+BreakableStatement* Parser::LookupBreakTarget(const AstRawString* 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; |
@@ -3833,9 +3841,9 @@ BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { |
} |
-IterationStatement* Parser::LookupContinueTarget(Handle<String> label, |
+IterationStatement* Parser::LookupContinueTarget(const AstRawString* 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; |
@@ -3862,16 +3870,18 @@ void Parser::RegisterTargetUse(Label* target, Target* stop) { |
void Parser::ThrowPendingError() { |
+ ASSERT(ast_value_factory_->IsInternalized()); |
if (has_pending_error_) { |
MessageLocation location(script_, |
pending_error_location_.beg_pos, |
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_)) |
@@ -4785,6 +4795,18 @@ bool RegExpParser::ParseRegExp(FlatStringReader* input, |
bool Parser::Parse() { |
ASSERT(info()->function() == NULL); |
FunctionLiteral* result = NULL; |
+ ast_value_factory_ = info()->ast_value_factory(); |
+ if (ast_value_factory_ == NULL) { |
+ ast_value_factory_ = |
+ new AstValueFactory(zone(), isolate()->heap()->HashSeed()); |
+ } |
+ 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()) { |
@@ -4810,6 +4832,12 @@ bool Parser::Parse() { |
} |
} |
info()->SetFunction(result); |
+ ASSERT(ast_value_factory_->IsInternalized()); |
+ // info takes ownership of ast_value_factory_. |
+ if (info()->ast_value_factory() == NULL) { |
+ info()->SetAstValueFactory(ast_value_factory_); |
+ } |
+ ast_value_factory_ = NULL; |
return (result != NULL); |
} |