"src/assembler.h",
"src/assert-scope.h",
"src/assert-scope.cc",
+ "src/ast-literal-reindexer.cc",
+ "src/ast-literal-reindexer.h",
"src/ast-numbering.cc",
"src/ast-numbering.h",
"src/ast-value-factory.cc",
--- /dev/null
+// 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.
+#include "src/v8.h"
+
+#include "src/ast.h"
+#include "src/ast-literal-reindexer.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+
+
+void AstLiteralReindexer::VisitVariableDeclaration(VariableDeclaration* node) {
+ VisitVariableProxy(node->proxy());
+}
+
+
+void AstLiteralReindexer::VisitExportDeclaration(ExportDeclaration* node) {
+ VisitVariableProxy(node->proxy());
+}
+
+
+void AstLiteralReindexer::VisitEmptyStatement(EmptyStatement* node) {}
+
+
+void AstLiteralReindexer::VisitContinueStatement(ContinueStatement* node) {}
+
+
+void AstLiteralReindexer::VisitBreakStatement(BreakStatement* node) {}
+
+
+void AstLiteralReindexer::VisitDebuggerStatement(DebuggerStatement* node) {}
+
+
+void AstLiteralReindexer::VisitNativeFunctionLiteral(
+ NativeFunctionLiteral* node) {}
+
+
+void AstLiteralReindexer::VisitLiteral(Literal* node) {}
+
+
+void AstLiteralReindexer::VisitRegExpLiteral(RegExpLiteral* node) {
+ UpdateIndex(node);
+}
+
+
+void AstLiteralReindexer::VisitVariableProxy(VariableProxy* node) {}
+
+
+void AstLiteralReindexer::VisitThisFunction(ThisFunction* node) {}
+
+
+void AstLiteralReindexer::VisitSuperPropertyReference(
+ SuperPropertyReference* node) {
+ Visit(node->this_var());
+ Visit(node->home_object());
+}
+
+
+void AstLiteralReindexer::VisitSuperCallReference(SuperCallReference* node) {
+ Visit(node->this_var());
+ Visit(node->new_target_var());
+ Visit(node->this_function_var());
+}
+
+
+void AstLiteralReindexer::VisitImportDeclaration(ImportDeclaration* node) {
+ VisitVariableProxy(node->proxy());
+}
+
+
+void AstLiteralReindexer::VisitExpressionStatement(ExpressionStatement* node) {
+ Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitReturnStatement(ReturnStatement* node) {
+ Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitYield(Yield* node) {
+ Visit(node->generator_object());
+ Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitThrow(Throw* node) { Visit(node->exception()); }
+
+
+void AstLiteralReindexer::VisitUnaryOperation(UnaryOperation* node) {
+ Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitCountOperation(CountOperation* node) {
+ Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitBlock(Block* node) {
+ VisitStatements(node->statements());
+}
+
+
+void AstLiteralReindexer::VisitFunctionDeclaration(FunctionDeclaration* node) {
+ VisitVariableProxy(node->proxy());
+ VisitFunctionLiteral(node->fun());
+}
+
+
+void AstLiteralReindexer::VisitCallRuntime(CallRuntime* node) {
+ VisitArguments(node->arguments());
+}
+
+
+void AstLiteralReindexer::VisitWithStatement(WithStatement* node) {
+ Visit(node->expression());
+ Visit(node->statement());
+}
+
+
+void AstLiteralReindexer::VisitDoWhileStatement(DoWhileStatement* node) {
+ Visit(node->body());
+ Visit(node->cond());
+}
+
+
+void AstLiteralReindexer::VisitWhileStatement(WhileStatement* node) {
+ Visit(node->cond());
+ Visit(node->body());
+}
+
+
+void AstLiteralReindexer::VisitTryCatchStatement(TryCatchStatement* node) {
+ Visit(node->try_block());
+ Visit(node->catch_block());
+}
+
+
+void AstLiteralReindexer::VisitTryFinallyStatement(TryFinallyStatement* node) {
+ Visit(node->try_block());
+ Visit(node->finally_block());
+}
+
+
+void AstLiteralReindexer::VisitProperty(Property* node) {
+ Visit(node->key());
+ Visit(node->obj());
+}
+
+
+void AstLiteralReindexer::VisitAssignment(Assignment* node) {
+ Visit(node->target());
+ Visit(node->value());
+}
+
+
+void AstLiteralReindexer::VisitBinaryOperation(BinaryOperation* node) {
+ Visit(node->left());
+ Visit(node->right());
+}
+
+
+void AstLiteralReindexer::VisitCompareOperation(CompareOperation* node) {
+ Visit(node->left());
+ Visit(node->right());
+}
+
+
+void AstLiteralReindexer::VisitSpread(Spread* node) {
+ Visit(node->expression());
+}
+
+
+void AstLiteralReindexer::VisitForInStatement(ForInStatement* node) {
+ Visit(node->each());
+ Visit(node->enumerable());
+ Visit(node->body());
+}
+
+
+void AstLiteralReindexer::VisitForOfStatement(ForOfStatement* node) {
+ Visit(node->assign_iterator());
+ Visit(node->next_result());
+ Visit(node->result_done());
+ Visit(node->assign_each());
+ Visit(node->body());
+}
+
+
+void AstLiteralReindexer::VisitConditional(Conditional* node) {
+ Visit(node->condition());
+ Visit(node->then_expression());
+ Visit(node->else_expression());
+}
+
+
+void AstLiteralReindexer::VisitIfStatement(IfStatement* node) {
+ Visit(node->condition());
+ Visit(node->then_statement());
+ if (node->HasElseStatement()) {
+ Visit(node->else_statement());
+ }
+}
+
+
+void AstLiteralReindexer::VisitSwitchStatement(SwitchStatement* node) {
+ Visit(node->tag());
+ ZoneList<CaseClause*>* cases = node->cases();
+ for (int i = 0; i < cases->length(); i++) {
+ VisitCaseClause(cases->at(i));
+ }
+}
+
+
+void AstLiteralReindexer::VisitCaseClause(CaseClause* node) {
+ if (!node->is_default()) Visit(node->label());
+ VisitStatements(node->statements());
+}
+
+
+void AstLiteralReindexer::VisitForStatement(ForStatement* node) {
+ if (node->init() != NULL) Visit(node->init());
+ if (node->cond() != NULL) Visit(node->cond());
+ if (node->next() != NULL) Visit(node->next());
+ Visit(node->body());
+}
+
+
+void AstLiteralReindexer::VisitClassLiteral(ClassLiteral* node) {
+ if (node->extends()) Visit(node->extends());
+ if (node->constructor()) Visit(node->constructor());
+ if (node->class_variable_proxy()) {
+ VisitVariableProxy(node->class_variable_proxy());
+ }
+ for (int i = 0; i < node->properties()->length(); i++) {
+ VisitObjectLiteralProperty(node->properties()->at(i));
+ }
+}
+
+
+void AstLiteralReindexer::VisitObjectLiteral(ObjectLiteral* node) {
+ UpdateIndex(node);
+ for (int i = 0; i < node->properties()->length(); i++) {
+ VisitObjectLiteralProperty(node->properties()->at(i));
+ }
+}
+
+
+void AstLiteralReindexer::VisitObjectLiteralProperty(
+ ObjectLiteralProperty* node) {
+ Visit(node->key());
+ Visit(node->value());
+}
+
+
+void AstLiteralReindexer::VisitArrayLiteral(ArrayLiteral* node) {
+ UpdateIndex(node);
+ for (int i = 0; i < node->values()->length(); i++) {
+ Visit(node->values()->at(i));
+ }
+}
+
+
+void AstLiteralReindexer::VisitCall(Call* node) {
+ Visit(node->expression());
+ VisitArguments(node->arguments());
+}
+
+
+void AstLiteralReindexer::VisitCallNew(CallNew* node) {
+ Visit(node->expression());
+ VisitArguments(node->arguments());
+}
+
+
+void AstLiteralReindexer::VisitStatements(ZoneList<Statement*>* statements) {
+ if (statements == NULL) return;
+ for (int i = 0; i < statements->length(); i++) {
+ Visit(statements->at(i));
+ }
+}
+
+
+void AstLiteralReindexer::VisitDeclarations(
+ ZoneList<Declaration*>* declarations) {
+ for (int i = 0; i < declarations->length(); i++) {
+ Visit(declarations->at(i));
+ }
+}
+
+
+void AstLiteralReindexer::VisitArguments(ZoneList<Expression*>* arguments) {
+ for (int i = 0; i < arguments->length(); i++) {
+ Visit(arguments->at(i));
+ }
+}
+
+
+void AstLiteralReindexer::VisitFunctionLiteral(FunctionLiteral* node) {
+ // We don't recurse into the declarations or body of the function literal:
+}
+
+
+void AstLiteralReindexer::Reindex(Expression* pattern) {
+ pattern->Accept(this);
+}
+}
+} // namespace v8::internal
--- /dev/null
+// 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.
+
+#ifndef V8_AST_LITERAL_REINDEXER
+#define V8_AST_LITERAL_REINDEXER
+
+#include "src/v8.h"
+
+#include "src/ast.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+
+class AstLiteralReindexer final : public AstVisitor {
+ public:
+ AstLiteralReindexer() : AstVisitor(), next_index_(0) {}
+
+ int count() const { return next_index_; }
+ void Reindex(Expression* pattern);
+
+ private:
+#define DEFINE_VISIT(type) virtual void Visit##type(type* node) override;
+ AST_NODE_LIST(DEFINE_VISIT)
+#undef DEFINE_VISIT
+
+ void VisitStatements(ZoneList<Statement*>* statements) override;
+ void VisitDeclarations(ZoneList<Declaration*>* declarations) override;
+ void VisitArguments(ZoneList<Expression*>* arguments);
+ void VisitObjectLiteralProperty(ObjectLiteralProperty* property);
+
+ void UpdateIndex(MaterializedLiteral* literal) {
+ literal->literal_index_ = next_index_++;
+ }
+
+ void Visit(AstNode* node) override { node->Accept(this); }
+
+ int next_index_;
+
+ DISALLOW_COPY_AND_ASSIGN(AstLiteralReindexer);
+};
+}
+} // namespace v8::internal
+
+#endif // V8_AST_LITERAL_REINDEXER
};
+class AstLiteralReindexer;
+
// Base class for literals that needs space in the corresponding JSFunction.
class MaterializedLiteral : public Expression {
public:
bool is_simple_;
bool is_strong_;
int depth_;
+
+ friend class AstLiteralReindexer;
};
#include "src/api.h"
#include "src/ast.h"
+#include "src/ast-literal-reindexer.h"
#include "src/bailout-reason.h"
#include "src/base/platform/platform.h"
#include "src/bootstrapper.h"
scope->set_start_position(shared_info->start_position());
ExpressionClassifier formals_classifier;
ParserFormalParameterParsingState parsing_state(scope);
+ Checkpoint checkpoint(this);
{
// Parsing patterns as variable reference expression creates
// NewUnresolved references in current scope. Entrer arrow function
}
if (ok) {
+ checkpoint.Restore(&parsing_state.materialized_literals_count);
Expression* expression =
ParseArrowFunctionLiteral(parsing_state, formals_classifier, &ok);
if (ok) {
}
+void ParserTraits::ReindexLiterals(
+ const ParserFormalParameterParsingState& parsing_state) {
+ if (parser_->function_state_->materialized_literal_count() > 0) {
+ AstLiteralReindexer reindexer;
+
+ for (const auto p : parsing_state.params) {
+ if (p.pattern != nullptr) reindexer.Reindex(p.pattern);
+ }
+ DCHECK(reindexer.count() <=
+ parser_->function_state_->materialized_literal_count());
+ }
+}
+
+
FunctionLiteral* Parser::ParseFunctionLiteral(
const AstRawString* function_name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
bool* ok);
+ void ReindexLiterals(const ParserFormalParameterParsingState& parsing_state);
+
// Temporary glue; these functions will move to ParserBase.
Expression* ParseV8Intrinsic(bool* ok);
FunctionLiteral* ParseFunctionLiteral(
return next_materialized_literal_index_;
}
+ void SkipMaterializedLiterals(int count) {
+ next_materialized_literal_index_ += count;
+ }
+
void AddProperty() { expected_property_count_++; }
int expected_property_count() { return expected_property_count_; }
expected_property_count_ = function_state_->expected_property_count_;
}
- void Restore() {
+ void Restore(int* materialized_literal_index_delta) {
+ *materialized_literal_index_delta =
+ function_state_->next_materialized_literal_index_ -
+ next_materialized_literal_index_;
function_state_->next_materialized_literal_index_ =
next_materialized_literal_index_;
function_state_->expected_property_count_ = expected_property_count_;
struct PreParserFormalParameterParsingState {
explicit PreParserFormalParameterParsingState(Scope* scope)
- : scope(scope), has_rest(false), is_simple_parameter_list(true) {}
+ : scope(scope),
+ has_rest(false),
+ is_simple_parameter_list(true),
+ materialized_literals_count(0) {}
Scope* scope;
bool has_rest;
bool is_simple_parameter_list;
+ int materialized_literals_count;
};
PreParserExpression expression, const Scanner::Location& params_loc,
Scanner::Location* duplicate_loc, bool* ok);
+ void ReindexLiterals(
+ const PreParserFormalParameterParsingState& parsing_state) {}
+
struct TemplateLiteralState {};
TemplateLiteralState OpenTemplateLiteral(int pos) {
accept_IN, &arrow_formals_classifier, CHECK_OK);
if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
- checkpoint.Restore();
BindingPatternUnexpectedToken(classifier);
ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
parenthesized_formals, CHECK_OK);
Scanner::Location loc(lhs_location.beg_pos, scanner()->location().end_pos);
Scope* scope =
this->NewScope(scope_, ARROW_SCOPE, FunctionKind::kArrowFunction);
+ FormalParameterParsingStateT parsing_state(scope);
+ checkpoint.Restore(&parsing_state.materialized_literals_count);
+
scope->set_start_position(lhs_location.beg_pos);
Scanner::Location duplicate_loc = Scanner::Location::invalid();
- FormalParameterParsingStateT parsing_state(scope);
this->ParseArrowFunctionFormalParameters(&parsing_state, expression, loc,
&duplicate_loc, CHECK_OK);
if (duplicate_loc.IsValid()) {
formal_parameters.scope, kArrowFunction,
&function_factory);
+ function_state.SkipMaterializedLiterals(
+ formal_parameters.materialized_literals_count);
+
+ this->ReindexLiterals(formal_parameters);
+
Expect(Token::ARROW, CHECK_OK);
if (peek() == Token::LBRACE) {
void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
Print("[ ");
+ Print(" literal_index = %d", node->literal_index());
for (int i = 0; i < node->values()->length(); i++) {
if (i != 0) Print(",");
Visit(node->values()->at(i));
void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
IndentedScope indent(this, "REGEXP LITERAL");
+ EmbeddedVector<char, 128> buf;
+ SNPrintF(buf, "literal_index = %d\n", node->literal_index());
+ PrintIndented(buf.start());
PrintLiteralIndented("PATTERN", node->pattern(), false);
PrintLiteralIndented("FLAGS", node->flags(), false);
}
void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
IndentedScope indent(this, "OBJ LITERAL");
+ EmbeddedVector<char, 128> buf;
+ SNPrintF(buf, "literal_index = %d\n", node->literal_index());
+ PrintIndented(buf.start());
PrintProperties(node->properties());
}
void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
IndentedScope indent(this, "ARRAY LITERAL");
+
+ EmbeddedVector<char, 128> buf;
+ SNPrintF(buf, "literal_index = %d\n", node->literal_index());
+ PrintIndented(buf.start());
if (node->values()->length() > 0) {
IndentedScope indent(this, "VALUES");
for (int i = 0; i < node->values()->length(); i++) {
--- /dev/null
+// 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.
+//
+// Flags: --harmony-destructuring --harmony-computed-property-names
+// Flags: --harmony-arrow-functions --no-lazy --allow-natives-syntax
+
+
+var t1 = [1];
+var t2 = [2];
+var t3 = [3];
+var t4 = [4];
+var t5 = [5];
+function g({x = {a:10,b:20}},
+ {y = [1,2,3],
+ n = [],
+ p = /abc/}) {
+ assertSame(10, x.a);
+ assertSame(20, x.b);
+ assertSame(2, y[1]);
+ assertSame(0, n.length);
+ assertTrue(p.test("abc"));
+}
+g({},{});
+%OptimizeFunctionOnNextCall(g);
+g({},{});
+
+
+var h = ({x = {a:10,b:20}},
+ {y = [1,2,3],
+ n = [],
+ p = /abc/ }) => {
+ assertSame(10, x.a);
+ assertSame(20, x.b);
+ assertSame(2, y[1]);
+ assertSame(0, n.length);
+ assertTrue(p.test("abc"));
+ };
+h({},{});
+%OptimizeFunctionOnNextCall(h);
+h({},{});
--- /dev/null
+// 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.
+//
+// Flags: --harmony-destructuring --harmony-computed-property-names
+// Flags: --harmony-arrow-functions --allow-natives-syntax
+
+
+var t1 = [1];
+var t2 = [2];
+var t3 = [3];
+var t4 = [4];
+var t5 = [5];
+function g({x = {a:10,b:20}},
+ {y = [1,2,3],
+ n = [],
+ p = /abc/}) {
+ assertSame(10, x.a);
+ assertSame(20, x.b);
+ assertSame(2, y[1]);
+ assertSame(0, n.length);
+ assertTrue(p.test("abc"));
+}
+g({},{});
+%OptimizeFunctionOnNextCall(g);
+g({},{});
+
+
+var h = ({x = {a:10,b:20}},
+ {y = [1,2,3],
+ n = [],
+ p = /abc/ }) => {
+ assertSame(10, x.a);
+ assertSame(20, x.b);
+ assertSame(2, y[1]);
+ assertSame(0, n.length);
+ assertTrue(p.test("abc"));
+ };
+h({},{});
+%OptimizeFunctionOnNextCall(h);
+h({},{});
'../../src/assert-scope.cc',
'../../src/ast-value-factory.cc',
'../../src/ast-value-factory.h',
+ '../../src/ast-literal-reindexer.cc',
+ '../../src/ast-literal-reindexer.h',
'../../src/ast-numbering.cc',
'../../src/ast-numbering.h',
'../../src/ast.cc',