Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 49e76618ca6fbea9b0787b3ced1ca9050eeb37e5..89366b56ae7b25f55c4d24fd0518a05b729561d4 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -326,7 +326,8 @@ unsigned* ScriptData::ReadAddress(int position) const { |
Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
- Scope* result = new(zone()) Scope(parent, scope_type, zone()); |
+ ASSERT(string_table_); |
+ Scope* result = new(zone()) Scope(parent, scope_type, string_table_, zone()); |
result->Initialize(); |
return result; |
} |
@@ -399,10 +400,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_->string_table_->eval_string() || |
+ identifier == parser_->string_table_->arguments_string(); |
} |
@@ -424,10 +424,9 @@ bool ParserTraits::IsIdentifier(Expression* expression) { |
void ParserTraits::PushPropertyName(FuncNameInferrer* fni, |
Expression* expression) { |
if (expression->IsPropertyName()) { |
- fni->PushLiteralName(expression->AsLiteral()->AsPropertyName()); |
+ fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); |
} else { |
- fni->PushLiteralName( |
- parser_->isolate()->factory()->anonymous_function_string()); |
+ fni->PushLiteralName(parser_->string_table_->anonymous_function_string()); |
} |
} |
@@ -446,7 +445,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_->string_table_->eval_string()) { |
scope->DeclarationScope()->RecordEvalCall(); |
} |
} |
@@ -464,10 +463,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 +525,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->NewLiteral(!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; |
@@ -568,50 +565,39 @@ Expression* ParserTraits::BuildUnaryExpression( |
Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
- return NewThrowError( |
- parser_->isolate()->factory()->MakeReferenceError_string(), |
- message, HandleVector<Object>(NULL, 0), pos); |
+ return NewThrowError(parser_->string_table_->make_reference_error_string(), |
+ message, NULL, pos); |
} |
Expression* ParserTraits::NewThrowSyntaxError( |
- const char* message, Handle<Object> arg, int pos) { |
- int argc = arg.is_null() ? 0 : 1; |
- Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); |
- return NewThrowError( |
- parser_->isolate()->factory()->MakeSyntaxError_string(), |
- message, arguments, pos); |
+ const char* message, const AstString* arg, int pos) { |
+ return NewThrowError(parser_->string_table_->make_syntax_error_string(), |
+ message, arg, pos); |
} |
Expression* ParserTraits::NewThrowTypeError( |
- const char* message, Handle<Object> arg, int pos) { |
- int argc = arg.is_null() ? 0 : 1; |
- Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); |
- return NewThrowError( |
- parser_->isolate()->factory()->MakeTypeError_string(), |
- message, arguments, pos); |
+ const char* message, const AstString* arg, int pos) { |
+ return NewThrowError(parser_->string_table_->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); |
+ int argc = arg != NULL ? 1 : 0; |
+ const AstString* type = |
+ parser_->string_table_->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()->NewLiteral(type, pos), zone); |
args->Add(parser_->factory()->NewLiteral(array, pos), zone); |
CallRuntime* call_constructor = |
@@ -634,13 +620,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* char_arg, |
+ bool is_reference_error) { |
+ Scanner::Location source_location = parser_->scanner()->location(); |
+ ReportMessageAt(source_location, message, char_arg, is_reference_error); |
+} |
+ |
+ |
+void ParserTraits::ReportMessage(const char* message, |
+ const AstString* arg, |
bool is_reference_error) { |
Scanner::Location source_location = parser_->scanner()->location(); |
ReportMessageAt(source_location, message, arg, is_reference_error); |
@@ -649,7 +643,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 +660,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_->string_table_); |
+ 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_->string_table_); |
} |
@@ -691,14 +684,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->NewLiteral( |
+ parser_->string_table_->NewValue(AstValue::NULL_TYPE), pos); |
case Token::TRUE_LITERAL: |
- return factory->NewLiteral(isolate_factory->true_value(), pos); |
+ return factory->NewLiteral(true, pos); |
case Token::FALSE_LITERAL: |
- return factory->NewLiteral(isolate_factory->false_value(), pos); |
+ return factory->NewLiteral(false, pos); |
case Token::NUMBER: { |
double value = scanner->DoubleValue(); |
return factory->NewNumberLiteral(value, pos); |
@@ -711,13 +704,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,7 +720,7 @@ 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); |
} |
@@ -735,8 +728,9 @@ Expression* ParserTraits::ExpressionFromString( |
Literal* ParserTraits::GetLiteralTheHole( |
int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
- return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), |
- RelocInfo::kNoPosition); |
+ return factory->NewLiteral( |
+ parser_->string_table_->NewValue(AstValue::THE_HOLE), |
+ RelocInfo::kNoPosition); |
} |
@@ -746,7 +740,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 +768,11 @@ Parser::Parser(CompilationInfo* info) |
target_stack_(NULL), |
cached_data_(NULL), |
cached_data_mode_(NO_CACHED_DATA), |
+ string_table_(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 +796,7 @@ FunctionLiteral* Parser::ParseProgram() { |
if (FLAG_trace_parse) { |
timer.Start(); |
} |
- fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
+ fni_ = new(zone()) FuncNameInferrer(string_table_, zone()); |
// Initialize parser state. |
CompleteParserRecorder recorder; |
@@ -855,13 +851,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. |
+ string_table_->Internalize(isolate()); |
} |
original_scope_ = scope; |
if (info->is_eval()) { |
@@ -884,7 +883,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(), |
+ string_table_); |
scope_->SetStrictMode(info->strict_mode()); |
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
@@ -911,7 +911,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
if (ok) { |
result = factory()->NewFunctionLiteral( |
- no_name, |
+ string_table_->empty_string(), |
+ string_table_, |
scope_, |
body, |
function_state.materialized_literal_count(), |
@@ -983,8 +984,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(string_table_); |
+ fni_ = new(zone()) FuncNameInferrer(string_table_, zone()); |
+ const AstString* raw_name = string_table_->GetString(name); |
+ fni_->PushEnclosingName(raw_name); |
ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
@@ -1000,7 +1003,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(), |
+ string_table_); |
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 +1014,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 +1083,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() == |
+ string_table_->use_strict_string() && |
+ token_loc.end_pos - token_loc.beg_pos == 12) { |
// TODO(mstarzinger): Global strict eval calls, need their own scope |
// as specified in ES5 10.4.2(3). The correct fix would be to always |
// add this scope in DoParseProgram(), but that requires adaptations |
@@ -1118,7 +1119,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 +1153,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() == |
+ string_table_->module_string() && |
!scanner()->literal_contains_escapes()) { |
return ParseModuleDeclaration(NULL, ok); |
} |
@@ -1166,16 +1166,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 +1187,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 +1290,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 +1322,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 +1341,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 +1385,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 +1405,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 +1444,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 != string_table_->module_string()) { |
names.Add(name, zone()); |
while (peek() == Token::COMMA) { |
Consume(Token::COMMA); |
@@ -1486,7 +1487,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 +1507,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 +1532,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 +1643,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 +1657,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 +1786,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 +1817,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 +1852,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 +1863,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 +1889,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 +1916,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 +1951,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 +1972,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 +2081,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(); |
@@ -2206,7 +2212,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(), |
+ string_table_->initialize_const_global_string(), |
Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), |
arguments, pos); |
} else { |
@@ -2229,7 +2235,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(), |
+ string_table_->initialize_var_global_string(), |
Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
arguments, pos); |
} |
@@ -2285,19 +2291,20 @@ 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; |
return false; |
} |
-Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
- bool* ok) { |
+Statement* Parser::ParseExpressionOrLabelledStatement( |
+ ZoneList<const AstString*>* labels, bool* ok) { |
// ExpressionStatement | LabelledStatement :: |
// Expression ';' |
// Identifier ':' Statement |
@@ -2310,7 +2317,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 |
@@ -2322,7 +2329,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 |
@@ -2341,8 +2348,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
!scanner()->HasAnyLineTerminatorBeforeNext() && |
expr != NULL && |
expr->AsVariableProxy() != NULL && |
- String::Equals(isolate()->factory()->native_string(), |
- expr->AsVariableProxy()->name()) && |
+ expr->AsVariableProxy()->raw_name() == string_table_->native_string() && |
!scanner()->literal_contains_escapes()) { |
return ParseNativeDeclaration(ok); |
} |
@@ -2353,8 +2359,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
peek() != Token::IDENTIFIER || |
scanner()->HasAnyLineTerminatorBeforeNext() || |
expr->AsVariableProxy() == NULL || |
- !String::Equals(isolate()->factory()->module_string(), |
- expr->AsVariableProxy()->name()) || |
+ expr->AsVariableProxy()->raw_name() != string_table_->module_string() || |
scanner()->literal_contains_escapes()) { |
ExpectSemicolon(CHECK_OK); |
} |
@@ -2362,7 +2367,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)? |
@@ -2390,19 +2396,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::ReportMessageAt(scanner()->location(), message, label); |
@@ -2414,13 +2419,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) { |
@@ -2429,7 +2435,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); |
} |
@@ -2438,7 +2444,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::ReportMessageAt(scanner()->location(), message, label); |
@@ -2492,7 +2498,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 |
@@ -2554,8 +2561,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* '}' |
@@ -2638,7 +2645,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); |
@@ -2708,8 +2715,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 ')' ';' |
@@ -2736,7 +2743,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 |
@@ -2775,11 +2783,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()); |
+ string_table_->dot_iterator_string()); |
Variable* result = scope_->DeclarationScope()->NewTemporary( |
- heap_factory->dot_result_string()); |
+ string_table_->dot_result_string()); |
Expression* assign_iterator; |
Expression* next_result; |
@@ -2797,7 +2804,7 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
{ |
Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
Expression* next_literal = factory()->NewLiteral( |
- heap_factory->next_string(), RelocInfo::kNoPosition); |
+ string_table_->next_string(), RelocInfo::kNoPosition); |
Expression* next_property = factory()->NewProperty( |
iterator_proxy, next_literal, RelocInfo::kNoPosition); |
ZoneList<Expression*>* next_arguments = |
@@ -2812,7 +2819,7 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
// result.done |
{ |
Expression* done_literal = factory()->NewLiteral( |
- heap_factory->done_string(), RelocInfo::kNoPosition); |
+ string_table_->done_string(), RelocInfo::kNoPosition); |
Expression* result_proxy = factory()->NewVariableProxy(result); |
result_done = factory()->NewProperty( |
result_proxy, done_literal, RelocInfo::kNoPosition); |
@@ -2821,7 +2828,7 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
// each = result.value |
{ |
Expression* value_literal = factory()->NewLiteral( |
- heap_factory->value_string(), RelocInfo::kNoPosition); |
+ string_table_->value_string(), RelocInfo::kNoPosition); |
Expression* result_proxy = factory()->NewVariableProxy(result); |
Expression* result_value = factory()->NewProperty( |
result_proxy, value_literal, RelocInfo::kNoPosition); |
@@ -2838,9 +2845,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 |
@@ -2881,10 +2888,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 = string_table_->dot_for_string(); |
// For each let variable x: |
// make statement: temp_x = x. |
@@ -2905,7 +2909,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( |
@@ -2945,7 +2949,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, RelocInfo::kNoPosition); |
@@ -2954,7 +2958,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); |
@@ -2968,7 +2972,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, RelocInfo::kNoPosition); |
@@ -2999,13 +3003,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_; |
@@ -3018,7 +3023,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, |
@@ -3026,7 +3031,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 = |
@@ -3054,12 +3059,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; |
@@ -3079,14 +3084,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( |
+ string_table_->dot_for_string()); |
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
ForEachStatement* loop = |
factory()->NewForEachStatement(mode, labels, pos); |
@@ -3217,7 +3216,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; |
} |
@@ -3267,7 +3266,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, |
@@ -3283,11 +3282,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 = string_table_->empty_string(); |
} |
int num_parameters = 0; |
@@ -3339,7 +3338,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(), |
+ string_table_); |
scope_->SetScopeName(function_name); |
if (is_generator) { |
@@ -3352,7 +3353,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()); |
+ string_table_->dot_generator_object_string()); |
function_state.set_generator_object_variable(temp); |
} |
@@ -3371,7 +3372,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. |
@@ -3415,6 +3416,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()); |
@@ -3518,6 +3520,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
: FunctionLiteral::kNotGenerator; |
FunctionLiteral* function_literal = |
factory()->NewFunctionLiteral(function_name, |
+ string_table_, |
scope, |
body, |
materialized_literal_count, |
@@ -3539,7 +3542,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) { |
@@ -3618,7 +3621,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). |
@@ -3641,7 +3644,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
ZoneList<Expression*>* arguments = |
new(zone()) ZoneList<Expression*>(0, zone()); |
CallRuntime* allocation = factory()->NewCallRuntime( |
- isolate()->factory()->empty_string(), |
+ string_table_->empty_string(), |
Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), |
arguments, pos); |
VariableProxy* init_proxy = factory()->NewVariableProxy( |
@@ -3661,8 +3664,9 @@ 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); |
+ Expression* undefined = factory()->NewLiteral( |
+ string_table_->NewValue(AstValue::UNDEFINED), |
+ RelocInfo::kNoPosition); |
Yield* yield = factory()->NewYield( |
get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
body->Add(factory()->NewExpressionStatement( |
@@ -3708,7 +3712,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) { |
@@ -3717,7 +3721,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 && |
@@ -3745,7 +3749,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->raw_data()[0] == '_') { |
ParserTraits::ReportMessage("not_defined", name); |
*ok = false; |
return NULL; |
@@ -3757,8 +3761,8 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { |
Literal* Parser::GetLiteralUndefined(int position) { |
- return factory()->NewLiteral( |
- isolate()->factory()->undefined_value(), position); |
+ return factory()->NewLiteral(string_table_->NewValue(AstValue::UNDEFINED), |
+ position); |
} |
@@ -3767,7 +3771,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() |
@@ -3782,7 +3786,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)) |
@@ -3792,8 +3796,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; |
@@ -3807,9 +3812,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; |
@@ -3842,10 +3847,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_)) |
@@ -4758,7 +4764,16 @@ bool RegExpParser::ParseRegExp(FlatStringReader* input, |
bool Parser::Parse() { |
ASSERT(info()->function() == NULL); |
+ ASSERT(info()->string_table() == NULL); |
FunctionLiteral* result = NULL; |
+ string_table_ = new AstStringTable(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. |
+ string_table_->Internalize(isolate()); |
+ } |
+ |
if (info()->is_lazy()) { |
ASSERT(!info()->is_eval()); |
if (info()->shared_info()->is_function()) { |
@@ -4784,6 +4799,10 @@ bool Parser::Parse() { |
} |
} |
info()->SetFunction(result); |
+ string_table_->Internalize(isolate()); |
+ // info takes ownership of string_table_. |
+ info()->SetStringTable(string_table_); |
+ string_table_ = NULL; |
return (result != NULL); |
} |