Commit 7f764978 authored by lrn@chromium.org's avatar lrn@chromium.org

Remove old preparser option and behavior from the parser.

Review URL: http://codereview.chromium.org/4244003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5752 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ef06d712
...@@ -279,7 +279,6 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source, ...@@ -279,7 +279,6 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
// in that case too. // in that case too.
ScriptDataImpl* pre_data = input_pre_data; ScriptDataImpl* pre_data = input_pre_data;
if (pre_data == NULL if (pre_data == NULL
&& FLAG_lazy
&& source_length >= FLAG_min_preparse_length) { && source_length >= FLAG_min_preparse_length) {
pre_data = ParserApi::PartialPreParse(source, NULL, extension); pre_data = ParserApi::PartialPreParse(source, NULL, extension);
} }
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#include "preparser.h" #include "preparser.h"
#include "runtime.h" #include "runtime.h"
#include "scopeinfo.h" #include "scopeinfo.h"
#include "scopes.h"
#include "string-stream.h" #include "string-stream.h"
#include "ast-inl.h" #include "ast-inl.h"
...@@ -324,144 +323,37 @@ TemporaryScope::~TemporaryScope() { ...@@ -324,144 +323,37 @@ TemporaryScope::~TemporaryScope() {
} }
// A zone list wrapper lets code either access a access a zone list Handle<String> Parser::LookupSymbol(int symbol_id,
// or appear to do so while actually ignoring all operations.
template <typename T>
class ZoneListWrapper {
public:
ZoneListWrapper() : list_(NULL) { }
explicit ZoneListWrapper(int size) : list_(new ZoneList<T*>(size)) { }
void Add(T* that) { if (list_) list_->Add(that); }
int length() { return list_->length(); }
ZoneList<T*>* elements() { return list_; }
T* at(int index) { return list_->at(index); }
private:
ZoneList<T*>* list_;
};
// Allocation macro that should be used to allocate objects that must
// only be allocated in real parsing mode. Note that in preparse mode
// not only is the syntax tree not created but the constructor
// arguments are not evaluated.
#define NEW(expr) (is_pre_parsing_ ? NULL : new expr)
class ParserFactory BASE_EMBEDDED {
public:
explicit ParserFactory(bool is_pre_parsing) :
is_pre_parsing_(is_pre_parsing) { }
virtual ~ParserFactory() { }
virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
virtual Handle<String> LookupSymbol(int index, Vector<const char> string) {
return Handle<String>();
}
virtual Handle<String> EmptySymbol() {
return Handle<String>();
}
virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) {
if (obj == VariableProxySentinel::this_proxy()) {
return Property::this_property();
} else {
return ValidLeftHandSideSentinel::instance();
}
}
virtual Expression* NewCall(Expression* expression,
ZoneList<Expression*>* arguments,
int pos) {
return Call::sentinel();
}
virtual Statement* EmptyStatement() {
return NULL;
}
template <typename T> ZoneListWrapper<T> NewList(int size) {
return is_pre_parsing_ ? ZoneListWrapper<T>() : ZoneListWrapper<T>(size);
}
private:
bool is_pre_parsing_;
};
class ConditionalLogPauseScope {
public:
ConditionalLogPauseScope(bool pause, ParserLog* log)
: log_(log), pause_(pause) {
if (pause) log->PauseRecording();
}
~ConditionalLogPauseScope() {
if (pause_) log_->ResumeRecording();
}
private:
ParserLog* log_;
bool pause_;
};
class AstBuildingParserFactory : public ParserFactory {
public:
explicit AstBuildingParserFactory(int expected_symbols)
: ParserFactory(false), symbol_cache_(expected_symbols) { }
virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
virtual Handle<String> LookupSymbol(int symbol_id,
Vector<const char> string) {
// Length of symbol cache is the number of identified symbols.
// If we are larger than that, or negative, it's not a cached symbol.
// This might also happen if there is no preparser symbol data, even
// if there is some preparser data.
if (static_cast<unsigned>(symbol_id)
>= static_cast<unsigned>(symbol_cache_.length())) {
return Factory::LookupSymbol(string);
}
return LookupCachedSymbol(symbol_id, string);
}
Handle<String> LookupCachedSymbol(int symbol_id,
Vector<const char> string) { Vector<const char> string) {
// Make sure the cache is large enough to hold the symbol identifier. // Length of symbol cache is the number of identified symbols.
if (symbol_cache_.length() <= symbol_id) { // If we are larger than that, or negative, it's not a cached symbol.
// Increase length to index + 1. // This might also happen if there is no preparser symbol data, even
symbol_cache_.AddBlock(Handle<String>::null(), // if there is some preparser data.
symbol_id + 1 - symbol_cache_.length()); if (static_cast<unsigned>(symbol_id)
} >= static_cast<unsigned>(symbol_cache_.length())) {
Handle<String> result = symbol_cache_.at(symbol_id); return Factory::LookupSymbol(string);
if (result.is_null()) { }
result = Factory::LookupSymbol(string); return LookupCachedSymbol(symbol_id, string);
symbol_cache_.at(symbol_id) = result; }
return result;
}
Counters::total_preparse_symbols_skipped.Increment(); Handle<String> Parser::LookupCachedSymbol(int symbol_id,
Vector<const char> string) {
// Make sure the cache is large enough to hold the symbol identifier.
if (symbol_cache_.length() <= symbol_id) {
// Increase length to index + 1.
symbol_cache_.AddBlock(Handle<String>::null(),
symbol_id + 1 - symbol_cache_.length());
}
Handle<String> result = symbol_cache_.at(symbol_id);
if (result.is_null()) {
result = Factory::LookupSymbol(string);
symbol_cache_.at(symbol_id) = result;
return result; return result;
} }
Counters::total_preparse_symbols_skipped.Increment();
virtual Handle<String> EmptySymbol() { return result;
return Factory::empty_symbol(); }
}
virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) {
return new Property(obj, key, pos);
}
virtual Expression* NewCall(Expression* expression,
ZoneList<Expression*>* arguments,
int pos) {
return new Call(expression, arguments, pos);
}
virtual Statement* EmptyStatement();
private:
List<Handle<String> > symbol_cache_;
};
Vector<unsigned> PartialParserRecorder::ExtractData() { Vector<unsigned> PartialParserRecorder::ExtractData() {
...@@ -523,8 +415,6 @@ Vector<unsigned> CompleteParserRecorder::ExtractData() { ...@@ -523,8 +415,6 @@ Vector<unsigned> CompleteParserRecorder::ExtractData() {
} }
FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
// The current pre-data entry must be a FunctionEntry with the given // The current pre-data entry must be a FunctionEntry with the given
// start position. // start position.
...@@ -704,108 +594,12 @@ unsigned* ScriptDataImpl::ReadAddress(int position) { ...@@ -704,108 +594,12 @@ unsigned* ScriptDataImpl::ReadAddress(int position) {
} }
class AstBuildingParser : public Parser { Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) {
public:
AstBuildingParser(Handle<Script> script, bool allow_natives_syntax,
v8::Extension* extension, ScriptDataImpl* pre_data)
: Parser(script,
allow_natives_syntax,
extension,
PARSE,
factory(),
log(),
pre_data),
factory_(pre_data ? pre_data->symbol_count() : 0) { }
virtual void ReportMessageAt(Scanner::Location loc, const char* message,
Vector<const char*> args);
virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
FunctionLiteral* fun, bool resolve, bool* ok);
AstBuildingParserFactory* factory() { return &factory_; }
ParserLog* log() { return &log_; }
private:
ParserLog log_;
AstBuildingParserFactory factory_;
};
class PreParser : public Parser {
public:
PreParser(Handle<Script> script, bool allow_natives_syntax,
v8::Extension* extension, ParserLog* recorder)
: Parser(script, allow_natives_syntax, extension, PREPARSE,
factory(), recorder, NULL),
factory_(true) { }
virtual void ReportMessageAt(Scanner::Location loc, const char* message,
Vector<const char*> args);
virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
FunctionLiteral* fun, bool resolve, bool* ok);
ParserFactory* factory() { return &factory_; }
virtual PartialParserRecorder* recorder() = 0;
private:
ParserFactory factory_;
};
class CompletePreParser : public PreParser {
public:
CompletePreParser(Handle<Script> script, bool allow_natives_syntax,
v8::Extension* extension)
: PreParser(script, allow_natives_syntax, extension, &recorder_),
recorder_() { }
virtual PartialParserRecorder* recorder() { return &recorder_; }
private:
CompleteParserRecorder recorder_;
};
class PartialPreParser : public PreParser {
public:
PartialPreParser(Handle<Script> script, bool allow_natives_syntax,
v8::Extension* extension)
: PreParser(script, allow_natives_syntax, extension, &recorder_),
recorder_() { }
virtual PartialParserRecorder* recorder() { return &recorder_; }
private:
PartialParserRecorder recorder_;
};
Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type,
bool inside_with) {
Scope* result = new Scope(parent, type); Scope* result = new Scope(parent, type);
result->Initialize(inside_with); result->Initialize(inside_with);
return result; return result;
} }
Statement* AstBuildingParserFactory::EmptyStatement() {
// Use a statically allocated empty statement singleton to avoid
// allocating lots and lots of empty statements.
static v8::internal::EmptyStatement empty;
return &empty;
}
Scope* ParserFactory::NewScope(Scope* parent, Scope::Type type,
bool inside_with) {
ASSERT(parent != NULL);
parent->type_ = type;
// Initialize function is hijacked by DummyScope to increment scope depth.
parent->Initialize(inside_with);
return parent;
}
VariableProxy* PreParser::Declare(Handle<String> name, Variable::Mode mode,
FunctionLiteral* fun, bool resolve,
bool* ok) {
return NULL;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Target is a support class to facilitate manipulation of the // Target is a support class to facilitate manipulation of the
// Parser's target_stack_ (the stack of potential 'break' and // Parser's target_stack_ (the stack of potential 'break' and
...@@ -908,11 +702,9 @@ class LexicalScope BASE_EMBEDDED { ...@@ -908,11 +702,9 @@ class LexicalScope BASE_EMBEDDED {
Parser::Parser(Handle<Script> script, Parser::Parser(Handle<Script> script,
bool allow_natives_syntax, bool allow_natives_syntax,
v8::Extension* extension, v8::Extension* extension,
ParserMode is_pre_parsing,
ParserFactory* factory,
ParserLog* log,
ScriptDataImpl* pre_data) ScriptDataImpl* pre_data)
: script_(script), : symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
script_(script),
scanner_(), scanner_(),
top_scope_(NULL), top_scope_(NULL),
with_nesting_level_(0), with_nesting_level_(0),
...@@ -920,9 +712,6 @@ Parser::Parser(Handle<Script> script, ...@@ -920,9 +712,6 @@ Parser::Parser(Handle<Script> script,
target_stack_(NULL), target_stack_(NULL),
allow_natives_syntax_(allow_natives_syntax), allow_natives_syntax_(allow_natives_syntax),
extension_(extension), extension_(extension),
factory_(factory),
log_(log),
is_pre_parsing_(is_pre_parsing == PREPARSE),
pre_data_(pre_data), pre_data_(pre_data),
fni_(NULL) { fni_(NULL) {
} }
...@@ -950,21 +739,21 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source, ...@@ -950,21 +739,21 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
in_global_context in_global_context
? Scope::GLOBAL_SCOPE ? Scope::GLOBAL_SCOPE
: Scope::EVAL_SCOPE; : Scope::EVAL_SCOPE;
Handle<String> no_name = factory()->EmptySymbol(); Handle<String> no_name = Factory::empty_symbol();
FunctionLiteral* result = NULL; FunctionLiteral* result = NULL;
{ Scope* scope = factory()->NewScope(top_scope_, type, inside_with()); { Scope* scope = NewScope(top_scope_, type, inside_with());
LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
scope); scope);
TemporaryScope temp_scope(&this->temp_scope_); TemporaryScope temp_scope(&this->temp_scope_);
ZoneListWrapper<Statement> body(16); ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
bool ok = true; bool ok = true;
ParseSourceElements(&body, Token::EOS, &ok); ParseSourceElements(body, Token::EOS, &ok);
if (ok) { if (ok) {
result = NEW(FunctionLiteral( result = new FunctionLiteral(
no_name, no_name,
top_scope_, top_scope_,
body.elements(), body,
temp_scope.materialized_literal_count(), temp_scope.materialized_literal_count(),
temp_scope.expected_property_count(), temp_scope.expected_property_count(),
temp_scope.only_simple_this_property_assignments(), temp_scope.only_simple_this_property_assignments(),
...@@ -973,7 +762,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source, ...@@ -973,7 +762,7 @@ FunctionLiteral* Parser::ParseProgram(Handle<String> source,
0, 0,
source->length(), source->length(),
false, false,
temp_scope.ContainsLoops())); temp_scope.ContainsLoops());
} else if (scanner().stack_overflow()) { } else if (scanner().stack_overflow()) {
Top::StackOverflow(); Top::StackOverflow();
} }
...@@ -1011,9 +800,9 @@ FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) { ...@@ -1011,9 +800,9 @@ FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) {
{ {
// Parse the function literal. // Parse the function literal.
Handle<String> no_name = factory()->EmptySymbol(); Handle<String> no_name = Factory::empty_symbol();
Scope* scope = Scope* scope =
factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
scope); scope);
TemporaryScope temp_scope(&this->temp_scope_); TemporaryScope temp_scope(&this->temp_scope_);
...@@ -1041,28 +830,24 @@ FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) { ...@@ -1041,28 +830,24 @@ FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) {
} }
void Parser::ReportMessage(const char* type, Vector<const char*> args) {
Scanner::Location source_location = scanner_.location();
ReportMessageAt(source_location, type, args);
}
Handle<String> Parser::GetSymbol(bool* ok) { Handle<String> Parser::GetSymbol(bool* ok) {
if (is_pre_parsing_) {
log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
return Handle<String>::null();
}
int symbol_id = -1; int symbol_id = -1;
if (pre_data() != NULL) { if (pre_data() != NULL) {
symbol_id = pre_data()->GetSymbolIdentifier(); symbol_id = pre_data()->GetSymbolIdentifier();
} }
return factory()->LookupSymbol(symbol_id, scanner_.literal()); return LookupSymbol(symbol_id, scanner_.literal());
}
void Parser::ReportMessage(const char* type, Vector<const char*> args) {
Scanner::Location source_location = scanner_.location();
ReportMessageAt(source_location, type, args);
} }
void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, void Parser::ReportMessageAt(Scanner::Location source_location,
const char* type, const char* type,
Vector<const char*> args) { Vector<const char*> args) {
MessageLocation location(script_, MessageLocation location(script_,
source_location.beg_pos, source_location.end_pos); source_location.beg_pos, source_location.end_pos);
Handle<JSArray> array = Factory::NewJSArray(args.length()); Handle<JSArray> array = Factory::NewJSArray(args.length());
...@@ -1074,13 +859,6 @@ void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, ...@@ -1074,13 +859,6 @@ void AstBuildingParser::ReportMessageAt(Scanner::Location source_location,
} }
void PreParser::ReportMessageAt(Scanner::Location source_location,
const char* type,
Vector<const char*> args) {
recorder()->LogMessage(source_location, type, args);
}
// Base class containing common code for the different finder classes used by // Base class containing common code for the different finder classes used by
// the parser. // the parser.
class ParserFinder { class ParserFinder {
...@@ -1122,6 +900,11 @@ class InitializationBlockFinder : public ParserFinder { ...@@ -1122,6 +900,11 @@ class InitializationBlockFinder : public ParserFinder {
} }
private: private:
// The minimum number of contiguous assignment that will
// be treated as an initialization block. Benchmarks show that
// the overhead exceeds the savings below this limit.
static const int kMinInitializationBlock = 3;
// Returns true if the expressions appear to denote the same object. // Returns true if the expressions appear to denote the same object.
// In the context of initialization blocks, we only consider expressions // In the context of initialization blocks, we only consider expressions
// of the form 'expr.x' or expr["x"]. // of the form 'expr.x' or expr["x"].
...@@ -1174,7 +957,7 @@ class InitializationBlockFinder : public ParserFinder { ...@@ -1174,7 +957,7 @@ class InitializationBlockFinder : public ParserFinder {
} }
void EndBlock() { void EndBlock() {
if (block_size_ >= Parser::kMinInitializationBlock) { if (block_size_ >= kMinInitializationBlock) {
first_in_block_->mark_block_start(); first_in_block_->mark_block_start();
last_in_block_->mark_block_end(); last_in_block_->mark_block_end();
} }
...@@ -1332,7 +1115,7 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder { ...@@ -1332,7 +1115,7 @@ class ThisNamedPropertyAssigmentFinder : public ParserFinder {
}; };
void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
int end_token, int end_token,
bool* ok) { bool* ok) {
// SourceElements :: // SourceElements ::
...@@ -1364,7 +1147,7 @@ void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, ...@@ -1364,7 +1147,7 @@ void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor,
} }
// Propagate the collected information on this property assignments. // Propagate the collected information on this property assignments.
if (!is_pre_parsing_ && top_scope_->is_function_scope()) { if (top_scope_->is_function_scope()) {
bool only_simple_this_property_assignments = bool only_simple_this_property_assignments =
this_property_assignment_finder.only_simple_this_property_assignments() this_property_assignment_finder.only_simple_this_property_assignments()
&& top_scope_->declarations()->length() == 0; && top_scope_->declarations()->length() == 0;
...@@ -1417,7 +1200,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { ...@@ -1417,7 +1200,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
case Token::SEMICOLON: case Token::SEMICOLON:
Next(); Next();
return factory()->EmptyStatement(); return EmptyStatement();
case Token::IF: case Token::IF:
stmt = ParseIfStatement(labels, ok); stmt = ParseIfStatement(labels, ok);
...@@ -1465,7 +1248,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { ...@@ -1465,7 +1248,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
// one must take great care not to treat it as a // one must take great care not to treat it as a
// fall-through. It is much easier just to wrap the entire // fall-through. It is much easier just to wrap the entire
// try-statement in a statement block and put the labels there // try-statement in a statement block and put the labels there
Block* result = NEW(Block(labels, 1, false)); Block* result = new Block(labels, 1, false);
Target target(&this->target_stack_, result); Target target(&this->target_stack_, result);
TryStatement* statement = ParseTryStatement(CHECK_OK); TryStatement* statement = ParseTryStatement(CHECK_OK);
if (statement) { if (statement) {
...@@ -1495,11 +1278,11 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { ...@@ -1495,11 +1278,11 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
} }
VariableProxy* AstBuildingParser::Declare(Handle<String> name, VariableProxy* Parser::Declare(Handle<String> name,
Variable::Mode mode, Variable::Mode mode,
FunctionLiteral* fun, FunctionLiteral* fun,
bool resolve, bool resolve,
bool* ok) { bool* ok) {
Variable* var = NULL; Variable* var = NULL;
// If we are inside a function, a declaration of a variable // If we are inside a function, a declaration of a variable
// is a truly local variable, and the scope of the variable // is a truly local variable, and the scope of the variable
...@@ -1554,13 +1337,13 @@ VariableProxy* AstBuildingParser::Declare(Handle<String> name, ...@@ -1554,13 +1337,13 @@ VariableProxy* AstBuildingParser::Declare(Handle<String> name,
// a performance issue since it may lead to repeated // a performance issue since it may lead to repeated
// Runtime::DeclareContextSlot() calls. // Runtime::DeclareContextSlot() calls.
VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with()); VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with());
top_scope_->AddDeclaration(NEW(Declaration(proxy, mode, fun))); top_scope_->AddDeclaration(new Declaration(proxy, mode, fun));
// For global const variables we bind the proxy to a variable. // For global const variables we bind the proxy to a variable.
if (mode == Variable::CONST && top_scope_->is_global_scope()) { if (mode == Variable::CONST && top_scope_->is_global_scope()) {
ASSERT(resolve); // should be set by all callers ASSERT(resolve); // should be set by all callers
Variable::Kind kind = Variable::NORMAL; Variable::Kind kind = Variable::NORMAL;
var = NEW(Variable(top_scope_, name, Variable::CONST, true, kind)); var = new Variable(top_scope_, name, Variable::CONST, true, kind);
} }
// If requested and we have a local variable, bind the proxy to the variable // If requested and we have a local variable, bind the proxy to the variable
...@@ -1619,8 +1402,6 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { ...@@ -1619,8 +1402,6 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
Expect(Token::SEMICOLON, CHECK_OK); Expect(Token::SEMICOLON, CHECK_OK);
if (is_pre_parsing_) return NULL;
// Make sure that the function containing the native declaration // Make sure that the function containing the native declaration
// isn't lazily compiled. The extension structures are only // isn't lazily compiled. The extension structures are only
// accessible while parsing the first time not when reparsing // accessible while parsing the first time not when reparsing
...@@ -1650,10 +1431,10 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { ...@@ -1650,10 +1431,10 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
// TODO(1240846): It's weird that native function declarations are // TODO(1240846): It's weird that native function declarations are
// introduced dynamically when we meet their declarations, whereas // introduced dynamically when we meet their declarations, whereas
// other functions are setup when entering the surrounding scope. // other functions are setup when entering the surrounding scope.
SharedFunctionInfoLiteral* lit = NEW(SharedFunctionInfoLiteral(shared)); SharedFunctionInfoLiteral* lit = new SharedFunctionInfoLiteral(shared);
VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK); VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
return NEW(ExpressionStatement( return new ExpressionStatement(
new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition))); new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
} }
...@@ -1671,7 +1452,7 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) { ...@@ -1671,7 +1452,7 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) {
// scope, we treat is as such and introduce the function with it's // scope, we treat is as such and introduce the function with it's
// initial value upon entering the corresponding scope. // initial value upon entering the corresponding scope.
Declare(name, Variable::VAR, fun, true, CHECK_OK); Declare(name, Variable::VAR, fun, true, CHECK_OK);
return factory()->EmptyStatement(); return EmptyStatement();
} }
...@@ -1683,7 +1464,7 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { ...@@ -1683,7 +1464,7 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) {
// (ECMA-262, 3rd, 12.2) // (ECMA-262, 3rd, 12.2)
// //
// Construct block expecting 16 statements. // Construct block expecting 16 statements.
Block* result = NEW(Block(labels, 16, false)); Block* result = new Block(labels, 16, false);
Target target(&this->target_stack_, result); Target target(&this->target_stack_, result);
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
while (peek() != Token::RBRACE) { while (peek() != Token::RBRACE) {
...@@ -1742,7 +1523,7 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, ...@@ -1742,7 +1523,7 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
// is inside an initializer block, it is ignored. // is inside an initializer block, it is ignored.
// //
// Create new block with one expected declaration. // Create new block with one expected declaration.
Block* block = NEW(Block(NULL, 1, true)); Block* block = new Block(NULL, 1, true);
VariableProxy* last_var = NULL; // the last variable declared VariableProxy* last_var = NULL; // the last variable declared
int nvars = 0; // the number of variables declared int nvars = 0; // the number of variables declared
do { do {
...@@ -1833,14 +1614,14 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, ...@@ -1833,14 +1614,14 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
// browsers where the global object (window) has lots of // browsers where the global object (window) has lots of
// properties defined in prototype objects. // properties defined in prototype objects.
if (!is_pre_parsing_ && top_scope_->is_global_scope()) { if (top_scope_->is_global_scope()) {
// Compute the arguments for the runtime call. // Compute the arguments for the runtime call.
ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2); ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2);
// Be careful not to assign a value to the global variable if // Be careful not to assign a value to the global variable if
// we're in a with. The initialization value should not // we're in a with. The initialization value should not
// necessarily be stored in the global object in that case, // necessarily be stored in the global object in that case,
// which is why we need to generate a separate assignment node. // which is why we need to generate a separate assignment node.
arguments->Add(NEW(Literal(name))); // we have at least 1 parameter arguments->Add(new Literal(name)); // we have at least 1 parameter
if (is_const || (value != NULL && !inside_with())) { if (is_const || (value != NULL && !inside_with())) {
arguments->Add(value); arguments->Add(value);
value = NULL; // zap the value to avoid the unnecessary assignment value = NULL; // zap the value to avoid the unnecessary assignment
...@@ -1852,18 +1633,18 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, ...@@ -1852,18 +1633,18 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
CallRuntime* initialize; CallRuntime* initialize;
if (is_const) { if (is_const) {
initialize = initialize =
NEW(CallRuntime( new CallRuntime(
Factory::InitializeConstGlobal_symbol(), Factory::InitializeConstGlobal_symbol(),
Runtime::FunctionForId(Runtime::kInitializeConstGlobal), Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
arguments)); arguments);
} else { } else {
initialize = initialize =
NEW(CallRuntime( new CallRuntime(
Factory::InitializeVarGlobal_symbol(), Factory::InitializeVarGlobal_symbol(),
Runtime::FunctionForId(Runtime::kInitializeVarGlobal), Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
arguments)); arguments);
} }
block->AddStatement(NEW(ExpressionStatement(initialize))); block->AddStatement(new ExpressionStatement(initialize));
} }
// Add an assignment node to the initialization statement block if // Add an assignment node to the initialization statement block if
...@@ -1878,8 +1659,8 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, ...@@ -1878,8 +1659,8 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
// the top context for variables). Sigh... // the top context for variables). Sigh...
if (value != NULL) { if (value != NULL) {
Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR);
Assignment* assignment = NEW(Assignment(op, last_var, value, position)); Assignment* assignment = new Assignment(op, last_var, value, position);
if (block) block->AddStatement(NEW(ExpressionStatement(assignment))); if (block) block->AddStatement(new ExpressionStatement(assignment));
} }
if (fni_ != NULL) fni_->Leave(); if (fni_ != NULL) fni_->Leave();
...@@ -1887,14 +1668,8 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN, ...@@ -1887,14 +1668,8 @@ Block* Parser::ParseVariableDeclarations(bool accept_IN,
if (!is_const && nvars == 1) { if (!is_const && nvars == 1) {
// We have a single, non-const variable. // We have a single, non-const variable.
if (is_pre_parsing_) { ASSERT(last_var != NULL);
// If we're preparsing then we need to set the var to something *var = last_var;
// in order for for-in loops to parse correctly.
*var = ValidLeftHandSideSentinel::instance();
} else {
ASSERT(last_var != NULL);
*var = last_var;
}
} }
return block; return block;
...@@ -1929,29 +1704,27 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, ...@@ -1929,29 +1704,27 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
// labels requires nontrivial changes to the way scopes are // labels requires nontrivial changes to the way scopes are
// structured. However, these are probably changes we want to // structured. However, these are probably changes we want to
// make later anyway so we should go back and fix this then. // make later anyway so we should go back and fix this then.
if (!is_pre_parsing_) { if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS); const char* elms[2] = { "Label", *c_string };
const char* elms[2] = { "Label", *c_string }; Vector<const char*> args(elms, 2);
Vector<const char*> args(elms, 2); ReportMessage("redeclaration", args);
ReportMessage("redeclaration", args); *ok = false;
*ok = false; return NULL;
return NULL;
}
if (labels == NULL) labels = new 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
// during the scope processing.
top_scope_->RemoveUnresolved(var);
} }
if (labels == NULL) labels = new 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
// during the scope processing.
top_scope_->RemoveUnresolved(var);
Expect(Token::COLON, CHECK_OK); Expect(Token::COLON, CHECK_OK);
return ParseStatement(labels, ok); return ParseStatement(labels, ok);
} }
// Parsed expression statement. // Parsed expression statement.
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return NEW(ExpressionStatement(expr)); return new ExpressionStatement(expr);
} }
...@@ -1968,10 +1741,10 @@ IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { ...@@ -1968,10 +1741,10 @@ IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) {
if (peek() == Token::ELSE) { if (peek() == Token::ELSE) {
Next(); Next();
else_statement = ParseStatement(labels, CHECK_OK); else_statement = ParseStatement(labels, CHECK_OK);
} else if (!is_pre_parsing_) { } else {
else_statement = factory()->EmptyStatement(); else_statement = EmptyStatement();
} }
return NEW(IfStatement(condition, then_statement, else_statement)); return new IfStatement(condition, then_statement, else_statement);
} }
...@@ -1987,19 +1760,17 @@ Statement* Parser::ParseContinueStatement(bool* ok) { ...@@ -1987,19 +1760,17 @@ Statement* Parser::ParseContinueStatement(bool* ok) {
label = ParseIdentifier(CHECK_OK); label = ParseIdentifier(CHECK_OK);
} }
IterationStatement* target = NULL; IterationStatement* target = NULL;
if (!is_pre_parsing_) { target = LookupContinueTarget(label, CHECK_OK);
target = LookupContinueTarget(label, CHECK_OK); if (target == NULL) {
if (target == NULL) { // Illegal continue statement. To be consistent with KJS we delay
// Illegal continue statement. To be consistent with KJS we delay // reporting of the syntax error until runtime.
// reporting of the syntax error until runtime. Handle<String> error_type = Factory::illegal_continue_symbol();
Handle<String> error_type = Factory::illegal_continue_symbol(); if (!label.is_null()) error_type = Factory::unknown_label_symbol();
if (!label.is_null()) error_type = Factory::unknown_label_symbol(); Expression* throw_error = NewThrowSyntaxError(error_type, label);
Expression* throw_error = NewThrowSyntaxError(error_type, label); return new ExpressionStatement(throw_error);
return NEW(ExpressionStatement(throw_error));
}
} }
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return NEW(ContinueStatement(target)); return new ContinueStatement(target);
} }
...@@ -2017,22 +1788,20 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { ...@@ -2017,22 +1788,20 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
// Parse labeled break statements that target themselves into // Parse labeled break statements that target themselves into
// empty statements, e.g. 'l1: l2: l3: break l2;' // empty statements, e.g. 'l1: l2: l3: break l2;'
if (!label.is_null() && ContainsLabel(labels, label)) { if (!label.is_null() && ContainsLabel(labels, label)) {
return factory()->EmptyStatement(); return EmptyStatement();
} }
BreakableStatement* target = NULL; BreakableStatement* target = NULL;
if (!is_pre_parsing_) { target = LookupBreakTarget(label, CHECK_OK);
target = LookupBreakTarget(label, CHECK_OK); if (target == NULL) {
if (target == NULL) { // Illegal break statement. To be consistent with KJS we delay
// Illegal break statement. To be consistent with KJS we delay // reporting of the syntax error until runtime.
// reporting of the syntax error until runtime. Handle<String> error_type = Factory::illegal_break_symbol();
Handle<String> error_type = Factory::illegal_break_symbol(); if (!label.is_null()) error_type = Factory::unknown_label_symbol();
if (!label.is_null()) error_type = Factory::unknown_label_symbol(); Expression* throw_error = NewThrowSyntaxError(error_type, label);
Expression* throw_error = NewThrowSyntaxError(error_type, label); return new ExpressionStatement(throw_error);
return NEW(ExpressionStatement(throw_error));
}
} }
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return NEW(BreakStatement(target)); return new BreakStatement(target);
} }
...@@ -2050,10 +1819,10 @@ Statement* Parser::ParseReturnStatement(bool* ok) { ...@@ -2050,10 +1819,10 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
// function. See ECMA-262, section 12.9, page 67. // function. See ECMA-262, section 12.9, page 67.
// //
// To be consistent with KJS we report the syntax error at runtime. // To be consistent with KJS we report the syntax error at runtime.
if (!is_pre_parsing_ && !top_scope_->is_function_scope()) { if (!top_scope_->is_function_scope()) {
Handle<String> type = Factory::illegal_return_symbol(); Handle<String> type = Factory::illegal_return_symbol();
Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null());
return NEW(ExpressionStatement(throw_error)); return new ExpressionStatement(throw_error);
} }
Token::Value tok = peek(); Token::Value tok = peek();
...@@ -2062,12 +1831,12 @@ Statement* Parser::ParseReturnStatement(bool* ok) { ...@@ -2062,12 +1831,12 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
tok == Token::RBRACE || tok == Token::RBRACE ||
tok == Token::EOS) { tok == Token::EOS) {
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return NEW(ReturnStatement(GetLiteralUndefined())); return new ReturnStatement(GetLiteralUndefined());
} }
Expression* expr = ParseExpression(true, CHECK_OK); Expression* expr = ParseExpression(true, CHECK_OK);
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return NEW(ReturnStatement(expr)); return new ReturnStatement(expr);
} }
...@@ -2076,7 +1845,7 @@ Block* Parser::WithHelper(Expression* obj, ...@@ -2076,7 +1845,7 @@ Block* Parser::WithHelper(Expression* obj,
bool is_catch_block, bool is_catch_block,
bool* ok) { bool* ok) {
// Parse the statement and collect escaping labels. // Parse the statement and collect escaping labels.
ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0)); ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0);
TargetCollector collector(target_list); TargetCollector collector(target_list);
Statement* stat; Statement* stat;
{ Target target(&this->target_stack_, &collector); { Target target(&this->target_stack_, &collector);
...@@ -2088,21 +1857,21 @@ Block* Parser::WithHelper(Expression* obj, ...@@ -2088,21 +1857,21 @@ Block* Parser::WithHelper(Expression* obj,
// Create resulting block with two statements. // Create resulting block with two statements.
// 1: Evaluate the with expression. // 1: Evaluate the with expression.
// 2: The try-finally block evaluating the body. // 2: The try-finally block evaluating the body.
Block* result = NEW(Block(NULL, 2, false)); Block* result = new Block(NULL, 2, false);
if (result != NULL) { if (result != NULL) {
result->AddStatement(NEW(WithEnterStatement(obj, is_catch_block))); result->AddStatement(new WithEnterStatement(obj, is_catch_block));
// Create body block. // Create body block.
Block* body = NEW(Block(NULL, 1, false)); Block* body = new Block(NULL, 1, false);
body->AddStatement(stat); body->AddStatement(stat);
// Create exit block. // Create exit block.
Block* exit = NEW(Block(NULL, 1, false)); Block* exit = new Block(NULL, 1, false);
exit->AddStatement(NEW(WithExitStatement())); exit->AddStatement(new WithExitStatement());
// Return a try-finally statement. // Return a try-finally statement.
TryFinallyStatement* wrapper = NEW(TryFinallyStatement(body, exit)); TryFinallyStatement* wrapper = new TryFinallyStatement(body, exit);
wrapper->set_escaping_targets(collector.targets()); wrapper->set_escaping_targets(collector.targets());
result->AddStatement(wrapper); result->AddStatement(wrapper);
} }
...@@ -2144,15 +1913,15 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { ...@@ -2144,15 +1913,15 @@ CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
} }
Expect(Token::COLON, CHECK_OK); Expect(Token::COLON, CHECK_OK);
ZoneListWrapper<Statement> statements = factory()->NewList<Statement>(5); ZoneList<Statement*>* statements = new ZoneList<Statement*>(5);
while (peek() != Token::CASE && while (peek() != Token::CASE &&
peek() != Token::DEFAULT && peek() != Token::DEFAULT &&
peek() != Token::RBRACE) { peek() != Token::RBRACE) {
Statement* stat = ParseStatement(NULL, CHECK_OK); Statement* stat = ParseStatement(NULL, CHECK_OK);
statements.Add(stat); statements->Add(stat);
} }
return NEW(CaseClause(label, statements.elements())); return new CaseClause(label, statements);
} }
...@@ -2161,7 +1930,7 @@ SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, ...@@ -2161,7 +1930,7 @@ SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
// SwitchStatement :: // SwitchStatement ::
// 'switch' '(' Expression ')' '{' CaseClause* '}' // 'switch' '(' Expression ')' '{' CaseClause* '}'
SwitchStatement* statement = NEW(SwitchStatement(labels)); SwitchStatement* statement = new SwitchStatement(labels);
Target target(&this->target_stack_, statement); Target target(&this->target_stack_, statement);
Expect(Token::SWITCH, CHECK_OK); Expect(Token::SWITCH, CHECK_OK);
...@@ -2170,15 +1939,15 @@ SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, ...@@ -2170,15 +1939,15 @@ SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels,
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
bool default_seen = false; bool default_seen = false;
ZoneListWrapper<CaseClause> cases = factory()->NewList<CaseClause>(4); ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4);
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
while (peek() != Token::RBRACE) { while (peek() != Token::RBRACE) {
CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
cases.Add(clause); cases->Add(clause);
} }
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE, CHECK_OK);
if (statement) statement->Initialize(tag, cases.elements()); if (statement) statement->Initialize(tag, cases);
return statement; return statement;
} }
...@@ -2197,7 +1966,7 @@ Statement* Parser::ParseThrowStatement(bool* ok) { ...@@ -2197,7 +1966,7 @@ Statement* Parser::ParseThrowStatement(bool* ok) {
Expression* exception = ParseExpression(true, CHECK_OK); Expression* exception = ParseExpression(true, CHECK_OK);
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return NEW(ExpressionStatement(new Throw(exception, pos))); return new ExpressionStatement(new Throw(exception, pos));
} }
...@@ -2215,7 +1984,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2215,7 +1984,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
Expect(Token::TRY, CHECK_OK); Expect(Token::TRY, CHECK_OK);
ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0)); ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0);
TargetCollector collector(target_list); TargetCollector collector(target_list);
Block* try_block; Block* try_block;
...@@ -2238,7 +2007,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2238,7 +2007,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
// then we will need to collect jump targets from the catch block. Since // 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 // we don't know yet if there will be a finally block, we always collect
// the jump targets. // the jump targets.
ZoneList<BreakTarget*>* catch_target_list = NEW(ZoneList<BreakTarget*>(0)); ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0);
TargetCollector catch_collector(catch_target_list); TargetCollector catch_collector(catch_target_list);
bool has_catch = false; bool has_catch = false;
if (tok == Token::CATCH) { if (tok == Token::CATCH) {
...@@ -2253,8 +2022,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2253,8 +2022,8 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
// Allocate a temporary for holding the finally state while // Allocate a temporary for holding the finally state while
// executing the finally block. // executing the finally block.
catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol());
Literal* name_literal = NEW(Literal(name)); Literal* name_literal = new Literal(name);
Expression* obj = NEW(CatchExtensionObject(name_literal, catch_var)); Expression* obj = new CatchExtensionObject(name_literal, catch_var);
{ Target target(&this->target_stack_, &catch_collector); { Target target(&this->target_stack_, &catch_collector);
catch_block = WithHelper(obj, NULL, true, CHECK_OK); catch_block = WithHelper(obj, NULL, true, CHECK_OK);
} }
...@@ -2277,30 +2046,28 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2277,30 +2046,28 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
// to: // to:
// 'try { try { } catch { } } finally { }' // 'try { try { } catch { } } finally { }'
if (!is_pre_parsing_ && catch_block != NULL && finally_block != NULL) { if (catch_block != NULL && finally_block != NULL) {
TryCatchStatement* statement = TryCatchStatement* statement =
NEW(TryCatchStatement(try_block, catch_var, catch_block)); new TryCatchStatement(try_block, catch_var, catch_block);
statement->set_escaping_targets(collector.targets()); statement->set_escaping_targets(collector.targets());
try_block = NEW(Block(NULL, 1, false)); try_block = new Block(NULL, 1, false);
try_block->AddStatement(statement); try_block->AddStatement(statement);
catch_block = NULL; catch_block = NULL;
} }
TryStatement* result = NULL; TryStatement* result = NULL;
if (!is_pre_parsing_) { if (catch_block != NULL) {
if (catch_block != NULL) { ASSERT(finally_block == NULL);
ASSERT(finally_block == NULL); result = new TryCatchStatement(try_block, catch_var, catch_block);
result = NEW(TryCatchStatement(try_block, catch_var, catch_block)); result->set_escaping_targets(collector.targets());
result->set_escaping_targets(collector.targets()); } else {
} else { ASSERT(finally_block != NULL);
ASSERT(finally_block != NULL); result = new TryFinallyStatement(try_block, finally_block);
result = NEW(TryFinallyStatement(try_block, finally_block)); // Add the jump targets of the try block and the catch block.
// Add the jump targets of the try block and the catch block. for (int i = 0; i < collector.targets()->length(); i++) {
for (int i = 0; i < collector.targets()->length(); i++) { catch_collector.AddTarget(collector.targets()->at(i));
catch_collector.AddTarget(collector.targets()->at(i));
}
result->set_escaping_targets(catch_collector.targets());
} }
result->set_escaping_targets(catch_collector.targets());
} }
return result; return result;
...@@ -2313,7 +2080,7 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, ...@@ -2313,7 +2080,7 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels,
// 'do' Statement 'while' '(' Expression ')' ';' // 'do' Statement 'while' '(' Expression ')' ';'
temp_scope_->AddLoop(); temp_scope_->AddLoop();
DoWhileStatement* loop = NEW(DoWhileStatement(labels)); DoWhileStatement* loop = new DoWhileStatement(labels);
Target target(&this->target_stack_, loop); Target target(&this->target_stack_, loop);
Expect(Token::DO, CHECK_OK); Expect(Token::DO, CHECK_OK);
...@@ -2346,7 +2113,7 @@ WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { ...@@ -2346,7 +2113,7 @@ WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) {
// 'while' '(' Expression ')' Statement // 'while' '(' Expression ')' Statement
temp_scope_->AddLoop(); temp_scope_->AddLoop();
WhileStatement* loop = NEW(WhileStatement(labels)); WhileStatement* loop = new WhileStatement(labels);
Target target(&this->target_stack_, loop); Target target(&this->target_stack_, loop);
Expect(Token::WHILE, CHECK_OK); Expect(Token::WHILE, CHECK_OK);
...@@ -2376,7 +2143,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { ...@@ -2376,7 +2143,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Block* variable_statement = Block* variable_statement =
ParseVariableDeclarations(false, &each, CHECK_OK); ParseVariableDeclarations(false, &each, CHECK_OK);
if (peek() == Token::IN && each != NULL) { if (peek() == Token::IN && each != NULL) {
ForInStatement* loop = NEW(ForInStatement(labels)); ForInStatement* loop = new ForInStatement(labels);
Target target(&this->target_stack_, loop); Target target(&this->target_stack_, loop);
Expect(Token::IN, CHECK_OK); Expect(Token::IN, CHECK_OK);
...@@ -2384,17 +2151,12 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { ...@@ -2384,17 +2151,12 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
Statement* body = ParseStatement(NULL, CHECK_OK); Statement* body = ParseStatement(NULL, CHECK_OK);
if (is_pre_parsing_) { loop->Initialize(each, enumerable, body);
return NULL; Block* result = new Block(NULL, 2, false);
} else { result->AddStatement(variable_statement);
loop->Initialize(each, enumerable, body); result->AddStatement(loop);
Block* result = NEW(Block(NULL, 2, false)); // Parsed for-in loop w/ variable/const declaration.
result->AddStatement(variable_statement); return result;
result->AddStatement(loop);
// Parsed for-in loop w/ variable/const declaration.
return result;
}
} else { } else {
init = variable_statement; init = variable_statement;
} }
...@@ -2410,7 +2172,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { ...@@ -2410,7 +2172,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); Handle<String> type = Factory::invalid_lhs_in_for_in_symbol();
expression = NewThrowReferenceError(type); expression = NewThrowReferenceError(type);
} }
ForInStatement* loop = NEW(ForInStatement(labels)); ForInStatement* loop = new ForInStatement(labels);
Target target(&this->target_stack_, loop); Target target(&this->target_stack_, loop);
Expect(Token::IN, CHECK_OK); Expect(Token::IN, CHECK_OK);
...@@ -2423,13 +2185,13 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { ...@@ -2423,13 +2185,13 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
return loop; return loop;
} else { } else {
init = NEW(ExpressionStatement(expression)); init = new ExpressionStatement(expression);
} }
} }
} }
// Standard 'for' loop // Standard 'for' loop
ForStatement* loop = NEW(ForStatement(labels)); ForStatement* loop = new ForStatement(labels);
Target target(&this->target_stack_, loop); Target target(&this->target_stack_, loop);
// Parsed initializer at this point. // Parsed initializer at this point.
...@@ -2445,7 +2207,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { ...@@ -2445,7 +2207,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) {
Statement* next = NULL; Statement* next = NULL;
if (peek() != Token::RPAREN) { if (peek() != Token::RPAREN) {
Expression* exp = ParseExpression(true, CHECK_OK); Expression* exp = ParseExpression(true, CHECK_OK);
next = NEW(ExpressionStatement(exp)); next = new ExpressionStatement(exp);
} }
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
...@@ -2466,7 +2228,7 @@ Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { ...@@ -2466,7 +2228,7 @@ Expression* Parser::ParseExpression(bool accept_IN, bool* ok) {
Expect(Token::COMMA, CHECK_OK); Expect(Token::COMMA, CHECK_OK);
int position = scanner().location().beg_pos; int position = scanner().location().beg_pos;
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
result = NEW(BinaryOperation(Token::COMMA, result, right, position)); result = new BinaryOperation(Token::COMMA, result, right, position);
} }
return result; return result;
} }
...@@ -2526,7 +2288,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { ...@@ -2526,7 +2288,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) {
fni_->Leave(); fni_->Leave();
} }
return NEW(Assignment(op, expression, right, pos)); return new Assignment(op, expression, right, pos);
} }
...@@ -2548,8 +2310,8 @@ Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { ...@@ -2548,8 +2310,8 @@ Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) {
Expect(Token::COLON, CHECK_OK); Expect(Token::COLON, CHECK_OK);
int right_position = scanner().peek_location().beg_pos; int right_position = scanner().peek_location().beg_pos;
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
return NEW(Conditional(expression, left, right, return new Conditional(expression, left, right,
left_position, right_position)); left_position, right_position);
} }
...@@ -2656,12 +2418,12 @@ Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { ...@@ -2656,12 +2418,12 @@ Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
x = NewCompareNode(cmp, x, y, position); x = NewCompareNode(cmp, x, y, position);
if (cmp != op) { if (cmp != op) {
// The comparison was negated - add a NOT. // The comparison was negated - add a NOT.
x = NEW(UnaryOperation(Token::NOT, x)); x = new UnaryOperation(Token::NOT, x);
} }
} else { } else {
// We have a "normal" binary operation. // We have a "normal" binary operation.
x = NEW(BinaryOperation(op, x, y, position)); x = new BinaryOperation(op, x, y, position);
} }
} }
} }
...@@ -2674,19 +2436,19 @@ Expression* Parser::NewCompareNode(Token::Value op, ...@@ -2674,19 +2436,19 @@ Expression* Parser::NewCompareNode(Token::Value op,
Expression* y, Expression* y,
int position) { int position) {
ASSERT(op != Token::NE && op != Token::NE_STRICT); ASSERT(op != Token::NE && op != Token::NE_STRICT);
if (!is_pre_parsing_ && (op == Token::EQ || op == Token::EQ_STRICT)) { if (op == Token::EQ || op == Token::EQ_STRICT) {
bool is_strict = (op == Token::EQ_STRICT); bool is_strict = (op == Token::EQ_STRICT);
Literal* x_literal = x->AsLiteral(); Literal* x_literal = x->AsLiteral();
if (x_literal != NULL && x_literal->IsNull()) { if (x_literal != NULL && x_literal->IsNull()) {
return NEW(CompareToNull(is_strict, y)); return new CompareToNull(is_strict, y);
} }
Literal* y_literal = y->AsLiteral(); Literal* y_literal = y->AsLiteral();
if (y_literal != NULL && y_literal->IsNull()) { if (y_literal != NULL && y_literal->IsNull()) {
return NEW(CompareToNull(is_strict, x)); return new CompareToNull(is_strict, x);
} }
} }
return NEW(CompareOperation(op, x, y, position)); return new CompareOperation(op, x, y, position);
} }
...@@ -2723,7 +2485,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { ...@@ -2723,7 +2485,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
} }
} }
return NEW(UnaryOperation(op, expression)); return new UnaryOperation(op, expression);
} else if (Token::IsCountOp(op)) { } else if (Token::IsCountOp(op)) {
op = Next(); op = Next();
...@@ -2737,8 +2499,8 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { ...@@ -2737,8 +2499,8 @@ Expression* Parser::ParseUnaryExpression(bool* ok) {
expression = NewThrowReferenceError(type); expression = NewThrowReferenceError(type);
} }
int position = scanner().location().beg_pos; int position = scanner().location().beg_pos;
IncrementOperation* increment = NEW(IncrementOperation(op, expression)); IncrementOperation* increment = new IncrementOperation(op, expression);
return NEW(CountOperation(true /* prefix */, increment, position)); return new CountOperation(true /* prefix */, increment, position);
} else { } else {
return ParsePostfixExpression(ok); return ParsePostfixExpression(ok);
...@@ -2762,8 +2524,8 @@ Expression* Parser::ParsePostfixExpression(bool* ok) { ...@@ -2762,8 +2524,8 @@ Expression* Parser::ParsePostfixExpression(bool* ok) {
} }
Token::Value next = Next(); Token::Value next = Next();
int position = scanner().location().beg_pos; int position = scanner().location().beg_pos;
IncrementOperation* increment = NEW(IncrementOperation(next, expression)); IncrementOperation* increment = new IncrementOperation(next, expression);
expression = NEW(CountOperation(false /* postfix */, increment, position)); expression = new CountOperation(false /* postfix */, increment, position);
} }
return expression; return expression;
} }
...@@ -2786,7 +2548,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) { ...@@ -2786,7 +2548,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
Consume(Token::LBRACK); Consume(Token::LBRACK);
int pos = scanner().location().beg_pos; int pos = scanner().location().beg_pos;
Expression* index = ParseExpression(true, CHECK_OK); Expression* index = ParseExpression(true, CHECK_OK);
result = factory()->NewProperty(result, index, pos); result = new Property(result, index, pos);
Expect(Token::RBRACK, CHECK_OK); Expect(Token::RBRACK, CHECK_OK);
break; break;
} }
...@@ -2803,17 +2565,15 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) { ...@@ -2803,17 +2565,15 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
// declared in the current scope chain. These calls are marked as // declared in the current scope chain. These calls are marked as
// potentially direct eval calls. Whether they are actually direct calls // potentially direct eval calls. Whether they are actually direct calls
// to eval is determined at run time. // to eval is determined at run time.
if (!is_pre_parsing_) { VariableProxy* callee = result->AsVariableProxy();
VariableProxy* callee = result->AsVariableProxy(); if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) {
if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) { Handle<String> name = callee->name();
Handle<String> name = callee->name(); Variable* var = top_scope_->Lookup(name);
Variable* var = top_scope_->Lookup(name); if (var == NULL) {
if (var == NULL) { top_scope_->RecordEvalCall();
top_scope_->RecordEvalCall();
}
} }
} }
result = factory()->NewCall(result, args, pos); result = NewCall(result, args, pos);
break; break;
} }
...@@ -2821,7 +2581,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) { ...@@ -2821,7 +2581,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
Consume(Token::PERIOD); Consume(Token::PERIOD);
int pos = scanner().location().beg_pos; int pos = scanner().location().beg_pos;
Handle<String> name = ParseIdentifierName(CHECK_OK); Handle<String> name = ParseIdentifierName(CHECK_OK);
result = factory()->NewProperty(result, NEW(Literal(name)), pos); result = new Property(result, new Literal(name), pos);
if (fni_ != NULL) fni_->PushLiteralName(name); if (fni_ != NULL) fni_->PushLiteralName(name);
break; break;
} }
...@@ -2833,7 +2593,6 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) { ...@@ -2833,7 +2593,6 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
} }
Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
// NewExpression :: // NewExpression ::
// ('new')+ MemberExpression // ('new')+ MemberExpression
...@@ -2858,7 +2617,7 @@ Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { ...@@ -2858,7 +2617,7 @@ Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
if (!stack->is_empty()) { if (!stack->is_empty()) {
int last = stack->pop(); int last = stack->pop();
result = NEW(CallNew(result, new ZoneList<Expression*>(0), last)); result = new CallNew(result, new ZoneList<Expression*>(0), last);
} }
return result; return result;
} }
...@@ -2900,7 +2659,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, ...@@ -2900,7 +2659,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
Consume(Token::LBRACK); Consume(Token::LBRACK);
int pos = scanner().location().beg_pos; int pos = scanner().location().beg_pos;
Expression* index = ParseExpression(true, CHECK_OK); Expression* index = ParseExpression(true, CHECK_OK);
result = factory()->NewProperty(result, index, pos); result = new Property(result, index, pos);
Expect(Token::RBRACK, CHECK_OK); Expect(Token::RBRACK, CHECK_OK);
break; break;
} }
...@@ -2908,7 +2667,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, ...@@ -2908,7 +2667,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
Consume(Token::PERIOD); Consume(Token::PERIOD);
int pos = scanner().location().beg_pos; int pos = scanner().location().beg_pos;
Handle<String> name = ParseIdentifierName(CHECK_OK); Handle<String> name = ParseIdentifierName(CHECK_OK);
result = factory()->NewProperty(result, NEW(Literal(name)), pos); result = new Property(result, new Literal(name), pos);
if (fni_ != NULL) fni_->PushLiteralName(name); if (fni_ != NULL) fni_->PushLiteralName(name);
break; break;
} }
...@@ -2917,7 +2676,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, ...@@ -2917,7 +2676,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
// Consume one of the new prefixes (already parsed). // Consume one of the new prefixes (already parsed).
ZoneList<Expression*>* args = ParseArguments(CHECK_OK); ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
int last = stack->pop(); int last = stack->pop();
result = NEW(CallNew(result, args, last)); result = new CallNew(result, args, last);
break; break;
} }
default: default:
...@@ -2936,7 +2695,7 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { ...@@ -2936,7 +2695,7 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) {
Expect(Token::DEBUGGER, CHECK_OK); Expect(Token::DEBUGGER, CHECK_OK);
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return NEW(DebuggerStatement()); return new DebuggerStatement();
} }
...@@ -2994,38 +2753,30 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) { ...@@ -2994,38 +2753,30 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
switch (peek()) { switch (peek()) {
case Token::THIS: { case Token::THIS: {
Consume(Token::THIS); Consume(Token::THIS);
if (is_pre_parsing_) { VariableProxy* recv = top_scope_->receiver();
result = VariableProxySentinel::this_proxy(); result = recv;
} else {
VariableProxy* recv = top_scope_->receiver();
result = recv;
}
break; break;
} }
case Token::NULL_LITERAL: case Token::NULL_LITERAL:
Consume(Token::NULL_LITERAL); Consume(Token::NULL_LITERAL);
result = NEW(Literal(Factory::null_value())); result = new Literal(Factory::null_value());
break; break;
case Token::TRUE_LITERAL: case Token::TRUE_LITERAL:
Consume(Token::TRUE_LITERAL); Consume(Token::TRUE_LITERAL);
result = NEW(Literal(Factory::true_value())); result = new Literal(Factory::true_value());
break; break;
case Token::FALSE_LITERAL: case Token::FALSE_LITERAL:
Consume(Token::FALSE_LITERAL); Consume(Token::FALSE_LITERAL);
result = NEW(Literal(Factory::false_value())); result = new Literal(Factory::false_value());
break; break;
case Token::IDENTIFIER: { case Token::IDENTIFIER: {
Handle<String> name = ParseIdentifier(CHECK_OK); Handle<String> name = ParseIdentifier(CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name); if (fni_ != NULL) fni_->PushVariableName(name);
if (is_pre_parsing_) { result = top_scope_->NewUnresolved(name, inside_with());
result = VariableProxySentinel::identifier_proxy();
} else {
result = top_scope_->NewUnresolved(name, inside_with());
}
break; break;
} }
...@@ -3040,7 +2791,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) { ...@@ -3040,7 +2791,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
case Token::STRING: { case Token::STRING: {
Consume(Token::STRING); Consume(Token::STRING);
Handle<String> symbol = GetSymbol(CHECK_OK); Handle<String> symbol = GetSymbol(CHECK_OK);
result = NEW(Literal(symbol)); result = new Literal(symbol);
if (fni_ != NULL) fni_->PushLiteralName(symbol); if (fni_ != NULL) fni_->PushLiteralName(symbol);
break; break;
} }
...@@ -3118,7 +2869,7 @@ Expression* Parser::ParseArrayLiteral(bool* ok) { ...@@ -3118,7 +2869,7 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
// ArrayLiteral :: // ArrayLiteral ::
// '[' Expression? (',' Expression?)* ']' // '[' Expression? (',' Expression?)* ']'
ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4); ZoneList<Expression*>* values = new ZoneList<Expression*>(4);
Expect(Token::LBRACK, CHECK_OK); Expect(Token::LBRACK, CHECK_OK);
while (peek() != Token::RBRACK) { while (peek() != Token::RBRACK) {
Expression* elem; Expression* elem;
...@@ -3127,7 +2878,7 @@ Expression* Parser::ParseArrayLiteral(bool* ok) { ...@@ -3127,7 +2878,7 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
} else { } else {
elem = ParseAssignmentExpression(true, CHECK_OK); elem = ParseAssignmentExpression(true, CHECK_OK);
} }
values.Add(elem); values->Add(elem);
if (peek() != Token::RBRACK) { if (peek() != Token::RBRACK) {
Expect(Token::COMMA, CHECK_OK); Expect(Token::COMMA, CHECK_OK);
} }
...@@ -3137,21 +2888,19 @@ Expression* Parser::ParseArrayLiteral(bool* ok) { ...@@ -3137,21 +2888,19 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
// Update the scope information before the pre-parsing bailout. // Update the scope information before the pre-parsing bailout.
int literal_index = temp_scope_->NextMaterializedLiteralIndex(); int literal_index = temp_scope_->NextMaterializedLiteralIndex();
if (is_pre_parsing_) return NULL;
// Allocate a fixed array with all the literals. // Allocate a fixed array with all the literals.
Handle<FixedArray> literals = Handle<FixedArray> literals =
Factory::NewFixedArray(values.length(), TENURED); Factory::NewFixedArray(values->length(), TENURED);
// Fill in the literals. // Fill in the literals.
bool is_simple = true; bool is_simple = true;
int depth = 1; int depth = 1;
for (int i = 0; i < values.length(); i++) { for (int i = 0, n = values->length(); i < n; i++) {
MaterializedLiteral* m_literal = values.at(i)->AsMaterializedLiteral(); MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral();
if (m_literal != NULL && m_literal->depth() + 1 > depth) { if (m_literal != NULL && m_literal->depth() + 1 > depth) {
depth = m_literal->depth() + 1; depth = m_literal->depth() + 1;
} }
Handle<Object> boilerplate_value = GetBoilerplateValue(values.at(i)); Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i));
if (boilerplate_value->IsUndefined()) { if (boilerplate_value->IsUndefined()) {
literals->set_the_hole(i); literals->set_the_hole(i);
is_simple = false; is_simple = false;
...@@ -3162,12 +2911,12 @@ Expression* Parser::ParseArrayLiteral(bool* ok) { ...@@ -3162,12 +2911,12 @@ Expression* Parser::ParseArrayLiteral(bool* ok) {
// Simple and shallow arrays can be lazily copied, we transform the // Simple and shallow arrays can be lazily copied, we transform the
// elements array to a copy-on-write array. // elements array to a copy-on-write array.
if (is_simple && depth == 1 && values.length() > 0) { if (is_simple && depth == 1 && values->length() > 0) {
literals->set_map(Heap::fixed_cow_array_map()); literals->set_map(Heap::fixed_cow_array_map());
} }
return NEW(ArrayLiteral(literals, values.elements(), return new ArrayLiteral(literals, values,
literal_index, is_simple, depth)); literal_index, is_simple, depth);
} }
...@@ -3314,7 +3063,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, ...@@ -3314,7 +3063,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
DECLARATION, DECLARATION,
CHECK_OK); CHECK_OK);
ObjectLiteral::Property* property = ObjectLiteral::Property* property =
NEW(ObjectLiteral::Property(is_getter, value)); new ObjectLiteral::Property(is_getter, value);
return property; return property;
} else { } else {
ReportUnexpectedToken(next); ReportUnexpectedToken(next);
...@@ -3331,8 +3080,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3331,8 +3080,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
// | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
// )*[','] '}' // )*[','] '}'
ZoneListWrapper<ObjectLiteral::Property> properties = ZoneList<ObjectLiteral::Property*>* properties =
factory()->NewList<ObjectLiteral::Property>(4); new ZoneList<ObjectLiteral::Property*>(4);
int number_of_boilerplate_properties = 0; int number_of_boilerplate_properties = 0;
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
...@@ -3355,7 +3104,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3355,7 +3104,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
if (IsBoilerplateProperty(property)) { if (IsBoilerplateProperty(property)) {
number_of_boilerplate_properties++; number_of_boilerplate_properties++;
} }
properties.Add(property); properties->Add(property);
if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
if (fni_ != NULL) { if (fni_ != NULL) {
...@@ -3366,7 +3115,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3366,7 +3115,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
} }
// Failed to parse as get/set property, so it's just a property // Failed to parse as get/set property, so it's just a property
// called "get" or "set". // called "get" or "set".
key = NEW(Literal(id)); key = new Literal(id);
break; break;
} }
case Token::STRING: { case Token::STRING: {
...@@ -3378,7 +3127,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3378,7 +3127,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
key = NewNumberLiteral(index); key = NewNumberLiteral(index);
break; break;
} }
key = NEW(Literal(string)); key = new Literal(string);
break; break;
} }
case Token::NUMBER: { case Token::NUMBER: {
...@@ -3392,7 +3141,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3392,7 +3141,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
if (Token::IsKeyword(next)) { if (Token::IsKeyword(next)) {
Consume(next); Consume(next);
Handle<String> string = GetSymbol(CHECK_OK); Handle<String> string = GetSymbol(CHECK_OK);
key = NEW(Literal(string)); key = new Literal(string);
} else { } else {
// Unexpected token. // Unexpected token.
Token::Value next = Next(); Token::Value next = Next();
...@@ -3406,11 +3155,11 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3406,11 +3155,11 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
Expression* value = ParseAssignmentExpression(true, CHECK_OK); Expression* value = ParseAssignmentExpression(true, CHECK_OK);
ObjectLiteral::Property* property = ObjectLiteral::Property* property =
NEW(ObjectLiteral::Property(key, value)); new ObjectLiteral::Property(key, value);
// Count CONSTANT or COMPUTED properties to maintain the enumeration order. // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
properties.Add(property); properties->Add(property);
// TODO(1240767): Consider allowing trailing comma. // TODO(1240767): Consider allowing trailing comma.
if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
...@@ -3423,7 +3172,6 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3423,7 +3172,6 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE, CHECK_OK);
// Computation of literal_index must happen before pre parse bailout. // Computation of literal_index must happen before pre parse bailout.
int literal_index = temp_scope_->NextMaterializedLiteralIndex(); int literal_index = temp_scope_->NextMaterializedLiteralIndex();
if (is_pre_parsing_) return NULL;
Handle<FixedArray> constant_properties = Handle<FixedArray> constant_properties =
Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
...@@ -3431,13 +3179,13 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3431,13 +3179,13 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
bool is_simple = true; bool is_simple = true;
bool fast_elements = true; bool fast_elements = true;
int depth = 1; int depth = 1;
BuildObjectLiteralConstantProperties(properties.elements(), BuildObjectLiteralConstantProperties(properties,
constant_properties, constant_properties,
&is_simple, &is_simple,
&fast_elements, &fast_elements,
&depth); &depth);
return new ObjectLiteral(constant_properties, return new ObjectLiteral(constant_properties,
properties.elements(), properties,
literal_index, literal_index,
is_simple, is_simple,
fast_elements, fast_elements,
...@@ -3455,19 +3203,6 @@ Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { ...@@ -3455,19 +3203,6 @@ Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) {
int literal_index = temp_scope_->NextMaterializedLiteralIndex(); int literal_index = temp_scope_->NextMaterializedLiteralIndex();
if (is_pre_parsing_) {
// If we're preparsing we just do all the parsing stuff without
// building anything.
if (!scanner_.ScanRegExpFlags()) {
Next();
ReportMessage("invalid_regexp_flags", Vector<const char*>::empty());
*ok = false;
return NULL;
}
Next();
return NULL;
}
Handle<String> js_pattern = Handle<String> js_pattern =
Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED); Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED);
scanner_.ScanRegExpFlags(); scanner_.ScanRegExpFlags();
...@@ -3483,17 +3218,17 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { ...@@ -3483,17 +3218,17 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
// Arguments :: // Arguments ::
// '(' (AssignmentExpression)*[','] ')' // '(' (AssignmentExpression)*[','] ')'
ZoneListWrapper<Expression> result = factory()->NewList<Expression>(4); ZoneList<Expression*>* result = new ZoneList<Expression*>(4);
Expect(Token::LPAREN, CHECK_OK); Expect(Token::LPAREN, CHECK_OK);
bool done = (peek() == Token::RPAREN); bool done = (peek() == Token::RPAREN);
while (!done) { while (!done) {
Expression* argument = ParseAssignmentExpression(true, CHECK_OK); Expression* argument = ParseAssignmentExpression(true, CHECK_OK);
result.Add(argument); result->Add(argument);
done = (peek() == Token::RPAREN); done = (peek() == Token::RPAREN);
if (!done) Expect(Token::COMMA, CHECK_OK); if (!done) Expect(Token::COMMA, CHECK_OK);
} }
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
return result.elements(); return result;
} }
...@@ -3509,9 +3244,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, ...@@ -3509,9 +3244,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
// this is the actual function name, otherwise this is the name of the // this is the actual function name, otherwise this is the name of the
// variable declared and initialized with the function (expression). In // variable declared and initialized with the function (expression). In
// that case, we don't have a function name (it's empty). // that case, we don't have a function name (it's empty).
Handle<String> name = is_named ? var_name : factory()->EmptySymbol(); Handle<String> name = is_named ? var_name : Factory::empty_symbol();
// The function name, if any. // The function name, if any.
Handle<String> function_name = factory()->EmptySymbol(); Handle<String> function_name = Factory::empty_symbol();
if (is_named && (type == EXPRESSION || type == NESTED)) { if (is_named && (type == EXPRESSION || type == NESTED)) {
function_name = name; function_name = name;
} }
...@@ -3519,7 +3254,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, ...@@ -3519,7 +3254,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
int num_parameters = 0; int num_parameters = 0;
// Parse function body. // Parse function body.
{ Scope* scope = { Scope* scope =
factory()->NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
scope); scope);
TemporaryScope temp_scope(&this->temp_scope_); TemporaryScope temp_scope(&this->temp_scope_);
...@@ -3532,18 +3267,16 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, ...@@ -3532,18 +3267,16 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
bool done = (peek() == Token::RPAREN); bool done = (peek() == Token::RPAREN);
while (!done) { while (!done) {
Handle<String> param_name = ParseIdentifier(CHECK_OK); Handle<String> param_name = ParseIdentifier(CHECK_OK);
if (!is_pre_parsing_) { top_scope_->AddParameter(top_scope_->DeclareLocal(param_name,
top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, Variable::VAR));
Variable::VAR)); num_parameters++;
num_parameters++;
}
done = (peek() == Token::RPAREN); done = (peek() == Token::RPAREN);
if (!done) Expect(Token::COMMA, CHECK_OK); if (!done) Expect(Token::COMMA, CHECK_OK);
} }
Expect(Token::RPAREN, CHECK_OK); Expect(Token::RPAREN, CHECK_OK);
Expect(Token::LBRACE, CHECK_OK); Expect(Token::LBRACE, CHECK_OK);
ZoneListWrapper<Statement> body = factory()->NewList<Statement>(8); ZoneList<Statement*>* body = new ZoneList<Statement*>(8);
// If we have a named function expression, we add a local variable // If we have a named function expression, we add a local variable
// declaration to the body of the function with the name of the // declaration to the body of the function with the name of the
...@@ -3551,17 +3284,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, ...@@ -3551,17 +3284,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
// NOTE: We create a proxy and resolve it here so that in the // NOTE: We create a proxy and resolve it here so that in the
// future we can change the AST to only refer to VariableProxies // future we can change the AST to only refer to VariableProxies
// instead of Variables and Proxis as is the case now. // instead of Variables and Proxis as is the case now.
if (!is_pre_parsing_ if (!function_name.is_null() && function_name->length() > 0) {
&& !function_name.is_null()
&& function_name->length() > 0) {
Variable* fvar = top_scope_->DeclareFunctionVar(function_name); Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
VariableProxy* fproxy = VariableProxy* fproxy =
top_scope_->NewUnresolved(function_name, inside_with()); top_scope_->NewUnresolved(function_name, inside_with());
fproxy->BindTo(fvar); fproxy->BindTo(fvar);
body.Add(new ExpressionStatement( body->Add(new ExpressionStatement(
new Assignment(Token::INIT_CONST, fproxy, new Assignment(Token::INIT_CONST, fproxy,
NEW(ThisFunction()), new ThisFunction(),
RelocInfo::kNoPosition))); RelocInfo::kNoPosition)));
} }
// Determine if the function will be lazily compiled. The mode can // Determine if the function will be lazily compiled. The mode can
...@@ -3593,11 +3324,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, ...@@ -3593,11 +3324,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
this_property_assignments = Factory::empty_fixed_array(); this_property_assignments = Factory::empty_fixed_array();
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE, CHECK_OK);
} else { } else {
FunctionEntry entry; ParseSourceElements(body, Token::RBRACE, CHECK_OK);
{
ConditionalLogPauseScope pause_if(is_lazily_compiled, log());
ParseSourceElements(&body, Token::RBRACE, CHECK_OK);
}
materialized_literal_count = temp_scope.materialized_literal_count(); materialized_literal_count = temp_scope.materialized_literal_count();
expected_property_count = temp_scope.expected_property_count(); expected_property_count = temp_scope.expected_property_count();
only_simple_this_property_assignments = only_simple_this_property_assignments =
...@@ -3606,18 +3334,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, ...@@ -3606,18 +3334,12 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
Expect(Token::RBRACE, CHECK_OK); Expect(Token::RBRACE, CHECK_OK);
end_pos = scanner_.location().end_pos; end_pos = scanner_.location().end_pos;
if (is_pre_parsing_ && is_lazily_compiled) {
ASSERT(is_pre_parsing_);
log()->LogFunction(function_block_pos, end_pos,
materialized_literal_count,
expected_property_count);
}
} }
FunctionLiteral* function_literal = FunctionLiteral* function_literal =
NEW(FunctionLiteral(name, new FunctionLiteral(name,
top_scope_, top_scope_,
body.elements(), body,
materialized_literal_count, materialized_literal_count,
expected_property_count, expected_property_count,
only_simple_this_property_assignments, only_simple_this_property_assignments,
...@@ -3626,10 +3348,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, ...@@ -3626,10 +3348,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
start_pos, start_pos,
end_pos, end_pos,
function_name->length() > 0, function_name->length() > 0,
temp_scope.ContainsLoops())); temp_scope.ContainsLoops());
if (!is_pre_parsing_) { function_literal->set_function_token_position(function_token_position);
function_literal->set_function_token_position(function_token_position);
}
if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
return function_literal; return function_literal;
...@@ -3644,7 +3364,6 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { ...@@ -3644,7 +3364,6 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
Expect(Token::MOD, CHECK_OK); Expect(Token::MOD, CHECK_OK);
Handle<String> name = ParseIdentifier(CHECK_OK); Handle<String> name = ParseIdentifier(CHECK_OK);
ZoneList<Expression*>* args = ParseArguments(CHECK_OK); ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
if (is_pre_parsing_) return NULL;
if (extension_ != NULL) { if (extension_ != NULL) {
// The extension structures are only accessible while parsing the // The extension structures are only accessible while parsing the
...@@ -3680,7 +3399,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { ...@@ -3680,7 +3399,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
} }
// We have a valid intrinsics call or a call to a builtin. // We have a valid intrinsics call or a call to a builtin.
return NEW(CallRuntime(name, function, args)); return new CallRuntime(name, function, args);
} }
...@@ -3728,12 +3447,12 @@ void Parser::ExpectSemicolon(bool* ok) { ...@@ -3728,12 +3447,12 @@ void Parser::ExpectSemicolon(bool* ok) {
Literal* Parser::GetLiteralUndefined() { Literal* Parser::GetLiteralUndefined() {
return NEW(Literal(Factory::undefined_value())); return new Literal(Factory::undefined_value());
} }
Literal* Parser::GetLiteralTheHole() { Literal* Parser::GetLiteralTheHole() {
return NEW(Literal(Factory::the_hole_value())); return new Literal(Factory::the_hole_value());
} }
...@@ -3836,7 +3555,7 @@ void Parser::RegisterTargetUse(BreakTarget* target, Target* stop) { ...@@ -3836,7 +3555,7 @@ void Parser::RegisterTargetUse(BreakTarget* target, Target* stop) {
Literal* Parser::NewNumberLiteral(double number) { Literal* Parser::NewNumberLiteral(double number) {
return NEW(Literal(Factory::NewNumber(number, TENURED))); return new Literal(Factory::NewNumber(number, TENURED));
} }
...@@ -3868,8 +3587,6 @@ Expression* Parser::NewThrowTypeError(Handle<String> type, ...@@ -3868,8 +3587,6 @@ Expression* Parser::NewThrowTypeError(Handle<String> type,
Expression* Parser::NewThrowError(Handle<String> constructor, Expression* Parser::NewThrowError(Handle<String> constructor,
Handle<String> type, Handle<String> type,
Vector< Handle<Object> > arguments) { Vector< Handle<Object> > arguments) {
if (is_pre_parsing_) return NULL;
int argc = arguments.length(); int argc = arguments.length();
Handle<JSArray> array = Factory::NewJSArray(argc, TENURED); Handle<JSArray> array = Factory::NewJSArray(argc, TENURED);
ASSERT(array->IsJSArray() && array->HasFastElements()); ASSERT(array->IsJSArray() && array->HasFastElements());
...@@ -4057,17 +3774,17 @@ Handle<Object> JsonParser::ParseJsonArray() { ...@@ -4057,17 +3774,17 @@ Handle<Object> JsonParser::ParseJsonArray() {
RegExpParser::RegExpParser(FlatStringReader* in, RegExpParser::RegExpParser(FlatStringReader* in,
Handle<String>* error, Handle<String>* error,
bool multiline) bool multiline)
: current_(kEndMarker), : error_(error),
captures_(NULL),
in_(in),
current_(kEndMarker),
next_pos_(0),
capture_count_(0),
has_more_(true), has_more_(true),
multiline_(multiline), multiline_(multiline),
next_pos_(0),
in_(in),
error_(error),
simple_(false), simple_(false),
contains_anchor_(false), contains_anchor_(false),
captures_(NULL),
is_scanned_for_captures_(false), is_scanned_for_captures_(false),
capture_count_(0),
failed_(false) { failed_(false) {
Advance(1); Advance(1);
} }
...@@ -4924,10 +4641,15 @@ ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, ...@@ -4924,10 +4641,15 @@ ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source,
unibrow::CharacterStream* stream, unibrow::CharacterStream* stream,
v8::Extension* extension) { v8::Extension* extension) {
Handle<Script> no_script; Handle<Script> no_script;
bool allow_lazy = FLAG_lazy && (extension == NULL);
if (!allow_lazy) {
// Partial preparsing is only about lazily compiled functions.
// If we don't allow lazy compilation, the log data will be empty.
return NULL;
}
preparser::PreParser<Scanner, PartialParserRecorder> parser; preparser::PreParser<Scanner, PartialParserRecorder> parser;
Scanner scanner; Scanner scanner;
scanner.Initialize(source, stream, JAVASCRIPT); scanner.Initialize(source, stream, JAVASCRIPT);
bool allow_lazy = FLAG_lazy && (extension == NULL);
PartialParserRecorder recorder; PartialParserRecorder recorder;
if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) { if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) {
Top::StackOverflow(); Top::StackOverflow();
...@@ -4988,14 +4710,13 @@ bool ParserApi::Parse(CompilationInfo* info) { ...@@ -4988,14 +4710,13 @@ bool ParserApi::Parse(CompilationInfo* info) {
FunctionLiteral* result = NULL; FunctionLiteral* result = NULL;
Handle<Script> script = info->script(); Handle<Script> script = info->script();
if (info->is_lazy()) { if (info->is_lazy()) {
AstBuildingParser parser(script, true, NULL, NULL); Parser parser(script, true, NULL, NULL);
result = parser.ParseLazy(info->shared_info()); result = parser.ParseLazy(info->shared_info());
} else { } else {
bool allow_natives_syntax = bool allow_natives_syntax =
FLAG_allow_natives_syntax || Bootstrapper::IsActive(); FLAG_allow_natives_syntax || Bootstrapper::IsActive();
ScriptDataImpl* pre_data = info->pre_parse_data(); ScriptDataImpl* pre_data = info->pre_parse_data();
AstBuildingParser parser(script, allow_natives_syntax, info->extension(), Parser parser(script, allow_natives_syntax, info->extension(), pre_data);
pre_data);
if (pre_data != NULL && pre_data->has_error()) { if (pre_data != NULL && pre_data->has_error()) {
Scanner::Location loc = pre_data->MessageLocation(); Scanner::Location loc = pre_data->MessageLocation();
const char* message = pre_data->BuildMessage(); const char* message = pre_data->BuildMessage();
...@@ -5017,6 +4738,4 @@ bool ParserApi::Parse(CompilationInfo* info) { ...@@ -5017,6 +4738,4 @@ bool ParserApi::Parse(CompilationInfo* info) {
return (result != NULL); return (result != NULL);
} }
#undef NEW
} } // namespace v8::internal } } // namespace v8::internal
...@@ -31,13 +31,13 @@ ...@@ -31,13 +31,13 @@
#include "allocation.h" #include "allocation.h"
#include "ast.h" #include "ast.h"
#include "scanner.h" #include "scanner.h"
#include "scopes.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class CompilationInfo; class CompilationInfo;
class FuncNameInferrer; class FuncNameInferrer;
class ParserFactory;
class ParserLog; class ParserLog;
class PositionStack; class PositionStack;
class Target; class Target;
...@@ -177,50 +177,20 @@ class ScriptDataImpl : public ScriptData { ...@@ -177,50 +177,20 @@ class ScriptDataImpl : public ScriptData {
}; };
class ParserLog BASE_EMBEDDED {
public:
virtual ~ParserLog() { }
// Records the occurrence of a function.
virtual void LogFunction(int start, int end, int literals, int properties) {}
// Records the occurrence of a symbol in the source. The vector holds the
// UTF-8 encoded symbol content.
virtual void LogSymbol(int start, Vector<const char> symbol) {}
// Records the occurrence of a symbol in the source. The symbol pointer
// points to the UTF-8 encoded symbol content.
virtual void LogSymbol(int start, const char* symbol, int length) {}
// Return the current position in the function entry log.
virtual int function_position() { return 0; }
// Return the current position in the symbol entry log.
// Notice: Functions and symbols are currently logged separately.
virtual int symbol_position() { return 0; }
// Return the number of distinct symbols logged.
virtual int symbol_ids() { return 0; }
// Pauses recording. The Log-functions above will do nothing during pausing.
// Pauses can be nested.
virtual void PauseRecording() {}
// Ends a recording pause.
virtual void ResumeRecording() {}
// Extracts a representation of the logged data that can be used by
// ScriptData.
virtual Vector<unsigned> ExtractData() {
return Vector<unsigned>();
};
};
// Record only functions. // Record only functions.
class PartialParserRecorder: public ParserLog { class PartialParserRecorder {
public: public:
PartialParserRecorder(); PartialParserRecorder();
virtual void LogFunction(int start, int end, int literals, int properties) { void LogFunction(int start, int end, int literals, int properties) {
function_store_.Add(start); function_store_.Add(start);
function_store_.Add(end); function_store_.Add(end);
function_store_.Add(literals); function_store_.Add(literals);
function_store_.Add(properties); function_store_.Add(properties);
} }
void LogSymbol(int start, const char* symbol, int length) { }
// Logs an error message and marks the log as containing an error. // Logs an error message and marks the log as containing an error.
// Further logging will be ignored, and ExtractData will return a vector // Further logging will be ignored, and ExtractData will return a vector
// representing the error only. // representing the error only.
...@@ -236,24 +206,27 @@ class PartialParserRecorder: public ParserLog { ...@@ -236,24 +206,27 @@ class PartialParserRecorder: public ParserLog {
this->LogMessage(location, message, arguments); this->LogMessage(location, message, arguments);
} }
virtual int function_position() { return function_store_.size(); } int function_position() { return function_store_.size(); }
virtual void LogMessage(Scanner::Location loc, void LogMessage(Scanner::Location loc,
const char* message, const char* message,
Vector<const char*> args); Vector<const char*> args);
virtual Vector<unsigned> ExtractData(); Vector<unsigned> ExtractData();
virtual void PauseRecording() { void PauseRecording() {
pause_count_++; pause_count_++;
is_recording_ = false; is_recording_ = false;
} }
virtual void ResumeRecording() { void ResumeRecording() {
ASSERT(pause_count_ > 0); ASSERT(pause_count_ > 0);
if (--pause_count_ == 0) is_recording_ = !has_error(); if (--pause_count_ == 0) is_recording_ = !has_error();
} }
int symbol_position() { return 0; }
int symbol_ids() { return 0; }
protected: protected:
bool has_error() { bool has_error() {
return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
...@@ -281,16 +254,16 @@ class CompleteParserRecorder: public PartialParserRecorder { ...@@ -281,16 +254,16 @@ class CompleteParserRecorder: public PartialParserRecorder {
public: public:
CompleteParserRecorder(); CompleteParserRecorder();
virtual void LogSymbol(int start, Vector<const char> literal); void LogSymbol(int start, Vector<const char> literal);
virtual void LogSymbol(int start, const char* symbol, int length) { void LogSymbol(int start, const char* symbol, int length) {
LogSymbol(start, Vector<const char>(symbol, length)); LogSymbol(start, Vector<const char>(symbol, length));
} }
virtual Vector<unsigned> ExtractData(); Vector<unsigned> ExtractData();
virtual int symbol_position() { return symbol_store_.size(); } int symbol_position() { return symbol_store_.size(); }
virtual int symbol_ids() { return symbol_id_; } int symbol_ids() { return symbol_id_; }
private: private:
static int vector_hash(Vector<const char> string) { static int vector_hash(Vector<const char> string) {
...@@ -342,6 +315,8 @@ class ParserApi { ...@@ -342,6 +315,8 @@ class ParserApi {
v8::Extension* extension); v8::Extension* extension);
}; };
// ----------------------------------------------------------------------------
// REGEXP PARSING
// A BuffferedZoneList is an automatically growing list, just like (and backed // A BuffferedZoneList is an automatically growing list, just like (and backed
// by) a ZoneList, that is optimized for the case of adding and removing // by) a ZoneList, that is optimized for the case of adding and removing
...@@ -557,47 +532,44 @@ class RegExpParser { ...@@ -557,47 +532,44 @@ class RegExpParser {
uc32 Next(); uc32 Next();
FlatStringReader* in() { return in_; } FlatStringReader* in() { return in_; }
void ScanForCaptures(); void ScanForCaptures();
Handle<String>* error_;
ZoneList<RegExpCapture*>* captures_;
FlatStringReader* in_;
uc32 current_; uc32 current_;
int next_pos_;
// The capture count is only valid after we have scanned for captures.
int capture_count_;
bool has_more_; bool has_more_;
bool multiline_; bool multiline_;
int next_pos_;
FlatStringReader* in_;
Handle<String>* error_;
bool simple_; bool simple_;
bool contains_anchor_; bool contains_anchor_;
ZoneList<RegExpCapture*>* captures_;
bool is_scanned_for_captures_; bool is_scanned_for_captures_;
// The capture count is only valid after we have scanned for captures.
int capture_count_;
bool failed_; bool failed_;
}; };
// ----------------------------------------------------------------------------
// JAVASCRIPT PARSING
class Parser { class Parser {
public: public:
Parser(Handle<Script> script, bool allow_natives_syntax, Parser(Handle<Script> script,
v8::Extension* extension, ParserMode is_pre_parsing, bool allow_natives_syntax,
ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data); v8::Extension* extension,
ScriptDataImpl* pre_data);
virtual ~Parser() { } virtual ~Parser() { }
void ReportMessage(const char* message, Vector<const char*> args);
virtual void ReportMessageAt(Scanner::Location loc,
const char* message,
Vector<const char*> args) = 0;
// Returns NULL if parsing failed. // Returns NULL if parsing failed.
FunctionLiteral* ParseProgram(Handle<String> source, FunctionLiteral* ParseProgram(Handle<String> source,
bool in_global_context); bool in_global_context);
FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info); FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info);
// The minimum number of contiguous assignment that will void ReportMessageAt(Scanner::Location loc,
// be treated as an initialization block. Benchmarks show that const char* message,
// the overhead exceeds the savings below this limit. Vector<const char*> args);
static const int kMinInitializationBlock = 3;
protected: protected:
enum Mode { enum Mode {
PARSE_LAZILY, PARSE_LAZILY,
PARSE_EAGERLY PARSE_EAGERLY
...@@ -606,28 +578,9 @@ class Parser { ...@@ -606,28 +578,9 @@ class Parser {
// Report syntax error // Report syntax error
void ReportUnexpectedToken(Token::Value token); void ReportUnexpectedToken(Token::Value token);
void ReportInvalidPreparseData(Handle<String> name, bool* ok); void ReportInvalidPreparseData(Handle<String> name, bool* ok);
void ReportMessage(const char* message, Vector<const char*> args);
Handle<Script> script_;
Scanner scanner_;
Scope* top_scope_;
int with_nesting_level_;
TemporaryScope* temp_scope_;
Mode mode_;
Target* target_stack_; // for break, continue statements
bool allow_natives_syntax_;
v8::Extension* extension_;
ParserFactory* factory_;
ParserLog* log_;
bool is_pre_parsing_;
ScriptDataImpl* pre_data_;
FuncNameInferrer* fni_;
bool inside_with() const { return with_nesting_level_ > 0; } bool inside_with() const { return with_nesting_level_ > 0; }
ParserFactory* factory() const { return factory_; }
ParserLog* log() const { return log_; }
Scanner& scanner() { return scanner_; } Scanner& scanner() { return scanner_; }
Mode mode() const { return mode_; } Mode mode() const { return mode_; }
ScriptDataImpl* pre_data() const { return pre_data_; } ScriptDataImpl* pre_data() const { return pre_data_; }
...@@ -636,7 +589,7 @@ class Parser { ...@@ -636,7 +589,7 @@ class Parser {
// which is set to false if parsing failed; it is unchanged otherwise. // which is set to false if parsing failed; it is unchanged otherwise.
// By making the 'exception handling' explicit, we are forced to check // By making the 'exception handling' explicit, we are forced to check
// for failure at the call sites. // for failure at the call sites.
void* ParseSourceElements(ZoneListWrapper<Statement>* processor, void* ParseSourceElements(ZoneList<Statement*>* processor,
int end_token, bool* ok); int end_token, bool* ok);
Statement* ParseStatement(ZoneStringList* labels, bool* ok); Statement* ParseStatement(ZoneStringList* labels, bool* ok);
Statement* ParseFunctionDeclaration(bool* ok); Statement* ParseFunctionDeclaration(bool* ok);
...@@ -749,10 +702,10 @@ class Parser { ...@@ -749,10 +702,10 @@ class Parser {
bool* ok); bool* ok);
// Parser support // Parser support
virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
FunctionLiteral* fun, FunctionLiteral* fun,
bool resolve, bool resolve,
bool* ok) = 0; bool* ok);
bool TargetStackContainsLabel(Handle<String> label); bool TargetStackContainsLabel(Handle<String> label);
BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok); BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
...@@ -760,6 +713,28 @@ class Parser { ...@@ -760,6 +713,28 @@ class Parser {
void RegisterTargetUse(BreakTarget* target, Target* stop); void RegisterTargetUse(BreakTarget* target, Target* stop);
// Factory methods.
Statement* EmptyStatement() {
static v8::internal::EmptyStatement empty;
return &empty;
}
Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
Handle<String> LookupSymbol(int symbol_id,
Vector<const char> string);
Handle<String> LookupCachedSymbol(int symbol_id,
Vector<const char> string);
Expression* NewCall(Expression* expression,
ZoneList<Expression*>* arguments,
int pos) {
return new Call(expression, arguments, pos);
}
// Create a number literal. // Create a number literal.
Literal* NewNumberLiteral(double value); Literal* NewNumberLiteral(double value);
...@@ -781,6 +756,24 @@ class Parser { ...@@ -781,6 +756,24 @@ class Parser {
Expression* NewThrowError(Handle<String> constructor, Expression* NewThrowError(Handle<String> constructor,
Handle<String> type, Handle<String> type,
Vector< Handle<Object> > arguments); Vector< Handle<Object> > arguments);
ZoneList<Handle<String> > symbol_cache_;
Handle<Script> script_;
Scanner scanner_;
Scope* top_scope_;
int with_nesting_level_;
TemporaryScope* temp_scope_;
Mode mode_;
Target* target_stack_; // for break, continue statements
bool allow_natives_syntax_;
v8::Extension* extension_;
bool is_pre_parsing_;
ScriptDataImpl* pre_data_;
FuncNameInferrer* fni_;
}; };
...@@ -815,6 +808,9 @@ class CompileTimeValue: public AllStatic { ...@@ -815,6 +808,9 @@ class CompileTimeValue: public AllStatic {
}; };
// ----------------------------------------------------------------------------
// JSON PARSING
// JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5 // JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
// specification section 15.12.1 (and appendix A.8). // specification section 15.12.1 (and appendix A.8).
// The grammar is given section 15.12.1.2 (and appendix A.8.2). // The grammar is given section 15.12.1.2 (and appendix A.8.2).
......
...@@ -262,7 +262,6 @@ class KeywordMatcher { ...@@ -262,7 +262,6 @@ class KeywordMatcher {
}; };
enum ParserMode { PARSE, PREPARSE };
enum ParserLanguage { JAVASCRIPT, JSON }; enum ParserLanguage { JAVASCRIPT, JSON };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment