|
|
@ -481,62 +481,6 @@ class Parser::BlockState BASE_EMBEDDED { |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class Parser::FunctionState BASE_EMBEDDED { |
|
|
|
public: |
|
|
|
FunctionState(Parser* parser, Scope* scope, Isolate* isolate); |
|
|
|
~FunctionState(); |
|
|
|
|
|
|
|
int NextMaterializedLiteralIndex() { |
|
|
|
return next_materialized_literal_index_++; |
|
|
|
} |
|
|
|
int materialized_literal_count() { |
|
|
|
return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
|
|
|
} |
|
|
|
|
|
|
|
int NextHandlerIndex() { return next_handler_index_++; } |
|
|
|
int handler_count() { return next_handler_index_; } |
|
|
|
|
|
|
|
void SetThisPropertyAssignmentInfo( |
|
|
|
bool only_simple_this_property_assignments, |
|
|
|
Handle<FixedArray> this_property_assignments) { |
|
|
|
only_simple_this_property_assignments_ = |
|
|
|
only_simple_this_property_assignments; |
|
|
|
this_property_assignments_ = this_property_assignments; |
|
|
|
} |
|
|
|
bool only_simple_this_property_assignments() { |
|
|
|
return only_simple_this_property_assignments_; |
|
|
|
} |
|
|
|
Handle<FixedArray> this_property_assignments() { |
|
|
|
return this_property_assignments_; |
|
|
|
} |
|
|
|
|
|
|
|
void AddProperty() { expected_property_count_++; } |
|
|
|
int expected_property_count() { return expected_property_count_; } |
|
|
|
|
|
|
|
private: |
|
|
|
// Used to assign an index to each literal that needs materialization in
|
|
|
|
// the function. Includes regexp literals, and boilerplate for object and
|
|
|
|
// array literals.
|
|
|
|
int next_materialized_literal_index_; |
|
|
|
|
|
|
|
// Used to assign a per-function index to try and catch handlers.
|
|
|
|
int next_handler_index_; |
|
|
|
|
|
|
|
// Properties count estimation.
|
|
|
|
int expected_property_count_; |
|
|
|
|
|
|
|
// Keeps track of assignments to properties of this. Used for
|
|
|
|
// optimizing constructors.
|
|
|
|
bool only_simple_this_property_assignments_; |
|
|
|
Handle<FixedArray> this_property_assignments_; |
|
|
|
|
|
|
|
Parser* parser_; |
|
|
|
FunctionState* outer_function_state_; |
|
|
|
Scope* outer_scope_; |
|
|
|
unsigned saved_ast_node_id_; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Parser::FunctionState::FunctionState(Parser* parser, |
|
|
|
Scope* scope, |
|
|
|
Isolate* isolate) |
|
|
@ -548,7 +492,8 @@ Parser::FunctionState::FunctionState(Parser* parser, |
|
|
|
parser_(parser), |
|
|
|
outer_function_state_(parser->current_function_state_), |
|
|
|
outer_scope_(parser->top_scope_), |
|
|
|
saved_ast_node_id_(isolate->ast_node_id()) { |
|
|
|
saved_ast_node_id_(isolate->ast_node_id()), |
|
|
|
factory_(isolate) { |
|
|
|
parser->top_scope_ = scope; |
|
|
|
parser->current_function_state_ = this; |
|
|
|
isolate->set_ast_node_id(AstNode::kDeclarationsId + 1); |
|
|
@ -602,12 +547,16 @@ Parser::Parser(Handle<Script> script, |
|
|
|
fni_(NULL), |
|
|
|
allow_natives_syntax_((parser_flags & kAllowNativesSyntax) != 0), |
|
|
|
allow_lazy_((parser_flags & kAllowLazy) != 0), |
|
|
|
allow_modules_((parser_flags & kAllowModules) != 0), |
|
|
|
stack_overflow_(false), |
|
|
|
parenthesized_function_(false) { |
|
|
|
AstNode::ResetIds(); |
|
|
|
if ((parser_flags & kLanguageModeMask) == EXTENDED_MODE) { |
|
|
|
scanner().SetHarmonyScoping(true); |
|
|
|
} |
|
|
|
if ((parser_flags & kAllowModules) != 0) { |
|
|
|
scanner().SetHarmonyModules(true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -674,8 +623,7 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
|
|
|
} |
|
|
|
|
|
|
|
if (ok) { |
|
|
|
result = new(zone()) FunctionLiteral( |
|
|
|
isolate(), |
|
|
|
result = factory()->NewFunctionLiteral( |
|
|
|
no_name, |
|
|
|
top_scope_, |
|
|
|
body, |
|
|
@ -685,8 +633,10 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
|
|
|
function_state.only_simple_this_property_assignments(), |
|
|
|
function_state.this_property_assignments(), |
|
|
|
0, |
|
|
|
false, // Does not have duplicate parameters.
|
|
|
|
FunctionLiteral::ANONYMOUS_EXPRESSION, |
|
|
|
false); // Does not have duplicate parameters.
|
|
|
|
false); // Top-level literal doesn't count for the AST's properties.
|
|
|
|
result->set_ast_properties(factory()->visitor()->ast_properties()); |
|
|
|
} else if (stack_overflow_) { |
|
|
|
isolate()->StackOverflow(); |
|
|
|
} |
|
|
@ -1274,7 +1224,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
|
|
|
|
case Token::SEMICOLON: |
|
|
|
Next(); |
|
|
|
return EmptyStatement(); |
|
|
|
return factory()->NewEmptyStatement(); |
|
|
|
|
|
|
|
case Token::IF: |
|
|
|
stmt = ParseIfStatement(labels, ok); |
|
|
@ -1322,7 +1272,7 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
// one must take great care not to treat it as a
|
|
|
|
// fall-through. It is much easier just to wrap the entire
|
|
|
|
// try-statement in a statement block and put the labels there
|
|
|
|
Block* result = new(zone()) Block(isolate(), labels, 1, false); |
|
|
|
Block* result = factory()->NewBlock(labels, 1, false); |
|
|
|
Target target(&this->target_stack_, result); |
|
|
|
TryStatement* statement = ParseTryStatement(CHECK_OK); |
|
|
|
if (statement) { |
|
|
@ -1454,9 +1404,9 @@ VariableProxy* Parser::Declare(Handle<String> name, |
|
|
|
// a performance issue since it may lead to repeated
|
|
|
|
// Runtime::DeclareContextSlot() calls.
|
|
|
|
VariableProxy* proxy = declaration_scope->NewUnresolved( |
|
|
|
name, scanner().location().beg_pos); |
|
|
|
factory(), name, scanner().location().beg_pos); |
|
|
|
declaration_scope->AddDeclaration( |
|
|
|
new(zone()) Declaration(proxy, mode, fun, top_scope_)); |
|
|
|
factory()->NewVariableDeclaration(proxy, mode, fun, top_scope_)); |
|
|
|
|
|
|
|
if ((mode == CONST || mode == CONST_HARMONY) && |
|
|
|
declaration_scope->is_global_scope()) { |
|
|
@ -1564,10 +1514,11 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) { |
|
|
|
// introduced dynamically when we meet their declarations, whereas
|
|
|
|
// other functions are set up when entering the surrounding scope.
|
|
|
|
SharedFunctionInfoLiteral* lit = |
|
|
|
new(zone()) SharedFunctionInfoLiteral(isolate(), shared); |
|
|
|
factory()->NewSharedFunctionInfoLiteral(shared); |
|
|
|
VariableProxy* var = Declare(name, VAR, NULL, true, CHECK_OK); |
|
|
|
return new(zone()) ExpressionStatement(new(zone()) Assignment( |
|
|
|
isolate(), Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); |
|
|
|
return factory()->NewExpressionStatement( |
|
|
|
factory()->NewAssignment( |
|
|
|
Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1589,7 +1540,7 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
|
|
|
// initial value upon entering the corresponding scope.
|
|
|
|
VariableMode mode = is_extended_mode() ? LET : VAR; |
|
|
|
Declare(name, mode, fun, true, CHECK_OK); |
|
|
|
return EmptyStatement(); |
|
|
|
return factory()->NewEmptyStatement(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1603,7 +1554,7 @@ Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
|
|
|
// (ECMA-262, 3rd, 12.2)
|
|
|
|
//
|
|
|
|
// Construct block expecting 16 statements.
|
|
|
|
Block* result = new(zone()) Block(isolate(), labels, 16, false); |
|
|
|
Block* result = factory()->NewBlock(labels, 16, false); |
|
|
|
Target target(&this->target_stack_, result); |
|
|
|
Expect(Token::LBRACE, CHECK_OK); |
|
|
|
InitializationBlockFinder block_finder(top_scope_, target_stack_); |
|
|
@ -1626,7 +1577,7 @@ Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
|
|
|
// '{' SourceElement* '}'
|
|
|
|
|
|
|
|
// Construct block expecting 16 statements.
|
|
|
|
Block* body = new(zone()) Block(isolate(), labels, 16, false); |
|
|
|
Block* body = factory()->NewBlock(labels, 16, false); |
|
|
|
Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
|
|
|
|
|
|
|
// Parse the statements and collect escaping labels.
|
|
|
@ -1676,8 +1627,8 @@ bool Parser::IsEvalOrArguments(Handle<String> string) { |
|
|
|
|
|
|
|
|
|
|
|
// If the variable declaration declares exactly one non-const
|
|
|
|
// variable, then *var is set to that variable. In all other cases,
|
|
|
|
// *var is untouched; in particular, it is the caller's responsibility
|
|
|
|
// variable, then *out is set to that variable. In all other cases,
|
|
|
|
// *out is untouched; in particular, it is the caller's responsibility
|
|
|
|
// to initialize it properly. This mechanism is used for the parsing
|
|
|
|
// of 'for-in' loops.
|
|
|
|
Block* Parser::ParseVariableDeclarations( |
|
|
@ -1786,7 +1737,7 @@ Block* Parser::ParseVariableDeclarations( |
|
|
|
// is inside an initializer block, it is ignored.
|
|
|
|
//
|
|
|
|
// Create new block with one expected declaration.
|
|
|
|
Block* block = new(zone()) Block(isolate(), NULL, 1, true); |
|
|
|
Block* block = factory()->NewBlock(NULL, 1, true); |
|
|
|
int nvars = 0; // the number of variables declared
|
|
|
|
Handle<String> name; |
|
|
|
do { |
|
|
@ -1907,7 +1858,7 @@ Block* Parser::ParseVariableDeclarations( |
|
|
|
// Compute the arguments for the runtime call.
|
|
|
|
ZoneList<Expression*>* arguments = new(zone()) ZoneList<Expression*>(3); |
|
|
|
// We have at least 1 parameter.
|
|
|
|
arguments->Add(NewLiteral(name)); |
|
|
|
arguments->Add(factory()->NewLiteral(name)); |
|
|
|
CallRuntime* initialize; |
|
|
|
|
|
|
|
if (is_const) { |
|
|
@ -1918,9 +1869,7 @@ Block* Parser::ParseVariableDeclarations( |
|
|
|
// and add it to the initialization statement block.
|
|
|
|
// Note that the function does different things depending on
|
|
|
|
// the number of arguments (1 or 2).
|
|
|
|
initialize = |
|
|
|
new(zone()) CallRuntime( |
|
|
|
isolate(), |
|
|
|
initialize = factory()->NewCallRuntime( |
|
|
|
isolate()->factory()->InitializeConstGlobal_symbol(), |
|
|
|
Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
|
|
|
arguments); |
|
|
@ -1928,7 +1877,7 @@ Block* Parser::ParseVariableDeclarations( |
|
|
|
// Add strict mode.
|
|
|
|
// We may want to pass singleton to avoid Literal allocations.
|
|
|
|
LanguageMode language_mode = initialization_scope->language_mode(); |
|
|
|
arguments->Add(NewNumberLiteral(language_mode)); |
|
|
|
arguments->Add(factory()->NewNumberLiteral(language_mode)); |
|
|
|
|
|
|
|
// Be careful not to assign a value to the global variable if
|
|
|
|
// we're in a with. The initialization value should not
|
|
|
@ -1943,15 +1892,13 @@ Block* Parser::ParseVariableDeclarations( |
|
|
|
// and add it to the initialization statement block.
|
|
|
|
// Note that the function does different things depending on
|
|
|
|
// the number of arguments (2 or 3).
|
|
|
|
initialize = |
|
|
|
new(zone()) CallRuntime( |
|
|
|
isolate(), |
|
|
|
initialize = factory()->NewCallRuntime( |
|
|
|
isolate()->factory()->InitializeVarGlobal_symbol(), |
|
|
|
Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
|
|
|
arguments); |
|
|
|
} |
|
|
|
|
|
|
|
block->AddStatement(new(zone()) ExpressionStatement(initialize)); |
|
|
|
block->AddStatement(factory()->NewExpressionStatement(initialize)); |
|
|
|
} else if (needs_init) { |
|
|
|
// Constant initializations always assign to the declared constant which
|
|
|
|
// is always at the function scope level. This is only relevant for
|
|
|
@ -1964,8 +1911,8 @@ Block* Parser::ParseVariableDeclarations( |
|
|
|
ASSERT(proxy->var() != NULL); |
|
|
|
ASSERT(value != NULL); |
|
|
|
Assignment* assignment = |
|
|
|
new(zone()) Assignment(isolate(), init_op, proxy, value, position); |
|
|
|
block->AddStatement(new(zone()) ExpressionStatement(assignment)); |
|
|
|
factory()->NewAssignment(init_op, proxy, value, position); |
|
|
|
block->AddStatement(factory()->NewExpressionStatement(assignment)); |
|
|
|
value = NULL; |
|
|
|
} |
|
|
|
|
|
|
@ -1976,10 +1923,11 @@ Block* Parser::ParseVariableDeclarations( |
|
|
|
// 'var' initializations are simply assignments (with all the consequences
|
|
|
|
// if they are inside a 'with' statement - they may change a 'with' object
|
|
|
|
// property).
|
|
|
|
VariableProxy* proxy = initialization_scope->NewUnresolved(name); |
|
|
|
VariableProxy* proxy = |
|
|
|
initialization_scope->NewUnresolved(factory(), name); |
|
|
|
Assignment* assignment = |
|
|
|
new(zone()) Assignment(isolate(), init_op, proxy, value, position); |
|
|
|
block->AddStatement(new(zone()) ExpressionStatement(assignment)); |
|
|
|
factory()->NewAssignment(init_op, proxy, value, position); |
|
|
|
block->AddStatement(factory()->NewExpressionStatement(assignment)); |
|
|
|
} |
|
|
|
|
|
|
|
if (fni_ != NULL) fni_->Leave(); |
|
|
@ -2059,7 +2007,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
|
|
|
|
|
|
|
// Parsed expression statement.
|
|
|
|
ExpectSemicolon(CHECK_OK); |
|
|
|
return new(zone()) ExpressionStatement(expr); |
|
|
|
return factory()->NewExpressionStatement(expr); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2077,10 +2025,9 @@ IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
Next(); |
|
|
|
else_statement = ParseStatement(labels, CHECK_OK); |
|
|
|
} else { |
|
|
|
else_statement = EmptyStatement(); |
|
|
|
else_statement = factory()->NewEmptyStatement(); |
|
|
|
} |
|
|
|
return new(zone()) IfStatement( |
|
|
|
isolate(), condition, then_statement, else_statement); |
|
|
|
return factory()->NewIfStatement(condition, then_statement, else_statement); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2110,7 +2057,7 @@ Statement* Parser::ParseContinueStatement(bool* ok) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
ExpectSemicolon(CHECK_OK); |
|
|
|
return new(zone()) ContinueStatement(target); |
|
|
|
return factory()->NewContinueStatement(target); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2128,7 +2075,8 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
// Parse labeled break statements that target themselves into
|
|
|
|
// empty statements, e.g. 'l1: l2: l3: break l2;'
|
|
|
|
if (!label.is_null() && ContainsLabel(labels, label)) { |
|
|
|
return EmptyStatement(); |
|
|
|
ExpectSemicolon(CHECK_OK); |
|
|
|
return factory()->NewEmptyStatement(); |
|
|
|
} |
|
|
|
BreakableStatement* target = NULL; |
|
|
|
target = LookupBreakTarget(label, CHECK_OK); |
|
|
@ -2145,7 +2093,7 @@ Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
ExpectSemicolon(CHECK_OK); |
|
|
|
return new(zone()) BreakStatement(target); |
|
|
|
return factory()->NewBreakStatement(target); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2165,11 +2113,11 @@ Statement* Parser::ParseReturnStatement(bool* ok) { |
|
|
|
tok == Token::RBRACE || |
|
|
|
tok == Token::EOS) { |
|
|
|
ExpectSemicolon(CHECK_OK); |
|
|
|
result = new(zone()) ReturnStatement(GetLiteralUndefined()); |
|
|
|
result = factory()->NewReturnStatement(GetLiteralUndefined()); |
|
|
|
} else { |
|
|
|
Expression* expr = ParseExpression(true, CHECK_OK); |
|
|
|
ExpectSemicolon(CHECK_OK); |
|
|
|
result = new(zone()) ReturnStatement(expr); |
|
|
|
result = factory()->NewReturnStatement(expr); |
|
|
|
} |
|
|
|
|
|
|
|
// An ECMAScript program is considered syntactically incorrect if it
|
|
|
@ -2182,7 +2130,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) { |
|
|
|
declaration_scope->is_eval_scope()) { |
|
|
|
Handle<String> type = isolate()->factory()->illegal_return_symbol(); |
|
|
|
Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); |
|
|
|
return new(zone()) ExpressionStatement(throw_error); |
|
|
|
return factory()->NewExpressionStatement(throw_error); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
@ -2212,7 +2160,7 @@ Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
stmt = ParseStatement(labels, CHECK_OK); |
|
|
|
with_scope->set_end_position(scanner().location().end_pos); |
|
|
|
} |
|
|
|
return new(zone()) WithStatement(expr, stmt); |
|
|
|
return factory()->NewWithStatement(expr, stmt); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2254,7 +2202,7 @@ SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
|
|
|
// SwitchStatement ::
|
|
|
|
// 'switch' '(' Expression ')' '{' CaseClause* '}'
|
|
|
|
|
|
|
|
SwitchStatement* statement = new(zone()) SwitchStatement(isolate(), labels); |
|
|
|
SwitchStatement* statement = factory()->NewSwitchStatement(labels); |
|
|
|
Target target(&this->target_stack_, statement); |
|
|
|
|
|
|
|
Expect(Token::SWITCH, CHECK_OK); |
|
|
@ -2290,8 +2238,7 @@ Statement* Parser::ParseThrowStatement(bool* ok) { |
|
|
|
Expression* exception = ParseExpression(true, CHECK_OK); |
|
|
|
ExpectSemicolon(CHECK_OK); |
|
|
|
|
|
|
|
return new(zone()) ExpressionStatement( |
|
|
|
new(zone()) Throw(isolate(), exception, pos)); |
|
|
|
return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2378,13 +2325,10 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
|
|
|
// If we have both, create an inner try/catch.
|
|
|
|
ASSERT(catch_scope != NULL && catch_variable != NULL); |
|
|
|
int index = current_function_state_->NextHandlerIndex(); |
|
|
|
TryCatchStatement* statement = new(zone()) TryCatchStatement(index, |
|
|
|
try_block, |
|
|
|
catch_scope, |
|
|
|
catch_variable, |
|
|
|
catch_block); |
|
|
|
TryCatchStatement* statement = factory()->NewTryCatchStatement( |
|
|
|
index, try_block, catch_scope, catch_variable, catch_block); |
|
|
|
statement->set_escaping_targets(try_collector.targets()); |
|
|
|
try_block = new(zone()) Block(isolate(), NULL, 1, false); |
|
|
|
try_block = factory()->NewBlock(NULL, 1, false); |
|
|
|
try_block->AddStatement(statement); |
|
|
|
catch_block = NULL; // Clear to indicate it's been handled.
|
|
|
|
} |
|
|
@ -2394,17 +2338,12 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { |
|
|
|
ASSERT(finally_block == NULL); |
|
|
|
ASSERT(catch_scope != NULL && catch_variable != NULL); |
|
|
|
int index = current_function_state_->NextHandlerIndex(); |
|
|
|
result = new(zone()) TryCatchStatement(index, |
|
|
|
try_block, |
|
|
|
catch_scope, |
|
|
|
catch_variable, |
|
|
|
catch_block); |
|
|
|
result = factory()->NewTryCatchStatement( |
|
|
|
index, try_block, catch_scope, catch_variable, catch_block); |
|
|
|
} else { |
|
|
|
ASSERT(finally_block != NULL); |
|
|
|
int index = current_function_state_->NextHandlerIndex(); |
|
|
|
result = new(zone()) TryFinallyStatement(index, |
|
|
|
try_block, |
|
|
|
finally_block); |
|
|
|
result = factory()->NewTryFinallyStatement(index, try_block, finally_block); |
|
|
|
// Combine the jump targets of the try block and the possible catch block.
|
|
|
|
try_collector.targets()->AddAll(*catch_collector.targets()); |
|
|
|
} |
|
|
@ -2419,7 +2358,7 @@ DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
|
|
|
// DoStatement ::
|
|
|
|
// 'do' Statement 'while' '(' Expression ')' ';'
|
|
|
|
|
|
|
|
DoWhileStatement* loop = new(zone()) DoWhileStatement(isolate(), labels); |
|
|
|
DoWhileStatement* loop = factory()->NewDoWhileStatement(labels); |
|
|
|
Target target(&this->target_stack_, loop); |
|
|
|
|
|
|
|
Expect(Token::DO, CHECK_OK); |
|
|
@ -2450,7 +2389,7 @@ WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
// WhileStatement ::
|
|
|
|
// 'while' '(' Expression ')' Statement
|
|
|
|
|
|
|
|
WhileStatement* loop = new(zone()) WhileStatement(isolate(), labels); |
|
|
|
WhileStatement* loop = factory()->NewWhileStatement(labels); |
|
|
|
Target target(&this->target_stack_, loop); |
|
|
|
|
|
|
|
Expect(Token::WHILE, CHECK_OK); |
|
|
@ -2485,8 +2424,8 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
ParseVariableDeclarations(kForStatement, NULL, &name, CHECK_OK); |
|
|
|
|
|
|
|
if (peek() == Token::IN && !name.is_null()) { |
|
|
|
VariableProxy* each = top_scope_->NewUnresolved(name); |
|
|
|
ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); |
|
|
|
VariableProxy* each = top_scope_->NewUnresolved(factory(), name); |
|
|
|
ForInStatement* loop = factory()->NewForInStatement(labels); |
|
|
|
Target target(&this->target_stack_, loop); |
|
|
|
|
|
|
|
Expect(Token::IN, CHECK_OK); |
|
|
@ -2495,7 +2434,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
|
|
|
|
Statement* body = ParseStatement(NULL, CHECK_OK); |
|
|
|
loop->Initialize(each, enumerable, body); |
|
|
|
Block* result = new(zone()) Block(isolate(), NULL, 2, false); |
|
|
|
Block* result = factory()->NewBlock(NULL, 2, false); |
|
|
|
result->AddStatement(variable_statement); |
|
|
|
result->AddStatement(loop); |
|
|
|
top_scope_ = saved_scope; |
|
|
@ -2533,9 +2472,9 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
// TODO(keuchel): Move the temporary variable to the block scope, after
|
|
|
|
// implementing stack allocated block scoped variables.
|
|
|
|
Variable* temp = top_scope_->DeclarationScope()->NewTemporary(name); |
|
|
|
VariableProxy* temp_proxy = new(zone()) VariableProxy(isolate(), temp); |
|
|
|
VariableProxy* each = top_scope_->NewUnresolved(name); |
|
|
|
ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); |
|
|
|
VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
|
|
|
VariableProxy* each = top_scope_->NewUnresolved(factory(), name); |
|
|
|
ForInStatement* loop = factory()->NewForInStatement(labels); |
|
|
|
Target target(&this->target_stack_, loop); |
|
|
|
|
|
|
|
Expect(Token::IN, CHECK_OK); |
|
|
@ -2543,14 +2482,11 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
Expect(Token::RPAREN, CHECK_OK); |
|
|
|
|
|
|
|
Statement* body = ParseStatement(NULL, CHECK_OK); |
|
|
|
Block* body_block = new(zone()) Block(isolate(), NULL, 3, false); |
|
|
|
Assignment* assignment = new(zone()) Assignment(isolate(), |
|
|
|
Token::ASSIGN, |
|
|
|
each, |
|
|
|
temp_proxy, |
|
|
|
RelocInfo::kNoPosition); |
|
|
|
Block* body_block = factory()->NewBlock(NULL, 3, false); |
|
|
|
Assignment* assignment = factory()->NewAssignment( |
|
|
|
Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
|
|
|
Statement* assignment_statement = |
|
|
|
new(zone()) ExpressionStatement(assignment); |
|
|
|
factory()->NewExpressionStatement(assignment); |
|
|
|
body_block->AddStatement(variable_statement); |
|
|
|
body_block->AddStatement(assignment_statement); |
|
|
|
body_block->AddStatement(body); |
|
|
@ -2577,7 +2513,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
isolate()->factory()->invalid_lhs_in_for_in_symbol(); |
|
|
|
expression = NewThrowReferenceError(type); |
|
|
|
} |
|
|
|
ForInStatement* loop = new(zone()) ForInStatement(isolate(), labels); |
|
|
|
ForInStatement* loop = factory()->NewForInStatement(labels); |
|
|
|
Target target(&this->target_stack_, loop); |
|
|
|
|
|
|
|
Expect(Token::IN, CHECK_OK); |
|
|
@ -2594,13 +2530,13 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
return loop; |
|
|
|
|
|
|
|
} else { |
|
|
|
init = new(zone()) ExpressionStatement(expression); |
|
|
|
init = factory()->NewExpressionStatement(expression); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Standard 'for' loop
|
|
|
|
ForStatement* loop = new(zone()) ForStatement(isolate(), labels); |
|
|
|
ForStatement* loop = factory()->NewForStatement(labels); |
|
|
|
Target target(&this->target_stack_, loop); |
|
|
|
|
|
|
|
// Parsed initializer at this point.
|
|
|
@ -2615,7 +2551,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
Statement* next = NULL; |
|
|
|
if (peek() != Token::RPAREN) { |
|
|
|
Expression* exp = ParseExpression(true, CHECK_OK); |
|
|
|
next = new(zone()) ExpressionStatement(exp); |
|
|
|
next = factory()->NewExpressionStatement(exp); |
|
|
|
} |
|
|
|
Expect(Token::RPAREN, CHECK_OK); |
|
|
|
|
|
|
@ -2635,7 +2571,7 @@ Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
|
|
|
// for (; c; n) b
|
|
|
|
// }
|
|
|
|
ASSERT(init != NULL); |
|
|
|
Block* result = new(zone()) Block(isolate(), NULL, 2, false); |
|
|
|
Block* result = factory()->NewBlock(NULL, 2, false); |
|
|
|
result->AddStatement(init); |
|
|
|
result->AddStatement(loop); |
|
|
|
result->set_block_scope(for_scope); |
|
|
@ -2659,8 +2595,8 @@ Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
|
|
|
Expect(Token::COMMA, CHECK_OK); |
|
|
|
int position = scanner().location().beg_pos; |
|
|
|
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
|
|
|
result = new(zone()) BinaryOperation( |
|
|
|
isolate(), Token::COMMA, result, right, position); |
|
|
|
result = |
|
|
|
factory()->NewBinaryOperation(Token::COMMA, result, right, position); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
@ -2735,7 +2671,7 @@ Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
|
|
|
fni_->Leave(); |
|
|
|
} |
|
|
|
|
|
|
|
return new(zone()) Assignment(isolate(), op, expression, right, pos); |
|
|
|
return factory()->NewAssignment(op, expression, right, pos); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2757,8 +2693,8 @@ Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
|
|
|
Expect(Token::COLON, CHECK_OK); |
|
|
|
int right_position = scanner().peek_location().beg_pos; |
|
|
|
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
|
|
|
return new(zone()) Conditional( |
|
|
|
isolate(), expression, left, right, left_position, right_position); |
|
|
|
return factory()->NewConditional( |
|
|
|
expression, left, right, left_position, right_position); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2789,41 +2725,47 @@ Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
|
|
|
|
|
|
|
switch (op) { |
|
|
|
case Token::ADD: |
|
|
|
x = NewNumberLiteral(x_val + y_val); |
|
|
|
x = factory()->NewNumberLiteral(x_val + y_val); |
|
|
|
continue; |
|
|
|
case Token::SUB: |
|
|
|
x = NewNumberLiteral(x_val - y_val); |
|
|
|
x = factory()->NewNumberLiteral(x_val - y_val); |
|
|
|
continue; |
|
|
|
case Token::MUL: |
|
|
|
x = NewNumberLiteral(x_val * y_val); |
|
|
|
x = factory()->NewNumberLiteral(x_val * y_val); |
|
|
|
continue; |
|
|
|
case Token::DIV: |
|
|
|
x = NewNumberLiteral(x_val / y_val); |
|
|
|
x = factory()->NewNumberLiteral(x_val / y_val); |
|
|
|
continue; |
|
|
|
case Token::BIT_OR: |
|
|
|
x = NewNumberLiteral(DoubleToInt32(x_val) | DoubleToInt32(y_val)); |
|
|
|
case Token::BIT_OR: { |
|
|
|
int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); |
|
|
|
x = factory()->NewNumberLiteral(value); |
|
|
|
continue; |
|
|
|
case Token::BIT_AND: |
|
|
|
x = NewNumberLiteral(DoubleToInt32(x_val) & DoubleToInt32(y_val)); |
|
|
|
} |
|
|
|
case Token::BIT_AND: { |
|
|
|
int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); |
|
|
|
x = factory()->NewNumberLiteral(value); |
|
|
|
continue; |
|
|
|
case Token::BIT_XOR: |
|
|
|
x = NewNumberLiteral(DoubleToInt32(x_val) ^ DoubleToInt32(y_val)); |
|
|
|
} |
|
|
|
case Token::BIT_XOR: { |
|
|
|
int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); |
|
|
|
x = factory()->NewNumberLiteral(value); |
|
|
|
continue; |
|
|
|
} |
|
|
|
case Token::SHL: { |
|
|
|
int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); |
|
|
|
x = NewNumberLiteral(value); |
|
|
|
x = factory()->NewNumberLiteral(value); |
|
|
|
continue; |
|
|
|
} |
|
|
|
case Token::SHR: { |
|
|
|
uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
|
|
|
uint32_t value = DoubleToUint32(x_val) >> shift; |
|
|
|
x = NewNumberLiteral(value); |
|
|
|
x = factory()->NewNumberLiteral(value); |
|
|
|
continue; |
|
|
|
} |
|
|
|
case Token::SAR: { |
|
|
|
uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
|
|
|
int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); |
|
|
|
x = NewNumberLiteral(value); |
|
|
|
x = factory()->NewNumberLiteral(value); |
|
|
|
continue; |
|
|
|
} |
|
|
|
default: |
|
|
@ -2842,15 +2784,15 @@ Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
|
|
|
case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
|
|
|
default: break; |
|
|
|
} |
|
|
|
x = new(zone()) CompareOperation(isolate(), cmp, x, y, position); |
|
|
|
x = factory()->NewCompareOperation(cmp, x, y, position); |
|
|
|
if (cmp != op) { |
|
|
|
// The comparison was negated - add a NOT.
|
|
|
|
x = new(zone()) UnaryOperation(isolate(), Token::NOT, x, position); |
|
|
|
x = factory()->NewUnaryOperation(Token::NOT, x, position); |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
// We have a "normal" binary operation.
|
|
|
|
x = new(zone()) BinaryOperation(isolate(), op, x, y, position); |
|
|
|
x = factory()->NewBinaryOperation(op, x, y, position); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -2883,7 +2825,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { |
|
|
|
// Convert the literal to a boolean condition and negate it.
|
|
|
|
bool condition = literal->ToBoolean()->IsTrue(); |
|
|
|
Handle<Object> result(isolate()->heap()->ToBoolean(!condition)); |
|
|
|
return NewLiteral(result); |
|
|
|
return factory()->NewLiteral(result); |
|
|
|
} else if (literal->IsNumber()) { |
|
|
|
// Compute some expressions involving only number literals.
|
|
|
|
double value = literal->Number(); |
|
|
@ -2891,9 +2833,9 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { |
|
|
|
case Token::ADD: |
|
|
|
return expression; |
|
|
|
case Token::SUB: |
|
|
|
return NewNumberLiteral(-value); |
|
|
|
return factory()->NewNumberLiteral(-value); |
|
|
|
case Token::BIT_NOT: |
|
|
|
return NewNumberLiteral(~DoubleToInt32(value)); |
|
|
|
return factory()->NewNumberLiteral(~DoubleToInt32(value)); |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
@ -2910,7 +2852,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return new(zone()) UnaryOperation(isolate(), op, expression, position); |
|
|
|
return factory()->NewUnaryOperation(op, expression, position); |
|
|
|
|
|
|
|
} else if (Token::IsCountOp(op)) { |
|
|
|
op = Next(); |
|
|
@ -2932,8 +2874,7 @@ Expression* Parser::ParseUnaryExpression(bool* ok) { |
|
|
|
MarkAsLValue(expression); |
|
|
|
|
|
|
|
int position = scanner().location().beg_pos; |
|
|
|
return new(zone()) CountOperation(isolate(), |
|
|
|
op, |
|
|
|
return factory()->NewCountOperation(op, |
|
|
|
true /* prefix */, |
|
|
|
expression, |
|
|
|
position); |
|
|
@ -2970,8 +2911,7 @@ Expression* Parser::ParsePostfixExpression(bool* ok) { |
|
|
|
Token::Value next = Next(); |
|
|
|
int position = scanner().location().beg_pos; |
|
|
|
expression = |
|
|
|
new(zone()) CountOperation(isolate(), |
|
|
|
next, |
|
|
|
factory()->NewCountOperation(next, |
|
|
|
false /* postfix */, |
|
|
|
expression, |
|
|
|
position); |
|
|
@ -2997,7 +2937,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
|
|
|
Consume(Token::LBRACK); |
|
|
|
int pos = scanner().location().beg_pos; |
|
|
|
Expression* index = ParseExpression(true, CHECK_OK); |
|
|
|
result = new(zone()) Property(isolate(), result, index, pos); |
|
|
|
result = factory()->NewProperty(result, index, pos); |
|
|
|
Expect(Token::RBRACK, CHECK_OK); |
|
|
|
break; |
|
|
|
} |
|
|
@ -3030,7 +2970,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
|
|
|
callee->IsVariable(isolate()->factory()->eval_symbol())) { |
|
|
|
top_scope_->DeclarationScope()->RecordEvalCall(); |
|
|
|
} |
|
|
|
result = NewCall(result, args, pos); |
|
|
|
result = factory()->NewCall(result, args, pos); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
@ -3038,10 +2978,8 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
|
|
|
Consume(Token::PERIOD); |
|
|
|
int pos = scanner().location().beg_pos; |
|
|
|
Handle<String> name = ParseIdentifierName(CHECK_OK); |
|
|
|
result = new(zone()) Property(isolate(), |
|
|
|
result, |
|
|
|
NewLiteral(name), |
|
|
|
pos); |
|
|
|
result = |
|
|
|
factory()->NewProperty(result, factory()->NewLiteral(name), pos); |
|
|
|
if (fni_ != NULL) fni_->PushLiteralName(name); |
|
|
|
break; |
|
|
|
} |
|
|
@ -3077,10 +3015,8 @@ Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { |
|
|
|
|
|
|
|
if (!stack->is_empty()) { |
|
|
|
int last = stack->pop(); |
|
|
|
result = new(zone()) CallNew(isolate(), |
|
|
|
result, |
|
|
|
new(zone()) ZoneList<Expression*>(0), |
|
|
|
last); |
|
|
|
result = factory()->NewCallNew( |
|
|
|
result, new(zone()) ZoneList<Expression*>(0), last); |
|
|
|
} |
|
|
|
return result; |
|
|
|
} |
|
|
@ -3132,7 +3068,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
|
|
|
Consume(Token::LBRACK); |
|
|
|
int pos = scanner().location().beg_pos; |
|
|
|
Expression* index = ParseExpression(true, CHECK_OK); |
|
|
|
result = new(zone()) Property(isolate(), result, index, pos); |
|
|
|
result = factory()->NewProperty(result, index, pos); |
|
|
|
if (fni_ != NULL) { |
|
|
|
if (index->IsPropertyName()) { |
|
|
|
fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); |
|
|
@ -3148,10 +3084,8 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
|
|
|
Consume(Token::PERIOD); |
|
|
|
int pos = scanner().location().beg_pos; |
|
|
|
Handle<String> name = ParseIdentifierName(CHECK_OK); |
|
|
|
result = new(zone()) Property(isolate(), |
|
|
|
result, |
|
|
|
NewLiteral(name), |
|
|
|
pos); |
|
|
|
result = |
|
|
|
factory()->NewProperty(result, factory()->NewLiteral(name), pos); |
|
|
|
if (fni_ != NULL) fni_->PushLiteralName(name); |
|
|
|
break; |
|
|
|
} |
|
|
@ -3160,7 +3094,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
|
|
|
// Consume one of the new prefixes (already parsed).
|
|
|
|
ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
|
|
|
int last = stack->pop(); |
|
|
|
result = new(zone()) CallNew(isolate(), result, args, last); |
|
|
|
result = factory()->NewCallNew(result, args, last); |
|
|
|
break; |
|
|
|
} |
|
|
|
default: |
|
|
@ -3179,7 +3113,7 @@ DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
|
|
|
|
|
|
|
Expect(Token::DEBUGGER, CHECK_OK); |
|
|
|
ExpectSemicolon(CHECK_OK); |
|
|
|
return new(zone()) DebuggerStatement(); |
|
|
|
return factory()->NewDebuggerStatement(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -3244,33 +3178,31 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) { |
|
|
|
switch (peek()) { |
|
|
|
case Token::THIS: { |
|
|
|
Consume(Token::THIS); |
|
|
|
result = new(zone()) VariableProxy(isolate(), top_scope_->receiver()); |
|
|
|
result = factory()->NewVariableProxy(top_scope_->receiver()); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case Token::NULL_LITERAL: |
|
|
|
Consume(Token::NULL_LITERAL); |
|
|
|
result = new(zone()) Literal( |
|
|
|
isolate(), isolate()->factory()->null_value()); |
|
|
|
result = factory()->NewLiteral(isolate()->factory()->null_value()); |
|
|
|
break; |
|
|
|
|
|
|
|
case Token::TRUE_LITERAL: |
|
|
|
Consume(Token::TRUE_LITERAL); |
|
|
|
result = new(zone()) Literal( |
|
|
|
isolate(), isolate()->factory()->true_value()); |
|
|
|
result = factory()->NewLiteral(isolate()->factory()->true_value()); |
|
|
|
break; |
|
|
|
|
|
|
|
case Token::FALSE_LITERAL: |
|
|
|
Consume(Token::FALSE_LITERAL); |
|
|
|
result = new(zone()) Literal( |
|
|
|
isolate(), isolate()->factory()->false_value()); |
|
|
|
result = factory()->NewLiteral(isolate()->factory()->false_value()); |
|
|
|
break; |
|
|
|
|
|
|
|
case Token::IDENTIFIER: |
|
|
|
case Token::FUTURE_STRICT_RESERVED_WORD: { |
|
|
|
Handle<String> name = ParseIdentifier(CHECK_OK); |
|
|
|
if (fni_ != NULL) fni_->PushVariableName(name); |
|
|
|
result = top_scope_->NewUnresolved(name, scanner().location().beg_pos); |
|
|
|
result = top_scope_->NewUnresolved( |
|
|
|
factory(), name, scanner().location().beg_pos); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
@ -3280,14 +3212,14 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) { |
|
|
|
double value = StringToDouble(isolate()->unicode_cache(), |
|
|
|
scanner().literal_ascii_string(), |
|
|
|
ALLOW_HEX | ALLOW_OCTALS); |
|
|
|
result = NewNumberLiteral(value); |
|
|
|
result = factory()->NewNumberLiteral(value); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case Token::STRING: { |
|
|
|
Consume(Token::STRING); |
|
|
|
Handle<String> symbol = GetSymbol(CHECK_OK); |
|
|
|
result = NewLiteral(symbol); |
|
|
|
result = factory()->NewLiteral(symbol); |
|
|
|
if (fni_ != NULL) fni_->PushLiteralName(symbol); |
|
|
|
break; |
|
|
|
} |
|
|
@ -3481,8 +3413,8 @@ Expression* Parser::ParseArrayLiteral(bool* ok) { |
|
|
|
literals->set(0, Smi::FromInt(elements_kind)); |
|
|
|
literals->set(1, *element_values); |
|
|
|
|
|
|
|
return new(zone()) ArrayLiteral( |
|
|
|
isolate(), literals, values, literal_index, is_simple, depth); |
|
|
|
return factory()->NewArrayLiteral( |
|
|
|
literals, values, literal_index, is_simple, depth); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -3759,9 +3691,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, |
|
|
|
CHECK_OK); |
|
|
|
// Allow any number of parameters for compatibilty with JSC.
|
|
|
|
// Specification only allows zero parameters for get and one for set.
|
|
|
|
ObjectLiteral::Property* property = |
|
|
|
new(zone()) ObjectLiteral::Property(is_getter, value); |
|
|
|
return property; |
|
|
|
return factory()->NewObjectLiteralProperty(is_getter, value); |
|
|
|
} else { |
|
|
|
ReportUnexpectedToken(next); |
|
|
|
*ok = false; |
|
|
@ -3826,7 +3756,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { |
|
|
|
} |
|
|
|
// Failed to parse as get/set property, so it's just a property
|
|
|
|
// called "get" or "set".
|
|
|
|
key = NewLiteral(id); |
|
|
|
key = factory()->NewLiteral(id); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Token::STRING: { |
|
|
@ -3835,10 +3765,10 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { |
|
|
|
if (fni_ != NULL) fni_->PushLiteralName(string); |
|
|
|
uint32_t index; |
|
|
|
if (!string.is_null() && string->AsArrayIndex(&index)) { |
|
|
|
key = NewNumberLiteral(index); |
|
|
|
key = factory()->NewNumberLiteral(index); |
|
|
|
break; |
|
|
|
} |
|
|
|
key = NewLiteral(string); |
|
|
|
key = factory()->NewLiteral(string); |
|
|
|
break; |
|
|
|
} |
|
|
|
case Token::NUMBER: { |
|
|
@ -3847,14 +3777,14 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { |
|
|
|
double value = StringToDouble(isolate()->unicode_cache(), |
|
|
|
scanner().literal_ascii_string(), |
|
|
|
ALLOW_HEX | ALLOW_OCTALS); |
|
|
|
key = NewNumberLiteral(value); |
|
|
|
key = factory()->NewNumberLiteral(value); |
|
|
|
break; |
|
|
|
} |
|
|
|
default: |
|
|
|
if (Token::IsKeyword(next)) { |
|
|
|
Consume(next); |
|
|
|
Handle<String> string = GetSymbol(CHECK_OK); |
|
|
|
key = NewLiteral(string); |
|
|
|
key = factory()->NewLiteral(string); |
|
|
|
} else { |
|
|
|
// Unexpected token.
|
|
|
|
Token::Value next = Next(); |
|
|
@ -3909,8 +3839,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { |
|
|
|
&is_simple, |
|
|
|
&fast_elements, |
|
|
|
&depth); |
|
|
|
return new(zone()) ObjectLiteral(isolate(), |
|
|
|
constant_properties, |
|
|
|
return factory()->NewObjectLiteral(constant_properties, |
|
|
|
properties, |
|
|
|
literal_index, |
|
|
|
is_simple, |
|
|
@ -3935,8 +3864,7 @@ Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
|
|
|
Handle<String> js_flags = NextLiteralString(TENURED); |
|
|
|
Next(); |
|
|
|
|
|
|
|
return new(zone()) RegExpLiteral( |
|
|
|
isolate(), js_pattern, js_flags, literal_index); |
|
|
|
return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -3967,7 +3895,7 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
|
|
|
class SingletonLogger : public ParserRecorder { |
|
|
|
public: |
|
|
|
SingletonLogger() : has_error_(false), start_(-1), end_(-1) { } |
|
|
|
~SingletonLogger() { } |
|
|
|
virtual ~SingletonLogger() { } |
|
|
|
|
|
|
|
void Reset() { has_error_ = false; } |
|
|
|
|
|
|
@ -4088,6 +4016,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
|
|
|
bool only_simple_this_property_assignments; |
|
|
|
Handle<FixedArray> this_property_assignments; |
|
|
|
bool has_duplicate_parameters = false; |
|
|
|
AstProperties ast_properties; |
|
|
|
// Parse function body.
|
|
|
|
{ FunctionState function_state(this, scope, isolate()); |
|
|
|
top_scope_->SetScopeName(function_name); |
|
|
@ -4150,7 +4079,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
|
|
|
} else { |
|
|
|
fvar_mode = CONST; |
|
|
|
} |
|
|
|
fvar = top_scope_->DeclareFunctionVar(function_name, fvar_mode); |
|
|
|
fvar = |
|
|
|
top_scope_->DeclareFunctionVar(function_name, fvar_mode, factory()); |
|
|
|
} |
|
|
|
|
|
|
|
// Determine whether the function will be lazily compiled.
|
|
|
@ -4237,13 +4167,13 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
|
|
|
if (!is_lazily_compiled) { |
|
|
|
body = new(zone()) ZoneList<Statement*>(8); |
|
|
|
if (fvar != NULL) { |
|
|
|
VariableProxy* fproxy = top_scope_->NewUnresolved(function_name); |
|
|
|
VariableProxy* fproxy = |
|
|
|
top_scope_->NewUnresolved(factory(), function_name); |
|
|
|
fproxy->BindTo(fvar); |
|
|
|
body->Add(new(zone()) ExpressionStatement( |
|
|
|
new(zone()) Assignment(isolate(), |
|
|
|
fvar_init_op, |
|
|
|
body->Add(factory()->NewExpressionStatement( |
|
|
|
factory()->NewAssignment(fvar_init_op, |
|
|
|
fproxy, |
|
|
|
new(zone()) ThisFunction(isolate()), |
|
|
|
factory()->NewThisFunction(), |
|
|
|
RelocInfo::kNoPosition))); |
|
|
|
} |
|
|
|
ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
|
|
@ -4305,6 +4235,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
|
|
|
scope->end_position(), |
|
|
|
CHECK_OK); |
|
|
|
} |
|
|
|
ast_properties = *factory()->visitor()->ast_properties(); |
|
|
|
} |
|
|
|
|
|
|
|
if (is_extended_mode()) { |
|
|
@ -4312,8 +4243,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
|
|
|
} |
|
|
|
|
|
|
|
FunctionLiteral* function_literal = |
|
|
|
new(zone()) FunctionLiteral(isolate(), |
|
|
|
function_name, |
|
|
|
factory()->NewFunctionLiteral(function_name, |
|
|
|
scope, |
|
|
|
body, |
|
|
|
materialized_literal_count, |
|
|
@ -4322,9 +4252,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, |
|
|
|
only_simple_this_property_assignments, |
|
|
|
this_property_assignments, |
|
|
|
num_parameters, |
|
|
|
has_duplicate_parameters, |
|
|
|
type, |
|
|
|
has_duplicate_parameters); |
|
|
|
true); |
|
|
|
function_literal->set_function_token_position(function_token_position); |
|
|
|
function_literal->set_ast_properties(&ast_properties); |
|
|
|
|
|
|
|
if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
|
|
|
return function_literal; |
|
|
@ -4343,7 +4275,8 @@ preparser::PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
|
|
|
NULL, |
|
|
|
stack_limit, |
|
|
|
do_allow_lazy, |
|
|
|
allow_natives_syntax_); |
|
|
|
allow_natives_syntax_, |
|
|
|
allow_modules_); |
|
|
|
} |
|
|
|
preparser::PreParser::PreParseResult result = |
|
|
|
reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), |
|
|
@ -4394,7 +4327,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) { |
|
|
|
} |
|
|
|
|
|
|
|
// We have a valid intrinsics call or a call to a builtin.
|
|
|
|
return new(zone()) CallRuntime(isolate(), name, function, args); |
|
|
|
return factory()->NewCallRuntime(name, function, args); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -4450,17 +4383,12 @@ void Parser::ExpectSemicolon(bool* ok) { |
|
|
|
|
|
|
|
|
|
|
|
Literal* Parser::GetLiteralUndefined() { |
|
|
|
return NewLiteral(isolate()->factory()->undefined_value()); |
|
|
|
return factory()->NewLiteral(isolate()->factory()->undefined_value()); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Literal* Parser::GetLiteralTheHole() { |
|
|
|
return NewLiteral(isolate()->factory()->the_hole_value()); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Literal* Parser::GetLiteralNumber(double value) { |
|
|
|
return NewNumberLiteral(value); |
|
|
|
return factory()->NewLiteral(isolate()->factory()->the_hole_value()); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -4638,11 +4566,6 @@ void Parser::RegisterTargetUse(Label* target, Target* stop) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Literal* Parser::NewNumberLiteral(double number) { |
|
|
|
return NewLiteral(isolate()->factory()->NewNumber(number, TENURED)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Expression* Parser::NewThrowReferenceError(Handle<String> type) { |
|
|
|
return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(), |
|
|
|
type, HandleVector<Object>(NULL, 0)); |
|
|
@ -4686,15 +4609,11 @@ Expression* Parser::NewThrowError(Handle<String> constructor, |
|
|
|
elements, FAST_ELEMENTS, TENURED); |
|
|
|
|
|
|
|
ZoneList<Expression*>* args = new(zone()) ZoneList<Expression*>(2); |
|
|
|
args->Add(NewLiteral(type)); |
|
|
|
args->Add(NewLiteral(array)); |
|
|
|
CallRuntime* call_constructor = new(zone()) CallRuntime(isolate(), |
|
|
|
constructor, |
|
|
|
NULL, |
|
|
|
args); |
|
|
|
return new(zone()) Throw(isolate(), |
|
|
|
call_constructor, |
|
|
|
scanner().location().beg_pos); |
|
|
|
args->Add(factory()->NewLiteral(type)); |
|
|
|
args->Add(factory()->NewLiteral(array)); |
|
|
|
CallRuntime* call_constructor = |
|
|
|
factory()->NewCallRuntime(constructor, NULL, args); |
|
|
|
return factory()->NewThrow(call_constructor, scanner().location().beg_pos); |
|
|
|
} |
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
@ -5665,8 +5584,11 @@ bool ParserApi::Parse(CompilationInfo* info, int parsing_flags) { |
|
|
|
// Harmony scoping is requested.
|
|
|
|
parsing_flags |= EXTENDED_MODE; |
|
|
|
} |
|
|
|
if (!info->is_native() && FLAG_harmony_modules) { |
|
|
|
parsing_flags |= kAllowModules; |
|
|
|
} |
|
|
|
if (FLAG_allow_natives_syntax || info->is_native()) { |
|
|
|
// We requre %identifier(..) syntax.
|
|
|
|
// We require %identifier(..) syntax.
|
|
|
|
parsing_flags |= kAllowNativesSyntax; |
|
|
|
} |
|
|
|
if (info->is_lazy()) { |
|
|
|