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

Unified Diff: src/parser.cc

Issue 938443002: [es6] implement spread calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase + clang-format 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
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | test/js-perf-test/JSTests.json » ('J')
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 4412b8a98cdca5618ec0b7caf1a77caf246718b3..0dc013202f857d8398a72fb599c2b6daadc94ce1 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -877,6 +877,7 @@ Parser::Parser(ParseInfo* info)
set_allow_harmony_computed_property_names(
FLAG_harmony_computed_property_names);
set_allow_harmony_rest_params(FLAG_harmony_rest_parameters);
+ set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
set_allow_strong_mode(FLAG_strong_mode);
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) {
@@ -4231,6 +4232,8 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
allow_harmony_computed_property_names());
reusable_preparser_->set_allow_harmony_rest_params(
allow_harmony_rest_params());
+ reusable_preparser_->set_allow_harmony_spreadcalls(
+ allow_harmony_spreadcalls());
reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
}
PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
@@ -4349,7 +4352,10 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
Expect(Token::MOD, CHECK_OK);
// Allow "eval" or "arguments" for backward compatibility.
const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK);
- ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
+ Scanner::Location spread_pos;
+ ZoneList<Expression*>* args = ParseArguments(&spread_pos, CHECK_OK);
+
+ DCHECK(!spread_pos.IsValid());
if (extension_ != NULL) {
// The extension structures are only accessible while parsing the
@@ -5614,4 +5620,121 @@ uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
return running_hash;
}
+
+
+ZoneList<v8::internal::Expression*>* Parser::PrepareSpreadArguments(
+ ZoneList<v8::internal::Expression*>* list) {
+ ZoneList<v8::internal::Expression*>* args =
+ new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
+ if (list->length() == 1) {
+ // Spread-call with single spread argument produces an InternalArray
+ // containing the values from the array.
+ //
+ // Function is called or constructed with the produced array of arguments
+ //
+ // EG: Apply(Func, Spread(spread0))
+ ZoneList<Expression*>* spread_list =
+ new (zone()) ZoneList<Expression*>(0, zone());
+ spread_list->Add(list->at(0)->AsSpread()->expression(), zone());
+ args->Add(
+ factory()->NewCallRuntime(ast_value_factory()->spread_iterable_string(),
+ NULL, spread_list, RelocInfo::kNoPosition),
+ zone());
+ return args;
+ } else {
+ // Spread-call with multiple arguments produces array literals for each
+ // sequences of unspread arguments, and converts each spread iterable to
+ // an Internal array. Finally, all of these produced arrays are flattened
+ // into a single InternalArray, containing the arguments for the call.
+ //
+ // EG: Apply(Func, Flatten([unspread0, unspread1], Spread(spread0),
+ // Spread(spread1), [unspread2, unspread3]))
+ int i = 0;
+ int n = list->length();
+ while (i < n) {
+ if (!list->at(i)->IsSpread()) {
+ ZoneList<v8::internal::Expression*>* unspread =
+ new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
+
+ // Push array of unspread parameters
+ while (i < n && !list->at(i)->IsSpread()) {
+ unspread->Add(list->at(i++), zone());
+ }
+ int literal_index = function_state_->NextMaterializedLiteralIndex();
+ args->Add(factory()->NewArrayLiteral(unspread, literal_index,
+ RelocInfo::kNoPosition),
+ zone());
+
+ if (i == n) break;
+ }
+
+ // Push eagerly spread argument
+ ZoneList<v8::internal::Expression*>* spread_list =
+ new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
+ spread_list->Add(list->at(i++)->AsSpread()->expression(), zone());
+ args->Add(factory()->NewCallRuntime(
+ ast_value_factory()->spread_iterable_string(), NULL,
+ spread_list, RelocInfo::kNoPosition),
+ zone());
+ }
+
+ list = new (zone()) ZoneList<v8::internal::Expression*>(1, zone());
+ list->Add(factory()->NewCallRuntime(
+ ast_value_factory()->spread_arguments_string(), NULL, args,
+ RelocInfo::kNoPosition),
+ zone());
+ return list;
+ }
+ UNREACHABLE();
+}
+
+
+Expression* Parser::SpreadCall(Expression* function,
+ ZoneList<v8::internal::Expression*>* args,
+ int pos) {
+ if (function->IsSuperReference()) {
+ // Super calls
+ args->InsertAt(0, function, zone());
+ args->Add(factory()->NewVariableProxy(scope_->new_target_var()), zone());
+ Expression* result = factory()->NewCallRuntime(
+ ast_value_factory()->reflect_construct_string(), NULL, args, pos);
+ args = new (zone()) ZoneList<Expression*>(0, zone());
+ args->Add(result, zone());
+ return factory()->NewCallRuntime(
+ ast_value_factory()->empty_string(),
+ Runtime::FunctionForId(Runtime::kInlineCallSuperWithSpread), args, pos);
+ } else {
+ if (function->IsProperty()) {
+ // Method calls
+ Variable* temp =
+ scope_->NewTemporary(ast_value_factory()->empty_string());
+ VariableProxy* obj = factory()->NewVariableProxy(temp);
+ Assignment* assign_obj = factory()->NewAssignment(
+ Token::ASSIGN, obj, function->AsProperty()->obj(),
+ RelocInfo::kNoPosition);
+ function = factory()->NewProperty(
+ assign_obj, function->AsProperty()->key(), RelocInfo::kNoPosition);
+ args->InsertAt(0, function, zone());
+ obj = factory()->NewVariableProxy(temp);
+ args->InsertAt(1, obj, zone());
+ } else {
+ // Non-method calls
+ args->InsertAt(0, function, zone());
+ args->InsertAt(1, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
+ zone());
+ }
+ return factory()->NewCallRuntime(
+ ast_value_factory()->reflect_apply_string(), NULL, args, pos);
+ }
+}
+
+
+Expression* Parser::SpreadCallNew(Expression* function,
+ ZoneList<v8::internal::Expression*>* args,
+ int pos) {
+ args->InsertAt(0, function, zone());
+
+ return factory()->NewCallRuntime(
+ ast_value_factory()->reflect_construct_string(), NULL, args, pos);
+}
} } // namespace v8::internal
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | test/js-perf-test/JSTests.json » ('J')

Powered by Google App Engine
This is Rietveld 408576698