summaryrefslogtreecommitdiff
path: root/deps/v8/src/parser.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2011-06-29 17:26:51 +0200
committerRyan Dahl <ry@tinyclouds.org>2011-06-29 17:26:51 +0200
commit33af2720f26c2b25bc7f75ce7eb454ff99db6d35 (patch)
tree9a38f0c96420edf503eebd6325dd8d2d8249f653 /deps/v8/src/parser.cc
parent6afdca885adeeeed9eef8cbb01c3d97af0bc084d (diff)
downloadnode-new-33af2720f26c2b25bc7f75ce7eb454ff99db6d35.tar.gz
Upgrade V8 to 3.4.8
Diffstat (limited to 'deps/v8/src/parser.cc')
-rw-r--r--deps/v8/src/parser.cc1315
1 files changed, 592 insertions, 723 deletions
diff --git a/deps/v8/src/parser.cc b/deps/v8/src/parser.cc
index 6d462bc53c..4e5ba1389a 100644
--- a/deps/v8/src/parser.cc
+++ b/deps/v8/src/parser.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -28,7 +28,7 @@
#include "v8.h"
#include "api.h"
-#include "ast.h"
+#include "ast-inl.h"
#include "bootstrapper.h"
#include "codegen.h"
#include "compiler.h"
@@ -41,9 +41,6 @@
#include "scopeinfo.h"
#include "string-stream.h"
-#include "ast-inl.h"
-#include "jump-target-inl.h"
-
namespace v8 {
namespace internal {
@@ -88,12 +85,13 @@ class PositionStack {
RegExpBuilder::RegExpBuilder()
- : pending_empty_(false),
- characters_(NULL),
- terms_(),
- alternatives_()
+ : zone_(Isolate::Current()->zone()),
+ pending_empty_(false),
+ characters_(NULL),
+ terms_(),
+ alternatives_()
#ifdef DEBUG
- , last_added_(ADD_NONE)
+ , last_added_(ADD_NONE)
#endif
{}
@@ -101,7 +99,7 @@ RegExpBuilder::RegExpBuilder()
void RegExpBuilder::FlushCharacters() {
pending_empty_ = false;
if (characters_ != NULL) {
- RegExpTree* atom = new RegExpAtom(characters_->ToConstVector());
+ RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
characters_ = NULL;
text_.Add(atom);
LAST(ADD_ATOM);
@@ -117,7 +115,7 @@ void RegExpBuilder::FlushText() {
} else if (num_text == 1) {
terms_.Add(text_.last());
} else {
- RegExpText* text = new RegExpText();
+ RegExpText* text = new(zone()) RegExpText();
for (int i = 0; i < num_text; i++)
text_.Get(i)->AppendToText(text);
terms_.Add(text);
@@ -129,7 +127,7 @@ void RegExpBuilder::FlushText() {
void RegExpBuilder::AddCharacter(uc16 c) {
pending_empty_ = false;
if (characters_ == NULL) {
- characters_ = new ZoneList<uc16>(4);
+ characters_ = new(zone()) ZoneList<uc16>(4);
}
characters_->Add(c);
LAST(ADD_CHAR);
@@ -178,7 +176,7 @@ void RegExpBuilder::FlushTerms() {
} else if (num_terms == 1) {
alternative = terms_.last();
} else {
- alternative = new RegExpAlternative(terms_.GetList());
+ alternative = new(zone()) RegExpAlternative(terms_.GetList());
}
alternatives_.Add(alternative);
terms_.Clear();
@@ -195,7 +193,7 @@ RegExpTree* RegExpBuilder::ToRegExp() {
if (num_alternatives == 1) {
return alternatives_.last();
}
- return new RegExpDisjunction(alternatives_.GetList());
+ return new(zone()) RegExpDisjunction(alternatives_.GetList());
}
@@ -214,11 +212,11 @@ void RegExpBuilder::AddQuantifierToAtom(int min,
int num_chars = char_vector.length();
if (num_chars > 1) {
Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
- text_.Add(new RegExpAtom(prefix));
+ text_.Add(new(zone()) RegExpAtom(prefix));
char_vector = char_vector.SubVector(num_chars - 1, num_chars);
}
characters_ = NULL;
- atom = new RegExpAtom(char_vector);
+ atom = new(zone()) RegExpAtom(char_vector);
FlushText();
} else if (text_.length() > 0) {
ASSERT(last_added_ == ADD_ATOM);
@@ -241,98 +239,11 @@ void RegExpBuilder::AddQuantifierToAtom(int min,
UNREACHABLE();
return;
}
- terms_.Add(new RegExpQuantifier(min, max, type, atom));
+ terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom));
LAST(ADD_TERM);
}
-// A temporary scope stores information during parsing, just like
-// a plain scope. However, temporary scopes are not kept around
-// after parsing or referenced by syntax trees so they can be stack-
-// allocated and hence used by the pre-parser.
-class TemporaryScope BASE_EMBEDDED {
- public:
- explicit TemporaryScope(TemporaryScope** variable);
- ~TemporaryScope();
-
- int NextMaterializedLiteralIndex() {
- int next_index =
- materialized_literal_count_ + JSFunction::kLiteralsPrefixSize;
- materialized_literal_count_++;
- return next_index;
- }
- int materialized_literal_count() { return materialized_literal_count_; }
-
- void SetThisPropertyAssignmentInfo(
- bool only_simple_this_property_assignments,
- Handle<FixedArray> this_property_assignments) {
- only_simple_this_property_assignments_ =
- only_simple_this_property_assignments;
- this_property_assignments_ = this_property_assignments;
- }
- bool only_simple_this_property_assignments() {
- return only_simple_this_property_assignments_;
- }
- Handle<FixedArray> this_property_assignments() {
- return this_property_assignments_;
- }
-
- void AddProperty() { expected_property_count_++; }
- int expected_property_count() { return expected_property_count_; }
-
- void AddLoop() { loop_count_++; }
- bool ContainsLoops() const { return loop_count_ > 0; }
-
- bool StrictMode() { return strict_mode_; }
- void EnableStrictMode() {
- strict_mode_ = FLAG_strict_mode;
- }
-
- private:
- // Captures the number of literals that need materialization in the
- // function. Includes regexp literals, and boilerplate for object
- // and array literals.
- int materialized_literal_count_;
-
- // Properties count estimation.
- int expected_property_count_;
-
- // Keeps track of assignments to properties of this. Used for
- // optimizing constructors.
- bool only_simple_this_property_assignments_;
- Handle<FixedArray> this_property_assignments_;
-
- // Captures the number of loops inside the scope.
- int loop_count_;
-
- // Parsing strict mode code.
- bool strict_mode_;
-
- // Bookkeeping
- TemporaryScope** variable_;
- TemporaryScope* parent_;
-};
-
-
-TemporaryScope::TemporaryScope(TemporaryScope** variable)
- : materialized_literal_count_(0),
- expected_property_count_(0),
- only_simple_this_property_assignments_(false),
- this_property_assignments_(Factory::empty_fixed_array()),
- loop_count_(0),
- variable_(variable),
- parent_(*variable) {
- // Inherit the strict mode from the parent scope.
- strict_mode_ = (parent_ != NULL) && parent_->strict_mode_;
- *variable = this;
-}
-
-
-TemporaryScope::~TemporaryScope() {
- *variable_ = parent_;
-}
-
-
Handle<String> Parser::LookupSymbol(int symbol_id) {
// Length of symbol cache is the number of identified symbols.
// If we are larger than that, or negative, it's not a cached symbol.
@@ -341,9 +252,11 @@ Handle<String> Parser::LookupSymbol(int symbol_id) {
if (static_cast<unsigned>(symbol_id)
>= static_cast<unsigned>(symbol_cache_.length())) {
if (scanner().is_literal_ascii()) {
- return Factory::LookupAsciiSymbol(scanner().literal_ascii_string());
+ return isolate()->factory()->LookupAsciiSymbol(
+ scanner().literal_ascii_string());
} else {
- return Factory::LookupTwoByteSymbol(scanner().literal_uc16_string());
+ return isolate()->factory()->LookupTwoByteSymbol(
+ scanner().literal_uc16_string());
}
}
return LookupCachedSymbol(symbol_id);
@@ -360,14 +273,16 @@ Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
Handle<String> result = symbol_cache_.at(symbol_id);
if (result.is_null()) {
if (scanner().is_literal_ascii()) {
- result = Factory::LookupAsciiSymbol(scanner().literal_ascii_string());
+ result = isolate()->factory()->LookupAsciiSymbol(
+ scanner().literal_ascii_string());
} else {
- result = Factory::LookupTwoByteSymbol(scanner().literal_uc16_string());
+ result = isolate()->factory()->LookupTwoByteSymbol(
+ scanner().literal_uc16_string());
}
symbol_cache_.at(symbol_id) = result;
return result;
}
- Counters::total_preparse_symbols_skipped.Increment();
+ isolate()->counters()->total_preparse_symbols_skipped()->Increment();
return result;
}
@@ -491,7 +406,7 @@ unsigned* ScriptDataImpl::ReadAddress(int position) {
Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) {
- Scope* result = new Scope(parent, type);
+ Scope* result = new(zone()) Scope(parent, type);
result->Initialize(inside_with);
return result;
}
@@ -544,33 +459,90 @@ class TargetScope BASE_EMBEDDED {
// LexicalScope is a support class to facilitate manipulation of the
// Parser's scope stack. The constructor sets the parser's top scope
// to the incoming scope, and the destructor resets it.
+//
+// Additionally, it stores transient information used during parsing.
+// These scopes are not kept around after parsing or referenced by syntax
+// trees so they can be stack-allocated and hence used by the pre-parser.
class LexicalScope BASE_EMBEDDED {
public:
- LexicalScope(Scope** scope_variable,
- int* with_nesting_level_variable,
- Scope* scope)
- : scope_variable_(scope_variable),
- with_nesting_level_variable_(with_nesting_level_variable),
- prev_scope_(*scope_variable),
- prev_level_(*with_nesting_level_variable) {
- *scope_variable = scope;
- *with_nesting_level_variable = 0;
+ LexicalScope(Parser* parser, Scope* scope, Isolate* isolate);
+ ~LexicalScope();
+
+ int NextMaterializedLiteralIndex() {
+ int next_index =
+ materialized_literal_count_ + JSFunction::kLiteralsPrefixSize;
+ materialized_literal_count_++;
+ return next_index;
}
+ int materialized_literal_count() { return materialized_literal_count_; }
- ~LexicalScope() {
- (*scope_variable_)->Leave();
- *scope_variable_ = prev_scope_;
- *with_nesting_level_variable_ = prev_level_;
+ void SetThisPropertyAssignmentInfo(
+ bool only_simple_this_property_assignments,
+ Handle<FixedArray> this_property_assignments) {
+ only_simple_this_property_assignments_ =
+ only_simple_this_property_assignments;
+ this_property_assignments_ = this_property_assignments;
+ }
+ bool only_simple_this_property_assignments() {
+ return only_simple_this_property_assignments_;
+ }
+ Handle<FixedArray> this_property_assignments() {
+ return this_property_assignments_;
}
+ void AddProperty() { expected_property_count_++; }
+ int expected_property_count() { return expected_property_count_; }
+
private:
- Scope** scope_variable_;
- int* with_nesting_level_variable_;
- Scope* prev_scope_;
- int prev_level_;
+ // Captures the number of literals that need materialization in the
+ // function. Includes regexp literals, and boilerplate for object
+ // and array literals.
+ int materialized_literal_count_;
+
+ // Properties count estimation.
+ int expected_property_count_;
+
+ // Keeps track of assignments to properties of this. Used for
+ // optimizing constructors.
+ bool only_simple_this_property_assignments_;
+ Handle<FixedArray> this_property_assignments_;
+
+ // Bookkeeping
+ Parser* parser_;
+ // Previous values
+ LexicalScope* lexical_scope_parent_;
+ Scope* previous_scope_;
+ int previous_with_nesting_level_;
+ unsigned previous_ast_node_id_;
};
+
+LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate)
+ : materialized_literal_count_(0),
+ expected_property_count_(0),
+ only_simple_this_property_assignments_(false),
+ this_property_assignments_(isolate->factory()->empty_fixed_array()),
+ parser_(parser),
+ lexical_scope_parent_(parser->lexical_scope_),
+ previous_scope_(parser->top_scope_),
+ previous_with_nesting_level_(parser->with_nesting_level_),
+ previous_ast_node_id_(isolate->ast_node_id()) {
+ parser->top_scope_ = scope;
+ parser->lexical_scope_ = this;
+ parser->with_nesting_level_ = 0;
+ isolate->set_ast_node_id(AstNode::kFunctionEntryId + 1);
+}
+
+
+LexicalScope::~LexicalScope() {
+ parser_->top_scope_ = previous_scope_;
+ parser_->lexical_scope_ = lexical_scope_parent_;
+ parser_->with_nesting_level_ = previous_with_nesting_level_;
+ parser_->isolate()->set_ast_node_id(previous_ast_node_id_);
+}
+
+
// ----------------------------------------------------------------------------
// The CHECK_OK macro is a convenient macro to enforce error
// handling for functions that may fail (by returning !*ok).
@@ -598,12 +570,13 @@ Parser::Parser(Handle<Script> script,
bool allow_natives_syntax,
v8::Extension* extension,
ScriptDataImpl* pre_data)
- : symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
+ : isolate_(script->GetIsolate()),
+ symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
script_(script),
- scanner_(),
+ scanner_(isolate_->unicode_cache()),
top_scope_(NULL),
with_nesting_level_(0),
- temp_scope_(NULL),
+ lexical_scope_(NULL),
target_stack_(NULL),
allow_natives_syntax_(allow_natives_syntax),
extension_(extension),
@@ -618,11 +591,11 @@ Parser::Parser(Handle<Script> script,
FunctionLiteral* Parser::ParseProgram(Handle<String> source,
bool in_global_context,
StrictModeFlag strict_mode) {
- CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
+ ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
- HistogramTimerScope timer(&Counters::parse);
- Counters::total_parse_size.Increment(source->length());
- fni_ = new FuncNameInferrer();
+ HistogramTimerScope timer(isolate()->counters()->parse());
+ isolate()->counters()->total_parse_size()->Increment(source->length());
+ fni_ = new(zone()) FuncNameInferrer(isolate());
// Initialize parser state.
source->TryFlatten();
@@ -657,40 +630,37 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
in_global_context
? Scope::GLOBAL_SCOPE
: Scope::EVAL_SCOPE;
- Handle<String> no_name = Factory::empty_symbol();
+ Handle<String> no_name = isolate()->factory()->empty_symbol();
FunctionLiteral* result = NULL;
{ Scope* scope = NewScope(top_scope_, type, inside_with());
- LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
- scope);
- TemporaryScope temp_scope(&this->temp_scope_);
+ LexicalScope lexical_scope(this, scope, isolate());
if (strict_mode == kStrictMode) {
- temp_scope.EnableStrictMode();
+ top_scope_->EnableStrictMode();
}
- ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
+ ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
bool ok = true;
int beg_loc = scanner().location().beg_pos;
ParseSourceElements(body, Token::EOS, &ok);
- if (ok && temp_scope_->StrictMode()) {
+ if (ok && top_scope_->is_strict_mode()) {
CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
}
if (ok) {
- result = new FunctionLiteral(
+ result = new(zone()) FunctionLiteral(
no_name,
top_scope_,
body,
- temp_scope.materialized_literal_count(),
- temp_scope.expected_property_count(),
- temp_scope.only_simple_this_property_assignments(),
- temp_scope.this_property_assignments(),
+ lexical_scope.materialized_literal_count(),
+ lexical_scope.expected_property_count(),
+ lexical_scope.only_simple_this_property_assignments(),
+ lexical_scope.this_property_assignments(),
0,
0,
source->length(),
false,
- temp_scope.ContainsLoops(),
- temp_scope.StrictMode());
+ false);
} else if (stack_overflow_) {
- Top::StackOverflow();
+ isolate()->StackOverflow();
}
}
@@ -704,10 +674,10 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
}
FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
- CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
- HistogramTimerScope timer(&Counters::parse_lazy);
+ ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
+ HistogramTimerScope timer(isolate()->counters()->parse_lazy());
Handle<String> source(String::cast(script_->source()));
- Counters::total_parse_size.Increment(source->length());
+ isolate()->counters()->total_parse_size()->Increment(source->length());
Handle<SharedFunctionInfo> shared_info = info->shared_info();
// Initialize parser state.
@@ -737,7 +707,7 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
ASSERT(target_stack_ == NULL);
Handle<String> name(String::cast(shared_info->name()));
- fni_ = new FuncNameInferrer();
+ fni_ = new(zone()) FuncNameInferrer(isolate());
fni_->PushEnclosingName(name);
mode_ = PARSE_EAGERLY;
@@ -747,17 +717,15 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
{
// Parse the function literal.
- Handle<String> no_name = Factory::empty_symbol();
+ Handle<String> no_name = isolate()->factory()->empty_symbol();
Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
if (!info->closure().is_null()) {
scope = Scope::DeserializeScopeChain(info, scope);
}
- LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
- scope);
- TemporaryScope temp_scope(&this->temp_scope_);
+ LexicalScope lexical_scope(this, scope, isolate());
if (shared_info->strict_mode()) {
- temp_scope.EnableStrictMode();
+ top_scope_->EnableStrictMode();
}
FunctionLiteralType type =
@@ -777,7 +745,7 @@ FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
// not safe to do before scope has been deleted.
if (result == NULL) {
zone_scope->DeleteOnExit();
- if (stack_overflow_) Top::StackOverflow();
+ if (stack_overflow_) isolate()->StackOverflow();
} else {
Handle<String> inferred_name(shared_info->inferred_name());
result->set_inferred_name(inferred_name);
@@ -807,12 +775,15 @@ void Parser::ReportMessageAt(Scanner::Location source_location,
MessageLocation location(script_,
source_location.beg_pos,
source_location.end_pos);
- Handle<JSArray> array = Factory::NewJSArray(args.length());
+ Factory* factory = isolate()->factory();
+ Handle<FixedArray> elements = factory->NewFixedArray(args.length());
for (int i = 0; i < args.length(); i++) {
- SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i])));
+ Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i]));
+ elements->set(i, *arg_string);
}
- Handle<Object> result = Factory::NewSyntaxError(type, array);
- Top::Throw(*result, &location);
+ Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
+ Handle<Object> result = factory->NewSyntaxError(type, array);
+ isolate()->Throw(*result, &location);
}
@@ -822,12 +793,14 @@ void Parser::ReportMessageAt(Scanner::Location source_location,
MessageLocation location(script_,
source_location.beg_pos,
source_location.end_pos);
- Handle<JSArray> array = Factory::NewJSArray(args.length());
+ Factory* factory = isolate()->factory();
+ Handle<FixedArray> elements = factory->NewFixedArray(args.length());
for (int i = 0; i < args.length(); i++) {
- SetElement(array, i, args[i]);
+ elements->set(i, *args[i]);
}
- Handle<Object> result = Factory::NewSyntaxError(type, array);
- Top::Throw(*result, &location);
+ Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
+ Handle<Object> result = factory->NewSyntaxError(type, array);
+ isolate()->Throw(*result, &location);
}
@@ -952,8 +925,9 @@ class InitializationBlockFinder : public ParserFinder {
// function contains only assignments of this type.
class ThisNamedPropertyAssigmentFinder : public ParserFinder {
public:
- ThisNamedPropertyAssigmentFinder()
- : only_simple_this_property_assignments_(true),
+ explicit ThisNamedPropertyAssigmentFinder(Isolate* isolate)
+ : isolate_(isolate),
+ only_simple_this_property_assignments_(true),
names_(NULL),
assigned_arguments_(NULL),
assigned_constants_(NULL) {}
@@ -984,14 +958,14 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
// form this.x = y;
Handle<FixedArray> GetThisPropertyAssignments() {
if (names_ == NULL) {
- return Factory::empty_fixed_array();
+ return isolate_->factory()->empty_fixed_array();
}
ASSERT(names_ != NULL);
ASSERT(assigned_arguments_ != NULL);
ASSERT_EQ(names_->length(), assigned_arguments_->length());
ASSERT_EQ(names_->length(), assigned_constants_->length());
Handle<FixedArray> assignments =
- Factory::NewFixedArray(names_->length() * 3);
+ isolate_->factory()->NewFixedArray(names_->length() * 3);
for (int i = 0; i < names_->length(); i++) {
assignments->set(i * 3, *names_->at(i));
assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i)));
@@ -1021,7 +995,8 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
uint32_t dummy;
if (literal != NULL &&
literal->handle()->IsString() &&
- !String::cast(*(literal->handle()))->Equals(Heap::Proto_symbol()) &&
+ !String::cast(*(literal->handle()))->Equals(
+ isolate_->heap()->Proto_symbol()) &&
!String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) {
Handle<String> key = Handle<String>::cast(literal->handle());
@@ -1055,7 +1030,7 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
EnsureAllocation();
names_->Add(name);
assigned_arguments_->Add(index);
- assigned_constants_->Add(Factory::undefined_value());
+ assigned_constants_->Add(isolate_->factory()->undefined_value());
}
void AssignmentFromConstant(Handle<String> name, Handle<Object> value) {
@@ -1074,12 +1049,14 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
if (names_ == NULL) {
ASSERT(assigned_arguments_ == NULL);
ASSERT(assigned_constants_ == NULL);
- names_ = new ZoneStringList(4);
- assigned_arguments_ = new ZoneList<int>(4);
- assigned_constants_ = new ZoneObjectList(4);
+ Zone* zone = isolate_->zone();
+ names_ = new(zone) ZoneStringList(4);
+ assigned_arguments_ = new(zone) ZoneList<int>(4);
+ assigned_constants_ = new(zone) ZoneObjectList(4);
}
}
+ Isolate* isolate_;
bool only_simple_this_property_assignments_;
ZoneStringList* names_;
ZoneList<int>* assigned_arguments_;
@@ -1101,7 +1078,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
ASSERT(processor != NULL);
InitializationBlockFinder block_finder;
- ThisNamedPropertyAssigmentFinder this_property_assignment_finder;
+ ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate());
bool directive_prologue = true; // Parsing directive prologue.
while (peek() != end_token) {
@@ -1141,11 +1118,11 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
Handle<String> directive = Handle<String>::cast(literal->handle());
// Check "use strict" directive (ES5 14.1).
- if (!temp_scope_->StrictMode() &&
- directive->Equals(Heap::use_strict()) &&
+ if (!top_scope_->is_strict_mode() &&
+ directive->Equals(isolate()->heap()->use_strict()) &&
token_loc.end_pos - token_loc.beg_pos ==
- Heap::use_strict()->length() + 2) {
- temp_scope_->EnableStrictMode();
+ isolate()->heap()->use_strict()->length() + 2) {
+ top_scope_->EnableStrictMode();
// "use strict" is the only directive for now.
directive_prologue = false;
}
@@ -1174,7 +1151,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
this_property_assignment_finder.only_simple_this_property_assignments()
&& top_scope_->declarations()->length() == 0;
if (only_simple_this_property_assignments) {
- temp_scope_->SetThisPropertyAssignmentInfo(
+ lexical_scope_->SetThisPropertyAssignmentInfo(
only_simple_this_property_assignments,
this_property_assignment_finder.GetThisPropertyAssignments());
}
@@ -1270,7 +1247,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
// one must take great care not to treat it as a
// fall-through. It is much easier just to wrap the entire
// try-statement in a statement block and put the labels there
- Block* result = new Block(labels, 1, false);
+ Block* result = new(zone()) Block(labels, 1, false);
Target target(&this->target_stack_, result);
TryStatement* statement = ParseTryStatement(CHECK_OK);
if (statement) {
@@ -1283,7 +1260,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
case Token::FUNCTION: {
// In strict mode, FunctionDeclaration is only allowed in the context
// of SourceElements.
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
ReportMessageAt(scanner().peek_location(), "strict_function",
Vector<const char*>::empty());
*ok = false;
@@ -1292,9 +1269,6 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
return ParseFunctionDeclaration(ok);
}
- case Token::NATIVE:
- return ParseNativeDeclaration(ok);
-
case Token::DEBUGGER:
stmt = ParseDebuggerStatement(ok);
break;
@@ -1325,7 +1299,10 @@ VariableProxy* Parser::Declare(Handle<String> name,
// to the corresponding activation frame at runtime if necessary.
// For instance declarations inside an eval scope need to be added
// to the calling function context.
- if (top_scope_->is_function_scope()) {
+ // Similarly, strict mode eval scope does not leak variable declarations to
+ // the caller's scope so we declare all locals, too.
+ if (top_scope_->is_function_scope() ||
+ top_scope_->is_strict_mode_eval_scope()) {
// Declare the variable in the function scope.
var = top_scope_->LocalLookup(name);
if (var == NULL) {
@@ -1342,9 +1319,9 @@ VariableProxy* Parser::Declare(Handle<String> name,
var->mode() == Variable::CONST);
const char* type = (var->mode() == Variable::VAR) ? "var" : "const";
Handle<String> type_string =
- Factory::NewStringFromUtf8(CStrVector(type), TENURED);
+ isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED);
Expression* expression =
- NewThrowTypeError(Factory::redeclaration_symbol(),
+ NewThrowTypeError(isolate()->factory()->redeclaration_symbol(),
type_string, name);
top_scope_->SetIllegalRedeclaration(expression);
}
@@ -1368,13 +1345,13 @@ VariableProxy* Parser::Declare(Handle<String> name,
// a performance issue since it may lead to repeated
// Runtime::DeclareContextSlot() calls.
VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with());
- top_scope_->AddDeclaration(new Declaration(proxy, mode, fun));
+ top_scope_->AddDeclaration(new(zone()) Declaration(proxy, mode, fun));
// For global const variables we bind the proxy to a variable.
if (mode == Variable::CONST && top_scope_->is_global_scope()) {
ASSERT(resolve); // should be set by all callers
Variable::Kind kind = Variable::NORMAL;
- var = new Variable(top_scope_, name, Variable::CONST, true, kind);
+ var = new(zone()) Variable(top_scope_, name, Variable::CONST, true, kind);
}
// If requested and we have a local variable, bind the proxy to the variable
@@ -1412,13 +1389,6 @@ VariableProxy* Parser::Declare(Handle<String> name,
// declaration is resolved by looking up the function through a
// callback provided by the extension.
Statement* Parser::ParseNativeDeclaration(bool* ok) {
- if (extension_ == NULL) {
- ReportUnexpectedToken(Token::NATIVE);
- *ok = false;
- return NULL;
- }
-
- Expect(Token::NATIVE, CHECK_OK);
Expect(Token::FUNCTION, CHECK_OK);
Handle<String> name = ParseIdentifier(CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
@@ -1450,7 +1420,7 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
Handle<Code> code = Handle<Code>(fun->shared()->code());
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
Handle<SharedFunctionInfo> shared =
- Factory::NewSharedFunctionInfo(name, literals, code,
+ isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
Handle<SerializedScopeInfo>(fun->shared()->scope_info()));
shared->set_construct_stub(*construct_stub);
@@ -1462,10 +1432,11 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
// TODO(1240846): It's weird that native function declarations are
// introduced dynamically when we meet their declarations, whereas
// other functions are setup when entering the surrounding scope.
- SharedFunctionInfoLiteral* lit = new SharedFunctionInfoLiteral(shared);
+ SharedFunctionInfoLiteral* lit =
+ new(zone()) SharedFunctionInfoLiteral(shared);
VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
- return new ExpressionStatement(
- new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
+ return new(zone()) ExpressionStatement(new(zone()) Assignment(
+ Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
}
@@ -1474,10 +1445,11 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) {
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
- bool is_reserved = false;
- Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
+ bool is_strict_reserved = false;
+ Handle<String> name = ParseIdentifierOrStrictReservedWord(
+ &is_strict_reserved, CHECK_OK);
FunctionLiteral* fun = ParseFunctionLiteral(name,
- is_reserved,
+ is_strict_reserved,
function_token_position,
DECLARATION,
CHECK_OK);
@@ -1497,7 +1469,7 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
// (ECMA-262, 3rd, 12.2)
//
// Construct block expecting 16 statements.
- Block* result = new Block(labels, 16, false);
+ Block* result = new(zone()) Block(labels, 16, false);
Target target(&this->target_stack_, result);
Expect(Token::LBRACE, CHECK_OK);
while (peek() != Token::RBRACE) {
@@ -1519,11 +1491,13 @@ Block* Parser::ParseVariableStatement(bool* ok) {
return result;
}
-static bool IsEvalOrArguments(Handle<String> string) {
- return string.is_identical_to(Factory::eval_symbol()) ||
- string.is_identical_to(Factory::arguments_symbol());
+
+bool Parser::IsEvalOrArguments(Handle<String> string) {
+ return string.is_identical_to(isolate()->factory()->eval_symbol()) ||
+ string.is_identical_to(isolate()->factory()->arguments_symbol());
}
+
// If the variable declaration declares exactly one non-const
// variable, then *var is set to that variable. In all other cases,
// *var is untouched; in particular, it is the caller's responsibility
@@ -1541,7 +1515,7 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
Consume(Token::VAR);
} else if (peek() == Token::CONST) {
Consume(Token::CONST);
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
ReportMessage("strict_const", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -1565,7 +1539,7 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
// is inside an initializer block, it is ignored.
//
// Create new block with one expected declaration.
- Block* block = new Block(NULL, 1, true);
+ Block* block = new(zone()) Block(NULL, 1, true);
VariableProxy* last_var = NULL; // the last variable declared
int nvars = 0; // the number of variables declared
do {
@@ -1577,7 +1551,7 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
if (fni_ != NULL) fni_->PushVariableName(name);
// Strict mode variables may not be named eval or arguments
- if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
+ if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
ReportMessage("strict_var_name", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -1599,6 +1573,12 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
is_const /* always bound for CONST! */,
CHECK_OK);
nvars++;
+ if (top_scope_->num_var_or_const() > kMaxNumFunctionLocals) {
+ ReportMessageAt(scanner().location(), "too_many_variables",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
// Parse initialization expression if present and/or needed. A
// declaration of the form:
@@ -1634,7 +1614,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
position = scanner().location().beg_pos;
value = ParseAssignmentExpression(accept_IN, CHECK_OK);
// Don't infer if it is "a = function(){...}();"-like expression.
- if (fni_ != NULL && value->AsCall() == NULL) fni_->Infer();
+ if (fni_ != NULL &&
+ value->AsCall() == NULL &&
+ value->AsCallNew() == NULL) {
+ fni_->Infer();
+ }
}
// Make sure that 'const c' actually initializes 'c' to undefined
@@ -1665,8 +1649,9 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
if (top_scope_->is_global_scope()) {
// Compute the arguments for the runtime call.
- ZoneList<Expression*>* arguments = new ZoneList<Expression*>(3);
- arguments->Add(new Literal(name)); // we have at least 1 parameter
+ ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3);
+ // We have at least 1 parameter.
+ arguments->Add(new(zone()) Literal(name));
CallRuntime* initialize;
if (is_const) {
@@ -1678,15 +1663,15 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
// Note that the function does different things depending on
// the number of arguments (1 or 2).
initialize =
- new CallRuntime(
- Factory::InitializeConstGlobal_symbol(),
+ new(zone()) CallRuntime(
+ isolate()->factory()->InitializeConstGlobal_symbol(),
Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
arguments);
} else {
// Add strict mode.
// We may want to pass singleton to avoid Literal allocations.
arguments->Add(NewNumberLiteral(
- temp_scope_->StrictMode() ? kStrictMode : kNonStrictMode));
+ top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode));
// Be careful not to assign a value to the global variable if
// we're in a with. The initialization value should not
@@ -1702,13 +1687,13 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
// Note that the function does different things depending on
// the number of arguments (2 or 3).
initialize =
- new CallRuntime(
- Factory::InitializeVarGlobal_symbol(),
+ new(zone()) CallRuntime(
+ isolate()->factory()->InitializeVarGlobal_symbol(),
Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
arguments);
}
- block->AddStatement(new ExpressionStatement(initialize));
+ block->AddStatement(new(zone()) ExpressionStatement(initialize));
}
// Add an assignment node to the initialization statement block if
@@ -1723,8 +1708,11 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
// the top context for variables). Sigh...
if (value != NULL) {
Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR);
- Assignment* assignment = new Assignment(op, last_var, value, position);
- if (block) block->AddStatement(new ExpressionStatement(assignment));
+ Assignment* assignment =
+ new(zone()) Assignment(op, last_var, value, position);
+ if (block) {
+ block->AddStatement(new(zone()) ExpressionStatement(assignment));
+ }
}
if (fni_ != NULL) fni_->Leave();
@@ -1758,7 +1746,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
// Identifier ':' Statement
bool starts_with_idenfifier = peek_any_identifier();
Expression* expr = ParseExpression(true, CHECK_OK);
- if (peek() == Token::COLON && starts_with_idenfifier && expr &&
+ if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
expr->AsVariableProxy() != NULL &&
!expr->AsVariableProxy()->is_this()) {
// Expression is a single identifier, and not, e.g., a parenthesized
@@ -1778,7 +1766,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
*ok = false;
return NULL;
}
- if (labels == NULL) labels = new ZoneStringList(4);
+ if (labels == NULL) labels = new(zone()) ZoneStringList(4);
labels->Add(label);
// Remove the "ghost" variable that turned out to be a label
// from the top scope. This way, we don't try to resolve it
@@ -1788,9 +1776,23 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
return ParseStatement(labels, ok);
}
+ // If we have an extension, we allow a native function declaration.
+ // A native function declaration starts with "native function" with
+ // no line-terminator between the two words.
+ if (extension_ != NULL &&
+ peek() == Token::FUNCTION &&
+ !scanner().HasAnyLineTerminatorBeforeNext() &&
+ expr != NULL &&
+ expr->AsVariableProxy() != NULL &&
+ expr->AsVariableProxy()->name()->Equals(
+ isolate()->heap()->native_symbol()) &&
+ !scanner().literal_contains_escapes()) {
+ return ParseNativeDeclaration(ok);
+ }
+
// Parsed expression statement.
ExpectSemicolon(CHECK_OK);
- return new ExpressionStatement(expr);
+ return new(zone()) ExpressionStatement(expr);
}
@@ -1810,7 +1812,7 @@ IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
} else {
else_statement = EmptyStatement();
}
- return new IfStatement(condition, then_statement, else_statement);
+ return new(zone()) IfStatement(condition, then_statement, else_statement);
}
@@ -1821,7 +1823,7 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
Expect(Token::CONTINUE, CHECK_OK);
Handle<String> label = Handle<String>::null();
Token::Value tok = peek();
- if (!scanner().has_line_terminator_before_next() &&
+ if (!scanner().HasAnyLineTerminatorBeforeNext() &&
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
label = ParseIdentifier(CHECK_OK);
}
@@ -1840,7 +1842,7 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
return NULL;
}
ExpectSemicolon(CHECK_OK);
- return new ContinueStatement(target);
+ return new(zone()) ContinueStatement(target);
}
@@ -1851,7 +1853,7 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
Expect(Token::BREAK, CHECK_OK);
Handle<String> label;
Token::Value tok = peek();
- if (!scanner().has_line_terminator_before_next() &&
+ if (!scanner().HasAnyLineTerminatorBeforeNext() &&
tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
label = ParseIdentifier(CHECK_OK);
}
@@ -1875,7 +1877,7 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
return NULL;
}
ExpectSemicolon(CHECK_OK);
- return new BreakStatement(target);
+ return new(zone()) BreakStatement(target);
}
@@ -1894,33 +1896,29 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
//
// To be consistent with KJS we report the syntax error at runtime.
if (!top_scope_->is_function_scope()) {
- Handle<String> type = Factory::illegal_return_symbol();
+ Handle<String> type = isolate()->factory()->illegal_return_symbol();
Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
- return new ExpressionStatement(throw_error);
+ return new(zone()) ExpressionStatement(throw_error);
}
Token::Value tok = peek();
- if (scanner().has_line_terminator_before_next() ||
+ if (scanner().HasAnyLineTerminatorBeforeNext() ||
tok == Token::SEMICOLON ||
tok == Token::RBRACE ||
tok == Token::EOS) {
ExpectSemicolon(CHECK_OK);
- return new ReturnStatement(GetLiteralUndefined());
+ return new(zone()) ReturnStatement(GetLiteralUndefined());
}
Expression* expr = ParseExpression(true, CHECK_OK);
ExpectSemicolon(CHECK_OK);
- return new ReturnStatement(expr);
+ return new(zone()) ReturnStatement(expr);
}
-Block* Parser::WithHelper(Expression* obj,
- ZoneStringList* labels,
- bool is_catch_block,
- bool* ok) {
+Block* Parser::WithHelper(Expression* obj, ZoneStringList* labels, bool* ok) {
// Parse the statement and collect escaping labels.
- ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0);
- TargetCollector collector(target_list);
+ TargetCollector collector;
Statement* stat;
{ Target target(&this->target_stack_, &collector);
with_nesting_level_++;
@@ -1931,21 +1929,21 @@ Block* Parser::WithHelper(Expression* obj,
// Create resulting block with two statements.
// 1: Evaluate the with expression.
// 2: The try-finally block evaluating the body.
- Block* result = new Block(NULL, 2, false);
+ Block* result = new(zone()) Block(NULL, 2, false);
if (result != NULL) {
- result->AddStatement(new WithEnterStatement(obj, is_catch_block));
+ result->AddStatement(new(zone()) EnterWithContextStatement(obj));
// Create body block.
- Block* body = new Block(NULL, 1, false);
+ Block* body = new(zone()) Block(NULL, 1, false);
body->AddStatement(stat);
// Create exit block.
- Block* exit = new Block(NULL, 1, false);
- exit->AddStatement(new WithExitStatement());
+ Block* exit = new(zone()) Block(NULL, 1, false);
+ exit->AddStatement(new(zone()) ExitContextStatement());
// Return a try-finally statement.
- TryFinallyStatement* wrapper = new TryFinallyStatement(body, exit);
+ TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body, exit);
wrapper->set_escaping_targets(collector.targets());
result->AddStatement(wrapper);
}
@@ -1959,7 +1957,7 @@ Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
Expect(Token::WITH, CHECK_OK);
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
ReportMessage("strict_mode_with", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -1969,7 +1967,7 @@ Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
Expression* expr = ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
- return WithHelper(expr, labels, false, CHECK_OK);
+ return WithHelper(expr, labels, CHECK_OK);
}
@@ -1994,7 +1992,7 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
}
Expect(Token::COLON, CHECK_OK);
int pos = scanner().location().beg_pos;
- ZoneList<Statement*>* statements = new ZoneList<Statement*>(5);
+ ZoneList<Statement*>* statements = new(zone()) ZoneList<Statement*>(5);
while (peek() != Token::CASE &&
peek() != Token::DEFAULT &&
peek() != Token::RBRACE) {
@@ -2002,7 +2000,7 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
statements->Add(stat);
}
- return new CaseClause(label, statements, pos);
+ return new(zone()) CaseClause(label, statements, pos);
}
@@ -2011,7 +2009,7 @@ SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
// SwitchStatement ::
// 'switch' '(' Expression ')' '{' CaseClause* '}'
- SwitchStatement* statement = new SwitchStatement(labels);
+ SwitchStatement* statement = new(zone()) SwitchStatement(labels);
Target target(&this->target_stack_, statement);
Expect(Token::SWITCH, CHECK_OK);
@@ -2020,7 +2018,7 @@ SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
Expect(Token::RPAREN, CHECK_OK);
bool default_seen = false;
- ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4);
+ ZoneList<CaseClause*>* cases = new(zone()) ZoneList<CaseClause*>(4);
Expect(Token::LBRACE, CHECK_OK);
while (peek() != Token::RBRACE) {
CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
@@ -2039,7 +2037,7 @@ Statement* Parser::ParseThrowStatement(bool* ok) {
Expect(Token::THROW, CHECK_OK);
int pos = scanner().location().beg_pos;
- if (scanner().has_line_terminator_before_next()) {
+ if (scanner().HasAnyLineTerminatorBeforeNext()) {
ReportMessage("newline_after_throw", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -2047,7 +2045,7 @@ Statement* Parser::ParseThrowStatement(bool* ok) {
Expression* exception = ParseExpression(true, CHECK_OK);
ExpectSemicolon(CHECK_OK);
- return new ExpressionStatement(new Throw(exception, pos));
+ return new(zone()) ExpressionStatement(new(zone()) Throw(exception, pos));
}
@@ -2065,18 +2063,13 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
Expect(Token::TRY, CHECK_OK);
- ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0);
- TargetCollector collector(target_list);
+ TargetCollector try_collector;
Block* try_block;
- { Target target(&this->target_stack_, &collector);
+ { Target target(&this->target_stack_, &try_collector);
try_block = ParseBlock(NULL, CHECK_OK);
}
- Block* catch_block = NULL;
- Variable* catch_var = NULL;
- Block* finally_block = NULL;
-
Token::Value tok = peek();
if (tok != Token::CATCH && tok != Token::FINALLY) {
ReportMessage("no_catch_or_finally", Vector<const char*>::empty());
@@ -2085,20 +2078,19 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
}
// If we can break out from the catch block and there is a finally block,
- // then we will need to collect jump targets from the catch block. Since
- // we don't know yet if there will be a finally block, we always collect
- // the jump targets.
- ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0);
- TargetCollector catch_collector(catch_target_list);
- bool has_catch = false;
+ // then we will need to collect escaping targets from the catch
+ // block. Since we don't know yet if there will be a finally block, we
+ // always collect the targets.
+ TargetCollector catch_collector;
+ Block* catch_block = NULL;
+ Handle<String> name;
if (tok == Token::CATCH) {
- has_catch = true;
Consume(Token::CATCH);
Expect(Token::LPAREN, CHECK_OK);
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ name = ParseIdentifier(CHECK_OK);
- if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
+ if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
ReportMessage("strict_catch_variable", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -2107,15 +2099,33 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
Expect(Token::RPAREN, CHECK_OK);
if (peek() == Token::LBRACE) {
- // Allocate a temporary for holding the finally state while
- // executing the finally block.
- catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol());
- Literal* name_literal = new Literal(name);
- VariableProxy* catch_var_use = new VariableProxy(catch_var);
- Expression* obj = new CatchExtensionObject(name_literal, catch_var_use);
+ // Rewrite the catch body B to a single statement block
+ // { try B finally { PopContext }}.
+ Block* inner_body;
+ // We need to collect escapes from the body for both the inner
+ // try/finally used to pop the catch context and any possible outer
+ // try/finally.
+ TargetCollector inner_collector;
{ Target target(&this->target_stack_, &catch_collector);
- catch_block = WithHelper(obj, NULL, true, CHECK_OK);
+ { Target target(&this->target_stack_, &inner_collector);
+ ++with_nesting_level_;
+ top_scope_->RecordWithStatement();
+ inner_body = ParseBlock(NULL, CHECK_OK);
+ --with_nesting_level_;
+ }
}
+
+ // Create exit block.
+ Block* inner_finally = new(zone()) Block(NULL, 1, false);
+ inner_finally->AddStatement(new(zone()) ExitContextStatement());
+
+ // Create a try/finally statement.
+ TryFinallyStatement* inner_try_finally =
+ new(zone()) TryFinallyStatement(inner_body, inner_finally);
+ inner_try_finally->set_escaping_targets(inner_collector.targets());
+
+ catch_block = new(zone()) Block(NULL, 1, false);
+ catch_block->AddStatement(inner_try_finally);
} else {
Expect(Token::LBRACE, CHECK_OK);
}
@@ -2123,24 +2133,22 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
tok = peek();
}
- if (tok == Token::FINALLY || !has_catch) {
+ Block* finally_block = NULL;
+ if (tok == Token::FINALLY || catch_block == NULL) {
Consume(Token::FINALLY);
- // Declare a variable for holding the finally state while
- // executing the finally block.
finally_block = ParseBlock(NULL, CHECK_OK);
}
// Simplify the AST nodes by converting:
- // 'try { } catch { } finally { }'
+ // 'try B0 catch B1 finally B2'
// to:
- // 'try { try { } catch { } } finally { }'
+ // 'try { try B0 catch B1 } finally B2'
if (catch_block != NULL && finally_block != NULL) {
- VariableProxy* catch_var_defn = new VariableProxy(catch_var);
TryCatchStatement* statement =
- new TryCatchStatement(try_block, catch_var_defn, catch_block);
- statement->set_escaping_targets(collector.targets());
- try_block = new Block(NULL, 1, false);
+ new(zone()) TryCatchStatement(try_block, name, catch_block);
+ statement->set_escaping_targets(try_collector.targets());
+ try_block = new(zone()) Block(NULL, 1, false);
try_block->AddStatement(statement);
catch_block = NULL;
}
@@ -2148,19 +2156,16 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
TryStatement* result = NULL;
if (catch_block != NULL) {
ASSERT(finally_block == NULL);
- VariableProxy* catch_var_defn = new VariableProxy(catch_var);
- result = new TryCatchStatement(try_block, catch_var_defn, catch_block);
- result->set_escaping_targets(collector.targets());
+ result =
+ new(zone()) TryCatchStatement(try_block, name, catch_block);
} else {
ASSERT(finally_block != NULL);
- result = new TryFinallyStatement(try_block, finally_block);
- // Add the jump targets of the try block and the catch block.
- for (int i = 0; i < collector.targets()->length(); i++) {
- catch_collector.AddTarget(collector.targets()->at(i));
- }
- result->set_escaping_targets(catch_collector.targets());
+ result = new(zone()) TryFinallyStatement(try_block, finally_block);
+ // Combine the jump targets of the try block and the possible catch block.
+ try_collector.targets()->AddAll(*catch_collector.targets());
}
+ result->set_escaping_targets(try_collector.targets());
return result;
}
@@ -2170,8 +2175,7 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
// DoStatement ::
// 'do' Statement 'while' '(' Expression ')' ';'
- temp_scope_->AddLoop();
- DoWhileStatement* loop = new DoWhileStatement(labels);
+ DoWhileStatement* loop = new(zone()) DoWhileStatement(labels);
Target target(&this->target_stack_, loop);
Expect(Token::DO, CHECK_OK);
@@ -2185,7 +2189,6 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
}
Expression* cond = ParseExpression(true, CHECK_OK);
- if (cond != NULL) cond->set_is_loop_condition(true);
Expect(Token::RPAREN, CHECK_OK);
// Allow do-statements to be terminated with and without
@@ -2203,14 +2206,12 @@ WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
// WhileStatement ::
// 'while' '(' Expression ')' Statement
- temp_scope_->AddLoop();
- WhileStatement* loop = new WhileStatement(labels);
+ WhileStatement* loop = new(zone()) WhileStatement(labels);
Target target(&this->target_stack_, loop);
Expect(Token::WHILE, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
Expression* cond = ParseExpression(true, CHECK_OK);
- if (cond != NULL) cond->set_is_loop_condition(true);
Expect(Token::RPAREN, CHECK_OK);
Statement* body = ParseStatement(NULL, CHECK_OK);
@@ -2223,7 +2224,6 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
// ForStatement ::
// 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
- temp_scope_->AddLoop();
Statement* init = NULL;
Expect(Token::FOR, CHECK_OK);
@@ -2234,7 +2234,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Block* variable_statement =
ParseVariableDeclarations(false, &each, CHECK_OK);
if (peek() == Token::IN && each != NULL) {
- ForInStatement* loop = new ForInStatement(labels);
+ ForInStatement* loop = new(zone()) ForInStatement(labels);
Target target(&this->target_stack_, loop);
Expect(Token::IN, CHECK_OK);
@@ -2243,7 +2243,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Statement* body = ParseStatement(NULL, CHECK_OK);
loop->Initialize(each, enumerable, body);
- Block* result = new Block(NULL, 2, false);
+ Block* result = new(zone()) Block(NULL, 2, false);
result->AddStatement(variable_statement);
result->AddStatement(loop);
// Parsed for-in loop w/ variable/const declaration.
@@ -2260,10 +2260,11 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
// error here but for compatibility with JSC we choose to report
// the error at runtime.
if (expression == NULL || !expression->IsValidLeftHandSide()) {
- Handle<String> type = Factory::invalid_lhs_in_for_in_symbol();
+ Handle<String> type =
+ isolate()->factory()->invalid_lhs_in_for_in_symbol();
expression = NewThrowReferenceError(type);
}
- ForInStatement* loop = new ForInStatement(labels);
+ ForInStatement* loop = new(zone()) ForInStatement(labels);
Target target(&this->target_stack_, loop);
Expect(Token::IN, CHECK_OK);
@@ -2276,13 +2277,13 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
return loop;
} else {
- init = new ExpressionStatement(expression);
+ init = new(zone()) ExpressionStatement(expression);
}
}
}
// Standard 'for' loop
- ForStatement* loop = new ForStatement(labels);
+ ForStatement* loop = new(zone()) ForStatement(labels);
Target target(&this->target_stack_, loop);
// Parsed initializer at this point.
@@ -2291,14 +2292,13 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Expression* cond = NULL;
if (peek() != Token::SEMICOLON) {
cond = ParseExpression(true, CHECK_OK);
- if (cond != NULL) cond->set_is_loop_condition(true);
}
Expect(Token::SEMICOLON, CHECK_OK);
Statement* next = NULL;
if (peek() != Token::RPAREN) {
Expression* exp = ParseExpression(true, CHECK_OK);
- next = new ExpressionStatement(exp);
+ next = new(zone()) ExpressionStatement(exp);
}
Expect(Token::RPAREN, CHECK_OK);
@@ -2319,7 +2319,7 @@ Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
Expect(Token::COMMA, CHECK_OK);
int position = scanner().location().beg_pos;
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
- result = new BinaryOperation(Token::COMMA, result, right, position);
+ result = new(zone()) BinaryOperation(Token::COMMA, result, right, position);
}
return result;
}
@@ -2345,11 +2345,12 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
// for compatibility with JSC we choose to report the error at
// runtime.
if (expression == NULL || !expression->IsValidLeftHandSide()) {
- Handle<String> type = Factory::invalid_lhs_in_assignment_symbol();
+ Handle<String> type =
+ isolate()->factory()->invalid_lhs_in_assignment_symbol();
expression = NewThrowReferenceError(type);
}
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
// Assignment to eval or arguments is disallowed in strict mode.
CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
}
@@ -2368,7 +2369,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
property != NULL &&
property->obj()->AsVariableProxy() != NULL &&
property->obj()->AsVariableProxy()->is_this()) {
- temp_scope_->AddProperty();
+ lexical_scope_->AddProperty();
}
// If we assign a function literal to a property we pretenure the
@@ -2384,13 +2385,13 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
if ((op == Token::INIT_VAR
|| op == Token::INIT_CONST
|| op == Token::ASSIGN)
- && (right->AsCall() == NULL)) {
+ && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
fni_->Infer();
}
fni_->Leave();
}
- return new Assignment(op, expression, right, pos);
+ return new(zone()) Assignment(op, expression, right, pos);
}
@@ -2412,7 +2413,7 @@ Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
Expect(Token::COLON, CHECK_OK);
int right_position = scanner().peek_location().beg_pos;
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
- return new Conditional(expression, left, right,
+ return new(zone()) Conditional(expression, left, right,
left_position, right_position);
}
@@ -2500,12 +2501,12 @@ Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
x = NewCompareNode(cmp, x, y, position);
if (cmp != op) {
// The comparison was negated - add a NOT.
- x = new UnaryOperation(Token::NOT, x);
+ x = new(zone()) UnaryOperation(Token::NOT, x, position);
}
} else {
// We have a "normal" binary operation.
- x = new BinaryOperation(op, x, y, position);
+ x = new(zone()) BinaryOperation(op, x, y, position);
}
}
}
@@ -2522,15 +2523,15 @@ Expression* Parser::NewCompareNode(Token::Value op,
bool is_strict = (op == Token::EQ_STRICT);
Literal* x_literal = x->AsLiteral();
if (x_literal != NULL && x_literal->IsNull()) {
- return new CompareToNull(is_strict, y);
+ return new(zone()) CompareToNull(is_strict, y);
}
Literal* y_literal = y->AsLiteral();
if (y_literal != NULL && y_literal->IsNull()) {
- return new CompareToNull(is_strict, x);
+ return new(zone()) CompareToNull(is_strict, x);
}
}
- return new CompareOperation(op, x, y, position);
+ return new(zone()) CompareOperation(op, x, y, position);
}
@@ -2550,25 +2551,34 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
Token::Value op = peek();
if (Token::IsUnaryOp(op)) {
op = Next();
+ int position = scanner().location().beg_pos;
Expression* expression = ParseUnaryExpression(CHECK_OK);
- // Compute some expressions involving only number literals.
- if (expression != NULL && expression->AsLiteral() &&
- expression->AsLiteral()->handle()->IsNumber()) {
- double value = expression->AsLiteral()->handle()->Number();
- switch (op) {
- case Token::ADD:
- return expression;
- case Token::SUB:
- return NewNumberLiteral(-value);
- case Token::BIT_NOT:
- return NewNumberLiteral(~DoubleToInt32(value));
- default: break;
+ if (expression != NULL && (expression->AsLiteral() != NULL)) {
+ Handle<Object> literal = expression->AsLiteral()->handle();
+ if (op == Token::NOT) {
+ // Convert the literal to a boolean condition and negate it.
+ bool condition = literal->ToBoolean()->IsTrue();
+ Handle<Object> result(isolate()->heap()->ToBoolean(!condition));
+ return new(zone()) Literal(result);
+ } else if (literal->IsNumber()) {
+ // Compute some expressions involving only number literals.
+ double value = literal->Number();
+ switch (op) {
+ case Token::ADD:
+ return expression;
+ case Token::SUB:
+ return NewNumberLiteral(-value);
+ case Token::BIT_NOT:
+ return NewNumberLiteral(~DoubleToInt32(value));
+ default:
+ break;
+ }
}
}
// "delete identifier" is a syntax error in strict mode.
- if (op == Token::DELETE && temp_scope_->StrictMode()) {
+ if (op == Token::DELETE && top_scope_->is_strict_mode()) {
VariableProxy* operand = expression->AsVariableProxy();
if (operand != NULL && !operand->is_this()) {
ReportMessage("strict_delete", Vector<const char*>::empty());
@@ -2577,7 +2587,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
}
}
- return new UnaryOperation(op, expression);
+ return new(zone()) UnaryOperation(op, expression, position);
} else if (Token::IsCountOp(op)) {
op = Next();
@@ -2587,18 +2597,21 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
// error here but for compatibility with JSC we choose to report the
// error at runtime.
if (expression == NULL || !expression->IsValidLeftHandSide()) {
- Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol();
+ Handle<String> type =
+ isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
expression = NewThrowReferenceError(type);
}
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
// Prefix expression operand in strict mode may not be eval or arguments.
CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
}
int position = scanner().location().beg_pos;
- IncrementOperation* increment = new IncrementOperation(op, expression);
- return new CountOperation(true /* prefix */, increment, position);
+ return new(zone()) CountOperation(op,
+ true /* prefix */,
+ expression,
+ position);
} else {
return ParsePostfixExpression(ok);
@@ -2611,26 +2624,30 @@ Expression* Parser::ParsePostfixExpression(bool* ok) {
// LeftHandSideExpression ('++' | '--')?
Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
- if (!scanner().has_line_terminator_before_next() &&
+ if (!scanner().HasAnyLineTerminatorBeforeNext() &&
Token::IsCountOp(peek())) {
// Signal a reference error if the expression is an invalid
// left-hand side expression. We could report this as a syntax
// error here but for compatibility with JSC we choose to report the
// error at runtime.
if (expression == NULL || !expression->IsValidLeftHandSide()) {
- Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol();
+ Handle<String> type =
+ isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
expression = NewThrowReferenceError(type);
}
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
// Postfix expression operand in strict mode may not be eval or arguments.
CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
}
Token::Value next = Next();
int position = scanner().location().beg_pos;
- IncrementOperation* increment = new IncrementOperation(next, expression);
- expression = new CountOperation(false /* postfix */, increment, position);
+ expression =
+ new(zone()) CountOperation(next,
+ false /* postfix */,
+ expression,
+ position);
}
return expression;
}
@@ -2653,7 +2670,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
Consume(Token::LBRACK);
int pos = scanner().location().beg_pos;
Expression* index = ParseExpression(true, CHECK_OK);
- result = new Property(result, index, pos);
+ result = new(zone()) Property(result, index, pos);
Expect(Token::RBRACK, CHECK_OK);
break;
}
@@ -2675,7 +2692,8 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
// is called without a receiver and it refers to the original eval
// function.
VariableProxy* callee = result->AsVariableProxy();
- if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) {
+ if (callee != NULL &&
+ callee->IsVariable(isolate()->factory()->eval_symbol())) {
Handle<String> name = callee->name();
Variable* var = top_scope_->Lookup(name);
if (var == NULL) {
@@ -2690,7 +2708,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
Consume(Token::PERIOD);
int pos = scanner().location().beg_pos;
Handle<String> name = ParseIdentifierName(CHECK_OK);
- result = new Property(result, new Literal(name), pos);
+ result = new(zone()) Property(result, new(zone()) Literal(name), pos);
if (fni_ != NULL) fni_->PushLiteralName(name);
break;
}
@@ -2726,7 +2744,9 @@ Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
if (!stack->is_empty()) {
int last = stack->pop();
- result = new CallNew(result, new ZoneList<Expression*>(0), last);
+ result = new(zone()) CallNew(result,
+ new(zone()) ZoneList<Expression*>(0),
+ last);
}
return result;
}
@@ -2755,11 +2775,12 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
Handle<String> name;
- bool is_reserved_name = false;
+ bool is_strict_reserved_name = false;
if (peek_any_identifier()) {
- name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK);
+ name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
+ CHECK_OK);
}
- result = ParseFunctionLiteral(name, is_reserved_name,
+ result = ParseFunctionLiteral(name, is_strict_reserved_name,
function_token_position, NESTED, CHECK_OK);
} else {
result = ParsePrimaryExpression(CHECK_OK);
@@ -2771,7 +2792,15 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
Consume(Token::LBRACK);
int pos = scanner().location().beg_pos;
Expression* index = ParseExpression(true, CHECK_OK);
- result = new Property(result, index, pos);
+ result = new(zone()) Property(result, index, pos);
+ if (fni_ != NULL) {
+ if (index->IsPropertyName()) {
+ fni_->PushLiteralName(index->AsLiteral()->AsPropertyName());
+ } else {
+ fni_->PushLiteralName(
+ isolate()->factory()->anonymous_function_symbol());
+ }
+ }
Expect(Token::RBRACK, CHECK_OK);
break;
}
@@ -2779,7 +2808,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
Consume(Token::PERIOD);
int pos = scanner().location().beg_pos;
Handle<String> name = ParseIdentifierName(CHECK_OK);
- result = new Property(result, new Literal(name), pos);
+ result = new(zone()) Property(result, new(zone()) Literal(name), pos);
if (fni_ != NULL) fni_->PushLiteralName(name);
break;
}
@@ -2807,7 +2836,7 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
Expect(Token::DEBUGGER, CHECK_OK);
ExpectSemicolon(CHECK_OK);
- return new DebuggerStatement();
+ return new(zone()) DebuggerStatement();
}
@@ -2830,7 +2859,10 @@ void Parser::ReportUnexpectedToken(Token::Value token) {
return ReportMessage("unexpected_token_identifier",
Vector<const char*>::empty());
case Token::FUTURE_RESERVED_WORD:
- return ReportMessage(temp_scope_->StrictMode() ?
+ return ReportMessage("unexpected_reserved",
+ Vector<const char*>::empty());
+ case Token::FUTURE_STRICT_RESERVED_WORD:
+ return ReportMessage(top_scope_->is_strict_mode() ?
"unexpected_strict_reserved" :
"unexpected_token_identifier",
Vector<const char*>::empty());
@@ -2876,31 +2908,34 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
case Token::NULL_LITERAL:
Consume(Token::NULL_LITERAL);
- result = new Literal(Factory::null_value());
+ result = new(zone()) Literal(isolate()->factory()->null_value());
break;
case Token::TRUE_LITERAL:
Consume(Token::TRUE_LITERAL);
- result = new Literal(Factory::true_value());
+ result = new(zone()) Literal(isolate()->factory()->true_value());
break;
case Token::FALSE_LITERAL:
Consume(Token::FALSE_LITERAL);
- result = new Literal(Factory::false_value());
+ result = new(zone()) Literal(isolate()->factory()->false_value());
break;
case Token::IDENTIFIER:
- case Token::FUTURE_RESERVED_WORD: {
+ case Token::FUTURE_STRICT_RESERVED_WORD: {
Handle<String> name = ParseIdentifier(CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name);
- result = top_scope_->NewUnresolved(name, inside_with());
+ result = top_scope_->NewUnresolved(name,
+ inside_with(),
+ scanner().location().beg_pos);
break;
}
case Token::NUMBER: {
Consume(Token::NUMBER);
ASSERT(scanner().is_literal_ascii());
- double value = StringToDouble(scanner().literal_ascii_string(),
+ double value = StringToDouble(isolate()->unicode_cache(),
+ scanner().literal_ascii_string(),
ALLOW_HEX | ALLOW_OCTALS);
result = NewNumberLiteral(value);
break;
@@ -2909,7 +2944,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
case Token::STRING: {
Consume(Token::STRING);
Handle<String> symbol = GetSymbol(CHECK_OK);
- result = new Literal(symbol);
+ result = new(zone()) Literal(symbol);
if (fni_ != NULL) fni_->PushLiteralName(symbol);
break;
}
@@ -2990,7 +3025,7 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
// ArrayLiteral ::
// '[' Expression? (',' Expression?)* ']'
- ZoneList<Expression*>* values = new ZoneList<Expression*>(4);
+ ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4);
Expect(Token::LBRACK, CHECK_OK);
while (peek() != Token::RBRACK) {
Expression* elem;
@@ -3007,11 +3042,11 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
Expect(Token::RBRACK, CHECK_OK);
// Update the scope information before the pre-parsing bailout.
- int literal_index = temp_scope_->NextMaterializedLiteralIndex();
+ int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
// Allocate a fixed array with all the literals.
Handle<FixedArray> literals =
- Factory::NewFixedArray(values->length(), TENURED);
+ isolate()->factory()->NewFixedArray(values->length(), TENURED);
// Fill in the literals.
bool is_simple = true;
@@ -3033,10 +3068,10 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
// Simple and shallow arrays can be lazily copied, we transform the
// elements array to a copy-on-write array.
if (is_simple && depth == 1 && values->length() > 0) {
- literals->set_map(Heap::fixed_cow_array_map());
+ literals->set_map(isolate()->heap()->fixed_cow_array_map());
}
- return new ArrayLiteral(literals, values,
+ return new(zone()) ArrayLiteral(literals, values,
literal_index, is_simple, depth);
}
@@ -3068,7 +3103,7 @@ bool CompileTimeValue::ArrayLiteralElementNeedsInitialization(
Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) {
ASSERT(IsCompileTimeValue(expression));
- Handle<FixedArray> result = Factory::NewFixedArray(2, TENURED);
+ Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED);
ObjectLiteral* object_literal = expression->AsObjectLiteral();
if (object_literal != NULL) {
ASSERT(object_literal->is_simple());
@@ -3106,7 +3141,7 @@ Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
if (CompileTimeValue::IsCompileTimeValue(expression)) {
return CompileTimeValue::GetValue(expression);
}
- return Factory::undefined_value();
+ return isolate()->factory()->undefined_value();
}
// Defined in ast.cc
@@ -3172,7 +3207,7 @@ void ObjectLiteralPropertyChecker::CheckProperty(
if (handle->IsSymbol()) {
Handle<String> name(String::cast(*handle));
if (name->AsArrayIndex(&hash)) {
- Handle<Object> key_handle = Factory::NewNumberFromUint(hash);
+ Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash);
key = key_handle.location();
map = &elems;
} else {
@@ -3189,7 +3224,7 @@ void ObjectLiteralPropertyChecker::CheckProperty(
char arr[100];
Vector<char> buffer(arr, ARRAY_SIZE(arr));
const char* str = DoubleToCString(num, buffer);
- Handle<String> name = Factory::NewStringFromAscii(CStrVector(str));
+ Handle<String> name = FACTORY->NewStringFromAscii(CStrVector(str));
key = name.location();
hash = name->Hash();
map = &props;
@@ -3298,10 +3333,11 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
bool is_keyword = Token::IsKeyword(next);
if (next == Token::IDENTIFIER || next == Token::NUMBER ||
next == Token::FUTURE_RESERVED_WORD ||
+ next == Token::FUTURE_STRICT_RESERVED_WORD ||
next == Token::STRING || is_keyword) {
Handle<String> name;
if (is_keyword) {
- name = Factory::LookupAsciiSymbol(Token::String(next));
+ name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
} else {
name = GetSymbol(CHECK_OK);
}
@@ -3314,7 +3350,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
// Allow any number of parameters for compatiabilty with JSC.
// Specification only allows zero parameters for get and one for set.
ObjectLiteral::Property* property =
- new ObjectLiteral::Property(is_getter, value);
+ new(zone()) ObjectLiteral::Property(is_getter, value);
return property;
} else {
ReportUnexpectedToken(next);
@@ -3332,10 +3368,11 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
// )*[','] '}'
ZoneList<ObjectLiteral::Property*>* properties =
- new ZoneList<ObjectLiteral::Property*>(4);
+ new(zone()) ZoneList<ObjectLiteral::Property*>(4);
int number_of_boilerplate_properties = 0;
+ bool has_function = false;
- ObjectLiteralPropertyChecker checker(this, temp_scope_->StrictMode());
+ ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode());
Expect(Token::LBRACE, CHECK_OK);
Scanner::Location loc = scanner().location();
@@ -3351,11 +3388,12 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
switch (next) {
case Token::FUTURE_RESERVED_WORD:
+ case Token::FUTURE_STRICT_RESERVED_WORD:
case Token::IDENTIFIER: {
bool is_getter = false;
bool is_setter = false;
Handle<String> id =
- ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
+ ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
if (fni_ != NULL) fni_->PushLiteralName(id);
if ((is_getter || is_setter) && peek() != Token::COLON) {
@@ -3379,7 +3417,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
}
// Failed to parse as get/set property, so it's just a property
// called "get" or "set".
- key = new Literal(id);
+ key = new(zone()) Literal(id);
break;
}
case Token::STRING: {
@@ -3391,13 +3429,14 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
key = NewNumberLiteral(index);
break;
}
- key = new Literal(string);
+ key = new(zone()) Literal(string);
break;
}
case Token::NUMBER: {
Consume(Token::NUMBER);
ASSERT(scanner().is_literal_ascii());
- double value = StringToDouble(scanner().literal_ascii_string(),
+ double value = StringToDouble(isolate()->unicode_cache(),
+ scanner().literal_ascii_string(),
ALLOW_HEX | ALLOW_OCTALS);
key = NewNumberLiteral(value);
break;
@@ -3406,7 +3445,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
if (Token::IsKeyword(next)) {
Consume(next);
Handle<String> string = GetSymbol(CHECK_OK);
- key = new Literal(string);
+ key = new(zone()) Literal(string);
} else {
// Unexpected token.
Token::Value next = Next();
@@ -3420,7 +3459,14 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
Expression* value = ParseAssignmentExpression(true, CHECK_OK);
ObjectLiteral::Property* property =
- new ObjectLiteral::Property(key, value);
+ new(zone()) ObjectLiteral::Property(key, value);
+
+ // Mark object literals that contain function literals and pretenure the
+ // literal so it can be added as a constant function property.
+ if (value->AsFunctionLiteral() != NULL) {
+ has_function = true;
+ value->AsFunctionLiteral()->set_pretenure(true);
+ }
// Count CONSTANT or COMPUTED properties to maintain the enumeration order.
if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
@@ -3439,10 +3485,10 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
Expect(Token::RBRACE, CHECK_OK);
// Computation of literal_index must happen before pre parse bailout.
- int literal_index = temp_scope_->NextMaterializedLiteralIndex();
+ int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
- Handle<FixedArray> constant_properties =
- Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
+ Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
+ number_of_boilerplate_properties * 2, TENURED);
bool is_simple = true;
bool fast_elements = true;
@@ -3452,12 +3498,13 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
&is_simple,
&fast_elements,
&depth);
- return new ObjectLiteral(constant_properties,
+ return new(zone()) ObjectLiteral(constant_properties,
properties,
literal_index,
is_simple,
fast_elements,
- depth);
+ depth,
+ has_function);
}
@@ -3469,14 +3516,14 @@ Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
return NULL;
}
- int literal_index = temp_scope_->NextMaterializedLiteralIndex();
+ int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
Handle<String> js_pattern = NextLiteralString(TENURED);
scanner().ScanRegExpFlags();
Handle<String> js_flags = NextLiteralString(TENURED);
Next();
- return new RegExpLiteral(js_pattern, js_flags, literal_index);
+ return new(zone()) RegExpLiteral(js_pattern, js_flags, literal_index);
}
@@ -3484,7 +3531,7 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
// Arguments ::
// '(' (AssignmentExpression)*[','] ')'
- ZoneList<Expression*>* result = new ZoneList<Expression*>(4);
+ ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4);
Expect(Token::LPAREN, CHECK_OK);
bool done = (peek() == Token::RPAREN);
while (!done) {
@@ -3505,7 +3552,7 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
- bool name_is_reserved,
+ bool name_is_strict_reserved,
int function_token_position,
FunctionLiteralType type,
bool* ok) {
@@ -3517,49 +3564,56 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
// this is the actual function name, otherwise this is the name of the
// variable declared and initialized with the function (expression). In
// that case, we don't have a function name (it's empty).
- Handle<String> name = is_named ? var_name : Factory::empty_symbol();
+ Handle<String> name =
+ is_named ? var_name : isolate()->factory()->empty_symbol();
// The function name, if any.
- Handle<String> function_name = Factory::empty_symbol();
+ Handle<String> function_name = isolate()->factory()->empty_symbol();
if (is_named && (type == EXPRESSION || type == NESTED)) {
function_name = name;
}
int num_parameters = 0;
+ Scope* scope = NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
+ ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8);
+ int materialized_literal_count;
+ int expected_property_count;
+ int start_pos;
+ int end_pos;
+ bool only_simple_this_property_assignments;
+ Handle<FixedArray> this_property_assignments;
+ bool has_duplicate_parameters = false;
// Parse function body.
- { Scope* scope =
- NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
- LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
- scope);
- TemporaryScope temp_scope(&this->temp_scope_);
+ { LexicalScope lexical_scope(this, scope, isolate());
top_scope_->SetScopeName(name);
// FormalParameterList ::
// '(' (Identifier)*[','] ')'
Expect(Token::LPAREN, CHECK_OK);
- int start_pos = scanner().location().beg_pos;
- Scanner::Location name_loc = Scanner::NoLocation();
- Scanner::Location dupe_loc = Scanner::NoLocation();
- Scanner::Location reserved_loc = Scanner::NoLocation();
+ start_pos = scanner().location().beg_pos;
+ Scanner::Location name_loc = Scanner::Location::invalid();
+ Scanner::Location dupe_loc = Scanner::Location::invalid();
+ Scanner::Location reserved_loc = Scanner::Location::invalid();
bool done = (peek() == Token::RPAREN);
while (!done) {
- bool is_reserved = false;
+ bool is_strict_reserved = false;
Handle<String> param_name =
- ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
+ ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
+ CHECK_OK);
// Store locations for possible future error reports.
if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
name_loc = scanner().location();
}
if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
+ has_duplicate_parameters = true;
dupe_loc = scanner().location();
}
- if (!reserved_loc.IsValid() && is_reserved) {
+ if (!reserved_loc.IsValid() && is_strict_reserved) {
reserved_loc = scanner().location();
}
- Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
- top_scope_->AddParameter(parameter);
+ top_scope_->DeclareParameter(param_name);
num_parameters++;
if (num_parameters > kMaxNumFunctionParameters) {
ReportMessageAt(scanner().location(), "too_many_parameters",
@@ -3573,7 +3627,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
Expect(Token::RPAREN, CHECK_OK);
Expect(Token::LBRACE, CHECK_OK);
- ZoneList<Statement*>* body = new ZoneList<Statement*>(8);
// If we have a named function expression, we add a local variable
// declaration to the body of the function with the name of the
@@ -3586,9 +3639,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
VariableProxy* fproxy =
top_scope_->NewUnresolved(function_name, inside_with());
fproxy->BindTo(fvar);
- body->Add(new ExpressionStatement(
- new Assignment(Token::INIT_CONST, fproxy,
- new ThisFunction(),
+ body->Add(new(zone()) ExpressionStatement(
+ new(zone()) Assignment(Token::INIT_CONST, fproxy,
+ new(zone()) ThisFunction(),
RelocInfo::kNoPosition)));
}
@@ -3601,11 +3654,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
parenthesized_function_ = false; // The bit was set for this function only.
int function_block_pos = scanner().location().beg_pos;
- int materialized_literal_count;
- int expected_property_count;
- int end_pos;
- bool only_simple_this_property_assignments;
- Handle<FixedArray> this_property_assignments;
if (is_lazily_compiled && pre_data() != NULL) {
FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
if (!entry.is_valid()) {
@@ -3616,29 +3664,31 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
// End position greater than end of stream is safe, and hard to check.
ReportInvalidPreparseData(name, CHECK_OK);
}
- Counters::total_preparse_skipped.Increment(end_pos - function_block_pos);
+ isolate()->counters()->total_preparse_skipped()->Increment(
+ end_pos - function_block_pos);
// Seek to position just before terminal '}'.
scanner().SeekForward(end_pos - 1);
materialized_literal_count = entry.literal_count();
expected_property_count = entry.property_count();
+ if (entry.strict_mode()) top_scope_->EnableStrictMode();
only_simple_this_property_assignments = false;
- this_property_assignments = Factory::empty_fixed_array();
+ this_property_assignments = isolate()->factory()->empty_fixed_array();
Expect(Token::RBRACE, CHECK_OK);
} else {
ParseSourceElements(body, Token::RBRACE, CHECK_OK);
- materialized_literal_count = temp_scope.materialized_literal_count();
- expected_property_count = temp_scope.expected_property_count();
+ materialized_literal_count = lexical_scope.materialized_literal_count();
+ expected_property_count = lexical_scope.expected_property_count();
only_simple_this_property_assignments =
- temp_scope.only_simple_this_property_assignments();
- this_property_assignments = temp_scope.this_property_assignments();
+ lexical_scope.only_simple_this_property_assignments();
+ this_property_assignments = lexical_scope.this_property_assignments();
Expect(Token::RBRACE, CHECK_OK);
end_pos = scanner().location().end_pos;
}
// Validate strict mode.
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
if (IsEvalOrArguments(name)) {
int position = function_token_position != RelocInfo::kNoPosition
? function_token_position
@@ -3661,7 +3711,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
*ok = false;
return NULL;
}
- if (name_is_reserved) {
+ if (name_is_strict_reserved) {
int position = function_token_position != RelocInfo::kNoPosition
? function_token_position
: (start_pos > 0 ? start_pos - 1 : start_pos);
@@ -3679,26 +3729,25 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
}
CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
}
+ }
- FunctionLiteral* function_literal =
- new FunctionLiteral(name,
- top_scope_,
- body,
- materialized_literal_count,
- expected_property_count,
- only_simple_this_property_assignments,
- this_property_assignments,
- num_parameters,
- start_pos,
- end_pos,
- function_name->length() > 0,
- temp_scope.ContainsLoops(),
- temp_scope.StrictMode());
- function_literal->set_function_token_position(function_token_position);
+ FunctionLiteral* function_literal =
+ new(zone()) FunctionLiteral(name,
+ scope,
+ body,
+ materialized_literal_count,
+ expected_property_count,
+ only_simple_this_property_assignments,
+ this_property_assignments,
+ num_parameters,
+ start_pos,
+ end_pos,
+ (function_name->length() > 0),
+ has_duplicate_parameters);
+ function_literal->set_function_token_position(function_token_position);
- if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
- return function_literal;
- }
+ if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
+ return function_literal;
}
@@ -3716,7 +3765,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
top_scope_->ForceEagerCompilation();
}
- Runtime::Function* function = Runtime::FunctionForSymbol(name);
+ const Runtime::Function* function = Runtime::FunctionForSymbol(name);
// Check for built-in IS_VAR macro.
if (function != NULL &&
@@ -3744,14 +3793,15 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
}
// We have a valid intrinsics call or a call to a builtin.
- return new CallRuntime(name, function, args);
+ return new(zone()) CallRuntime(name, function, args);
}
bool Parser::peek_any_identifier() {
Token::Value next = peek();
return next == Token::IDENTIFIER ||
- next == Token::FUTURE_RESERVED_WORD;
+ next == Token::FUTURE_RESERVED_WORD ||
+ next == Token::FUTURE_STRICT_RESERVED_WORD;
}
@@ -3789,7 +3839,7 @@ void Parser::ExpectSemicolon(bool* ok) {
Next();
return;
}
- if (scanner().has_line_terminator_before_next() ||
+ if (scanner().HasAnyLineTerminatorBeforeNext() ||
tok == Token::RBRACE ||
tok == Token::EOS) {
return;
@@ -3799,12 +3849,12 @@ void Parser::ExpectSemicolon(bool* ok) {
Literal* Parser::GetLiteralUndefined() {
- return new Literal(Factory::undefined_value());
+ return new(zone()) Literal(isolate()->factory()->undefined_value());
}
Literal* Parser::GetLiteralTheHole() {
- return new Literal(Factory::the_hole_value());
+ return new(zone()) Literal(isolate()->factory()->the_hole_value());
}
@@ -3813,22 +3863,27 @@ Literal* Parser::GetLiteralNumber(double value) {
}
+// Parses and identifier that is valid for the current scope, in particular it
+// fails on strict mode future reserved keywords in a strict scope.
Handle<String> Parser::ParseIdentifier(bool* ok) {
- bool is_reserved;
- return ParseIdentifierOrReservedWord(&is_reserved, ok);
+ if (top_scope_->is_strict_mode()) {
+ Expect(Token::IDENTIFIER, ok);
+ } else if (!Check(Token::IDENTIFIER)) {
+ Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
+ }
+ if (!*ok) return Handle<String>();
+ return GetSymbol(ok);
}
-Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
- bool* ok) {
- *is_reserved = false;
- if (temp_scope_->StrictMode()) {
- Expect(Token::IDENTIFIER, ok);
- } else {
- if (!Check(Token::IDENTIFIER)) {
- Expect(Token::FUTURE_RESERVED_WORD, ok);
- *is_reserved = true;
- }
+// Parses and identifier or a strict mode future reserved word, and indicate
+// whether it is strict mode future reserved.
+Handle<String> Parser::ParseIdentifierOrStrictReservedWord(
+ bool* is_strict_reserved, bool* ok) {
+ *is_strict_reserved = false;
+ if (!Check(Token::IDENTIFIER)) {
+ Expect(Token::FUTURE_STRICT_RESERVED_WORD, ok);
+ *is_strict_reserved = true;
}
if (!*ok) return Handle<String>();
return GetSymbol(ok);
@@ -3838,8 +3893,9 @@ Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
Handle<String> Parser::ParseIdentifierName(bool* ok) {
Token::Value next = Next();
if (next != Token::IDENTIFIER &&
- next != Token::FUTURE_RESERVED_WORD &&
- !Token::IsKeyword(next)) {
+ next != Token::FUTURE_RESERVED_WORD &&
+ next != Token::FUTURE_STRICT_RESERVED_WORD &&
+ !Token::IsKeyword(next)) {
ReportUnexpectedToken(next);
*ok = false;
return Handle<String>();
@@ -3853,7 +3909,7 @@ Handle<String> Parser::ParseIdentifierName(bool* ok) {
void Parser::CheckStrictModeLValue(Expression* expression,
const char* error,
bool* ok) {
- ASSERT(temp_scope_->StrictMode());
+ ASSERT(top_scope_->is_strict_mode());
VariableProxy* lhs = expression != NULL
? expression->AsVariableProxy()
: NULL;
@@ -3865,12 +3921,14 @@ void Parser::CheckStrictModeLValue(Expression* expression,
}
-// Checks whether octal literal last seen is between beg_pos and end_pos.
-// If so, reports an error.
+// Checks whether an octal literal was last seen between beg_pos and end_pos.
+// If so, reports an error. Only called for strict mode.
void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
- int octal = scanner().octal_position();
- if (beg_pos <= octal && octal <= end_pos) {
- ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal",
+ Scanner::Location octal = scanner().octal_position();
+ if (octal.IsValid() &&
+ beg_pos <= octal.beg_pos &&
+ octal.end_pos <= end_pos) {
+ ReportMessageAt(octal, "strict_octal_literal",
Vector<const char*>::empty());
scanner().clear_octal_position();
*ok = false;
@@ -3878,12 +3936,12 @@ void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
}
-// This function reads an identifier and determines whether or not it
+// This function reads an identifier name and determines whether or not it
// is 'get' or 'set'.
-Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
- bool* is_set,
- bool* ok) {
- Handle<String> result = ParseIdentifier(ok);
+Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get,
+ bool* is_set,
+ bool* ok) {
+ Handle<String> result = ParseIdentifierName(ok);
if (!*ok) return Handle<String>();
if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
const char* token = scanner().literal_ascii_string().start();
@@ -3940,7 +3998,7 @@ IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
}
-void Parser::RegisterTargetUse(BreakTarget* target, Target* stop) {
+void Parser::RegisterTargetUse(Label* target, Target* stop) {
// Register that a break target found at the given stop in the
// target stack has been used from the top of the target stack. Add
// the break target to any TargetCollectors passed on the stack.
@@ -3952,12 +4010,12 @@ void Parser::RegisterTargetUse(BreakTarget* target, Target* stop) {
Literal* Parser::NewNumberLiteral(double number) {
- return new Literal(Factory::NewNumber(number, TENURED));
+ return new(zone()) Literal(isolate()->factory()->NewNumber(number, TENURED));
}
Expression* Parser::NewThrowReferenceError(Handle<String> type) {
- return NewThrowError(Factory::MakeReferenceError_symbol(),
+ return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(),
type, HandleVector<Object>(NULL, 0));
}
@@ -3966,7 +4024,8 @@ Expression* Parser::NewThrowSyntaxError(Handle<String> type,
Handle<Object> first) {
int argc = first.is_null() ? 0 : 1;
Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc);
- return NewThrowError(Factory::MakeSyntaxError_symbol(), type, arguments);
+ return NewThrowError(
+ isolate()->factory()->MakeSyntaxError_symbol(), type, arguments);
}
@@ -3977,7 +4036,8 @@ Expression* Parser::NewThrowTypeError(Handle<String> type,
Handle<Object> elements[] = { first, second };
Vector< Handle<Object> > arguments =
HandleVector<Object>(elements, ARRAY_SIZE(elements));
- return NewThrowError(Factory::MakeTypeError_symbol(), type, arguments);
+ return NewThrowError(
+ isolate()->factory()->MakeTypeError_symbol(), type, arguments);
}
@@ -3985,215 +4045,44 @@ Expression* Parser::NewThrowError(Handle<String> constructor,
Handle<String> type,
Vector< Handle<Object> > arguments) {
int argc = arguments.length();
- Handle<FixedArray> elements = Factory::NewFixedArray(argc, TENURED);
+ Handle<FixedArray> elements = isolate()->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, TENURED);
+ Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(elements,
+ TENURED);
- ZoneList<Expression*>* args = new ZoneList<Expression*>(2);
- args->Add(new Literal(type));
- args->Add(new Literal(array));
- return new Throw(new CallRuntime(constructor, NULL, args),
+ ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2);
+ args->Add(new(zone()) Literal(type));
+ args->Add(new(zone()) Literal(array));
+ return new(zone()) Throw(new(zone()) CallRuntime(constructor, NULL, args),
scanner().location().beg_pos);
}
// ----------------------------------------------------------------------------
-// JSON
-
-Handle<Object> JsonParser::ParseJson(Handle<String> script,
- UC16CharacterStream* source) {
- scanner_.Initialize(source);
- stack_overflow_ = false;
- Handle<Object> result = ParseJsonValue();
- if (result.is_null() || scanner_.Next() != Token::EOS) {
- if (stack_overflow_) {
- // Scanner failed.
- Top::StackOverflow();
- } else {
- // Parse failed. Scanner's current token is the unexpected token.
- Token::Value token = scanner_.current_token();
-
- const char* message;
- const char* name_opt = NULL;
-
- switch (token) {
- case Token::EOS:
- message = "unexpected_eos";
- break;
- case Token::NUMBER:
- message = "unexpected_token_number";
- break;
- case Token::STRING:
- message = "unexpected_token_string";
- break;
- case Token::IDENTIFIER:
- case Token::FUTURE_RESERVED_WORD:
- message = "unexpected_token_identifier";
- break;
- default:
- message = "unexpected_token";
- name_opt = Token::String(token);
- ASSERT(name_opt != NULL);
- break;
- }
-
- Scanner::Location source_location = scanner_.location();
- MessageLocation location(Factory::NewScript(script),
- source_location.beg_pos,
- source_location.end_pos);
- int argc = (name_opt == NULL) ? 0 : 1;
- Handle<JSArray> array = Factory::NewJSArray(argc);
- if (name_opt != NULL) {
- SetElement(array,
- 0,
- Factory::NewStringFromUtf8(CStrVector(name_opt)));
- }
- Handle<Object> result = Factory::NewSyntaxError(message, array);
- Top::Throw(*result, &location);
- return Handle<Object>::null();
- }
- }
- return result;
-}
-
-
-Handle<String> JsonParser::GetString() {
- int literal_length = scanner_.literal_length();
- if (literal_length == 0) {
- return Factory::empty_string();
- }
- if (scanner_.is_literal_ascii()) {
- return Factory::NewStringFromAscii(scanner_.literal_ascii_string());
- } else {
- return Factory::NewStringFromTwoByte(scanner_.literal_uc16_string());
- }
-}
-
-
-// Parse any JSON value.
-Handle<Object> JsonParser::ParseJsonValue() {
- Token::Value token = scanner_.Next();
- switch (token) {
- case Token::STRING:
- return GetString();
- case Token::NUMBER:
- return Factory::NewNumber(scanner_.number());
- case Token::FALSE_LITERAL:
- return Factory::false_value();
- case Token::TRUE_LITERAL:
- return Factory::true_value();
- case Token::NULL_LITERAL:
- return Factory::null_value();
- case Token::LBRACE:
- return ParseJsonObject();
- case Token::LBRACK:
- return ParseJsonArray();
- default:
- return ReportUnexpectedToken();
- }
-}
-
-
-// Parse a JSON object. Scanner must be right after '{' token.
-Handle<Object> JsonParser::ParseJsonObject() {
- Handle<JSFunction> object_constructor(
- Top::global_context()->object_function());
- Handle<JSObject> json_object = Factory::NewJSObject(object_constructor);
- if (scanner_.peek() == Token::RBRACE) {
- scanner_.Next();
- } else {
- if (StackLimitCheck().HasOverflowed()) {
- stack_overflow_ = true;
- return Handle<Object>::null();
- }
- do {
- if (scanner_.Next() != Token::STRING) {
- return ReportUnexpectedToken();
- }
- Handle<String> key = GetString();
- if (scanner_.Next() != Token::COLON) {
- return ReportUnexpectedToken();
- }
- Handle<Object> value = ParseJsonValue();
- if (value.is_null()) return Handle<Object>::null();
- uint32_t index;
- if (key->AsArrayIndex(&index)) {
- SetOwnElement(json_object, index, value);
- } else if (key->Equals(Heap::Proto_symbol())) {
- // We can't remove the __proto__ accessor since it's hardcoded
- // in several places. Instead go along and add the value as
- // the prototype of the created object if possible.
- SetPrototype(json_object, value);
- } else {
- SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
- }
- } while (scanner_.Next() == Token::COMMA);
- if (scanner_.current_token() != Token::RBRACE) {
- return ReportUnexpectedToken();
- }
- }
- return json_object;
-}
-
-
-// Parse a JSON array. Scanner must be right after '[' token.
-Handle<Object> JsonParser::ParseJsonArray() {
- ZoneScope zone_scope(DELETE_ON_EXIT);
- ZoneList<Handle<Object> > elements(4);
-
- Token::Value token = scanner_.peek();
- if (token == Token::RBRACK) {
- scanner_.Next();
- } else {
- if (StackLimitCheck().HasOverflowed()) {
- stack_overflow_ = true;
- return Handle<Object>::null();
- }
- do {
- Handle<Object> element = ParseJsonValue();
- if (element.is_null()) return Handle<Object>::null();
- elements.Add(element);
- token = scanner_.Next();
- } while (token == Token::COMMA);
- if (token != Token::RBRACK) {
- return ReportUnexpectedToken();
- }
- }
-
- // Allocate a fixed array with all the elements.
- Handle<FixedArray> fast_elements =
- Factory::NewFixedArray(elements.length());
-
- for (int i = 0, n = elements.length(); i < n; i++) {
- fast_elements->set(i, *elements[i]);
- }
-
- return Factory::NewJSArrayWithElements(fast_elements);
-}
-
-// ----------------------------------------------------------------------------
// Regular expressions
RegExpParser::RegExpParser(FlatStringReader* in,
Handle<String>* error,
bool multiline)
- : error_(error),
- captures_(NULL),
- in_(in),
- current_(kEndMarker),
- next_pos_(0),
- capture_count_(0),
- has_more_(true),
- multiline_(multiline),
- simple_(false),
- contains_anchor_(false),
- is_scanned_for_captures_(false),
- failed_(false) {
+ : isolate_(Isolate::Current()),
+ error_(error),
+ captures_(NULL),
+ in_(in),
+ current_(kEndMarker),
+ next_pos_(0),
+ capture_count_(0),
+ has_more_(true),
+ multiline_(multiline),
+ simple_(false),
+ contains_anchor_(false),
+ is_scanned_for_captures_(false),
+ failed_(false) {
Advance();
}
@@ -4209,10 +4098,10 @@ uc32 RegExpParser::Next() {
void RegExpParser::Advance() {
if (next_pos_ < in()->length()) {
- StackLimitCheck check;
+ StackLimitCheck check(isolate());
if (check.HasOverflowed()) {
- ReportError(CStrVector(Top::kStackOverflowMessage));
- } else if (Zone::excess_allocation()) {
+ ReportError(CStrVector(Isolate::kStackOverflowMessage));
+ } else if (isolate()->zone()->excess_allocation()) {
ReportError(CStrVector("Regular expression too large"));
} else {
current_ = in()->Get(next_pos_);
@@ -4243,7 +4132,7 @@ bool RegExpParser::simple() {
RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
failed_ = true;
- *error_ = Factory::NewStringFromAscii(message, NOT_TENURED);
+ *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED);
// Zip to the end to make sure the no more input is read.
current_ = kEndMarker;
next_pos_ = in()->length();
@@ -4313,13 +4202,13 @@ RegExpTree* RegExpParser::ParseDisjunction() {
// Build result of subexpression.
if (type == CAPTURE) {
- RegExpCapture* capture = new RegExpCapture(body, capture_index);
+ RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
captures_->at(capture_index - 1) = capture;
body = capture;
} else if (type != GROUPING) {
ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD);
bool is_positive = (type == POSITIVE_LOOKAHEAD);
- body = new RegExpLookahead(body,
+ body = new(zone()) RegExpLookahead(body,
is_positive,
end_capture_index - capture_index,
capture_index);
@@ -4342,10 +4231,10 @@ RegExpTree* RegExpParser::ParseDisjunction() {
Advance();
if (multiline_) {
builder->AddAssertion(
- new RegExpAssertion(RegExpAssertion::START_OF_LINE));
+ new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
} else {
builder->AddAssertion(
- new RegExpAssertion(RegExpAssertion::START_OF_INPUT));
+ new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
set_contains_anchor();
}
continue;
@@ -4355,15 +4244,16 @@ RegExpTree* RegExpParser::ParseDisjunction() {
RegExpAssertion::Type type =
multiline_ ? RegExpAssertion::END_OF_LINE :
RegExpAssertion::END_OF_INPUT;
- builder->AddAssertion(new RegExpAssertion(type));
+ builder->AddAssertion(new(zone()) RegExpAssertion(type));
continue;
}
case '.': {
Advance();
// everything except \x0a, \x0d, \u2028 and \u2029
- ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
+ ZoneList<CharacterRange>* ranges =
+ new(zone()) ZoneList<CharacterRange>(2);
CharacterRange::AddClassEscape('.', ranges);
- RegExpTree* atom = new RegExpCharacterClass(ranges, false);
+ RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
builder->AddAtom(atom);
break;
}
@@ -4388,7 +4278,7 @@ RegExpTree* RegExpParser::ParseDisjunction() {
Advance(2);
} else {
if (captures_ == NULL) {
- captures_ = new ZoneList<RegExpCapture*>(2);
+ captures_ = new(zone()) ZoneList<RegExpCapture*>(2);
}
if (captures_started() >= kMaxCaptures) {
ReportError(CStrVector("Too many captures") CHECK_FAILED);
@@ -4396,7 +4286,7 @@ RegExpTree* RegExpParser::ParseDisjunction() {
captures_->Add(NULL);
}
// Store current state and begin new disjunction parsing.
- stored_state = new RegExpParserState(stored_state,
+ stored_state = new(zone()) RegExpParserState(stored_state,
type,
captures_started());
builder = stored_state->builder();
@@ -4416,12 +4306,12 @@ RegExpTree* RegExpParser::ParseDisjunction() {
case 'b':
Advance(2);
builder->AddAssertion(
- new RegExpAssertion(RegExpAssertion::BOUNDARY));
+ new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
continue;
case 'B':
Advance(2);
builder->AddAssertion(
- new RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
+ new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
continue;
// AtomEscape ::
// CharacterClassEscape
@@ -4431,9 +4321,10 @@ RegExpTree* RegExpParser::ParseDisjunction() {
case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
uc32 c = Next();
Advance(2);
- ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
+ ZoneList<CharacterRange>* ranges =
+ new(zone()) ZoneList<CharacterRange>(2);
CharacterRange::AddClassEscape(c, ranges);
- RegExpTree* atom = new RegExpCharacterClass(ranges, false);
+ RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
builder->AddAtom(atom);
break;
}
@@ -4449,7 +4340,7 @@ RegExpTree* RegExpParser::ParseDisjunction() {
builder->AddEmpty();
break;
}
- RegExpTree* atom = new RegExpBackReference(capture);
+ RegExpTree* atom = new(zone()) RegExpBackReference(capture);
builder->AddAtom(atom);
break;
}
@@ -4597,30 +4488,6 @@ RegExpTree* RegExpParser::ParseDisjunction() {
}
}
-class SourceCharacter {
- public:
- static bool Is(uc32 c) {
- switch (c) {
- // case ']': case '}':
- // In spidermonkey and jsc these are treated as source characters
- // so we do too.
- case '^': case '$': case '\\': case '.': case '*': case '+':
- case '?': case '(': case ')': case '[': case '{': case '|':
- case RegExpParser::kEndMarker:
- return false;
- default:
- return true;
- }
- }
-};
-
-
-static unibrow::Predicate<SourceCharacter> source_character;
-
-
-static inline bool IsSourceCharacter(uc32 c) {
- return source_character.get(c);
-}
#ifdef DEBUG
// Currently only used in an ASSERT.
@@ -4951,7 +4818,7 @@ RegExpTree* RegExpParser::ParseCharacterClass() {
is_negated = true;
Advance();
}
- ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2);
+ ZoneList<CharacterRange>* ranges = new(zone()) ZoneList<CharacterRange>(2);
while (has_more() && current() != ']') {
uc16 char_class = kNoCharClass;
CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
@@ -4991,7 +4858,7 @@ RegExpTree* RegExpParser::ParseCharacterClass() {
ranges->Add(CharacterRange::Everything());
is_negated = !is_negated;
}
- return new RegExpCharacterClass(ranges, is_negated);
+ return new(zone()) RegExpCharacterClass(ranges, is_negated);
}
@@ -5073,14 +4940,15 @@ int ScriptDataImpl::ReadNumber(byte** source) {
static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
bool allow_lazy,
ParserRecorder* recorder) {
- V8JavaScriptScanner scanner;
+ Isolate* isolate = Isolate::Current();
+ JavaScriptScanner scanner(isolate->unicode_cache());
scanner.Initialize(source);
- intptr_t stack_limit = StackGuard::real_climit();
+ intptr_t stack_limit = isolate->stack_guard()->real_climit();
if (!preparser::PreParser::PreParseProgram(&scanner,
recorder,
allow_lazy,
stack_limit)) {
- Top::StackOverflow();
+ isolate->StackOverflow();
return NULL;
}
@@ -5145,8 +5013,9 @@ bool ParserApi::Parse(CompilationInfo* info) {
Parser parser(script, true, NULL, NULL);
result = parser.ParseLazy(info);
} else {
+ // Whether we allow %identifier(..) syntax.
bool allow_natives_syntax =
- FLAG_allow_natives_syntax || Bootstrapper::IsActive();
+ info->allows_natives_syntax() || FLAG_allow_natives_syntax;
ScriptDataImpl* pre_data = info->pre_parse_data();
Parser parser(script, allow_natives_syntax, info->extension(), pre_data);
if (pre_data != NULL && pre_data->has_error()) {
@@ -5159,7 +5028,7 @@ bool ParserApi::Parse(CompilationInfo* info) {
DeleteArray(args[i]);
}
DeleteArray(args.start());
- ASSERT(Top::has_pending_exception());
+ ASSERT(info->isolate()->has_pending_exception());
} else {
Handle<String> source = Handle<String>(String::cast(script->source()));
result = parser.ParseProgram(source,