Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index 08941f501f333511f612603e597e627327fc9373..caca0fe89c903d624fef5752d3027dffb6d3da79 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -815,6 +815,7 @@ Parser::Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed, |
| 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) { |
| @@ -4043,6 +4044,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( |
| @@ -4154,7 +4157,11 @@ 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); |
| + |
| + // TODO(caitp): support intrinsics |
| + DCHECK(!spread_pos.IsValid()); |
| if (extension_ != NULL) { |
| // The extension structures are only accessible while parsing the |
| @@ -5474,4 +5481,84 @@ 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) { |
| + args->Add( |
| + factory()->NewCallRuntime(ast_value_factory()->spread_iterable_string(), |
| + NULL, list, RelocInfo::kNoPosition), |
| + zone()); |
| + return args; |
| + } else { |
| + int i = 0; |
|
arv (Not doing code reviews)
2015/02/23 17:55:56
This could use a comment explaining what it desuga
rossberg
2015/02/25 14:28:18
+1
caitp (gmail)
2015/02/25 14:49:08
Acknowledged.
|
| + int n = list->length(); |
| + while (i < n) { |
| + ZoneList<v8::internal::Expression*>* unspread = |
| + new (zone()) ZoneList<v8::internal::Expression*>(1, zone()); |
| + |
| + // Push array of unspread parameters |
| + while (i < n && !list->at(i)->IsSpreadOperation()) { |
| + unspread->Add(list->at(i++), zone()); |
| + } |
| + int literal_index = function_state_->NextMaterializedLiteralIndex(); |
| + args->Add(factory()->NewArrayLiteral(unspread, literal_index, |
|
arv (Not doing code reviews)
2015/02/23 17:55:56
Will this be observable if someone overrides Array
caitp (gmail)
2015/02/25 14:49:08
The unspread array literals aren't iterated via it
|
| + RelocInfo::kNoPosition), |
| + zone()); |
| + |
| + if (i == n) break; |
| + |
| + // Push eagerly spread argument |
| + ZoneList<v8::internal::Expression*>* spread = |
| + new (zone()) ZoneList<v8::internal::Expression*>(1, zone()); |
| + spread->Add(list->at(i++), zone()); |
| + args->Add(factory()->NewCallRuntime( |
| + ast_value_factory()->spread_iterable_string(), NULL, spread, |
| + 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) { |
| + Expression* receiver; |
| + if (function->IsProperty()) { |
| + receiver = function->AsProperty()->obj(); |
| + } else { |
| + receiver = factory()->NewUndefinedLiteral(pos); |
| + } |
| + |
| + args->InsertAt(0, function, zone()); |
| + args->InsertAt(1, receiver, zone()); |
| + |
| + const Runtime::Function* apply = Runtime::FunctionForId(Runtime::kApply); |
| + return factory()->NewCallRuntime(ast_value_factory()->empty_string(), apply, |
| + args, pos); |
| +} |
| + |
| + |
| +Expression* Parser::SpreadCallNew(Expression* function, |
| + ZoneList<v8::internal::Expression*>* args, |
| + int pos) { |
| + args->InsertAt(0, function, zone()); |
| + |
| + const Runtime::Function* apply = |
| + Runtime::FunctionForId(Runtime::kApplyConstruct); |
| + return factory()->NewCallRuntime(ast_value_factory()->empty_string(), apply, |
| + args, pos); |
| +} |
| } } // namespace v8::internal |