Browse Source

deps: upgrade V8 to 4.6.85.25

Move up to the latest patch level from the V8 4.6 branch:
https://github.com/v8/v8/compare/4.6.85.23...4.6.85.25

PR-URL: https://github.com/nodejs/node/pull/3351
Reviewed-By: indutny - Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
v5.x
Ali Ijaz Sheikh 9 years ago
parent
commit
770cd229f9
  1. 2
      deps/v8/include/v8-version.h
  2. 202
      deps/v8/src/ast.h
  3. 38
      deps/v8/src/parser.cc
  4. 62
      deps/v8/test/cctest/test-parsing.cc
  5. 43
      deps/v8/test/mjsunit/compiler/lazy-iife-no-parens.js
  6. 45
      deps/v8/tools/run-tests.py

2
deps/v8/include/v8-version.h

@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 4 #define V8_MAJOR_VERSION 4
#define V8_MINOR_VERSION 6 #define V8_MINOR_VERSION 6
#define V8_BUILD_NUMBER 85 #define V8_BUILD_NUMBER 85
#define V8_PATCH_LEVEL 23 #define V8_PATCH_LEVEL 25
// Use 1 for candidates and 0 otherwise. // Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.) // (Boolean macro values are not supported by all preprocessors.)

202
deps/v8/src/ast.h

@ -3271,14 +3271,15 @@ class AstVisitor BASE_EMBEDDED {
class AstNodeFactory final BASE_EMBEDDED { class AstNodeFactory final BASE_EMBEDDED {
public: public:
explicit AstNodeFactory(AstValueFactory* ast_value_factory) explicit AstNodeFactory(AstValueFactory* ast_value_factory)
: zone_(ast_value_factory->zone()), : local_zone_(ast_value_factory->zone()),
parser_zone_(ast_value_factory->zone()),
ast_value_factory_(ast_value_factory) {} ast_value_factory_(ast_value_factory) {}
VariableDeclaration* NewVariableDeclaration( VariableDeclaration* NewVariableDeclaration(
VariableProxy* proxy, VariableMode mode, Scope* scope, int pos, VariableProxy* proxy, VariableMode mode, Scope* scope, int pos,
bool is_class_declaration = false, int declaration_group_start = -1) { bool is_class_declaration = false, int declaration_group_start = -1) {
return new (zone_) return new (parser_zone_)
VariableDeclaration(zone_, proxy, mode, scope, pos, VariableDeclaration(parser_zone_, proxy, mode, scope, pos,
is_class_declaration, declaration_group_start); is_class_declaration, declaration_group_start);
} }
@ -3287,32 +3288,34 @@ class AstNodeFactory final BASE_EMBEDDED {
FunctionLiteral* fun, FunctionLiteral* fun,
Scope* scope, Scope* scope,
int pos) { int pos) {
return new (zone_) FunctionDeclaration(zone_, proxy, mode, fun, scope, pos); return new (parser_zone_)
FunctionDeclaration(parser_zone_, proxy, mode, fun, scope, pos);
} }
ImportDeclaration* NewImportDeclaration(VariableProxy* proxy, ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
const AstRawString* import_name, const AstRawString* import_name,
const AstRawString* module_specifier, const AstRawString* module_specifier,
Scope* scope, int pos) { Scope* scope, int pos) {
return new (zone_) ImportDeclaration(zone_, proxy, import_name, return new (parser_zone_) ImportDeclaration(
module_specifier, scope, pos); parser_zone_, proxy, import_name, module_specifier, scope, pos);
} }
ExportDeclaration* NewExportDeclaration(VariableProxy* proxy, ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
Scope* scope, Scope* scope,
int pos) { int pos) {
return new (zone_) ExportDeclaration(zone_, proxy, scope, pos); return new (parser_zone_)
ExportDeclaration(parser_zone_, proxy, scope, pos);
} }
Block* NewBlock(ZoneList<const AstRawString*>* labels, int capacity, Block* NewBlock(ZoneList<const AstRawString*>* labels, int capacity,
bool ignore_completion_value, int pos) { bool ignore_completion_value, int pos) {
return new (zone_) return new (local_zone_)
Block(zone_, labels, capacity, ignore_completion_value, pos); Block(local_zone_, labels, capacity, ignore_completion_value, pos);
} }
#define STATEMENT_WITH_LABELS(NodeType) \ #define STATEMENT_WITH_LABELS(NodeType) \
NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \ NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
return new (zone_) NodeType(zone_, labels, pos); \ return new (local_zone_) NodeType(local_zone_, labels, pos); \
} }
STATEMENT_WITH_LABELS(DoWhileStatement) STATEMENT_WITH_LABELS(DoWhileStatement)
STATEMENT_WITH_LABELS(WhileStatement) STATEMENT_WITH_LABELS(WhileStatement)
@ -3325,10 +3328,10 @@ class AstNodeFactory final BASE_EMBEDDED {
int pos) { int pos) {
switch (visit_mode) { switch (visit_mode) {
case ForEachStatement::ENUMERATE: { case ForEachStatement::ENUMERATE: {
return new (zone_) ForInStatement(zone_, labels, pos); return new (local_zone_) ForInStatement(local_zone_, labels, pos);
} }
case ForEachStatement::ITERATE: { case ForEachStatement::ITERATE: {
return new (zone_) ForOfStatement(zone_, labels, pos); return new (local_zone_) ForOfStatement(local_zone_, labels, pos);
} }
} }
UNREACHABLE(); UNREACHABLE();
@ -3336,95 +3339,102 @@ class AstNodeFactory final BASE_EMBEDDED {
} }
ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) { ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
return new (zone_) ExpressionStatement(zone_, expression, pos); return new (local_zone_) ExpressionStatement(local_zone_, expression, pos);
} }
ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) { ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
return new (zone_) ContinueStatement(zone_, target, pos); return new (local_zone_) ContinueStatement(local_zone_, target, pos);
} }
BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) { BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
return new (zone_) BreakStatement(zone_, target, pos); return new (local_zone_) BreakStatement(local_zone_, target, pos);
} }
ReturnStatement* NewReturnStatement(Expression* expression, int pos) { ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
return new (zone_) ReturnStatement(zone_, expression, pos); return new (local_zone_) ReturnStatement(local_zone_, expression, pos);
} }
WithStatement* NewWithStatement(Scope* scope, WithStatement* NewWithStatement(Scope* scope,
Expression* expression, Expression* expression,
Statement* statement, Statement* statement,
int pos) { int pos) {
return new (zone_) WithStatement(zone_, scope, expression, statement, pos); return new (local_zone_)
WithStatement(local_zone_, scope, expression, statement, pos);
} }
IfStatement* NewIfStatement(Expression* condition, IfStatement* NewIfStatement(Expression* condition,
Statement* then_statement, Statement* then_statement,
Statement* else_statement, Statement* else_statement,
int pos) { int pos) {
return new (zone_) return new (local_zone_) IfStatement(local_zone_, condition, then_statement,
IfStatement(zone_, condition, then_statement, else_statement, pos); else_statement, pos);
} }
TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope, TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
Variable* variable, Variable* variable,
Block* catch_block, int pos) { Block* catch_block, int pos) {
return new (zone_) return new (local_zone_) TryCatchStatement(local_zone_, try_block, scope,
TryCatchStatement(zone_, try_block, scope, variable, catch_block, pos); variable, catch_block, pos);
} }
TryFinallyStatement* NewTryFinallyStatement(Block* try_block, TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
Block* finally_block, int pos) { Block* finally_block, int pos) {
return new (zone_) return new (local_zone_)
TryFinallyStatement(zone_, try_block, finally_block, pos); TryFinallyStatement(local_zone_, try_block, finally_block, pos);
} }
DebuggerStatement* NewDebuggerStatement(int pos) { DebuggerStatement* NewDebuggerStatement(int pos) {
return new (zone_) DebuggerStatement(zone_, pos); return new (local_zone_) DebuggerStatement(local_zone_, pos);
} }
EmptyStatement* NewEmptyStatement(int pos) { EmptyStatement* NewEmptyStatement(int pos) {
return new(zone_) EmptyStatement(zone_, pos); return new (local_zone_) EmptyStatement(local_zone_, pos);
} }
CaseClause* NewCaseClause( CaseClause* NewCaseClause(
Expression* label, ZoneList<Statement*>* statements, int pos) { Expression* label, ZoneList<Statement*>* statements, int pos) {
return new (zone_) CaseClause(zone_, label, statements, pos); return new (local_zone_) CaseClause(local_zone_, label, statements, pos);
} }
Literal* NewStringLiteral(const AstRawString* string, int pos) { Literal* NewStringLiteral(const AstRawString* string, int pos) {
return new (zone_) return new (local_zone_)
Literal(zone_, ast_value_factory_->NewString(string), pos); Literal(local_zone_, ast_value_factory_->NewString(string), pos);
} }
// A JavaScript symbol (ECMA-262 edition 6). // A JavaScript symbol (ECMA-262 edition 6).
Literal* NewSymbolLiteral(const char* name, int pos) { Literal* NewSymbolLiteral(const char* name, int pos) {
return new (zone_) Literal(zone_, ast_value_factory_->NewSymbol(name), pos); return new (local_zone_)
Literal(local_zone_, ast_value_factory_->NewSymbol(name), pos);
} }
Literal* NewNumberLiteral(double number, int pos, bool with_dot = false) { Literal* NewNumberLiteral(double number, int pos, bool with_dot = false) {
return new (zone_) return new (local_zone_) Literal(
Literal(zone_, ast_value_factory_->NewNumber(number, with_dot), pos); local_zone_, ast_value_factory_->NewNumber(number, with_dot), pos);
} }
Literal* NewSmiLiteral(int number, int pos) { Literal* NewSmiLiteral(int number, int pos) {
return new (zone_) Literal(zone_, ast_value_factory_->NewSmi(number), pos); return new (local_zone_)
Literal(local_zone_, ast_value_factory_->NewSmi(number), pos);
} }
Literal* NewBooleanLiteral(bool b, int pos) { Literal* NewBooleanLiteral(bool b, int pos) {
return new (zone_) Literal(zone_, ast_value_factory_->NewBoolean(b), pos); return new (local_zone_)
Literal(local_zone_, ast_value_factory_->NewBoolean(b), pos);
} }
Literal* NewNullLiteral(int pos) { Literal* NewNullLiteral(int pos) {
return new (zone_) Literal(zone_, ast_value_factory_->NewNull(), pos); return new (local_zone_)
Literal(local_zone_, ast_value_factory_->NewNull(), pos);
} }
Literal* NewUndefinedLiteral(int pos) { Literal* NewUndefinedLiteral(int pos) {
return new (zone_) Literal(zone_, ast_value_factory_->NewUndefined(), pos); return new (local_zone_)
Literal(local_zone_, ast_value_factory_->NewUndefined(), pos);
} }
Literal* NewTheHoleLiteral(int pos) { Literal* NewTheHoleLiteral(int pos) {
return new (zone_) Literal(zone_, ast_value_factory_->NewTheHole(), pos); return new (local_zone_)
Literal(local_zone_, ast_value_factory_->NewTheHole(), pos);
} }
ObjectLiteral* NewObjectLiteral( ObjectLiteral* NewObjectLiteral(
@ -3434,15 +3444,15 @@ class AstNodeFactory final BASE_EMBEDDED {
bool has_function, bool has_function,
bool is_strong, bool is_strong,
int pos) { int pos) {
return new (zone_) ObjectLiteral(zone_, properties, literal_index, return new (local_zone_)
boilerplate_properties, has_function, ObjectLiteral(local_zone_, properties, literal_index,
is_strong, pos); boilerplate_properties, has_function, is_strong, pos);
} }
ObjectLiteral::Property* NewObjectLiteralProperty( ObjectLiteral::Property* NewObjectLiteralProperty(
Expression* key, Expression* value, ObjectLiteralProperty::Kind kind, Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
bool is_static, bool is_computed_name) { bool is_static, bool is_computed_name) {
return new (zone_) return new (local_zone_)
ObjectLiteral::Property(key, value, kind, is_static, is_computed_name); ObjectLiteral::Property(key, value, kind, is_static, is_computed_name);
} }
@ -3450,8 +3460,8 @@ class AstNodeFactory final BASE_EMBEDDED {
Expression* value, Expression* value,
bool is_static, bool is_static,
bool is_computed_name) { bool is_computed_name) {
return new (zone_) ObjectLiteral::Property(ast_value_factory_, key, value, return new (local_zone_) ObjectLiteral::Property(
is_static, is_computed_name); ast_value_factory_, key, value, is_static, is_computed_name);
} }
RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern,
@ -3459,29 +3469,30 @@ class AstNodeFactory final BASE_EMBEDDED {
int literal_index, int literal_index,
bool is_strong, bool is_strong,
int pos) { int pos) {
return new (zone_) RegExpLiteral(zone_, pattern, flags, literal_index, return new (local_zone_) RegExpLiteral(local_zone_, pattern, flags,
is_strong, pos); literal_index, is_strong, pos);
} }
ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values, ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
int literal_index, int literal_index,
bool is_strong, bool is_strong,
int pos) { int pos) {
return new (zone_) return new (local_zone_)
ArrayLiteral(zone_, values, -1, literal_index, is_strong, pos); ArrayLiteral(local_zone_, values, -1, literal_index, is_strong, pos);
} }
ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values, ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
int first_spread_index, int literal_index, int first_spread_index, int literal_index,
bool is_strong, int pos) { bool is_strong, int pos) {
return new (zone_) ArrayLiteral(zone_, values, first_spread_index, return new (local_zone_) ArrayLiteral(
literal_index, is_strong, pos); local_zone_, values, first_spread_index, literal_index, is_strong, pos);
} }
VariableProxy* NewVariableProxy(Variable* var, VariableProxy* NewVariableProxy(Variable* var,
int start_position = RelocInfo::kNoPosition, int start_position = RelocInfo::kNoPosition,
int end_position = RelocInfo::kNoPosition) { int end_position = RelocInfo::kNoPosition) {
return new (zone_) VariableProxy(zone_, var, start_position, end_position); return new (parser_zone_)
VariableProxy(parser_zone_, var, start_position, end_position);
} }
VariableProxy* NewVariableProxy(const AstRawString* name, VariableProxy* NewVariableProxy(const AstRawString* name,
@ -3489,70 +3500,73 @@ class AstNodeFactory final BASE_EMBEDDED {
int start_position = RelocInfo::kNoPosition, int start_position = RelocInfo::kNoPosition,
int end_position = RelocInfo::kNoPosition) { int end_position = RelocInfo::kNoPosition) {
DCHECK_NOT_NULL(name); DCHECK_NOT_NULL(name);
return new (zone_) return new (parser_zone_) VariableProxy(parser_zone_, name, variable_kind,
VariableProxy(zone_, name, variable_kind, start_position, end_position); start_position, end_position);
} }
Property* NewProperty(Expression* obj, Expression* key, int pos) { Property* NewProperty(Expression* obj, Expression* key, int pos) {
return new (zone_) Property(zone_, obj, key, pos); return new (local_zone_) Property(local_zone_, obj, key, pos);
} }
Call* NewCall(Expression* expression, Call* NewCall(Expression* expression,
ZoneList<Expression*>* arguments, ZoneList<Expression*>* arguments,
int pos) { int pos) {
return new (zone_) Call(zone_, expression, arguments, pos); return new (local_zone_) Call(local_zone_, expression, arguments, pos);
} }
CallNew* NewCallNew(Expression* expression, CallNew* NewCallNew(Expression* expression,
ZoneList<Expression*>* arguments, ZoneList<Expression*>* arguments,
int pos) { int pos) {
return new (zone_) CallNew(zone_, expression, arguments, pos); return new (local_zone_) CallNew(local_zone_, expression, arguments, pos);
} }
CallRuntime* NewCallRuntime(const AstRawString* name, CallRuntime* NewCallRuntime(const AstRawString* name,
const Runtime::Function* function, const Runtime::Function* function,
ZoneList<Expression*>* arguments, ZoneList<Expression*>* arguments,
int pos) { int pos) {
return new (zone_) CallRuntime(zone_, name, function, arguments, pos); return new (local_zone_)
CallRuntime(local_zone_, name, function, arguments, pos);
} }
UnaryOperation* NewUnaryOperation(Token::Value op, UnaryOperation* NewUnaryOperation(Token::Value op,
Expression* expression, Expression* expression,
int pos) { int pos) {
return new (zone_) UnaryOperation(zone_, op, expression, pos); return new (local_zone_) UnaryOperation(local_zone_, op, expression, pos);
} }
BinaryOperation* NewBinaryOperation(Token::Value op, BinaryOperation* NewBinaryOperation(Token::Value op,
Expression* left, Expression* left,
Expression* right, Expression* right,
int pos) { int pos) {
return new (zone_) BinaryOperation(zone_, op, left, right, pos); return new (local_zone_) BinaryOperation(local_zone_, op, left, right, pos);
} }
CountOperation* NewCountOperation(Token::Value op, CountOperation* NewCountOperation(Token::Value op,
bool is_prefix, bool is_prefix,
Expression* expr, Expression* expr,
int pos) { int pos) {
return new (zone_) CountOperation(zone_, op, is_prefix, expr, pos); return new (local_zone_)
CountOperation(local_zone_, op, is_prefix, expr, pos);
} }
CompareOperation* NewCompareOperation(Token::Value op, CompareOperation* NewCompareOperation(Token::Value op,
Expression* left, Expression* left,
Expression* right, Expression* right,
int pos) { int pos) {
return new (zone_) CompareOperation(zone_, op, left, right, pos); return new (local_zone_)
CompareOperation(local_zone_, op, left, right, pos);
} }
Spread* NewSpread(Expression* expression, int pos) { Spread* NewSpread(Expression* expression, int pos) {
return new (zone_) Spread(zone_, expression, pos); return new (local_zone_) Spread(local_zone_, expression, pos);
} }
Conditional* NewConditional(Expression* condition, Conditional* NewConditional(Expression* condition,
Expression* then_expression, Expression* then_expression,
Expression* else_expression, Expression* else_expression,
int position) { int position) {
return new (zone_) Conditional(zone_, condition, then_expression, return new (local_zone_) Conditional(
else_expression, position); local_zone_, condition, then_expression, else_expression, position);
} }
Assignment* NewAssignment(Token::Value op, Assignment* NewAssignment(Token::Value op,
@ -3560,7 +3574,8 @@ class AstNodeFactory final BASE_EMBEDDED {
Expression* value, Expression* value,
int pos) { int pos) {
DCHECK(Token::IsAssignmentOp(op)); DCHECK(Token::IsAssignmentOp(op));
Assignment* assign = new (zone_) Assignment(zone_, op, target, value, pos); Assignment* assign =
new (local_zone_) Assignment(local_zone_, op, target, value, pos);
if (assign->is_compound()) { if (assign->is_compound()) {
DCHECK(Token::IsAssignmentOp(op)); DCHECK(Token::IsAssignmentOp(op));
assign->binary_operation_ = assign->binary_operation_ =
@ -3574,12 +3589,12 @@ class AstNodeFactory final BASE_EMBEDDED {
Yield::Kind yield_kind, Yield::Kind yield_kind,
int pos) { int pos) {
if (!expression) expression = NewUndefinedLiteral(pos); if (!expression) expression = NewUndefinedLiteral(pos);
return new (zone_) return new (local_zone_)
Yield(zone_, generator_object, expression, yield_kind, pos); Yield(local_zone_, generator_object, expression, yield_kind, pos);
} }
Throw* NewThrow(Expression* exception, int pos) { Throw* NewThrow(Expression* exception, int pos) {
return new (zone_) Throw(zone_, exception, pos); return new (local_zone_) Throw(local_zone_, exception, pos);
} }
FunctionLiteral* NewFunctionLiteral( FunctionLiteral* NewFunctionLiteral(
@ -3591,11 +3606,11 @@ class AstNodeFactory final BASE_EMBEDDED {
FunctionLiteral::IsFunctionFlag is_function, FunctionLiteral::IsFunctionFlag is_function,
FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind, FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
int position) { int position) {
return new (zone_) FunctionLiteral( return new (parser_zone_) FunctionLiteral(
zone_, name, ast_value_factory, scope, body, materialized_literal_count, parser_zone_, name, ast_value_factory, scope, body,
expected_property_count, parameter_count, function_type, materialized_literal_count, expected_property_count, parameter_count,
has_duplicate_parameters, is_function, eager_compile_hint, kind, function_type, has_duplicate_parameters, is_function,
position); eager_compile_hint, kind, position);
} }
ClassLiteral* NewClassLiteral(const AstRawString* name, Scope* scope, ClassLiteral* NewClassLiteral(const AstRawString* name, Scope* scope,
@ -3603,38 +3618,65 @@ class AstNodeFactory final BASE_EMBEDDED {
FunctionLiteral* constructor, FunctionLiteral* constructor,
ZoneList<ObjectLiteral::Property*>* properties, ZoneList<ObjectLiteral::Property*>* properties,
int start_position, int end_position) { int start_position, int end_position) {
return new (zone_) return new (parser_zone_)
ClassLiteral(zone_, name, scope, proxy, extends, constructor, ClassLiteral(parser_zone_, name, scope, proxy, extends, constructor,
properties, start_position, end_position); properties, start_position, end_position);
} }
NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name, NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
v8::Extension* extension, v8::Extension* extension,
int pos) { int pos) {
return new (zone_) NativeFunctionLiteral(zone_, name, extension, pos); return new (parser_zone_)
NativeFunctionLiteral(parser_zone_, name, extension, pos);
} }
ThisFunction* NewThisFunction(int pos) { ThisFunction* NewThisFunction(int pos) {
return new (zone_) ThisFunction(zone_, pos); return new (local_zone_) ThisFunction(local_zone_, pos);
} }
SuperPropertyReference* NewSuperPropertyReference(VariableProxy* this_var, SuperPropertyReference* NewSuperPropertyReference(VariableProxy* this_var,
Expression* home_object, Expression* home_object,
int pos) { int pos) {
return new (zone_) return new (parser_zone_)
SuperPropertyReference(zone_, this_var, home_object, pos); SuperPropertyReference(parser_zone_, this_var, home_object, pos);
} }
SuperCallReference* NewSuperCallReference(VariableProxy* this_var, SuperCallReference* NewSuperCallReference(VariableProxy* this_var,
VariableProxy* new_target_var, VariableProxy* new_target_var,
VariableProxy* this_function_var, VariableProxy* this_function_var,
int pos) { int pos) {
return new (zone_) SuperCallReference(zone_, this_var, new_target_var, return new (parser_zone_) SuperCallReference(
this_function_var, pos); parser_zone_, this_var, new_target_var, this_function_var, pos);
} }
Zone* zone() const { return local_zone_; }
// Handles use of temporary zones when parsing inner function bodies.
class BodyScope {
public:
BodyScope(AstNodeFactory* factory, Zone* temp_zone, bool use_temp_zone)
: factory_(factory), prev_zone_(factory->local_zone_) {
if (use_temp_zone) {
factory->local_zone_ = temp_zone;
}
}
~BodyScope() { factory_->local_zone_ = prev_zone_; }
private:
AstNodeFactory* factory_;
Zone* prev_zone_;
};
private: private:
Zone* zone_; // This zone may be deallocated upon returning from parsing a function body
// which we can guarantee is not going to be compiled or have its AST
// inspected.
// See ParseFunctionLiteral in parser.cc for preconditions.
Zone* local_zone_;
// ZoneObjects which need to persist until scope analysis must be allocated in
// the parser-level zone.
Zone* parser_zone_;
AstValueFactory* ast_value_factory_; AstValueFactory* ast_value_factory_;
}; };

38
deps/v8/src/parser.cc

@ -4135,10 +4135,44 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
} }
} }
if (!is_lazily_parsed) { if (!is_lazily_parsed) {
body = ParseEagerFunctionBody(function_name, pos, formals, kind, // Determine whether the function body can be discarded after parsing.
function_type, CHECK_OK); // The preconditions are:
// - Lazy compilation has to be enabled.
// - Neither V8 natives nor native function declarations can be allowed,
// since parsing one would retroactively force the function to be
// eagerly compiled.
// - The invoker of this parser can't depend on the AST being eagerly
// built (either because the function is about to be compiled, or
// because the AST is going to be inspected for some reason).
// - Because of the above, we can't be attempting to parse a
// FunctionExpression; even without enclosing parentheses it might be
// immediately invoked.
// - The function literal shouldn't be hinted to eagerly compile.
bool use_temp_zone =
FLAG_lazy && !allow_natives() && extension_ == NULL && allow_lazy() &&
function_type == FunctionLiteral::DECLARATION &&
eager_compile_hint != FunctionLiteral::kShouldEagerCompile;
// Open a new BodyScope, which sets our AstNodeFactory to allocate in the
// new temporary zone if the preconditions are satisfied, and ensures that
// the previous zone is always restored after parsing the body.
// For the purpose of scope analysis, some ZoneObjects allocated by the
// factory must persist after the function body is thrown away and
// temp_zone is deallocated. These objects are instead allocated in a
// parser-persistent zone (see parser_zone_ in AstNodeFactory).
{
Zone temp_zone;
AstNodeFactory::BodyScope inner(factory(), &temp_zone, use_temp_zone);
body = ParseEagerFunctionBody(function_name, pos, formals, kind,
function_type, CHECK_OK);
}
materialized_literal_count = function_state.materialized_literal_count(); materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count(); expected_property_count = function_state.expected_property_count();
if (use_temp_zone) {
// If the preconditions are correct the function body should never be
// accessed, but do this anyway for better behaviour if they're wrong.
body = NULL;
}
} }
// Parsing the body may change the language mode in our scope. // Parsing the body may change the language mode in our scope.

62
deps/v8/test/cctest/test-parsing.cc

@ -1388,6 +1388,68 @@ TEST(ScopePositions) {
} }
TEST(DiscardFunctionBody) {
// Test that inner function bodies are discarded if possible.
// See comments in ParseFunctionLiteral in parser.cc.
const char* discard_sources[] = {
"(function f() { function g() { var a; } })();",
/* TODO(conradw): In future it may be possible to apply this optimisation
* to these productions.
"(function f() { 0, function g() { var a; } })();",
"(function f() { 0, { g() { var a; } } })();",
"(function f() { 0, class c { g() { var a; } } })();", */
NULL
};
i::Isolate* isolate = CcTest::i_isolate();
i::Factory* factory = isolate->factory();
v8::HandleScope handles(CcTest::isolate());
i::FunctionLiteral* function;
for (int i = 0; discard_sources[i]; i++) {
const char* source = discard_sources[i];
i::Handle<i::String> source_code =
factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked();
i::Handle<i::Script> script = factory->NewScript(source_code);
i::Zone zone;
i::ParseInfo info(&zone, script);
info.set_allow_lazy_parsing();
i::Parser parser(&info);
parser.set_allow_harmony_sloppy(true);
parser.Parse(&info);
function = info.literal();
CHECK_NOT_NULL(function);
CHECK_NOT_NULL(function->body());
CHECK_EQ(1, function->body()->length());
i::FunctionLiteral* inner =
function->body()->first()->AsExpressionStatement()->expression()->
AsCall()->expression()->AsFunctionLiteral();
i::Scope* inner_scope = inner->scope();
i::FunctionLiteral* fun = nullptr;
if (inner_scope->declarations()->length() > 1) {
fun = inner_scope->declarations()->at(1)->AsFunctionDeclaration()->fun();
} else {
// TODO(conradw): This path won't be hit until the other test cases can be
// uncommented.
CHECK_NOT_NULL(inner->body());
CHECK_GE(2, inner->body()->length());
i::Expression* exp = inner->body()->at(1)->AsExpressionStatement()->
expression()->AsBinaryOperation()->right();
if (exp->IsFunctionLiteral()) {
fun = exp->AsFunctionLiteral();
} else if (exp->IsObjectLiteral()) {
fun = exp->AsObjectLiteral()->properties()->at(0)->value()->
AsFunctionLiteral();
} else {
fun = exp->AsClassLiteral()->properties()->at(0)->value()->
AsFunctionLiteral();
}
}
CHECK_NULL(fun->body());
}
}
const char* ReadString(unsigned* start) { const char* ReadString(unsigned* start) {
int length = start[0]; int length = start[0];
char* result = i::NewArray<char>(length + 1); char* result = i::NewArray<char>(length + 1);

43
deps/v8/test/mjsunit/compiler/lazy-iife-no-parens.js

@ -0,0 +1,43 @@
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// comments to trigger lazy compilation comments to trigger lazy compilation
// Test that IIFEs are compilable even under lazy conditions where the enclosing
// parentheses heuristic has not been triggered.
function f() {
return function(){ return 0; }();
}
function g() {
function h() {
return function(){ return 0; }();
}
return h();
}
f();
g();
0, function(){}();
(function(){ 0, function(){}(); })();
0, function(){ (function(){ 0, function(){}(); })(); }();

45
deps/v8/tools/run-tests.py

@ -52,13 +52,6 @@ from testrunner.objects import context
ARCH_GUESS = utils.DefaultArch() ARCH_GUESS = utils.DefaultArch()
DEFAULT_TESTS = [
"mjsunit",
"unittests",
"cctest",
"message",
"preparser",
]
# Map of test name synonyms to lists of test suites. Should be ordered by # Map of test name synonyms to lists of test suites. Should be ordered by
# expected runtimes (suites with slow test cases first). These groups are # expected runtimes (suites with slow test cases first). These groups are
@ -69,11 +62,14 @@ TEST_MAP = {
"cctest", "cctest",
"message", "message",
"preparser", "preparser",
"intl",
"unittests",
], ],
"optimize_for_size": [ "optimize_for_size": [
"mjsunit", "mjsunit",
"cctest", "cctest",
"webkit", "webkit",
"intl",
], ],
"unittests": [ "unittests": [
"unittests", "unittests",
@ -146,6 +142,7 @@ SUPPORTED_ARCHS = ["android_arm",
"x87", "x87",
"mips", "mips",
"mipsel", "mipsel",
"mips64",
"mips64el", "mips64el",
"nacl_ia32", "nacl_ia32",
"nacl_x64", "nacl_x64",
@ -162,6 +159,7 @@ SLOW_ARCHS = ["android_arm",
"arm", "arm",
"mips", "mips",
"mipsel", "mipsel",
"mips64",
"mips64el", "mips64el",
"nacl_ia32", "nacl_ia32",
"nacl_x64", "nacl_x64",
@ -171,9 +169,11 @@ SLOW_ARCHS = ["android_arm",
def BuildOptions(): def BuildOptions():
result = optparse.OptionParser() result = optparse.OptionParser()
result.usage = '%prog [options] [tests]'
result.description = """TESTS: %s""" % (TEST_MAP["default"])
result.add_option("--arch", result.add_option("--arch",
help=("The architecture to run tests for, " help=("The architecture to run tests for, "
"'auto' or 'native' for auto-detect"), "'auto' or 'native' for auto-detect: %s" % SUPPORTED_ARCHS),
default="ia32,x64,arm") default="ia32,x64,arm")
result.add_option("--arch-and-mode", result.add_option("--arch-and-mode",
help="Architecture and mode in the format 'arch.mode'", help="Architecture and mode in the format 'arch.mode'",
@ -220,7 +220,8 @@ def BuildOptions():
result.add_option("-j", help="The number of parallel tasks to run", result.add_option("-j", help="The number of parallel tasks to run",
default=0, type="int") default=0, type="int")
result.add_option("-m", "--mode", result.add_option("-m", "--mode",
help="The test modes in which to run (comma-separated)", help="The test modes in which to run (comma-separated,"
" uppercase for ninja and buildbot builds): %s" % MODES.keys(),
default="release,debug") default="release,debug")
result.add_option("--no-harness", "--noharness", result.add_option("--no-harness", "--noharness",
help="Run without test harness of a given suite", help="Run without test harness of a given suite",
@ -248,7 +249,7 @@ def BuildOptions():
help="Don't run any testing variants", help="Don't run any testing variants",
default=False, dest="no_variants", action="store_true") default=False, dest="no_variants", action="store_true")
result.add_option("--variants", result.add_option("--variants",
help="Comma-separated list of testing variants") help="Comma-separated list of testing variants: %s" % VARIANTS)
result.add_option("--outdir", help="Base directory with compile output", result.add_option("--outdir", help="Base directory with compile output",
default="out") default="out")
result.add_option("--predictable", result.add_option("--predictable",
@ -452,8 +453,8 @@ def ProcessOptions(options):
return False return False
if not CheckTestMode("pass|fail test", options.pass_fail_tests): if not CheckTestMode("pass|fail test", options.pass_fail_tests):
return False return False
if not options.no_i18n: if options.no_i18n:
DEFAULT_TESTS.append("intl") TEST_MAP["default"].remove("intl")
return True return True
@ -489,6 +490,10 @@ def Main():
suite_paths = utils.GetSuitePaths(join(workspace, "test")) suite_paths = utils.GetSuitePaths(join(workspace, "test"))
# Use default tests if no test configuration was provided at the cmd line.
if len(args) == 0:
args = ["default"]
# Expand arguments with grouped tests. The args should reflect the list of # Expand arguments with grouped tests. The args should reflect the list of
# suites as otherwise filters would break. # suites as otherwise filters would break.
def ExpandTestGroups(name): def ExpandTestGroups(name):
@ -500,13 +505,10 @@ def Main():
[ExpandTestGroups(arg) for arg in args], [ExpandTestGroups(arg) for arg in args],
[]) [])
if len(args) == 0: args_suites = OrderedDict() # Used as set
suite_paths = [ s for s in DEFAULT_TESTS if s in suite_paths ] for arg in args:
else: args_suites[arg.split('/')[0]] = True
args_suites = OrderedDict() # Used as set suite_paths = [ s for s in args_suites if s in suite_paths ]
for arg in args:
args_suites[arg.split('/')[0]] = True
suite_paths = [ s for s in args_suites if s in suite_paths ]
suites = [] suites = []
for root in suite_paths: for root in suite_paths:
@ -548,6 +550,8 @@ def Execute(arch, mode, args, options, suites, workspace):
"%s.%s" % (arch, MODES[mode]["output_folder"]), "%s.%s" % (arch, MODES[mode]["output_folder"]),
) )
shell_dir = os.path.relpath(shell_dir) shell_dir = os.path.relpath(shell_dir)
if not os.path.exists(shell_dir):
raise Exception('Could not find shell_dir: "%s"' % shell_dir)
# Populate context object. # Populate context object.
mode_flags = MODES[mode]["flags"] mode_flags = MODES[mode]["flags"]
@ -586,7 +590,7 @@ def Execute(arch, mode, args, options, suites, workspace):
# TODO(all): Combine "simulator" and "simulator_run". # TODO(all): Combine "simulator" and "simulator_run".
simulator_run = not options.dont_skip_simulator_slow_tests and \ simulator_run = not options.dont_skip_simulator_slow_tests and \
arch in ['arm64', 'arm', 'mipsel', 'mips', 'mips64el', \ arch in ['arm64', 'arm', 'mipsel', 'mips', 'mips64', 'mips64el', \
'ppc', 'ppc64'] and \ 'ppc', 'ppc64'] and \
ARCH_GUESS and arch != ARCH_GUESS ARCH_GUESS and arch != ARCH_GUESS
# Find available test suites and read test cases from them. # Find available test suites and read test cases from them.
@ -606,6 +610,7 @@ def Execute(arch, mode, args, options, suites, workspace):
"msan": options.msan, "msan": options.msan,
"dcheck_always_on": options.dcheck_always_on, "dcheck_always_on": options.dcheck_always_on,
"novfp3": options.novfp3, "novfp3": options.novfp3,
"predictable": options.predictable,
"byteorder": sys.byteorder, "byteorder": sys.byteorder,
} }
all_tests = [] all_tests = []

Loading…
Cancel
Save