Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: src/parser.cc

Issue 1309813007: [es6] implement destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: An implementation Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parser.h" 5 #include "src/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/ast-literal-reindexer.h" 9 #include "src/ast-literal-reindexer.h"
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
11 #include "src/base/platform/platform.h" 11 #include "src/base/platform/platform.h"
12 #include "src/bootstrapper.h" 12 #include "src/bootstrapper.h"
13 #include "src/char-predicates-inl.h" 13 #include "src/char-predicates-inl.h"
14 #include "src/codegen.h" 14 #include "src/codegen.h"
15 #include "src/compiler.h" 15 #include "src/compiler.h"
16 #include "src/messages.h" 16 #include "src/messages.h"
17 #include "src/parameter-initializer-rewriter.h" 17 #include "src/parameter-initializer-rewriter.h"
18 #include "src/preparser.h" 18 #include "src/preparser.h"
19 #include "src/rewriter.h" 19 #include "src/rewriter.h"
20 #include "src/runtime/runtime.h" 20 #include "src/runtime/runtime.h"
21 #include "src/scanner-character-streams.h" 21 #include "src/scanner-character-streams.h"
22 #include "src/scopeinfo.h" 22 #include "src/scopeinfo.h"
23 #include "src/string-stream.h" 23 #include "src/string-stream.h"
24 #include "src/ast-expression-visitor.h"
24 25
25 namespace v8 { 26 namespace v8 {
26 namespace internal { 27 namespace internal {
27 28
28 ScriptData::ScriptData(const byte* data, int length) 29 ScriptData::ScriptData(const byte* data, int length)
29 : owns_data_(false), rejected_(false), data_(data), length_(length) { 30 : owns_data_(false), rejected_(false), data_(data), length_(length) {
30 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { 31 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
31 byte* copy = NewArray<byte>(length); 32 byte* copy = NewArray<byte>(length);
32 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); 33 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
33 CopyBytes(copy, data, length); 34 CopyBytes(copy, data, length);
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 // ParseInfo during background parsing. 914 // ParseInfo during background parsing.
914 DCHECK(!info->script().is_null() || info->source_stream() != NULL); 915 DCHECK(!info->script().is_null() || info->source_stream() != NULL);
915 set_allow_lazy(info->allow_lazy_parsing()); 916 set_allow_lazy(info->allow_lazy_parsing());
916 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); 917 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
917 set_allow_harmony_sloppy(FLAG_harmony_sloppy); 918 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
918 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function); 919 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function);
919 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let); 920 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let);
920 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters); 921 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters);
921 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); 922 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
922 set_allow_harmony_destructuring(FLAG_harmony_destructuring); 923 set_allow_harmony_destructuring(FLAG_harmony_destructuring);
924 set_allow_harmony_destructuring_assignment(
925 FLAG_harmony_destructuring_assignment);
923 set_allow_strong_mode(FLAG_strong_mode); 926 set_allow_strong_mode(FLAG_strong_mode);
924 set_allow_legacy_const(FLAG_legacy_const); 927 set_allow_legacy_const(FLAG_legacy_const);
925 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); 928 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
926 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 929 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
927 ++feature) { 930 ++feature) {
928 use_counts_[feature] = 0; 931 use_counts_[feature] = 0;
929 } 932 }
930 if (info->ast_value_factory() == NULL) { 933 if (info->ast_value_factory() == NULL) {
931 // info takes ownership of AstValueFactory. 934 // info takes ownership of AstValueFactory.
932 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); 935 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 if (body->length() != 1 || 1086 if (body->length() != 1 ||
1084 !body->at(0)->IsExpressionStatement() || 1087 !body->at(0)->IsExpressionStatement() ||
1085 !body->at(0)->AsExpressionStatement()-> 1088 !body->at(0)->AsExpressionStatement()->
1086 expression()->IsFunctionLiteral()) { 1089 expression()->IsFunctionLiteral()) {
1087 ReportMessage(MessageTemplate::kSingleFunctionLiteral); 1090 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
1088 ok = false; 1091 ok = false;
1089 } 1092 }
1090 } 1093 }
1091 1094
1092 if (ok) { 1095 if (ok) {
1096 ParserTraits::RewriteDestructuringAssignments();
1093 result = factory()->NewFunctionLiteral( 1097 result = factory()->NewFunctionLiteral(
1094 ast_value_factory()->empty_string(), ast_value_factory(), scope_, 1098 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
1095 body, function_state.materialized_literal_count(), 1099 body, function_state.materialized_literal_count(),
1096 function_state.expected_property_count(), 0, 1100 function_state.expected_property_count(), 0,
1097 FunctionLiteral::kNoDuplicateParameters, 1101 FunctionLiteral::kNoDuplicateParameters,
1098 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, 1102 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
1099 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, 1103 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction,
1100 0); 1104 0);
1101 } 1105 }
1102 } 1106 }
(...skipping 2288 matching lines...) Expand 10 before | Expand all | Expand 10 after
3391 assign_iterator, 3395 assign_iterator,
3392 next_result, 3396 next_result,
3393 result_done, 3397 result_done,
3394 assign_each); 3398 assign_each);
3395 } else { 3399 } else {
3396 stmt->Initialize(each, subject, body); 3400 stmt->Initialize(each, subject, body);
3397 } 3401 }
3398 } 3402 }
3399 3403
3400 3404
3405 Expression* Parser::RewriteDestructuringAssignmentExpression(
3406 Expression* expression) {
3407 return expression;
3408 }
3409
3410
3401 Statement* Parser::DesugarLexicalBindingsInForStatement( 3411 Statement* Parser::DesugarLexicalBindingsInForStatement(
3402 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, 3412 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3403 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 3413 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3404 Statement* body, bool* ok) { 3414 Statement* body, bool* ok) {
3405 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are 3415 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are
3406 // copied into a new environment. Moreover, the "next" statement must be 3416 // copied into a new environment. Moreover, the "next" statement must be
3407 // evaluated not in the environment of the just completed iteration but in 3417 // evaluated not in the environment of the just completed iteration but in
3408 // that of the upcoming one. We achieve this with the following desugaring. 3418 // that of the upcoming one. We achieve this with the following desugaring.
3409 // Extra care is needed to preserve the completion value of the original loop. 3419 // Extra care is needed to preserve the completion value of the original loop.
3410 // 3420 //
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after
4405 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 4415 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4406 CHECK_OK); 4416 CHECK_OK);
4407 } 4417 }
4408 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) { 4418 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) {
4409 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK); 4419 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);
4410 } 4420 }
4411 if (is_strict(language_mode) || allow_harmony_sloppy() || 4421 if (is_strict(language_mode) || allow_harmony_sloppy() ||
4412 allow_harmony_destructuring()) { 4422 allow_harmony_destructuring()) {
4413 CheckConflictingVarDeclarations(scope, CHECK_OK); 4423 CheckConflictingVarDeclarations(scope, CHECK_OK);
4414 } 4424 }
4425
4426 ParserTraits::RewriteDestructuringAssignments();
4415 } 4427 }
4416 4428
4417 bool has_duplicate_parameters = 4429 bool has_duplicate_parameters =
4418 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); 4430 !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
4419 FunctionLiteral::ParameterFlag duplicate_parameters = 4431 FunctionLiteral::ParameterFlag duplicate_parameters =
4420 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 4432 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
4421 : FunctionLiteral::kNoDuplicateParameters; 4433 : FunctionLiteral::kNoDuplicateParameters;
4422 4434
4423 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 4435 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4424 function_name, ast_value_factory(), scope, body, 4436 function_name, ast_value_factory(), scope, body,
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
4533 RelocInfo::kNoPosition); 4545 RelocInfo::kNoPosition);
4534 IfStatement* if_statement = factory()->NewIfStatement( 4546 IfStatement* if_statement = factory()->NewIfStatement(
4535 condition, factory()->NewExpressionStatement(throw_type_error, 4547 condition, factory()->NewExpressionStatement(throw_type_error,
4536 RelocInfo::kNoPosition), 4548 RelocInfo::kNoPosition),
4537 factory()->NewEmptyStatement(RelocInfo::kNoPosition), 4549 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
4538 RelocInfo::kNoPosition); 4550 RelocInfo::kNoPosition);
4539 return if_statement; 4551 return if_statement;
4540 } 4552 }
4541 4553
4542 4554
4555 class InitializerRewriter : public AstExpressionVisitor {
4556 public:
4557 InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser,
4558 Scope* scope)
4559 : AstExpressionVisitor(stack_limit, root),
4560 parser_(parser),
4561 scope_(scope) {}
4562
4563 private:
4564 void VisitExpression(Expression* expr) {
4565 if (expr->IsAssignment()) {
4566 Assignment* node = expr->AsAssignment();
4567 Expression* target = node->target();
4568 if (node->op() == Token::ASSIGN && target->IsAssignmentPattern() &&
4569 !target->AsAssignmentPattern()->is_rewritten()) {
4570 bool ok = true;
4571 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, node,
4572 scope_, &ok);
4573 DCHECK(ok);
4574 }
4575 }
4576 }
4577 /*
4578 #define NOT_INITIALIZER(T) void Visit##T(T* node) {}
4579 NOT_INITIALIZER(FunctionLiteral)
4580 NOT_INITIALIZER(ClassLiteral)
4581 NOT_INITIALIZER(NativeFunctionLiteral)
4582 NOT_INITIALIZER(Conditional)
4583 NOT_INITIALIZER(VariableProxy)
4584 NOT_INITIALIZER(Literal)
4585 NOT_INITIALIZER(RegExpLiteral)
4586 NOT_INITIALIZER(ObjectLiteral)
4587 NOT_INITIALIZER(ArrayLiteral)
4588 NOT_INITIALIZER(AssignmentPattern)
4589 NOT_INITIALIZER(Yield)
4590 NOT_INITIALIZER(Throw)
4591 NOT_INITIALIZER(Property)
4592 NOT_INITIALIZER(Call)
4593 NOT_INITIALIZER(CallNew)
4594 NOT_INITIALIZER(CallRuntime)
4595 NOT_INITIALIZER(UnaryOperation)
4596 NOT_INITIALIZER(CountOperation)
4597 NOT_INITIALIZER(BinaryOperation)
4598 NOT_INITIALIZER(CompareOperation)
4599 NOT_INITIALIZER(Spread)
4600 NOT_INITIALIZER(ThisFunction)
4601 NOT_INITIALIZER(SuperPropertyReference)
4602 NOT_INITIALIZER(SuperCallReference)
4603 NOT_INITIALIZER(CaseClause)
4604 NOT_INITIALIZER(EmptyParentheses)
4605 NOT_INITIALIZER(DoExpression)
4606 #undef NOT_INITIALIZER*/
4607 private:
4608 Parser* parser_;
4609 Scope* scope_;
4610 };
4611
4612
4613 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) {
4614 InitializerRewriter rewriter(stack_limit_, expr, this, scope);
4615 rewriter.Run();
4616 }
4617
4618
4543 Block* Parser::BuildParameterInitializationBlock( 4619 Block* Parser::BuildParameterInitializationBlock(
4544 const ParserFormalParameters& parameters, bool* ok) { 4620 const ParserFormalParameters& parameters, bool* ok) {
4545 DCHECK(!parameters.is_simple); 4621 DCHECK(!parameters.is_simple);
4546 DCHECK(scope_->is_function_scope()); 4622 DCHECK(scope_->is_function_scope());
4547 Block* init_block = 4623 Block* init_block =
4548 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); 4624 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition);
4549 for (int i = 0; i < parameters.params.length(); ++i) { 4625 for (int i = 0; i < parameters.params.length(); ++i) {
4550 auto parameter = parameters.params[i]; 4626 auto parameter = parameters.params[i];
4551 DeclarationDescriptor descriptor; 4627 DeclarationDescriptor descriptor;
4552 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; 4628 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER;
4553 descriptor.parser = this; 4629 descriptor.parser = this;
4554 descriptor.declaration_scope = scope_; 4630 descriptor.declaration_scope = scope_;
4555 descriptor.scope = scope_; 4631 descriptor.scope = scope_;
4556 descriptor.hoist_scope = nullptr; 4632 descriptor.hoist_scope = nullptr;
4557 descriptor.mode = LET; 4633 descriptor.mode = LET;
4558 descriptor.is_const = false; 4634 descriptor.is_const = false;
4559 descriptor.needs_init = true; 4635 descriptor.needs_init = true;
4560 descriptor.declaration_pos = parameter.pattern->position(); 4636 descriptor.declaration_pos = parameter.pattern->position();
4561 descriptor.initialization_pos = parameter.pattern->position(); 4637 descriptor.initialization_pos = parameter.pattern->position();
4562 descriptor.init_op = Token::INIT_LET; 4638 descriptor.init_op = Token::INIT_LET;
4563 Expression* initial_value = 4639 Expression* initial_value =
4564 factory()->NewVariableProxy(parameters.scope->parameter(i)); 4640 factory()->NewVariableProxy(parameters.scope->parameter(i));
4565 if (parameter.initializer != nullptr) { 4641 if (parameter.initializer != nullptr) {
4566 // IS_UNDEFINED($param) ? initializer : $param 4642 // IS_UNDEFINED($param) ? initializer : $param
4567 DCHECK(!parameter.is_rest); 4643 DCHECK(!parameter.is_rest);
4644
4645 // Ensure initializer is rewritten
4646 RewriteParameterInitializer(parameter.initializer, scope_);
4647
4568 auto condition = factory()->NewCompareOperation( 4648 auto condition = factory()->NewCompareOperation(
4569 Token::EQ_STRICT, 4649 Token::EQ_STRICT,
4570 factory()->NewVariableProxy(parameters.scope->parameter(i)), 4650 factory()->NewVariableProxy(parameters.scope->parameter(i)),
4571 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), 4651 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4572 RelocInfo::kNoPosition); 4652 RelocInfo::kNoPosition);
4573 initial_value = factory()->NewConditional( 4653 initial_value = factory()->NewConditional(
4574 condition, parameter.initializer, initial_value, 4654 condition, parameter.initializer, initial_value,
4575 RelocInfo::kNoPosition); 4655 RelocInfo::kNoPosition);
4576 descriptor.initialization_pos = parameter.initializer->position(); 4656 descriptor.initialization_pos = parameter.initializer->position();
4577 } else if (parameter.is_rest) { 4657 } else if (parameter.is_rest) {
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after
6426 } 6506 }
6427 6507
6428 6508
6429 void Parser::RaiseLanguageMode(LanguageMode mode) { 6509 void Parser::RaiseLanguageMode(LanguageMode mode) {
6430 SetLanguageMode(scope_, 6510 SetLanguageMode(scope_,
6431 static_cast<LanguageMode>(scope_->language_mode() | mode)); 6511 static_cast<LanguageMode>(scope_->language_mode() | mode));
6432 } 6512 }
6433 6513
6434 } // namespace internal 6514 } // namespace internal
6435 } // namespace v8 6515 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698