Revision: 5752
Author: [email protected]
Date: Tue Nov 2 04:45:47 2010
Log: Remove old preparser option and behavior from the parser.
Review URL: http://codereview.chromium.org/4244003
http://code.google.com/p/v8/source/detail?r=5752
Modified:
/branches/bleeding_edge/src/compiler.cc
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/parser.h
/branches/bleeding_edge/src/scanner.h
=======================================
--- /branches/bleeding_edge/src/compiler.cc Wed Oct 27 05:33:48 2010
+++ /branches/bleeding_edge/src/compiler.cc Tue Nov 2 04:45:47 2010
@@ -279,7 +279,6 @@
// in that case too.
ScriptDataImpl* pre_data = input_pre_data;
if (pre_data == NULL
- && FLAG_lazy
&& source_length >= FLAG_min_preparse_length) {
pre_data = ParserApi::PartialPreParse(source, NULL, extension);
}
=======================================
--- /branches/bleeding_edge/src/parser.cc Tue Nov 2 00:21:37 2010
+++ /branches/bleeding_edge/src/parser.cc Tue Nov 2 04:45:47 2010
@@ -39,7 +39,6 @@
#include "preparser.h"
#include "runtime.h"
#include "scopeinfo.h"
-#include "scopes.h"
#include "string-stream.h"
#include "ast-inl.h"
@@ -324,144 +323,37 @@
}
-// A zone list wrapper lets code either access a access a zone list
-// 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) {
- // 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;
- }
- Counters::total_preparse_symbols_skipped.Increment();
+Handle<String> Parser::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> 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;
}
-
- virtual Handle<String> EmptySymbol() {
- 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_;
-};
+ Counters::total_preparse_symbols_skipped.Increment();
+ return result;
+}
Vector<unsigned> PartialParserRecorder::ExtractData() {
@@ -521,8 +413,6 @@
}
return data;
}
-
-
FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
@@ -704,107 +594,11 @@
}
-class AstBuildingParser : public Parser {
- 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* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with)
{
Scope* result = new Scope(parent, type);
result->Initialize(inside_with);
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 ∅
-}
-
-
-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
@@ -908,11 +702,9 @@
Parser::Parser(Handle<Script> script,
bool allow_natives_syntax,
v8::Extension* extension,
- ParserMode is_pre_parsing,
- ParserFactory* factory,
- ParserLog* log,
ScriptDataImpl* pre_data)
- : script_(script),
+ : symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
+ script_(script),
scanner_(),
top_scope_(NULL),
with_nesting_level_(0),
@@ -920,9 +712,6 @@
target_stack_(NULL),
allow_natives_syntax_(allow_natives_syntax),
extension_(extension),
- factory_(factory),
- log_(log),
- is_pre_parsing_(is_pre_parsing == PREPARSE),
pre_data_(pre_data),
fni_(NULL) {
}
@@ -950,21 +739,21 @@
in_global_context
? Scope::GLOBAL_SCOPE
: Scope::EVAL_SCOPE;
- Handle<String> no_name = factory()->EmptySymbol();
+ Handle<String> no_name = Factory::empty_symbol();
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_,
scope);
TemporaryScope temp_scope(&this->temp_scope_);
- ZoneListWrapper<Statement> body(16);
+ ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
bool ok = true;
- ParseSourceElements(&body, Token::EOS, &ok);
+ ParseSourceElements(body, Token::EOS, &ok);
if (ok) {
- result = NEW(FunctionLiteral(
+ result = new FunctionLiteral(
no_name,
top_scope_,
- body.elements(),
+ body,
temp_scope.materialized_literal_count(),
temp_scope.expected_property_count(),
temp_scope.only_simple_this_property_assignments(),
@@ -973,7 +762,7 @@
0,
source->length(),
false,
- temp_scope.ContainsLoops()));
+ temp_scope.ContainsLoops());
} else if (scanner().stack_overflow()) {
Top::StackOverflow();
}
@@ -1011,9 +800,9 @@
{
// Parse the function literal.
- Handle<String> no_name = factory()->EmptySymbol();
+ Handle<String> no_name = Factory::empty_symbol();
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_,
scope);
TemporaryScope temp_scope(&this->temp_scope_);
@@ -1039,30 +828,26 @@
}
return result;
}
-
-
-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) {
- if (is_pre_parsing_) {
- log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
- return Handle<String>::null();
- }
int symbol_id = -1;
if (pre_data() != NULL) {
symbol_id = pre_data()->GetSymbolIdentifier();
}
- return factory()->LookupSymbol(symbol_id, scanner_.literal());
+ return LookupSymbol(symbol_id, scanner_.literal());
}
-void AstBuildingParser::ReportMessageAt(Scanner::Location source_location,
- const char* type,
- Vector<const char*> args) {
+void Parser::ReportMessage(const char* type, Vector<const char*> args) {
+ Scanner::Location source_location = scanner_.location();
+ ReportMessageAt(source_location, type, args);
+}
+
+
+void Parser::ReportMessageAt(Scanner::Location source_location,
+ const char* type,
+ Vector<const char*> args) {
MessageLocation location(script_,
source_location.beg_pos,
source_location.end_pos);
Handle<JSArray> array = Factory::NewJSArray(args.length());
@@ -1072,13 +857,6 @@
Handle<Object> result = Factory::NewSyntaxError(type, array);
Top::Throw(*result, &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
@@ -1122,6 +900,11 @@
}
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.
// In the context of initialization blocks, we only consider expressions
// of the form 'expr.x' or expr["x"].
@@ -1174,7 +957,7 @@
}
void EndBlock() {
- if (block_size_ >= Parser::kMinInitializationBlock) {
+ if (block_size_ >= kMinInitializationBlock) {
first_in_block_->mark_block_start();
last_in_block_->mark_block_end();
}
@@ -1332,7 +1115,7 @@
};
-void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor,
+void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
int end_token,
bool* ok) {
// SourceElements ::
@@ -1364,7 +1147,7 @@
}
// 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 =
this_property_assignment_finder.only_simple_this_property_assignments()
&& top_scope_->declarations()->length() == 0;
@@ -1417,7 +1200,7 @@
case Token::SEMICOLON:
Next();
- return factory()->EmptyStatement();
+ return EmptyStatement();
case Token::IF:
stmt = ParseIfStatement(labels, ok);
@@ -1465,7 +1248,7 @@
// one must take great care not to treat it as a
// fall-through. It is much easier just to wrap the entire
// try-statement in a statement block and put the labels there
- Block* result = NEW(Block(labels, 1, false));
+ Block* result = new Block(labels, 1, false);
Target target(&this->target_stack_, result);
TryStatement* statement = ParseTryStatement(CHECK_OK);
if (statement) {
@@ -1495,11 +1278,11 @@
}
-VariableProxy* AstBuildingParser::Declare(Handle<String> name,
- Variable::Mode mode,
- FunctionLiteral* fun,
- bool resolve,
- bool* ok) {
+VariableProxy* Parser::Declare(Handle<String> name,
+ Variable::Mode mode,
+ FunctionLiteral* fun,
+ bool resolve,
+ bool* ok) {
Variable* var = NULL;
// If we are inside a function, a declaration of a variable
// is a truly local variable, and the scope of the variable
@@ -1554,13 +1337,13 @@
// a performance issue since it may lead to repeated
// Runtime::DeclareContextSlot() calls.
VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with());
- top_scope_->AddDeclaration(NEW(Declaration(proxy, mode, fun)));
+ top_scope_->AddDeclaration(new Declaration(proxy, mode, fun));
// For global const variables we bind the proxy to a variable.
if (mode == Variable::CONST && top_scope_->is_global_scope()) {
ASSERT(resolve); // should be set by all callers
Variable::Kind kind = Variable::NORMAL;
- var = NEW(Variable(top_scope_, name, Variable::CONST, true, kind));
+ var = new Variable(top_scope_, name, Variable::CONST, true, kind);
}
// If requested and we have a local variable, bind the proxy to the
variable
@@ -1619,8 +1402,6 @@
Expect(Token::RPAREN, CHECK_OK);
Expect(Token::SEMICOLON, CHECK_OK);
- if (is_pre_parsing_) return NULL;
-
// Make sure that the function containing the native declaration
// isn't lazily compiled. The extension structures are only
// accessible while parsing the first time not when reparsing
@@ -1650,10 +1431,10 @@
// TODO(1240846): It's weird that native function declarations are
// introduced dynamically when we meet their declarations, whereas
// other functions are setup when entering the surrounding scope.
- SharedFunctionInfoLiteral* lit = NEW(SharedFunctionInfoLiteral(shared));
+ SharedFunctionInfoLiteral* lit = new SharedFunctionInfoLiteral(shared);
VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK);
- return NEW(ExpressionStatement(
- new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)));
+ return new ExpressionStatement(
+ new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
}
@@ -1671,7 +1452,7 @@
// scope, we treat is as such and introduce the function with it's
// initial value upon entering the corresponding scope.
Declare(name, Variable::VAR, fun, true, CHECK_OK);
- return factory()->EmptyStatement();
+ return EmptyStatement();
}
@@ -1683,7 +1464,7 @@
// (ECMA-262, 3rd, 12.2)
//
// 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);
Expect(Token::LBRACE, CHECK_OK);
while (peek() != Token::RBRACE) {
@@ -1742,7 +1523,7 @@
// is inside an initializer block, it is ignored.
//
// Create new block with one expected declaration.
- Block* block = NEW(Block(NULL, 1, true));
+ Block* block = new Block(NULL, 1, true);
VariableProxy* last_var = NULL; // the last variable declared
int nvars = 0; // the number of variables declared
do {
@@ -1833,14 +1614,14 @@
// browsers where the global object (window) has lots of
// 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.
ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2);
// Be careful not to assign a value to the global variable if
// we're in a with. The initialization value should not
// necessarily be stored in the global object in that case,
// 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())) {
arguments->Add(value);
value = NULL; // zap the value to avoid the unnecessary assignment
@@ -1852,18 +1633,18 @@
CallRuntime* initialize;
if (is_const) {
initialize =
- NEW(CallRuntime(
+ new CallRuntime(
Factory::InitializeConstGlobal_symbol(),
Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
- arguments));
+ arguments);
} else {
initialize =
- NEW(CallRuntime(
+ new CallRuntime(
Factory::InitializeVarGlobal_symbol(),
Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
- arguments));
- }
- block->AddStatement(NEW(ExpressionStatement(initialize)));
+ arguments);
+ }
+ block->AddStatement(new ExpressionStatement(initialize));
}
// Add an assignment node to the initialization statement block if
@@ -1878,8 +1659,8 @@
// the top context for variables). Sigh...
if (value != NULL) {
Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR);
- Assignment* assignment = NEW(Assignment(op, last_var, value,
position));
- if (block) block->AddStatement(NEW(ExpressionStatement(assignment)));
+ Assignment* assignment = new Assignment(op, last_var, value,
position);
+ if (block) block->AddStatement(new ExpressionStatement(assignment));
}
if (fni_ != NULL) fni_->Leave();
@@ -1887,14 +1668,8 @@
if (!is_const && nvars == 1) {
// We have a single, non-const variable.
- if (is_pre_parsing_) {
- // If we're preparsing then we need to set the var to something
- // in order for for-in loops to parse correctly.
- *var = ValidLeftHandSideSentinel::instance();
- } else {
- ASSERT(last_var != NULL);
- *var = last_var;
- }
+ ASSERT(last_var != NULL);
+ *var = last_var;
}
return block;
@@ -1929,29 +1704,27 @@
// labels requires nontrivial changes to the way scopes are
// structured. However, these are probably changes we want to
// make later anyway so we should go back and fix this then.
- if (!is_pre_parsing_) {
- if (ContainsLabel(labels, label) || TargetStackContainsLabel(label))
{
- SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
- const char* elms[2] = { "Label", *c_string };
- Vector<const char*> args(elms, 2);
- ReportMessage("redeclaration", args);
- *ok = false;
- 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 (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
+ SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
+ const char* elms[2] = { "Label", *c_string };
+ Vector<const char*> args(elms, 2);
+ ReportMessage("redeclaration", args);
+ *ok = false;
+ 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);
Expect(Token::COLON, CHECK_OK);
return ParseStatement(labels, ok);
}
// Parsed expression statement.
ExpectSemicolon(CHECK_OK);
- return NEW(ExpressionStatement(expr));
+ return new ExpressionStatement(expr);
}
@@ -1968,10 +1741,10 @@
if (peek() == Token::ELSE) {
Next();
else_statement = ParseStatement(labels, CHECK_OK);
- } else if (!is_pre_parsing_) {
- else_statement = factory()->EmptyStatement();
- }
- return NEW(IfStatement(condition, then_statement, else_statement));
+ } else {
+ else_statement = EmptyStatement();
+ }
+ return new IfStatement(condition, then_statement, else_statement);
}
@@ -1987,19 +1760,17 @@
label = ParseIdentifier(CHECK_OK);
}
IterationStatement* target = NULL;
- if (!is_pre_parsing_) {
- target = LookupContinueTarget(label, CHECK_OK);
- if (target == NULL) {
- // Illegal continue statement. To be consistent with KJS we delay
- // reporting of the syntax error until runtime.
- Handle<String> error_type = Factory::illegal_continue_symbol();
- if (!label.is_null()) error_type = Factory::unknown_label_symbol();
- Expression* throw_error = NewThrowSyntaxError(error_type, label);
- return NEW(ExpressionStatement(throw_error));
- }
+ target = LookupContinueTarget(label, CHECK_OK);
+ if (target == NULL) {
+ // Illegal continue statement. To be consistent with KJS we delay
+ // reporting of the syntax error until runtime.
+ Handle<String> error_type = Factory::illegal_continue_symbol();
+ if (!label.is_null()) error_type = Factory::unknown_label_symbol();
+ Expression* throw_error = NewThrowSyntaxError(error_type, label);
+ return new ExpressionStatement(throw_error);
}
ExpectSemicolon(CHECK_OK);
- return NEW(ContinueStatement(target));
+ return new ContinueStatement(target);
}
@@ -2017,22 +1788,20 @@
// Parse labeled break statements that target themselves into
// empty statements, e.g. 'l1: l2: l3: break l2;'
if (!label.is_null() && ContainsLabel(labels, label)) {
- return factory()->EmptyStatement();
+ return EmptyStatement();
}
BreakableStatement* target = NULL;
- if (!is_pre_parsing_) {
- target = LookupBreakTarget(label, CHECK_OK);
- if (target == NULL) {
- // Illegal break statement. To be consistent with KJS we delay
- // reporting of the syntax error until runtime.
- Handle<String> error_type = Factory::illegal_break_symbol();
- if (!label.is_null()) error_type = Factory::unknown_label_symbol();
- Expression* throw_error = NewThrowSyntaxError(error_type, label);
- return NEW(ExpressionStatement(throw_error));
- }
+ target = LookupBreakTarget(label, CHECK_OK);
+ if (target == NULL) {
+ // Illegal break statement. To be consistent with KJS we delay
+ // reporting of the syntax error until runtime.
+ Handle<String> error_type = Factory::illegal_break_symbol();
+ if (!label.is_null()) error_type = Factory::unknown_label_symbol();
+ Expression* throw_error = NewThrowSyntaxError(error_type, label);
+ return new ExpressionStatement(throw_error);
}
ExpectSemicolon(CHECK_OK);
- return NEW(BreakStatement(target));
+ return new BreakStatement(target);
}
@@ -2050,10 +1819,10 @@
// function. See ECMA-262, section 12.9, page 67.
//
// 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();
Expression* throw_error = NewThrowSyntaxError(type,
Handle<Object>::null());
- return NEW(ExpressionStatement(throw_error));
+ return new ExpressionStatement(throw_error);
}
Token::Value tok = peek();
@@ -2062,12 +1831,12 @@
tok == Token::RBRACE ||
tok == Token::EOS) {
ExpectSemicolon(CHECK_OK);
- return NEW(ReturnStatement(GetLiteralUndefined()));
+ return new ReturnStatement(GetLiteralUndefined());
}
Expression* expr = ParseExpression(true, CHECK_OK);
ExpectSemicolon(CHECK_OK);
- return NEW(ReturnStatement(expr));
+ return new ReturnStatement(expr);
}
@@ -2076,7 +1845,7 @@
bool is_catch_block,
bool* ok) {
// 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);
Statement* stat;
{ Target target(&this->target_stack_, &collector);
@@ -2088,21 +1857,21 @@
// Create resulting block with two statements.
// 1: Evaluate the with expression.
// 2: The try-finally block evaluating the body.
- Block* result = NEW(Block(NULL, 2, false));
+ Block* result = new Block(NULL, 2, false);
if (result != NULL) {
- result->AddStatement(NEW(WithEnterStatement(obj, is_catch_block)));
+ result->AddStatement(new WithEnterStatement(obj, is_catch_block));
// Create body block.
- Block* body = NEW(Block(NULL, 1, false));
+ Block* body = new Block(NULL, 1, false);
body->AddStatement(stat);
// Create exit block.
- Block* exit = NEW(Block(NULL, 1, false));
- exit->AddStatement(NEW(WithExitStatement()));
+ Block* exit = new Block(NULL, 1, false);
+ exit->AddStatement(new WithExitStatement());
// Return a try-finally statement.
- TryFinallyStatement* wrapper = NEW(TryFinallyStatement(body, exit));
+ TryFinallyStatement* wrapper = new TryFinallyStatement(body, exit);
wrapper->set_escaping_targets(collector.targets());
result->AddStatement(wrapper);
}
@@ -2144,15 +1913,15 @@
}
Expect(Token::COLON, CHECK_OK);
- ZoneListWrapper<Statement> statements = factory()->NewList<Statement>(5);
+ ZoneList<Statement*>* statements = new ZoneList<Statement*>(5);
while (peek() != Token::CASE &&
peek() != Token::DEFAULT &&
peek() != Token::RBRACE) {
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 ::
// 'switch' '(' Expression ')' '{' CaseClause* '}'
- SwitchStatement* statement = NEW(SwitchStatement(labels));
+ SwitchStatement* statement = new SwitchStatement(labels);
Target target(&this->target_stack_, statement);
Expect(Token::SWITCH, CHECK_OK);
@@ -2170,15 +1939,15 @@
Expect(Token::RPAREN, CHECK_OK);
bool default_seen = false;
- ZoneListWrapper<CaseClause> cases = factory()->NewList<CaseClause>(4);
+ ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4);
Expect(Token::LBRACE, CHECK_OK);
while (peek() != Token::RBRACE) {
CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK);
- cases.Add(clause);
+ cases->Add(clause);
}
Expect(Token::RBRACE, CHECK_OK);
- if (statement) statement->Initialize(tag, cases.elements());
+ if (statement) statement->Initialize(tag, cases);
return statement;
}
@@ -2197,7 +1966,7 @@
Expression* exception = ParseExpression(true, CHECK_OK);
ExpectSemicolon(CHECK_OK);
- return NEW(ExpressionStatement(new Throw(exception, pos)));
+ return new ExpressionStatement(new Throw(exception, pos));
}
@@ -2215,7 +1984,7 @@
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);
Block* try_block;
@@ -2238,7 +2007,7 @@
// then we will need to collect jump targets from the catch block. Since
// we don't know yet if there will be a finally block, we always collect
// the jump targets.
- ZoneList<BreakTarget*>* catch_target_list =
NEW(ZoneList<BreakTarget*>(0));
+ ZoneList<BreakTarget*>* catch_target_list = new
ZoneList<BreakTarget*>(0);
TargetCollector catch_collector(catch_target_list);
bool has_catch = false;
if (tok == Token::CATCH) {
@@ -2253,8 +2022,8 @@
// Allocate a temporary for holding the finally state while
// executing the finally block.
catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol());
- Literal* name_literal = NEW(Literal(name));
- Expression* obj = NEW(CatchExtensionObject(name_literal, catch_var));
+ Literal* name_literal = new Literal(name);
+ Expression* obj = new CatchExtensionObject(name_literal, catch_var);
{ Target target(&this->target_stack_, &catch_collector);
catch_block = WithHelper(obj, NULL, true, CHECK_OK);
}
@@ -2277,30 +2046,28 @@
// to:
// 'try { try { } catch { } } finally { }'
- if (!is_pre_parsing_ && catch_block != NULL && finally_block != NULL) {
+ if (catch_block != NULL && finally_block != NULL) {
TryCatchStatement* statement =
- NEW(TryCatchStatement(try_block, catch_var, catch_block));
+ new TryCatchStatement(try_block, catch_var, catch_block);
statement->set_escaping_targets(collector.targets());
- try_block = NEW(Block(NULL, 1, false));
+ try_block = new Block(NULL, 1, false);
try_block->AddStatement(statement);
catch_block = NULL;
}
TryStatement* result = NULL;
- if (!is_pre_parsing_) {
- if (catch_block != NULL) {
- ASSERT(finally_block == NULL);
- result = NEW(TryCatchStatement(try_block, catch_var, catch_block));
- result->set_escaping_targets(collector.targets());
- } else {
- ASSERT(finally_block != NULL);
- result = NEW(TryFinallyStatement(try_block, finally_block));
- // Add the jump targets of the try block and the catch block.
- for (int i = 0; i < collector.targets()->length(); i++) {
- catch_collector.AddTarget(collector.targets()->at(i));
- }
- result->set_escaping_targets(catch_collector.targets());
- }
+ if (catch_block != NULL) {
+ ASSERT(finally_block == NULL);
+ result = new TryCatchStatement(try_block, catch_var, catch_block);
+ result->set_escaping_targets(collector.targets());
+ } else {
+ ASSERT(finally_block != NULL);
+ result = new TryFinallyStatement(try_block, finally_block);
+ // Add the jump targets of the try block and the catch block.
+ for (int i = 0; i < collector.targets()->length(); i++) {
+ catch_collector.AddTarget(collector.targets()->at(i));
+ }
+ result->set_escaping_targets(catch_collector.targets());
}
return result;
@@ -2313,7 +2080,7 @@
// 'do' Statement 'while' '(' Expression ')' ';'
temp_scope_->AddLoop();
- DoWhileStatement* loop = NEW(DoWhileStatement(labels));
+ DoWhileStatement* loop = new DoWhileStatement(labels);
Target target(&this->target_stack_, loop);
Expect(Token::DO, CHECK_OK);
@@ -2346,7 +2113,7 @@
// 'while' '(' Expression ')' Statement
temp_scope_->AddLoop();
- WhileStatement* loop = NEW(WhileStatement(labels));
+ WhileStatement* loop = new WhileStatement(labels);
Target target(&this->target_stack_, loop);
Expect(Token::WHILE, CHECK_OK);
@@ -2376,7 +2143,7 @@
Block* variable_statement =
ParseVariableDeclarations(false, &each, CHECK_OK);
if (peek() == Token::IN && each != NULL) {
- ForInStatement* loop = NEW(ForInStatement(labels));
+ ForInStatement* loop = new ForInStatement(labels);
Target target(&this->target_stack_, loop);
Expect(Token::IN, CHECK_OK);
@@ -2384,17 +2151,12 @@
Expect(Token::RPAREN, CHECK_OK);
Statement* body = ParseStatement(NULL, CHECK_OK);
- if (is_pre_parsing_) {
- return NULL;
- } else {
- loop->Initialize(each, enumerable, body);
- Block* result = NEW(Block(NULL, 2, false));
- result->AddStatement(variable_statement);
- result->AddStatement(loop);
- // Parsed for-in loop w/ variable/const declaration.
- return result;
- }
-
+ loop->Initialize(each, enumerable, body);
***The diff for this file has been truncated for email.***
=======================================
--- /branches/bleeding_edge/src/parser.h Tue Nov 2 00:21:37 2010
+++ /branches/bleeding_edge/src/parser.h Tue Nov 2 04:45:47 2010
@@ -31,13 +31,13 @@
#include "allocation.h"
#include "ast.h"
#include "scanner.h"
+#include "scopes.h"
namespace v8 {
namespace internal {
class CompilationInfo;
class FuncNameInferrer;
-class ParserFactory;
class ParserLog;
class PositionStack;
class Target;
@@ -177,49 +177,19 @@
};
-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.
-class PartialParserRecorder: public ParserLog {
+class PartialParserRecorder {
public:
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(end);
function_store_.Add(literals);
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.
// Further logging will be ignored, and ExtractData will return a vector
@@ -236,23 +206,26 @@
this->LogMessage(location, message, arguments);
}
- virtual int function_position() { return function_store_.size(); }
-
- virtual void LogMessage(Scanner::Location loc,
- const char* message,
- Vector<const char*> args);
-
- virtual Vector<unsigned> ExtractData();
-
- virtual void PauseRecording() {
+ int function_position() { return function_store_.size(); }
+
+ void LogMessage(Scanner::Location loc,
+ const char* message,
+ Vector<const char*> args);
+
+ Vector<unsigned> ExtractData();
+
+ void PauseRecording() {
pause_count_++;
is_recording_ = false;
}
- virtual void ResumeRecording() {
+ void ResumeRecording() {
ASSERT(pause_count_ > 0);
if (--pause_count_ == 0) is_recording_ = !has_error();
}
+
+ int symbol_position() { return 0; }
+ int symbol_ids() { return 0; }
protected:
bool has_error() {
@@ -281,16 +254,16 @@
public:
CompleteParserRecorder();
- virtual void LogSymbol(int start, Vector<const char> literal);
-
- virtual void LogSymbol(int start, const char* symbol, int length) {
+ void LogSymbol(int start, Vector<const char> literal);
+
+ void LogSymbol(int start, const char* symbol, int length) {
LogSymbol(start, Vector<const char>(symbol, length));
}
- virtual Vector<unsigned> ExtractData();
-
- virtual int symbol_position() { return symbol_store_.size(); }
- virtual int symbol_ids() { return symbol_id_; }
+ Vector<unsigned> ExtractData();
+
+ int symbol_position() { return symbol_store_.size(); }
+ int symbol_ids() { return symbol_id_; }
private:
static int vector_hash(Vector<const char> string) {
@@ -342,6 +315,8 @@
v8::Extension* extension);
};
+//
----------------------------------------------------------------------------
+// REGEXP PARSING
// A BuffferedZoneList is an automatically growing list, just like (and
backed
// by) a ZoneList, that is optimized for the case of adding and removing
@@ -557,47 +532,44 @@
uc32 Next();
FlatStringReader* in() { return in_; }
void ScanForCaptures();
+
+ Handle<String>* error_;
+ ZoneList<RegExpCapture*>* captures_;
+ FlatStringReader* in_;
uc32 current_;
+ int next_pos_;
+ // The capture count is only valid after we have scanned for captures.
+ int capture_count_;
bool has_more_;
bool multiline_;
- int next_pos_;
- FlatStringReader* in_;
- Handle<String>* error_;
bool simple_;
bool contains_anchor_;
- ZoneList<RegExpCapture*>* captures_;
bool is_scanned_for_captures_;
- // The capture count is only valid after we have scanned for captures.
- int capture_count_;
bool failed_;
};
+//
----------------------------------------------------------------------------
+// JAVASCRIPT PARSING
class Parser {
public:
- Parser(Handle<Script> script, bool allow_natives_syntax,
- v8::Extension* extension, ParserMode is_pre_parsing,
- ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data);
+ Parser(Handle<Script> script,
+ bool allow_natives_syntax,
+ v8::Extension* extension,
+ ScriptDataImpl* pre_data);
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.
FunctionLiteral* ParseProgram(Handle<String> source,
bool in_global_context);
+
FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info);
- // 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;
+ void ReportMessageAt(Scanner::Location loc,
+ const char* message,
+ Vector<const char*> args);
protected:
-
enum Mode {
PARSE_LAZILY,
PARSE_EAGERLY
@@ -606,28 +578,9 @@
// Report syntax error
void ReportUnexpectedToken(Token::Value token);
void ReportInvalidPreparseData(Handle<String> name, bool* ok);
-
- 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_;
+ void ReportMessage(const char* message, Vector<const char*> args);
bool inside_with() const { return with_nesting_level_ > 0; }
- ParserFactory* factory() const { return factory_; }
- ParserLog* log() const { return log_; }
Scanner& scanner() { return scanner_; }
Mode mode() const { return mode_; }
ScriptDataImpl* pre_data() const { return pre_data_; }
@@ -636,7 +589,7 @@
// which is set to false if parsing failed; it is unchanged otherwise.
// By making the 'exception handling' explicit, we are forced to check
// for failure at the call sites.
- void* ParseSourceElements(ZoneListWrapper<Statement>* processor,
+ void* ParseSourceElements(ZoneList<Statement*>* processor,
int end_token, bool* ok);
Statement* ParseStatement(ZoneStringList* labels, bool* ok);
Statement* ParseFunctionDeclaration(bool* ok);
@@ -749,10 +702,10 @@
bool* ok);
// Parser support
- virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
- FunctionLiteral* fun,
- bool resolve,
- bool* ok) = 0;
+ VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
+ FunctionLiteral* fun,
+ bool resolve,
+ bool* ok);
bool TargetStackContainsLabel(Handle<String> label);
BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
@@ -760,6 +713,28 @@
void RegisterTargetUse(BreakTarget* target, Target* stop);
+ // Factory methods.
+
+ Statement* EmptyStatement() {
+ static v8::internal::EmptyStatement empty;
+ return ∅
+ }
+
+ 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.
Literal* NewNumberLiteral(double value);
@@ -781,6 +756,24 @@
Expression* NewThrowError(Handle<String> constructor,
Handle<String> type,
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 @@
};
+//
----------------------------------------------------------------------------
+// JSON PARSING
+
// JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
// specification section 15.12.1 (and appendix A.8).
// The grammar is given section 15.12.1.2 (and appendix A.8.2).
=======================================
--- /branches/bleeding_edge/src/scanner.h Wed Oct 27 02:19:43 2010
+++ /branches/bleeding_edge/src/scanner.h Tue Nov 2 04:45:47 2010
@@ -262,7 +262,6 @@
};
-enum ParserMode { PARSE, PREPARSE };
enum ParserLanguage { JAVASCRIPT, JSON };
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev