Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index f07f37ebb2b271cc6466ff2dde8af462adb0a9a7..5788c50d201ddda36a53b5cdc105390b0ed65ad2 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -300,19 +300,16 @@ const char* ScriptData::BuildMessage() const { |
} |
-Vector<const char*> ScriptData::BuildArgs() const { |
+const char* ScriptData::BuildArg() const { |
int arg_count = Read(PreparseDataConstants::kMessageArgCountPos); |
- const char** array = NewArray<const char*>(arg_count); |
+ if (arg_count == 0) |
+ return NULL; |
// Position after text found by skipping past length field and |
// length field content words. |
int pos = PreparseDataConstants::kMessageTextPos + 1 |
+ Read(PreparseDataConstants::kMessageTextPos); |
- for (int i = 0; i < arg_count; i++) { |
- int count = 0; |
- array[i] = ReadString(ReadAddress(pos), &count); |
- pos += count + 1; |
- } |
- return Vector<const char*>(array, arg_count); |
+ int count = 0; |
+ return ReadString(ReadAddress(pos), &count); |
} |
@@ -327,7 +324,8 @@ unsigned* ScriptData::ReadAddress(int position) const { |
Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
- Scope* result = new(zone()) Scope(parent, scope_type, zone()); |
+ ASSERT(symbol_table_); |
+ Scope* result = new(zone()) Scope(parent, scope_type, symbol_table_, zone()); |
result->Initialize(); |
return result; |
} |
@@ -400,10 +398,10 @@ class TargetScope BASE_EMBEDDED { |
// ---------------------------------------------------------------------------- |
// Implementation of Parser |
-bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
- Factory* factory = parser_->isolate()->factory(); |
- return identifier.is_identical_to(factory->eval_string()) |
- || identifier.is_identical_to(factory->arguments_string()); |
+bool ParserTraits::IsEvalOrArguments( |
+ ParserSymbolTable::Symbol* identifier) const { |
+ return identifier == parser_->symbol_table_->eval_string() || |
+ identifier == parser_->symbol_table_->arguments_string(); |
} |
@@ -425,10 +423,9 @@ bool ParserTraits::IsIdentifier(Expression* expression) { |
void ParserTraits::PushPropertyName(FuncNameInferrer* fni, |
Expression* expression) { |
if (expression->IsPropertyName()) { |
- fni->PushLiteralName(expression->AsLiteral()->AsPropertyName()); |
+ fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); |
} else { |
- fni->PushLiteralName( |
- parser_->isolate()->factory()->anonymous_function_string()); |
+ fni->PushLiteralName(parser_->symbol_table_->anonymous_function_string()); |
} |
} |
@@ -447,7 +444,7 @@ void ParserTraits::CheckPossibleEvalCall(Expression* expression, |
Scope* scope) { |
VariableProxy* callee = expression->AsVariableProxy(); |
if (callee != NULL && |
- callee->IsVariable(parser_->isolate()->factory()->eval_string())) { |
+ callee->raw_name() == parser_->symbol_table_->eval_string()) { |
scope->DeclarationScope()->RecordEvalCall(); |
} |
} |
@@ -465,10 +462,13 @@ Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
Expression** x, Expression* y, Token::Value op, int pos, |
AstNodeFactory<AstConstructionVisitor>* factory) { |
- if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && |
- y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { |
- double x_val = (*x)->AsLiteral()->value()->Number(); |
- double y_val = y->AsLiteral()->value()->Number(); |
+ // FIXME: this needs to change when it cannot use handles. |
+ if ((*x)->AsLiteral() && !(*x)->AsLiteral()->valueIfNotString().is_null() && |
+ (*x)->AsLiteral()->valueIfNotString()->IsNumber() && y->AsLiteral() && |
+ !y->AsLiteral()->valueIfNotString().is_null() && |
+ y->AsLiteral()->valueIfNotString()->IsNumber()) { |
+ double x_val = (*x)->AsLiteral()->valueIfNotString()->Number(); |
+ double y_val = y->AsLiteral()->valueIfNotString()->Number(); |
switch (op) { |
case Token::ADD: |
*x = factory->NewNumberLiteral(x_val + y_val, pos); |
@@ -526,8 +526,12 @@ Expression* ParserTraits::BuildUnaryExpression( |
Expression* expression, Token::Value op, int pos, |
AstNodeFactory<AstConstructionVisitor>* factory) { |
ASSERT(expression != NULL); |
- if (expression->AsLiteral() != NULL) { |
- Handle<Object> literal = expression->AsLiteral()->value(); |
+ // FIXME: This needs to change when numbers and booleans are no longer |
+ // handles. |
+ // FIXME: The !"foo" shortcut doesn't work atm. |
+ if (expression->AsLiteral() != NULL && |
+ !expression->AsLiteral()->valueIfNotString().is_null()) { |
+ Handle<Object> literal = expression->AsLiteral()->valueIfNotString(); |
if (op == Token::NOT) { |
// Convert the literal to a boolean condition and negate it. |
bool condition = literal->BooleanValue(); |
@@ -569,52 +573,40 @@ Expression* ParserTraits::BuildUnaryExpression( |
Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) { |
- return NewThrowError( |
- parser_->isolate()->factory()->MakeReferenceError_string(), |
- message, HandleVector<Object>(NULL, 0), pos); |
+ return NewThrowError(parser_->symbol_table_->make_reference_error_string(), |
+ message, NULL, pos); |
} |
Expression* ParserTraits::NewThrowSyntaxError( |
- const char* message, Handle<Object> arg, int pos) { |
- int argc = arg.is_null() ? 0 : 1; |
- Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); |
- return NewThrowError( |
- parser_->isolate()->factory()->MakeSyntaxError_string(), |
- message, arguments, pos); |
+ const char* message, ParserSymbolTable::Symbol* arg, int pos) { |
+ return NewThrowError(parser_->symbol_table_->make_syntax_error_string(), |
+ message, arg, pos); |
} |
Expression* ParserTraits::NewThrowTypeError( |
- const char* message, Handle<Object> arg, int pos) { |
- int argc = arg.is_null() ? 0 : 1; |
- Vector< Handle<Object> > arguments = HandleVector<Object>(&arg, argc); |
- return NewThrowError( |
- parser_->isolate()->factory()->MakeTypeError_string(), |
- message, arguments, pos); |
+ const char* message, ParserSymbolTable::Symbol* arg, int pos) { |
+ return NewThrowError(parser_->symbol_table_->make_type_error_string(), |
+ message, arg, pos); |
} |
Expression* ParserTraits::NewThrowError( |
- Handle<String> constructor, const char* message, |
- Vector<Handle<Object> > arguments, int pos) { |
+ ParserSymbolTable::Symbol* constructor, const char* message, |
+ ParserSymbolTable::Symbol* arg, int pos) { |
Zone* zone = parser_->zone(); |
- Factory* factory = parser_->isolate()->factory(); |
- int argc = arguments.length(); |
- Handle<FixedArray> elements = factory->NewFixedArray(argc, TENURED); |
- for (int i = 0; i < argc; i++) { |
- Handle<Object> element = arguments[i]; |
- if (!element.is_null()) { |
- elements->set(i, *element); |
- } |
- } |
- Handle<JSArray> array = |
- factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED); |
- |
- ZoneList<Expression*>* args = new(zone) ZoneList<Expression*>(2, zone); |
- Handle<String> type = factory->InternalizeUtf8String(message); |
+ ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(arg != NULL ? 2 : 1, zone); |
+ ParserSymbolTable::Symbol* type = |
+ parser_->symbol_table_->GetOneByteSymbol(Vector<const uint8_t>( |
+ reinterpret_cast<const uint8_t*>(message), StrLength(message))); |
args->Add(parser_->factory()->NewLiteral(type, pos), zone); |
- args->Add(parser_->factory()->NewLiteral(array, pos), zone); |
+ if (arg != NULL) { |
+ ZoneList<ParserSymbolTable::Symbol*>* array = |
+ new (zone) ZoneList<ParserSymbolTable::Symbol*>(1, zone); |
+ array->Add(arg, zone); |
+ args->Add(parser_->factory()->NewLiteral(array, pos), zone); |
+ } |
CallRuntime* call_constructor = |
parser_->factory()->NewCallRuntime(constructor, NULL, args, pos); |
return parser_->factory()->NewThrow(call_constructor, pos); |
@@ -623,7 +615,7 @@ Expression* ParserTraits::NewThrowError( |
void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
const char* message, |
- Vector<const char*> args, |
+ const char* char_arg, |
bool is_reference_error) { |
if (parser_->stack_overflow()) { |
// Suppress the error message (syntax error or such) in the presence of a |
@@ -631,35 +623,18 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
// and we want to report the stack overflow later. |
return; |
} |
- MessageLocation location(parser_->script_, |
- source_location.beg_pos, |
- source_location.end_pos); |
- Factory* factory = parser_->isolate()->factory(); |
- Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
- for (int i = 0; i < args.length(); i++) { |
- Handle<String> arg_string = |
- factory->NewStringFromUtf8(CStrVector(args[i])).ToHandleChecked(); |
- elements->set(i, *arg_string); |
- } |
- Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
- Handle<Object> result = is_reference_error |
- ? factory->NewReferenceError(message, array) |
- : factory->NewSyntaxError(message, array); |
- parser_->isolate()->Throw(*result, &location); |
-} |
- |
- |
-void ParserTraits::ReportMessage(const char* message, |
- Vector<Handle<String> > args, |
- bool is_reference_error) { |
- Scanner::Location source_location = parser_->scanner()->location(); |
- ReportMessageAt(source_location, message, args, is_reference_error); |
+ parser_->has_pending_error_ = true; |
+ parser_->pending_location_ = source_location; |
+ parser_->pending_message_ = message; |
+ parser_->pending_char_arg_ = char_arg; |
+ parser_->pending_arg_ = NULL; |
+ parser_->pending_is_reference_error_ = is_reference_error; |
} |
void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
const char* message, |
- Vector<Handle<String> > args, |
+ ParserSymbolTable::Symbol* arg, |
bool is_reference_error) { |
if (parser_->stack_overflow()) { |
// Suppress the error message (syntax error or such) in the presence of a |
@@ -667,33 +642,38 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
// and we want to report the stack overflow later. |
return; |
} |
- MessageLocation location(parser_->script_, |
- source_location.beg_pos, |
- source_location.end_pos); |
- Factory* factory = parser_->isolate()->factory(); |
- Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
- for (int i = 0; i < args.length(); i++) { |
- elements->set(i, *args[i]); |
- } |
- Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
- Handle<Object> result = is_reference_error |
- ? factory->NewReferenceError(message, array) |
- : factory->NewSyntaxError(message, array); |
- parser_->isolate()->Throw(*result, &location); |
+ parser_->has_pending_error_ = true; |
+ parser_->pending_location_ = source_location; |
+ parser_->pending_message_ = message; |
+ parser_->pending_char_arg_ = NULL; |
+ parser_->pending_arg_ = arg; |
+ parser_->pending_is_reference_error_ = is_reference_error; |
} |
-Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { |
- Handle<String> result = |
- parser_->scanner()->AllocateInternalizedString(parser_->isolate()); |
- ASSERT(!result.is_null()); |
- return result; |
+void ParserTraits::ReportMessage(const char* message, |
+ const char* char_arg, |
+ bool is_reference_error) { |
+ Scanner::Location source_location = parser_->scanner()->location(); |
+ ReportMessageAt(source_location, message, char_arg, is_reference_error); |
+} |
+ |
+ |
+void ParserTraits::ReportMessage(const char* message, |
+ ParserSymbolTable::Symbol* arg, |
+ bool is_reference_error) { |
+ Scanner::Location source_location = parser_->scanner()->location(); |
+ ReportMessageAt(source_location, message, arg, is_reference_error); |
} |
-Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, |
- PretenureFlag tenured) { |
- return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); |
+ParserSymbolTable::Symbol* ParserTraits::GetSymbol(Scanner* scanner) { |
+ return parser_->scanner()->CurrentString(parser_->symbol_table_); |
+} |
+ |
+ |
+ParserSymbolTable::Symbol* ParserTraits::GetNextSymbol(Scanner* scanner) { |
+ return parser_->scanner()->NextString(parser_->symbol_table_); |
} |
@@ -728,13 +708,17 @@ Literal* ParserTraits::ExpressionFromLiteral( |
Expression* ParserTraits::ExpressionFromIdentifier( |
- Handle<String> name, int pos, Scope* scope, |
+ ParserSymbolTable::Symbol* name, int pos, Scope* scope, |
AstNodeFactory<AstConstructionVisitor>* factory) { |
- if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); |
+ if (parser_->fni_ != NULL) { |
+ parser_->fni_->PushVariableName(name); |
+ } |
// The name may refer to a module instance object, so its type is unknown. |
#ifdef DEBUG |
- if (FLAG_print_interface_details) |
- PrintF("# Variable %s ", name->ToAsciiArray()); |
+ if (FLAG_print_interface_details) { |
+ PrintF("# Variable %.*s ", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
+ } |
#endif |
Interface* interface = Interface::NewUnknown(parser_->zone()); |
return scope->NewUnresolved(factory, name, interface, pos); |
@@ -744,7 +728,7 @@ Expression* ParserTraits::ExpressionFromIdentifier( |
Expression* ParserTraits::ExpressionFromString( |
int pos, Scanner* scanner, |
AstNodeFactory<AstConstructionVisitor>* factory) { |
- Handle<String> symbol = GetSymbol(scanner); |
+ ParserSymbolTable::Symbol* symbol = GetSymbol(scanner); |
if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); |
return factory->NewLiteral(symbol, pos); |
} |
@@ -763,7 +747,7 @@ Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
- Handle<String> name, |
+ ParserSymbolTable::Symbol* name, |
Scanner::Location function_name_location, |
bool name_is_strict_reserved, |
bool is_generator, |
@@ -791,7 +775,12 @@ Parser::Parser(CompilationInfo* info) |
target_stack_(NULL), |
cached_data_(NULL), |
cached_data_mode_(NO_CACHED_DATA), |
- info_(info) { |
+ symbol_table_(NULL), |
+ info_(info), |
+ has_pending_error_(false), |
+ pending_message_(NULL), |
+ pending_arg_(NULL), |
+ pending_char_arg_(NULL) { |
ASSERT(!script_.is_null()); |
isolate_->set_ast_node_id(0); |
set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
@@ -814,7 +803,7 @@ FunctionLiteral* Parser::ParseProgram() { |
if (FLAG_trace_parse) { |
timer.Start(); |
} |
- fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
+ fni_ = new(zone()) FuncNameInferrer(symbol_table_, zone()); |
// Initialize parser state. |
CompleteParserRecorder recorder; |
@@ -869,13 +858,14 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
ASSERT(scope_ == NULL); |
ASSERT(target_stack_ == NULL); |
- Handle<String> no_name = isolate()->factory()->empty_string(); |
+ ParserSymbolTable::Symbol* no_name = symbol_table_->empty_string(); |
FunctionLiteral* result = NULL; |
{ Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
info->SetGlobalScope(scope); |
if (!info->context().is_null()) { |
scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
+ symbol_table_->AlwaysInternalize(isolate()); |
} |
original_scope_ = scope; |
if (info->is_eval()) { |
@@ -918,11 +908,13 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
!body->at(0)->IsExpressionStatement() || |
!body->at(0)->AsExpressionStatement()-> |
expression()->IsFunctionLiteral()) { |
- ReportMessage("single_function_literal", Vector<const char*>::empty()); |
+ ParserTraits::ReportMessage("single_function_literal"); |
ok = false; |
} |
} |
+ symbol_table_->Internalize(isolate()); |
+ |
if (ok) { |
result = factory()->NewFunctionLiteral( |
no_name, |
@@ -941,8 +933,11 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
result->set_ast_properties(factory()->visitor()->ast_properties()); |
result->set_dont_optimize_reason( |
factory()->visitor()->dont_optimize_reason()); |
+ |
} else if (stack_overflow()) { |
isolate()->StackOverflow(); |
+ } else { |
+ CheckPendingError(); |
} |
} |
@@ -995,8 +990,9 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
ASSERT(target_stack_ == NULL); |
Handle<String> name(String::cast(shared_info->name())); |
- fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
- fni_->PushEnclosingName(name); |
+ fni_ = new(zone()) FuncNameInferrer(symbol_table_, zone()); |
+ ParserSymbolTable::Symbol* raw_name = symbol_table_->GetSymbol(name); |
+ fni_->PushEnclosingName(raw_name); |
ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
@@ -1022,7 +1018,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(), |
@@ -1031,13 +1027,20 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
&ok); |
// Make sure the results agree. |
ASSERT(ok == (result != NULL)); |
+ |
+ // Start using the heap (before scope goes out of scope). |
rossberg
2014/05/08 12:52:08
"scope is exited"?
marja
2014/06/03 08:48:20
Actually, this is not needed any more, so moved th
|
+ symbol_table_->Internalize(isolate()); |
} |
// Make sure the target stack is empty. |
ASSERT(target_stack_ == NULL); |
if (result == NULL) { |
- if (stack_overflow()) isolate()->StackOverflow(); |
+ if (stack_overflow()) { |
+ isolate()->StackOverflow(); |
+ } else { |
+ CheckPendingError(); |
+ } |
} else { |
Handle<String> inferred_name(shared_info->inferred_name()); |
result->set_inferred_name(inferred_name); |
@@ -1087,15 +1090,11 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
// Still processing directive prologue? |
if ((e_stat = stat->AsExpressionStatement()) != NULL && |
(literal = e_stat->expression()->AsLiteral()) != NULL && |
- literal->value()->IsString()) { |
- Handle<String> directive = Handle<String>::cast(literal->value()); |
- |
+ literal->string() != NULL) { |
rossberg
2014/05/08 12:52:08
Would be nicer to have an IsString predicate on Li
marja
2014/06/03 08:48:20
The StringLiteral / StringArrayLiteral / Literal s
|
// Check "use strict" directive (ES5 14.1). |
if (strict_mode() == SLOPPY && |
- String::Equals(isolate()->factory()->use_strict_string(), |
- directive) && |
- token_loc.end_pos - token_loc.beg_pos == |
- isolate()->heap()->use_strict_string()->length() + 2) { |
+ literal->string() == symbol_table_->use_strict_string() && |
+ token_loc.end_pos - token_loc.beg_pos == 12) { |
// TODO(mstarzinger): Global strict eval calls, need their own scope |
// as specified in ES5 10.4.2(3). The correct fix would be to always |
// add this scope in DoParseProgram(), but that requires adaptations |
@@ -1126,8 +1125,8 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
} |
-Statement* Parser::ParseModuleElement(ZoneStringList* labels, |
- bool* ok) { |
+Statement* Parser::ParseModuleElement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// (Ecma 262 5th Edition, clause 14): |
// SourceElement: |
// Statement |
@@ -1160,10 +1159,9 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels, |
!scanner()->HasAnyLineTerminatorBeforeNext() && |
stmt != NULL) { |
ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
- if (estmt != NULL && |
- estmt->expression()->AsVariableProxy() != NULL && |
- String::Equals(isolate()->factory()->module_string(), |
- estmt->expression()->AsVariableProxy()->name()) && |
+ if (estmt != NULL && estmt->expression()->AsVariableProxy() != NULL && |
+ estmt->expression()->AsVariableProxy()->raw_name() == |
+ symbol_table_->module_string() && |
!scanner()->literal_contains_escapes()) { |
return ParseModuleDeclaration(NULL, ok); |
} |
@@ -1174,16 +1172,20 @@ Statement* Parser::ParseModuleElement(ZoneStringList* labels, |
} |
-Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
+Statement* Parser::ParseModuleDeclaration( |
+ ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) { |
// ModuleDeclaration: |
// 'module' Identifier Module |
int pos = peek_position(); |
- Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
+ ParserSymbolTable::Symbol* name = |
+ ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
#ifdef DEBUG |
- if (FLAG_print_interface_details) |
- PrintF("# Module %s...\n", name->ToAsciiArray()); |
+ if (FLAG_print_interface_details) { |
+ PrintF("# Module %.*s ", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
+ } |
#endif |
Module* module = ParseModule(CHECK_OK); |
@@ -1193,11 +1195,13 @@ Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
Declare(declaration, true, CHECK_OK); |
#ifdef DEBUG |
- if (FLAG_print_interface_details) |
- PrintF("# Module %s.\n", name->ToAsciiArray()); |
- |
+ if (FLAG_print_interface_details) { |
+ PrintF("# Module %.*s ", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
+ } |
if (FLAG_print_interfaces) { |
- PrintF("module %s : ", name->ToAsciiArray()); |
+ PrintF("module %.*s: ", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
module->interface()->Print(); |
} |
#endif |
@@ -1276,9 +1280,7 @@ Module* Parser::ParseModuleLiteral(bool* ok) { |
for (Interface::Iterator it = interface->iterator(); |
!it.done(); it.Advance()) { |
if (scope->LocalLookup(it.name()) == NULL) { |
- Handle<String> name(it.name()); |
- ParserTraits::ReportMessage("module_export_undefined", |
- Vector<Handle<String> >(&name, 1)); |
+ ParserTraits::ReportMessage("module_export_undefined", it.name()); |
*ok = false; |
return NULL; |
} |
@@ -1300,25 +1302,28 @@ Module* Parser::ParseModulePath(bool* ok) { |
int pos = peek_position(); |
Module* result = ParseModuleVariable(CHECK_OK); |
while (Check(Token::PERIOD)) { |
- Handle<String> name = ParseIdentifierName(CHECK_OK); |
+ ParserSymbolTable::Symbol* name = ParseIdentifierName(CHECK_OK); |
#ifdef DEBUG |
- if (FLAG_print_interface_details) |
- PrintF("# Path .%s ", name->ToAsciiArray()); |
+ if (FLAG_print_interface_details) { |
+ PrintF("# Path .%.*s ", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
+ } |
#endif |
- Module* member = factory()->NewModulePath(result, name, pos); |
+ Module* member = |
+ factory()->NewModulePath(result, name, pos); |
result->interface()->Add(name, member->interface(), zone(), ok); |
if (!*ok) { |
#ifdef DEBUG |
if (FLAG_print_interfaces) { |
- PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
+ PrintF("PATH TYPE ERROR at '%.*s'\n", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
PrintF("result: "); |
result->interface()->Print(); |
PrintF("member: "); |
member->interface()->Print(); |
} |
#endif |
- ParserTraits::ReportMessage("invalid_module_path", |
- Vector<Handle<String> >(&name, 1)); |
+ ParserTraits::ReportMessage("invalid_module_path", name); |
return NULL; |
} |
result = member; |
@@ -1333,10 +1338,13 @@ Module* Parser::ParseModuleVariable(bool* ok) { |
// Identifier |
int pos = peek_position(); |
- Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
+ ParserSymbolTable::Symbol* name = |
+ ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
#ifdef DEBUG |
- if (FLAG_print_interface_details) |
- PrintF("# Module variable %s ", name->ToAsciiArray()); |
+ if (FLAG_print_interface_details) { |
+ PrintF("# Module variable %.*s ", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
+ } |
#endif |
VariableProxy* proxy = scope_->NewUnresolved( |
factory(), name, Interface::NewModule(zone()), |
@@ -1352,7 +1360,7 @@ Module* Parser::ParseModuleUrl(bool* ok) { |
int pos = peek_position(); |
Expect(Token::STRING, CHECK_OK); |
- Handle<String> symbol = GetSymbol(); |
+ ParserSymbolTable::Symbol* symbol = GetSymbol(scanner()); |
// TODO(ES6): Request JS resource from environment... |
@@ -1396,9 +1404,9 @@ Block* Parser::ParseImportDeclaration(bool* ok) { |
int pos = peek_position(); |
Expect(Token::IMPORT, CHECK_OK); |
- ZoneStringList names(1, zone()); |
+ ZoneList<ParserSymbolTable::Symbol*> names(1, zone()); |
- Handle<String> name = ParseIdentifierName(CHECK_OK); |
+ ParserSymbolTable::Symbol* name = ParseIdentifierName(CHECK_OK); |
names.Add(name, zone()); |
while (peek() == Token::COMMA) { |
Consume(Token::COMMA); |
@@ -1415,21 +1423,23 @@ Block* Parser::ParseImportDeclaration(bool* ok) { |
Block* block = factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
for (int i = 0; i < names.length(); ++i) { |
#ifdef DEBUG |
- if (FLAG_print_interface_details) |
- PrintF("# Import %s ", names[i]->ToAsciiArray()); |
+ if (FLAG_print_interface_details) { |
+ PrintF("# Import %.*s ", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
+ } |
#endif |
Interface* interface = Interface::NewUnknown(zone()); |
module->interface()->Add(names[i], interface, zone(), ok); |
if (!*ok) { |
#ifdef DEBUG |
if (FLAG_print_interfaces) { |
- PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
+ PrintF("IMPORT TYPE ERROR at '%.*s'\n", name->literal_bytes.length(), |
+ name->literal_bytes.start()); |
PrintF("module: "); |
module->interface()->Print(); |
} |
#endif |
- ParserTraits::ReportMessage("invalid_module_path", |
- Vector<Handle<String> >(&name, 1)); |
+ ParserTraits::ReportMessage("invalid_module_path", name); |
return NULL; |
} |
VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
@@ -1455,14 +1465,14 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { |
Expect(Token::EXPORT, CHECK_OK); |
Statement* result = NULL; |
- ZoneStringList names(1, zone()); |
+ ZoneList<ParserSymbolTable::Symbol*> names(1, zone()); |
switch (peek()) { |
case Token::IDENTIFIER: { |
int pos = position(); |
- Handle<String> name = |
+ ParserSymbolTable::Symbol* name = |
ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
// Handle 'module' as a context-sensitive keyword. |
- if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
+ if (name != symbol_table_->module_string()) { |
names.Add(name, zone()); |
while (peek() == Token::COMMA) { |
Consume(Token::COMMA); |
@@ -1497,8 +1507,10 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { |
Interface* interface = scope_->interface(); |
for (int i = 0; i < names.length(); ++i) { |
#ifdef DEBUG |
- if (FLAG_print_interface_details) |
- PrintF("# Export %s ", names[i]->ToAsciiArray()); |
+ if (FLAG_print_interface_details) { |
+ PrintF("# Export %.*s ", names[i]->literal_bytes.length(), |
+ names[i]->literal_bytes.start()); |
+ } |
#endif |
Interface* inner = Interface::NewUnknown(zone()); |
interface->Add(names[i], inner, zone(), CHECK_OK); |
@@ -1518,8 +1530,8 @@ Statement* Parser::ParseExportDeclaration(bool* ok) { |
} |
-Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
- bool* ok) { |
+Statement* Parser::ParseBlockElement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// (Ecma 262 5th Edition, clause 14): |
// SourceElement: |
// Statement |
@@ -1543,7 +1555,8 @@ Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
} |
-Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
+Statement* Parser::ParseStatement(ZoneList<ParserSymbolTable::Symbol*>* labels, |
+ bool* ok) { |
// Statement :: |
// Block |
// VariableStatement |
@@ -1637,7 +1650,8 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
// Statement: |
// GeneratorDeclaration |
if (strict_mode() == STRICT) { |
- ReportMessageAt(scanner()->peek_location(), "strict_function"); |
+ ParserTraits::ReportMessageAt(scanner()->peek_location(), |
+ "strict_function"); |
*ok = false; |
return NULL; |
} |
@@ -1653,8 +1667,9 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
} |
+template<typename SymbolType> |
VariableProxy* Parser::NewUnresolved( |
- Handle<String> name, VariableMode mode, Interface* interface) { |
+ SymbolType name, VariableMode mode, Interface* interface) { |
// If we are inside a function, a declaration of a var/const variable is a |
// truly local variable, and the scope of the variable is always the function |
// scope. |
@@ -1667,7 +1682,8 @@ VariableProxy* Parser::NewUnresolved( |
void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
VariableProxy* proxy = declaration->proxy(); |
- Handle<String> name = proxy->name(); |
+ ASSERT(proxy->raw_name() != NULL); |
+ ParserSymbolTable::Symbol* name = proxy->raw_name(); |
VariableMode mode = declaration->mode(); |
Scope* declaration_scope = DeclarationScope(mode); |
Variable* var = NULL; |
@@ -1717,10 +1733,7 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
if (allow_harmony_scoping() && strict_mode() == STRICT) { |
// In harmony we treat re-declarations as early errors. See |
// ES5 16 for a definition of early errors. |
- SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
- const char* elms[1] = { c_string.get() }; |
- Vector<const char*> args(elms, 1); |
- ReportMessage("var_redeclaration", args); |
+ ParserTraits::ReportMessage("var_redeclaration", name); |
*ok = false; |
return; |
} |
@@ -1798,8 +1811,15 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
if (FLAG_harmony_modules) { |
bool ok; |
#ifdef DEBUG |
- if (FLAG_print_interface_details) |
- PrintF("# Declare %s\n", var->name()->ToAsciiArray()); |
+ if (FLAG_print_interface_details) { |
+ if (!var->name().is_null()) { |
rossberg
2014/05/08 12:52:08
Why is this case needed?
marja
2014/06/03 08:48:20
Done
(It wasn't.)
|
+ PrintF("# Declare %s\n", var->name()->ToAsciiArray()); |
+ } else { |
+ ASSERT(var->raw_name() != NULL); |
+ PrintF("# Declare %.*s ", var->raw_name()->literal_bytes.length(), |
+ var->raw_name()->literal_bytes.start()); |
+ } |
+ } |
#endif |
proxy->interface()->Unify(var->interface(), zone(), &ok); |
if (!ok) { |
@@ -1812,8 +1832,7 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) { |
var->interface()->Print(); |
} |
#endif |
- ParserTraits::ReportMessage("module_type_error", |
- Vector<Handle<String> >(&name, 1)); |
+ ParserTraits::ReportMessage("module_type_error", name); |
} |
} |
} |
@@ -1828,7 +1847,8 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { |
int pos = peek_position(); |
Expect(Token::FUNCTION, CHECK_OK); |
// Allow "eval" or "arguments" for backward compatibility. |
- Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
+ ParserSymbolTable::Symbol* name = |
+ ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
Expect(Token::LPAREN, CHECK_OK); |
bool done = (peek() == Token::RPAREN); |
while (!done) { |
@@ -1863,7 +1883,8 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { |
} |
-Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
+Statement* Parser::ParseFunctionDeclaration( |
+ ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) { |
// FunctionDeclaration :: |
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
// GeneratorDeclaration :: |
@@ -1873,7 +1894,7 @@ Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
int pos = position(); |
bool is_generator = allow_generators() && Check(Token::MUL); |
bool is_strict_reserved = false; |
- Handle<String> name = ParseIdentifierOrStrictReservedWord( |
+ ParserSymbolTable::Symbol* name = ParseIdentifierOrStrictReservedWord( |
&is_strict_reserved, CHECK_OK); |
FunctionLiteral* fun = ParseFunctionLiteral(name, |
scanner()->location(), |
@@ -1899,7 +1920,7 @@ Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
} |
-Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
+Block* Parser::ParseBlock(ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
if (allow_harmony_scoping() && strict_mode() == STRICT) { |
return ParseScopedBlock(labels, ok); |
} |
@@ -1926,7 +1947,7 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
} |
-Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
+Block* Parser::ParseScopedBlock(ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// The harmony mode uses block elements instead of statements. |
// |
// Block :: |
@@ -1960,13 +1981,13 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
} |
-Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
- ZoneStringList* names, |
- bool* ok) { |
+Block* Parser::ParseVariableStatement( |
+ VariableDeclarationContext var_context, |
+ ZoneList<ParserSymbolTable::Symbol*>* names, bool* ok) { |
// VariableStatement :: |
// VariableDeclarations ';' |
- Handle<String> ignore; |
+ ParserSymbolTable::Symbol* ignore; |
Block* result = |
ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
ExpectSemicolon(CHECK_OK); |
@@ -1982,8 +2003,8 @@ Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
Block* Parser::ParseVariableDeclarations( |
VariableDeclarationContext var_context, |
VariableDeclarationProperties* decl_props, |
- ZoneStringList* names, |
- Handle<String>* out, |
+ ZoneList<ParserSymbolTable::Symbol*>* names, |
+ ParserSymbolTable::Symbol** out, |
bool* ok) { |
// VariableDeclarations :: |
// ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[','] |
@@ -2032,14 +2053,14 @@ Block* Parser::ParseVariableDeclarations( |
if (var_context == kStatement) { |
// In strict mode 'const' declarations are only allowed in source |
// element positions. |
- ReportMessage("unprotected_const", Vector<const char*>::empty()); |
+ ParserTraits::ReportMessage("unprotected_const"); |
*ok = false; |
return NULL; |
} |
mode = CONST; |
init_op = Token::INIT_CONST; |
} else { |
- ReportMessage("strict_const", Vector<const char*>::empty()); |
+ ParserTraits::ReportMessage("strict_const"); |
*ok = false; |
return NULL; |
} |
@@ -2056,14 +2077,14 @@ Block* Parser::ParseVariableDeclarations( |
// |
// TODO(rossberg): make 'let' a legal identifier in sloppy mode. |
if (!allow_harmony_scoping() || strict_mode() == SLOPPY) { |
- ReportMessage("illegal_let", Vector<const char*>::empty()); |
+ ReportMessage("illegal_let"); |
*ok = false; |
return NULL; |
} |
Consume(Token::LET); |
if (var_context == kStatement) { |
// Let declarations are only allowed in source element positions. |
- ReportMessage("unprotected_let", Vector<const char*>::empty()); |
+ ReportMessage("unprotected_let"); |
*ok = false; |
return NULL; |
} |
@@ -2091,7 +2112,7 @@ Block* Parser::ParseVariableDeclarations( |
// Create new block with one expected declaration. |
Block* block = factory()->NewBlock(NULL, 1, true, pos); |
int nvars = 0; // the number of variables declared |
- Handle<String> name; |
+ ParserSymbolTable::Symbol* name = NULL; |
do { |
if (fni_ != NULL) fni_->Enter(); |
@@ -2123,7 +2144,7 @@ Block* Parser::ParseVariableDeclarations( |
Declare(declaration, mode != VAR, CHECK_OK); |
nvars++; |
if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
- ReportMessageAt(scanner()->location(), "too_many_variables"); |
+ ReportMessage("too_many_variables"); |
*ok = false; |
return NULL; |
} |
@@ -2222,7 +2243,7 @@ Block* Parser::ParseVariableDeclarations( |
// Note that the function does different things depending on |
// the number of arguments (1 or 2). |
initialize = factory()->NewCallRuntime( |
- isolate()->factory()->InitializeConstGlobal_string(), |
+ symbol_table_->initialize_const_global_string(), |
Runtime::FunctionForId(Runtime::kHiddenInitializeConstGlobal), |
arguments, pos); |
} else { |
@@ -2245,7 +2266,7 @@ Block* Parser::ParseVariableDeclarations( |
// Note that the function does different things depending on |
// the number of arguments (2 or 3). |
initialize = factory()->NewCallRuntime( |
- isolate()->factory()->InitializeVarGlobal_string(), |
+ symbol_table_->initialize_var_global_string(), |
Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
arguments, pos); |
} |
@@ -2301,19 +2322,20 @@ Block* Parser::ParseVariableDeclarations( |
} |
-static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { |
- ASSERT(!label.is_null()); |
+static bool ContainsLabel(ZoneList<ParserSymbolTable::Symbol*>* labels, |
+ ParserSymbolTable::Symbol* label) { |
+ ASSERT(label != NULL); |
if (labels != NULL) |
for (int i = labels->length(); i-- > 0; ) |
- if (labels->at(i).is_identical_to(label)) |
+ if (labels->at(i) == label) |
return true; |
return false; |
} |
-Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
- bool* ok) { |
+Statement* Parser::ParseExpressionOrLabelledStatement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// ExpressionStatement | LabelledStatement :: |
// Expression ';' |
// Identifier ':' Statement |
@@ -2326,22 +2348,19 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
// Expression is a single identifier, and not, e.g., a parenthesized |
// identifier. |
VariableProxy* var = expr->AsVariableProxy(); |
- Handle<String> label = var->name(); |
+ ParserSymbolTable::Symbol* label = var->raw_name(); |
// TODO(1240780): We don't check for redeclaration of labels |
// during preparsing since keeping track of the set of active |
// labels requires nontrivial changes to the way scopes are |
// structured. However, these are probably changes we want to |
// make later anyway so we should go back and fix this then. |
if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { |
- SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS); |
- const char* elms[1] = { c_string.get() }; |
- Vector<const char*> args(elms, 1); |
- ReportMessage("label_redeclaration", args); |
+ ParserTraits::ReportMessage("label_redeclaration", label); |
*ok = false; |
return NULL; |
} |
if (labels == NULL) { |
- labels = new(zone()) ZoneStringList(4, zone()); |
+ labels = new(zone()) ZoneList<ParserSymbolTable::Symbol*>(4, zone()); |
} |
labels->Add(label, zone()); |
// Remove the "ghost" variable that turned out to be a label |
@@ -2360,8 +2379,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
!scanner()->HasAnyLineTerminatorBeforeNext() && |
expr != NULL && |
expr->AsVariableProxy() != NULL && |
- String::Equals(isolate()->factory()->native_string(), |
- expr->AsVariableProxy()->name()) && |
+ expr->AsVariableProxy()->raw_name() == symbol_table_->native_string() && |
!scanner()->literal_contains_escapes()) { |
return ParseNativeDeclaration(ok); |
} |
@@ -2372,8 +2390,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
peek() != Token::IDENTIFIER || |
scanner()->HasAnyLineTerminatorBeforeNext() || |
expr->AsVariableProxy() == NULL || |
- !String::Equals(isolate()->factory()->module_string(), |
- expr->AsVariableProxy()->name()) || |
+ expr->AsVariableProxy()->raw_name() != symbol_table_->module_string() || |
scanner()->literal_contains_escapes()) { |
ExpectSemicolon(CHECK_OK); |
} |
@@ -2381,7 +2398,8 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
} |
-IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
+IfStatement* Parser::ParseIfStatement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// IfStatement :: |
// 'if' '(' Expression ')' Statement ('else' Statement)? |
@@ -2409,24 +2427,21 @@ Statement* Parser::ParseContinueStatement(bool* ok) { |
int pos = peek_position(); |
Expect(Token::CONTINUE, CHECK_OK); |
- Handle<String> label = Handle<String>::null(); |
+ ParserSymbolTable::Symbol* label = NULL; |
Token::Value tok = peek(); |
if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
// ECMA allows "eval" or "arguments" as labels even in strict mode. |
label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
} |
- IterationStatement* target = NULL; |
- target = LookupContinueTarget(label, CHECK_OK); |
+ IterationStatement* target = LookupContinueTarget(label, CHECK_OK); |
if (target == NULL) { |
// Illegal continue statement. |
- const char* message = "illegal_continue"; |
- Vector<Handle<String> > args; |
- if (!label.is_null()) { |
- message = "unknown_label"; |
- args = Vector<Handle<String> >(&label, 1); |
+ if (label != NULL) { |
+ ParserTraits::ReportMessage("unknown_label", label); |
+ } else { |
+ ParserTraits::ReportMessage("illegal_continue"); |
} |
- ParserTraits::ReportMessageAt(scanner()->location(), message, args); |
*ok = false; |
return NULL; |
} |
@@ -2435,13 +2450,13 @@ Statement* Parser::ParseContinueStatement(bool* ok) { |
} |
-Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
+Statement* Parser::ParseBreakStatement(ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// BreakStatement :: |
// 'break' Identifier? ';' |
int pos = peek_position(); |
Expect(Token::BREAK, CHECK_OK); |
- Handle<String> label; |
+ ParserSymbolTable::Symbol* label = NULL; |
Token::Value tok = peek(); |
if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
@@ -2450,7 +2465,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); |
} |
@@ -2458,13 +2473,11 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
target = LookupBreakTarget(label, CHECK_OK); |
if (target == NULL) { |
// Illegal break statement. |
- const char* message = "illegal_break"; |
- Vector<Handle<String> > args; |
- if (!label.is_null()) { |
- message = "unknown_label"; |
- args = Vector<Handle<String> >(&label, 1); |
+ if (label != NULL) { |
+ ParserTraits::ReportMessage("unknown_label", label); |
+ } else { |
+ ParserTraits::ReportMessage("illegal_break"); |
} |
- ParserTraits::ReportMessageAt(scanner()->location(), message, args); |
*ok = false; |
return NULL; |
} |
@@ -2507,7 +2520,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) { |
Scope* decl_scope = scope_->DeclarationScope(); |
if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) { |
- ReportMessageAt(loc, "illegal_return"); |
+ ParserTraits::ReportMessageAt(loc, "illegal_return"); |
*ok = false; |
return NULL; |
} |
@@ -2515,7 +2528,8 @@ Statement* Parser::ParseReturnStatement(bool* ok) { |
} |
-Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
+Statement* Parser::ParseWithStatement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// WithStatement :: |
// 'with' '(' Expression ')' Statement |
@@ -2523,7 +2537,7 @@ Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
int pos = position(); |
if (strict_mode() == STRICT) { |
- ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
+ ReportMessage("strict_mode_with"); |
*ok = false; |
return NULL; |
} |
@@ -2556,8 +2570,7 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
} else { |
Expect(Token::DEFAULT, CHECK_OK); |
if (*default_seen_ptr) { |
- ReportMessage("multiple_defaults_in_switch", |
- Vector<const char*>::empty()); |
+ ReportMessage("multiple_defaults_in_switch"); |
*ok = false; |
return NULL; |
} |
@@ -2578,8 +2591,8 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
} |
-SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
- bool* ok) { |
+SwitchStatement* Parser::ParseSwitchStatement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// SwitchStatement :: |
// 'switch' '(' Expression ')' '{' CaseClause* '}' |
@@ -2613,7 +2626,7 @@ Statement* Parser::ParseThrowStatement(bool* ok) { |
Expect(Token::THROW, CHECK_OK); |
int pos = position(); |
if (scanner()->HasAnyLineTerminatorBeforeNext()) { |
- ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
+ ReportMessage("newline_after_throw"); |
*ok = false; |
return NULL; |
} |
@@ -2649,7 +2662,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
Token::Value tok = peek(); |
if (tok != Token::CATCH && tok != Token::FINALLY) { |
- ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); |
+ ReportMessage("no_catch_or_finally"); |
*ok = false; |
return NULL; |
} |
@@ -2662,7 +2675,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
Scope* catch_scope = NULL; |
Variable* catch_variable = NULL; |
Block* catch_block = NULL; |
- Handle<String> name; |
+ ParserSymbolTable::Symbol* name = NULL; |
if (tok == Token::CATCH) { |
Consume(Token::CATCH); |
@@ -2732,8 +2745,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
} |
-DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
- bool* ok) { |
+DoWhileStatement* Parser::ParseDoWhileStatement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// DoStatement :: |
// 'do' Statement 'while' '(' Expression ')' ';' |
@@ -2760,7 +2773,8 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
} |
-WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
+WhileStatement* Parser::ParseWhileStatement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// WhileStatement :: |
// 'while' '(' Expression ')' Statement |
@@ -2801,9 +2815,9 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
if (for_of != NULL) { |
Factory* heap_factory = isolate()->factory(); |
Variable* iterator = scope_->DeclarationScope()->NewTemporary( |
- heap_factory->dot_iterator_string()); |
+ symbol_table_->dot_iterator_string()); |
Variable* result = scope_->DeclarationScope()->NewTemporary( |
- heap_factory->dot_result_string()); |
+ symbol_table_->dot_result_string()); |
Expression* assign_iterator; |
Expression* next_result; |
@@ -2861,7 +2875,8 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
} |
-Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
+Statement* Parser::ParseForStatement( |
+ ZoneList<ParserSymbolTable::Symbol*>* labels, bool* ok) { |
// ForStatement :: |
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
@@ -2879,7 +2894,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
if (peek() != Token::SEMICOLON) { |
if (peek() == Token::VAR || peek() == Token::CONST) { |
bool is_const = peek() == Token::CONST; |
- Handle<String> name; |
+ ParserSymbolTable::Symbol* name = NULL; |
VariableDeclarationProperties decl_props = kHasNoInitializers; |
Block* variable_statement = |
ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
@@ -2887,7 +2902,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 = |
@@ -2915,12 +2930,12 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
init = variable_statement; |
} |
} else if (peek() == Token::LET) { |
- Handle<String> name; |
+ ParserSymbolTable::Symbol* name = NULL; |
VariableDeclarationProperties decl_props = kHasNoInitializers; |
Block* variable_statement = |
ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
CHECK_OK); |
- bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
+ bool accept_IN = name != NULL && decl_props != kHasInitializers; |
bool accept_OF = decl_props == kHasNoInitializers; |
ForEachStatement::VisitMode mode; |
@@ -2940,14 +2955,14 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
// TODO(keuchel): Move the temporary variable to the block scope, after |
// implementing stack allocated block scoped variables. |
- Factory* heap_factory = isolate()->factory(); |
- Handle<String> tempstr; |
- ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
- isolate(), tempstr, |
- heap_factory->NewConsString(heap_factory->dot_for_string(), name), |
- 0); |
- Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
- Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); |
+ // Factory* heap_factory = isolate()->factory(); |
+ // FIXME: do this somehow independent of the heap. |
+ // ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
+ // isolate(), tempstr, |
+ // heap_factory->NewConsString(heap_factory->dot_for_string(), name), |
+ // 0); |
+ Variable* temp = scope_->DeclarationScope()->NewTemporary( |
+ symbol_table_->dot_for_string()); |
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
ForEachStatement* loop = |
factory()->NewForEachStatement(mode, labels, pos); |
@@ -3078,11 +3093,9 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
} |
-void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { |
- SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); |
- const char* element[1] = { name_string.get() }; |
- ReportMessage("invalid_cached_data_function", |
- Vector<const char*>(element, 1)); |
+void Parser::ReportInvalidCachedData(ParserSymbolTable::Symbol* name, |
+ bool* ok) { |
+ ParserTraits::ReportMessage("invalid_cached_data_function", name); |
*ok = false; |
} |
@@ -3131,7 +3144,7 @@ Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
FunctionLiteral* Parser::ParseFunctionLiteral( |
- Handle<String> function_name, |
+ ParserSymbolTable::Symbol* function_name, |
Scanner::Location function_name_location, |
bool name_is_strict_reserved, |
bool is_generator, |
@@ -3147,11 +3160,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
// Anonymous functions were passed either the empty symbol or a null |
// handle as the function name. Remember if we were passed a non-empty |
// handle to decide whether to invoke function name inference. |
- bool should_infer_name = function_name.is_null(); |
+ bool should_infer_name = function_name == NULL; |
// We want a non-null handle as the function name. |
if (should_infer_name) { |
- function_name = isolate()->factory()->empty_string(); |
+ function_name = symbol_table_->empty_string(); |
} |
int num_parameters = 0; |
@@ -3215,8 +3228,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
// Calling a generator returns a generator object. That object is stored |
// in a temporary variable, a definition that is used by "yield" |
// expressions. This also marks the FunctionState as a generator. |
- Variable* temp = scope_->DeclarationScope()->NewTemporary( |
- isolate()->factory()->dot_generator_object_string()); |
+ ParserSymbolTable::Symbol* generator_name = |
+ symbol_table_->GetOneByteSymbol(Vector<const uint8_t>( |
+ reinterpret_cast<const unsigned char*>(".generator"), 10)); |
+ Variable* temp = scope_->DeclarationScope()->NewTemporary(generator_name); |
function_state.set_generator_object_variable(temp); |
} |
@@ -3235,7 +3250,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
bool done = (peek() == Token::RPAREN); |
while (!done) { |
bool is_strict_reserved = false; |
- Handle<String> param_name = |
+ ParserSymbolTable::Symbol* param_name = |
ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
// Store locations for possible future error reports. |
@@ -3253,7 +3268,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
scope_->DeclareParameter(param_name, VAR); |
num_parameters++; |
if (num_parameters > Code::kMaxArguments) { |
- ReportMessageAt(scanner()->location(), "too_many_parameters"); |
+ ReportMessage("too_many_parameters"); |
*ok = false; |
return NULL; |
} |
@@ -3273,6 +3288,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
Variable* fvar = NULL; |
Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
+ ASSERT(function_name != NULL); |
if (allow_harmony_scoping() && strict_mode() == STRICT) { |
fvar_init_op = Token::INIT_CONST; |
} |
@@ -3403,7 +3419,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
} |
-void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
+void Parser::SkipLazyFunctionBody(ParserSymbolTable::Symbol* function_name, |
int* materialized_literal_count, |
int* expected_property_count, |
bool* ok) { |
@@ -3452,14 +3468,9 @@ void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
return; |
} |
if (logger.has_error()) { |
- const char* arg = logger.argument_opt(); |
- Vector<const char*> args; |
- if (arg != NULL) { |
- args = Vector<const char*>(&arg, 1); |
- } |
ParserTraits::ReportMessageAt( |
Scanner::Location(logger.start(), logger.end()), |
- logger.message(), args, logger.is_reference_error()); |
+ logger.message(), logger.argument_opt(), logger.is_reference_error()); |
*ok = false; |
return; |
} |
@@ -3487,7 +3498,7 @@ void Parser::SkipLazyFunctionBody(Handle<String> function_name, |
ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
- Handle<String> function_name, int pos, Variable* fvar, |
+ ParserSymbolTable::Symbol* function_name, int pos, Variable* fvar, |
Token::Value fvar_init_op, bool is_generator, bool* ok) { |
// Everything inside an eagerly parsed function will be parsed eagerly |
// (see comment above). |
@@ -3510,7 +3521,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
ZoneList<Expression*>* arguments = |
new(zone()) ZoneList<Expression*>(0, zone()); |
CallRuntime* allocation = factory()->NewCallRuntime( |
- isolate()->factory()->empty_string(), |
+ symbol_table_->empty_string(), |
Runtime::FunctionForId(Runtime::kHiddenCreateJSGeneratorObject), |
arguments, pos); |
VariableProxy* init_proxy = factory()->NewVariableProxy( |
@@ -3570,6 +3581,33 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
} |
+void Parser::CheckPendingError() { |
+ if (has_pending_error_) { |
+ MessageLocation location(script_, |
+ pending_location_.beg_pos, |
+ pending_location_.end_pos); |
+ Factory* factory = isolate()->factory(); |
+ bool has_arg = pending_arg_ != NULL || pending_char_arg_ != NULL; |
+ Handle<FixedArray> elements = |
+ factory->NewFixedArray(has_arg ? 1 : 0); |
+ if (pending_arg_ != NULL) { |
+ Handle<String> arg_string = pending_arg_->string(); |
+ elements->set(0, *arg_string); |
+ } else if (pending_char_arg_ != NULL) { |
+ Handle<String> arg_string = |
+ factory->NewStringFromUtf8(CStrVector(pending_char_arg_)) |
+ .ToHandleChecked(); |
+ elements->set(0, *arg_string); |
+ } |
+ Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
+ Handle<Object> result = pending_is_reference_error_ |
+ ? factory->NewReferenceError(pending_message_, array) |
+ : factory->NewSyntaxError(pending_message_, array); |
+ isolate()->Throw(*result, &location); |
+ } |
+} |
+ |
+ |
Expression* Parser::ParseV8Intrinsic(bool* ok) { |
// CallRuntime :: |
// '%' Identifier Arguments |
@@ -3577,7 +3615,8 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { |
int pos = peek_position(); |
Expect(Token::MOD, CHECK_OK); |
// Allow "eval" or "arguments" for backward compatibility. |
- Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
+ ParserSymbolTable::Symbol* name = |
+ ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
if (extension_ != NULL) { |
@@ -3586,7 +3625,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 && |
@@ -3598,7 +3637,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { |
if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { |
return args->at(0); |
} else { |
- ReportMessage("not_isvar", Vector<const char*>::empty()); |
+ ReportMessage("not_isvar"); |
*ok = false; |
return NULL; |
} |
@@ -3608,15 +3647,14 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { |
if (function != NULL && |
function->nargs != -1 && |
function->nargs != args->length()) { |
- ReportMessage("illegal_access", Vector<const char*>::empty()); |
+ ReportMessage("illegal_access"); |
*ok = false; |
return NULL; |
} |
// Check that the function is defined if it's an inline runtime call. |
- if (function == NULL && name->Get(0) == '_') { |
- ParserTraits::ReportMessage("not_defined", |
- Vector<Handle<String> >(&name, 1)); |
+ if (function == NULL && name->literal_bytes.at(0) == '_') { |
+ ParserTraits::ReportMessage("not_defined", name); |
*ok = false; |
return NULL; |
} |
@@ -3637,15 +3675,12 @@ 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(); |
- SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
- const char* elms[1] = { c_string.get() }; |
- Vector<const char*> args(elms, 1); |
+ ParserSymbolTable::Symbol* name = decl->proxy()->raw_name(); |
int position = decl->proxy()->position(); |
Scanner::Location location = position == RelocInfo::kNoPosition |
? Scanner::Location::invalid() |
: Scanner::Location(position, position + 1); |
- ParserTraits::ReportMessageAt(location, "var_redeclaration", args); |
+ ReportMessageAt(location, "var_redeclaration", name); |
*ok = false; |
} |
} |
@@ -3655,7 +3690,7 @@ void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
// Parser support |
-bool Parser::TargetStackContainsLabel(Handle<String> label) { |
+bool Parser::TargetStackContainsLabel(ParserSymbolTable::Symbol* label) { |
for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
BreakableStatement* stat = t->node()->AsBreakableStatement(); |
if (stat != NULL && ContainsLabel(stat->labels(), label)) |
@@ -3665,8 +3700,9 @@ bool Parser::TargetStackContainsLabel(Handle<String> label) { |
} |
-BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { |
- bool anonymous = label.is_null(); |
+BreakableStatement* Parser::LookupBreakTarget(ParserSymbolTable::Symbol* label, |
+ bool* ok) { |
+ bool anonymous = label == NULL; |
for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
BreakableStatement* stat = t->node()->AsBreakableStatement(); |
if (stat == NULL) continue; |
@@ -3680,9 +3716,9 @@ BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { |
} |
-IterationStatement* Parser::LookupContinueTarget(Handle<String> label, |
- bool* ok) { |
- bool anonymous = label.is_null(); |
+IterationStatement* Parser::LookupContinueTarget( |
+ ParserSymbolTable::Symbol* label, bool* ok) { |
+ bool anonymous = label == NULL; |
for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
IterationStatement* stat = t->node()->AsIterationStatement(); |
if (stat == NULL) continue; |
@@ -4605,7 +4641,13 @@ bool RegExpParser::ParseRegExp(FlatStringReader* input, |
bool Parser::Parse() { |
ASSERT(info()->function() == NULL); |
+ ASSERT(info()->symbol_table() == NULL); |
FunctionLiteral* result = NULL; |
+ symbol_table_ = new ParserSymbolTable(); |
+ if (allow_natives_syntax() || extension_ != NULL) { |
+ symbol_table_->AlwaysInternalize(isolate()); |
+ } |
+ |
if (info()->is_lazy()) { |
ASSERT(!info()->is_eval()); |
if (info()->shared_info()->is_function()) { |
@@ -4620,20 +4662,20 @@ bool Parser::Parse() { |
ScriptData* cached_data = *(info()->cached_data()); |
Scanner::Location loc = cached_data->MessageLocation(); |
const char* message = cached_data->BuildMessage(); |
- Vector<const char*> args = cached_data->BuildArgs(); |
- ParserTraits::ReportMessageAt(loc, message, args, |
+ const char* arg = cached_data->BuildArg(); |
+ ParserTraits::ReportMessageAt(loc, message, arg, |
cached_data->IsReferenceError()); |
DeleteArray(message); |
- for (int i = 0; i < args.length(); i++) { |
- DeleteArray(args[i]); |
- } |
- DeleteArray(args.start()); |
+ DeleteArray(arg); |
ASSERT(info()->isolate()->has_pending_exception()); |
} else { |
result = ParseProgram(); |
} |
} |
info()->SetFunction(result); |
+ // info takes ownership of symbol_table_. |
+ info()->SetSymbolTable(symbol_table_); |
+ symbol_table_ = NULL; |
return (result != NULL); |
} |