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

Unified Diff: src/parser.cc

Issue 1104223002: [es6] implement optional parameters via desugaring (with scoping) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make scoping sort-of work-ish, still no hole-checking Created 5 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« src/globals.h ('K') | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 87d347d4c56491499b05c55bdf05fac38c3b8435..e379f778fc5c4faa23288fc2e5645f795625158e 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -1133,13 +1133,20 @@ FunctionLiteral* Parser::ParseLazy(Isolate* isolate, ParseInfo* info,
scope->set_start_position(shared_info->start_position());
FormalParameterErrorLocations error_locs;
bool has_rest = false;
+ bool has_initializers = false;
+ ZoneList<Expression*>* initializers =
+ new (zone()) ZoneList<Expression*>(0, zone());
if (Check(Token::LPAREN)) {
// '(' StrictFormalParameters ')'
- ParseFormalParameterList(scope, &error_locs, &has_rest, &ok);
+ Scope* parameter_scope = NewScope(scope, PARAMETER_SCOPE);
+ ParseFormalParameterList(scope, parameter_scope, &error_locs,
+ initializers, &has_initializers,
+ &has_rest, &ok);
if (ok) ok = Check(Token::RPAREN);
} else {
// BindingIdentifier
- ParseFormalParameter(scope, &error_locs, has_rest, &ok);
+ ParseFormalParameter(scope, nullptr, &error_locs,
+ nullptr, nullptr, has_rest, &ok);
}
if (ok) {
@@ -3896,6 +3903,62 @@ void ParserTraits::ParseArrowFunctionFormalParameters(
}
+ZoneList<Statement*>* Parser::DesugarInitializeParameters(
+ bool has_initializers, ZoneList<Expression*>* initializers) {
+ ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(0, zone());
+ if (has_initializers) {
+ for (int i = 0; i < initializers->length(); ++i) {
+ Expression* initializer = initializers->at(i);
+ // TODO(caitp): ensure proper TDZ behaviour --- need hole-check for
+ // all parameter bindings, including ones without initializers
+ if (initializer) {
+ // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i);
+ const AstRawString* fn_name = ast_value_factory()->empty_string();
+ const Runtime::Function* arguments =
+ Runtime::FunctionForId(Runtime::kInlineArguments);
+ ZoneList<Expression*>* arguments_i0 =
+ new (zone()) ZoneList<Expression*>(0, zone());
+ arguments_i0->Add(
+ factory()->NewSmiLiteral(i, RelocInfo::kNoPosition), zone());
+
+ ZoneList<Expression*>* arguments_i1 =
+ new (zone()) ZoneList<Expression*>(0, zone());
+ arguments_i1->Add(
+ factory()->NewSmiLiteral(i, RelocInfo::kNoPosition), zone());
+
+ Expression* arg_or_default = factory()->NewConditional(
+ // condition:
+ factory()->NewCompareOperation(
+ Token::EQ_STRICT,
+ factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
+ RelocInfo::kNoPosition),
+ factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition),
+ // if true:
+ initializer,
+ // if false:
+ factory()->NewCallRuntime(fn_name, arguments, arguments_i1,
+ RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition);
+
+ Expression* assign = factory()->NewAssignment(
+ Token::ASSIGN,
+ factory()->NewVariableProxy(
+ scope_->parameter(i), RelocInfo::kNoPosition),
+ arg_or_default,
+ RelocInfo::kNoPosition);
+
+ body->Add(
+ factory()->NewExpressionStatement(
+ assign, RelocInfo::kNoPosition),
+ zone());
+ }
+ }
+ }
+ return body;
+}
+
+
FunctionLiteral* Parser::ParseFunctionLiteral(
const AstRawString* function_name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind, int function_token_pos,
@@ -3961,6 +4024,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
declaration_scope != original_declaration_scope)
? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
: NewScope(scope_, FUNCTION_SCOPE, kind);
+ Scope* parameter_scope = NewScope(scope, PARAMETER_SCOPE);
ZoneList<Statement*>* body = NULL;
int materialized_literal_count = -1;
int expected_property_count = -1;
@@ -3994,8 +4058,13 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
Expect(Token::LPAREN, CHECK_OK);
int start_position = scanner()->location().beg_pos;
scope_->set_start_position(start_position);
- num_parameters =
- ParseFormalParameterList(scope, &error_locs, &has_rest, CHECK_OK);
+ ZoneList<Expression*>* initializers =
+ new (zone()) ZoneList<Expression*>(0, zone());
+ bool has_initializers = false;
+ num_parameters = ParseFormalParameterList(scope, parameter_scope,
+ &error_locs, initializers,
+ &has_initializers, &has_rest,
+ CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
int formals_end_position = scanner()->location().end_pos;
@@ -4074,8 +4143,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
SkipLazyFunctionBody(&materialized_literal_count,
&expected_property_count, CHECK_OK);
} else {
- body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
- kind, CHECK_OK);
+ body = DesugarInitializeParameters(has_initializers, initializers);
+ ZoneList<Statement*>* inner_body =
+ ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
+ kind, CHECK_OK);
+ body->AddAll(*inner_body, zone());
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
handler_count = function_state.handler_count();
« src/globals.h ('K') | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698