Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(878)

Unified Diff: src/parser.cc

Issue 231073002: WIP: Parser: delay string internalization. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: internalizing better Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
}

Powered by Google App Engine
This is Rietveld 408576698