| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 67bd0ec commit e3b75cb
11 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -36,7 +36,7 @@ | |||
| 36 | 36 | ||
| 37 | 37 | # Reset this number to 0 on major V8 upgrades. | |
| 38 | 38 | # Increment by one for each non-official patch applied to deps/v8. | |
| 39 | - 'v8_embedder_string': '-node.10', | ||
| 39 | + 'v8_embedder_string': '-node.11', | ||
| 40 | 40 | ||
| 41 | 41 | ##### V8 defaults for Node.js ##### | |
| 42 | 42 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -935,6 +935,22 @@ Call::CallType Call::GetCallType() const { | |||
| 935 | 935 | return OTHER_CALL; | |
| 936 | 936 | } | |
| 937 | 937 | ||
| 938 | + void Call::ComputeSpreadPosition() { | ||
| 939 | + int arguments_length = arguments_.length(); | ||
| 940 | + int first_spread_index = 0; | ||
| 941 | + for (; first_spread_index < arguments_length; first_spread_index++) { | ||
| 942 | + if (arguments_.at(first_spread_index)->IsSpread()) break; | ||
| 943 | + } | ||
| 944 | + SpreadPosition position; | ||
| 945 | + if (first_spread_index == arguments_length - 1) { | ||
| 946 | + position = kHasFinalSpread; | ||
| 947 | + } else { | ||
| 948 | + DCHECK_LT(first_spread_index, arguments_length - 1); | ||
| 949 | + position = kHasNonFinalSpread; | ||
| 950 | + } | ||
| 951 | + bit_field_ |= SpreadPositionField::encode(position); | ||
| 952 | + } | ||
| 953 | + | ||
| 938 | 954 | CaseClause::CaseClause(Zone* zone, Expression* label, | |
| 939 | 955 | const ScopedPtrList<Statement>& statements) | |
| 940 | 956 | : label_(label), statements_(statements.ToConstVector(), zone) {} | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1635,6 +1635,12 @@ class Call final : public Expression { | |||
| 1635 | 1635 | return IsOptionalChainLinkField::decode(bit_field_); | |
| 1636 | 1636 | } | |
| 1637 | 1637 | ||
| 1638 | + enum SpreadPosition { kNoSpread, kHasFinalSpread, kHasNonFinalSpread }; | ||
| 1639 | + SpreadPosition spread_position() const { | ||
| 1640 | + return SpreadPositionField::decode(bit_field_); | ||
| 1641 | + } | ||
| 1642 | + | ||
| 1643 | + // TODO(syg): Remove this and its users. | ||
| 1638 | 1644 | bool only_last_arg_is_spread() { | |
| 1639 | 1645 | return !arguments_.is_empty() && arguments_.last()->IsSpread(); | |
| 1640 | 1646 | } | |
@@ -1669,15 +1675,17 @@ class Call final : public Expression { | |||
| 1669 | 1675 | friend Zone; | |
| 1670 | 1676 | ||
| 1671 | 1677 | Call(Zone* zone, Expression* expression, | |
| 1672 | - const ScopedPtrList<Expression>& arguments, int pos, | ||
| 1678 | + const ScopedPtrList<Expression>& arguments, int pos, bool has_spread, | ||
| 1673 | 1679 | PossiblyEval possibly_eval, bool optional_chain) | |
| 1674 | 1680 | : Expression(pos, kCall), | |
| 1675 | 1681 | expression_(expression), | |
| 1676 | 1682 | arguments_(arguments.ToConstVector(), zone) { | |
| 1677 | 1683 | bit_field_ |= | |
| 1678 | 1684 | IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) | | |
| 1679 | 1685 | IsTaggedTemplateField::encode(false) | | |
| 1680 | - IsOptionalChainLinkField::encode(optional_chain); | ||
| 1686 | + IsOptionalChainLinkField::encode(optional_chain) | | ||
| 1687 | + SpreadPositionField::encode(kNoSpread); | ||
| 1688 | + if (has_spread) ComputeSpreadPosition(); | ||
| 1681 | 1689 | } | |
| 1682 | 1690 | ||
| 1683 | 1691 | Call(Zone* zone, Expression* expression, | |
@@ -1688,12 +1696,17 @@ class Call final : public Expression { | |||
| 1688 | 1696 | arguments_(arguments.ToConstVector(), zone) { | |
| 1689 | 1697 | bit_field_ |= IsPossiblyEvalField::encode(false) | | |
| 1690 | 1698 | IsTaggedTemplateField::encode(true) | | |
| 1691 | - IsOptionalChainLinkField::encode(false); | ||
| 1699 | + IsOptionalChainLinkField::encode(false) | | ||
| 1700 | + SpreadPositionField::encode(kNoSpread); | ||
| 1692 | 1701 | } | |
| 1693 | 1702 | ||
| 1703 | + // Only valid to be called if there is a spread in arguments_. | ||
| 1704 | + void ComputeSpreadPosition(); | ||
| 1705 | + | ||
| 1694 | 1706 | using IsPossiblyEvalField = Expression::NextBitField<bool, 1>; | |
| 1695 | 1707 | using IsTaggedTemplateField = IsPossiblyEvalField::Next<bool, 1>; | |
| 1696 | 1708 | using IsOptionalChainLinkField = IsTaggedTemplateField::Next<bool, 1>; | |
| 1709 | + using SpreadPositionField = IsOptionalChainLinkField::Next<SpreadPosition, 2>; | ||
| 1697 | 1710 | ||
| 1698 | 1711 | Expression* expression_; | |
| 1699 | 1712 | ZonePtrList<Expression> arguments_; | |
@@ -3064,11 +3077,12 @@ class AstNodeFactory final { | |||
| 3064 | 3077 | ||
| 3065 | 3078 | Call* NewCall(Expression* expression, | |
| 3066 | 3079 | const ScopedPtrList<Expression>& arguments, int pos, | |
| 3080 | + bool has_spread, | ||
| 3067 | 3081 | Call::PossiblyEval possibly_eval = Call::NOT_EVAL, | |
| 3068 | 3082 | bool optional_chain = false) { | |
| 3069 | 3083 | DCHECK_IMPLIES(possibly_eval == Call::IS_POSSIBLY_EVAL, !optional_chain); | |
| 3070 | - return zone_->New<Call>(zone_, expression, arguments, pos, possibly_eval, | ||
| 3071 | - optional_chain); | ||
| 3084 | + return zone_->New<Call>(zone_, expression, arguments, pos, has_spread, | ||
| 3085 | + possibly_eval, optional_chain); | ||
| 3072 | 3086 | } | |
| 3073 | 3087 | ||
| 3074 | 3088 | Call* NewTaggedTemplate(Expression* expression, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3106,6 +3106,8 @@ void BytecodeGenerator::BuildCreateArrayLiteral( | |||
| 3106 | 3106 | .StoreAccumulatorInRegister(index); | |
| 3107 | 3107 | } | |
| 3108 | 3108 | } else { | |
| 3109 | + // TODO(v8:11582): Support allocating boilerplates here. | ||
| 3110 | + | ||
| 3109 | 3111 | // In other cases, we prepare an empty array to be filled in below. | |
| 3110 | 3112 | DCHECK(!elements->is_empty()); | |
| 3111 | 3113 | int literal_index = feedback_index(feedback_spec()->AddLiteralSlot()); | |
@@ -5022,17 +5024,30 @@ void BytecodeGenerator::VisitCall(Call* expr) { | |||
| 5022 | 5024 | return VisitCallSuper(expr); | |
| 5023 | 5025 | } | |
| 5024 | 5026 | ||
| 5027 | + // We compile the call differently depending on the presence of spreads and | ||
| 5028 | + // their positions. | ||
| 5029 | + // | ||
| 5030 | + // If there is only one spread and it is the final argument, there is a | ||
| 5031 | + // special CallWithSpread bytecode. | ||
| 5032 | + // | ||
| 5033 | + // If there is a non-final spread, we rewrite calls like | ||
| 5034 | + // callee(1, ...x, 2) | ||
| 5035 | + // to | ||
| 5036 | + // %reflect_apply(callee, receiver, [1, ...x, 2]) | ||
| 5037 | + const Call::SpreadPosition spread_position = expr->spread_position(); | ||
| 5038 | + | ||
| 5025 | 5039 | // Grow the args list as we visit receiver / arguments to avoid allocating all | |
| 5026 | 5040 | // the registers up-front. Otherwise these registers are unavailable during | |
| 5027 | 5041 | // receiver / argument visiting and we can end up with memory leaks due to | |
| 5028 | 5042 | // registers keeping objects alive. | |
| 5029 | - Register callee = register_allocator()->NewRegister(); | ||
| 5030 | 5043 | RegisterList args = register_allocator()->NewGrowableRegisterList(); | |
| 5031 | 5044 | ||
| 5045 | + // The callee is the first register in args for ease of calling %reflect_apply | ||
| 5046 | + // if we have a non-final spread. For all other cases it is popped from args | ||
| 5047 | + // before emitting the call below. | ||
| 5048 | + Register callee = register_allocator()->GrowRegisterList(&args); | ||
| 5049 | + | ||
| 5032 | 5050 | bool implicit_undefined_receiver = false; | |
| 5033 | - // When a call contains a spread, a Call AST node is only created if there is | ||
| 5034 | - // exactly one spread, and it is the last argument. | ||
| 5035 | - bool is_spread_call = expr->only_last_arg_is_spread(); | ||
| 5036 | 5051 | bool optimize_as_one_shot = ShouldOptimizeAsOneShot(); | |
| 5037 | 5052 | ||
| 5038 | 5053 | // TODO(petermarshall): We have a lot of call bytecodes that are very similar, | |
@@ -5052,7 +5067,7 @@ void BytecodeGenerator::VisitCall(Call* expr) { | |||
| 5052 | 5067 | } | |
| 5053 | 5068 | case Call::GLOBAL_CALL: { | |
| 5054 | 5069 | // Receiver is undefined for global calls. | |
| 5055 | - if (!is_spread_call && !optimize_as_one_shot) { | ||
| 5070 | + if (spread_position == Call::kNoSpread && !optimize_as_one_shot) { | ||
| 5056 | 5071 | implicit_undefined_receiver = true; | |
| 5057 | 5072 | } else { | |
| 5058 | 5073 | // TODO(leszeks): There's no special bytecode for tail calls or spread | |
@@ -5088,7 +5103,7 @@ void BytecodeGenerator::VisitCall(Call* expr) { | |||
| 5088 | 5103 | } | |
| 5089 | 5104 | case Call::OTHER_CALL: { | |
| 5090 | 5105 | // Receiver is undefined for other calls. | |
| 5091 | - if (!is_spread_call && !optimize_as_one_shot) { | ||
| 5106 | + if (spread_position == Call::kNoSpread && !optimize_as_one_shot) { | ||
| 5092 | 5107 | implicit_undefined_receiver = true; | |
| 5093 | 5108 | } else { | |
| 5094 | 5109 | // TODO(leszeks): There's no special bytecode for tail calls or spread | |
@@ -5137,25 +5152,51 @@ void BytecodeGenerator::VisitCall(Call* expr) { | |||
| 5137 | 5152 | BuildIncrementBlockCoverageCounterIfEnabled(right_range); | |
| 5138 | 5153 | } | |
| 5139 | 5154 | ||
| 5140 | - // Evaluate all arguments to the function call and store in sequential args | ||
| 5141 | - // registers. | ||
| 5142 | - VisitArguments(expr->arguments(), &args); | ||
| 5143 | - int receiver_arg_count = implicit_undefined_receiver ? 0 : 1; | ||
| 5144 | - CHECK_EQ(receiver_arg_count + expr->arguments()->length(), | ||
| 5145 | - args.register_count()); | ||
| 5155 | + int receiver_arg_count = -1; | ||
| 5156 | + if (spread_position == Call::kHasNonFinalSpread) { | ||
| 5157 | + // If we're building %reflect_apply, build the array literal and put it in | ||
| 5158 | + // the 3rd argument. | ||
| 5159 | + DCHECK(!implicit_undefined_receiver); | ||
| 5160 | + DCHECK_EQ(args.register_count(), 2); | ||
| 5161 | + BuildCreateArrayLiteral(expr->arguments(), nullptr); | ||
| 5162 | + builder()->StoreAccumulatorInRegister( | ||
| 5163 | + register_allocator()->GrowRegisterList(&args)); | ||
| 5164 | + } else { | ||
| 5165 | + // If we're not building %reflect_apply and don't need to build an array | ||
| 5166 | + // literal, pop the callee and evaluate all arguments to the function call | ||
| 5167 | + // and store in sequential args registers. | ||
| 5168 | + args = args.PopLeft(); | ||
| 5169 | + VisitArguments(expr->arguments(), &args); | ||
| 5170 | + receiver_arg_count = implicit_undefined_receiver ? 0 : 1; | ||
| 5171 | + CHECK_EQ(receiver_arg_count + expr->arguments()->length(), | ||
| 5172 | + args.register_count()); | ||
| 5173 | + } | ||
| 5146 | 5174 | ||
| 5147 | 5175 | // Resolve callee for a potential direct eval call. This block will mutate the | |
| 5148 | 5176 | // callee value. | |
| 5149 | 5177 | if (expr->is_possibly_eval() && expr->arguments()->length() > 0) { | |
| 5150 | 5178 | RegisterAllocationScope inner_register_scope(this); | |
| 5179 | + RegisterList runtime_call_args = register_allocator()->NewRegisterList(6); | ||
| 5151 | 5180 | // Set up arguments for ResolvePossiblyDirectEval by copying callee, source | |
| 5152 | 5181 | // strings and function closure, and loading language and | |
| 5153 | 5182 | // position. | |
| 5154 | - Register first_arg = args[receiver_arg_count]; | ||
| 5155 | - RegisterList runtime_call_args = register_allocator()->NewRegisterList(6); | ||
| 5183 | + | ||
| 5184 | + // Move the first arg. | ||
| 5185 | + if (spread_position == Call::kHasNonFinalSpread) { | ||
| 5186 | + int feedback_slot_index = | ||
| 5187 | + feedback_index(feedback_spec()->AddKeyedLoadICSlot()); | ||
| 5188 | + Register args_array = args[2]; | ||
| 5189 | + builder() | ||
| 5190 | + ->LoadLiteral(Smi::FromInt(0)) | ||
| 5191 | + .LoadKeyedProperty(args_array, feedback_slot_index) | ||
| 5192 | + .StoreAccumulatorInRegister(runtime_call_args[1]); | ||
| 5193 | + } else { | ||
| 5194 | + // FIXME(v8:5690): Support final spreads for eval. | ||
| 5195 | + DCHECK_GE(receiver_arg_count, 0); | ||
| 5196 | + builder()->MoveRegister(args[receiver_arg_count], runtime_call_args[1]); | ||
| 5197 | + } | ||
| 5156 | 5198 | builder() | |
| 5157 | 5199 | ->MoveRegister(callee, runtime_call_args[0]) | |
| 5158 | - .MoveRegister(first_arg, runtime_call_args[1]) | ||
| 5159 | 5200 | .MoveRegister(Register::function_closure(), runtime_call_args[2]) | |
| 5160 | 5201 | .LoadLiteral(Smi::FromEnum(language_mode())) | |
| 5161 | 5202 | .StoreAccumulatorInRegister(runtime_call_args[3]) | |
@@ -5172,10 +5213,12 @@ void BytecodeGenerator::VisitCall(Call* expr) { | |||
| 5172 | 5213 | ||
| 5173 | 5214 | builder()->SetExpressionPosition(expr); | |
| 5174 | 5215 | ||
| 5175 | - if (is_spread_call) { | ||
| 5216 | + if (spread_position == Call::kHasFinalSpread) { | ||
| 5176 | 5217 | DCHECK(!implicit_undefined_receiver); | |
| 5177 | 5218 | builder()->CallWithSpread(callee, args, | |
| 5178 | 5219 | feedback_index(feedback_spec()->AddCallICSlot())); | |
| 5220 | + } else if (spread_position == Call::kHasNonFinalSpread) { | ||
| 5221 | + builder()->CallJSRuntime(Context::REFLECT_APPLY_INDEX, args); | ||
| 5179 | 5222 | } else if (optimize_as_one_shot) { | |
| 5180 | 5223 | DCHECK(!implicit_undefined_receiver); | |
| 5181 | 5224 | builder()->CallNoFeedback(callee, args); | |
@@ -5198,10 +5241,20 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) { | |||
| 5198 | 5241 | SuperCallReference* super = expr->expression()->AsSuperCallReference(); | |
| 5199 | 5242 | const ZonePtrList<Expression>* args = expr->arguments(); | |
| 5200 | 5243 | ||
| 5201 | - int first_spread_index = 0; | ||
| 5202 | - for (; first_spread_index < args->length(); first_spread_index++) { | ||
| 5203 | - if (args->at(first_spread_index)->IsSpread()) break; | ||
| 5204 | - } | ||
| 5244 | + // We compile the super call differently depending on the presence of spreads | ||
| 5245 | + // and their positions. | ||
| 5246 | + // | ||
| 5247 | + // If there is only one spread and it is the final argument, there is a | ||
| 5248 | + // special ConstructWithSpread bytecode. | ||
| 5249 | + // | ||
| 5250 | + // It there is a non-final spread, we rewrite something like | ||
| 5251 | + // super(1, ...x, 2) | ||
| 5252 | + // to | ||
| 5253 | + // %reflect_construct(constructor, [1, ...x, 2], new_target) | ||
| 5254 | + // | ||
| 5255 | + // That is, we implement (non-last-arg) spreads in super calls via our | ||
| 5256 | + // mechanism for spreads in array literals. | ||
| 5257 | + const Call::SpreadPosition spread_position = expr->spread_position(); | ||
| 5205 | 5258 | ||
| 5206 | 5259 | // Prepare the constructor to the super call. | |
| 5207 | 5260 | Register this_function = VisitForRegisterValue(super->this_function_var()); | |
@@ -5210,14 +5263,7 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) { | |||
| 5210 | 5263 | ->LoadAccumulatorWithRegister(this_function) | |
| 5211 | 5264 | .GetSuperConstructor(constructor); | |
| 5212 | 5265 | ||
| 5213 | - if (first_spread_index < expr->arguments()->length() - 1) { | ||
| 5214 | - // We rewrite something like | ||
| 5215 | - // super(1, ...x, 2) | ||
| 5216 | - // to | ||
| 5217 | - // %reflect_construct(constructor, [1, ...x, 2], new_target) | ||
| 5218 | - // That is, we implement (non-last-arg) spreads in super calls via our | ||
| 5219 | - // mechanism for spreads in array literals. | ||
| 5220 | - | ||
| 5266 | + if (spread_position == Call::kHasNonFinalSpread) { | ||
| 5221 | 5267 | // First generate the array containing all arguments. | |
| 5222 | 5268 | BuildCreateArrayLiteral(args, nullptr); | |
| 5223 | 5269 | ||
@@ -5244,11 +5290,11 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) { | |||
| 5244 | 5290 | ||
| 5245 | 5291 | int feedback_slot_index = feedback_index(feedback_spec()->AddCallICSlot()); | |
| 5246 | 5292 | ||
| 5247 | - if (first_spread_index == expr->arguments()->length() - 1) { | ||
| 5293 | + if (spread_position == Call::kHasFinalSpread) { | ||
| 5248 | 5294 | builder()->ConstructWithSpread(constructor, args_regs, | |
| 5249 | 5295 | feedback_slot_index); | |
| 5250 | 5296 | } else { | |
| 5251 | - DCHECK_EQ(first_spread_index, expr->arguments()->length()); | ||
| 5297 | + DCHECK_EQ(spread_position, Call::kNoSpread); | ||
| 5252 | 5298 | // Call construct. | |
| 5253 | 5299 | // TODO(turbofan): For now we do gather feedback on super constructor | |
| 5254 | 5300 | // calls, utilizing the existing machinery to inline the actual call | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1186,6 +1186,7 @@ class ParserBase { | |||
| 1186 | 1186 | BlockT ParseClassStaticBlock(ClassInfo* class_info); | |
| 1187 | 1187 | ObjectLiteralPropertyT ParseObjectPropertyDefinition( | |
| 1188 | 1188 | ParsePropertyInfo* prop_info, bool* has_seen_proto); | |
| 1189 | + // TODO(syg): Remove has_spread once SpreadCallNew is removed. | ||
| 1189 | 1190 | void ParseArguments( | |
| 1190 | 1191 | ExpressionListT* args, bool* has_spread, | |
| 1191 | 1192 | ParsingArrowHeadFlag maybe_arrow = kCertainlyNotArrowHead); | |
@@ -3392,11 +3393,7 @@ ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result) { | |||
| 3392 | 3393 | return result; | |
| 3393 | 3394 | } | |
| 3394 | 3395 | ||
| 3395 | - if (has_spread) { | ||
| 3396 | - result = impl()->SpreadCall(result, args, pos, Call::NOT_EVAL, false); | ||
| 3397 | - } else { | ||
| 3398 | - result = factory()->NewCall(result, args, pos, Call::NOT_EVAL); | ||
| 3399 | - } | ||
| 3396 | + result = factory()->NewCall(result, args, pos, has_spread); | ||
| 3400 | 3397 | ||
| 3401 | 3398 | maybe_arrow.ValidateExpression(); | |
| 3402 | 3399 | ||
@@ -3490,13 +3487,8 @@ ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result) { | |||
| 3490 | 3487 | Call::PossiblyEval is_possibly_eval = | |
| 3491 | 3488 | CheckPossibleEvalCall(result, is_optional, scope()); | |
| 3492 | 3489 | ||
| 3493 | - if (has_spread) { | ||
| 3494 | - result = impl()->SpreadCall(result, args, pos, is_possibly_eval, | ||
| 3495 | - is_optional); | ||
| 3496 | - } else { | ||
| 3497 | - result = factory()->NewCall(result, args, pos, is_possibly_eval, | ||
| 3498 | - is_optional); | ||
| 3499 | - } | ||
| 3490 | + result = factory()->NewCall(result, args, pos, has_spread, | ||
| 3491 | + is_possibly_eval, is_optional); | ||
| 3500 | 3492 | ||
| 3501 | 3493 | fni_.RemoveLastFunction(); | |
| 3502 | 3494 | break; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -69,7 +69,8 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, | |||
| 69 | 69 | ||
| 70 | 70 | args.Add(spread_args); | |
| 71 | 71 | Expression* super_call_ref = NewSuperCallReference(pos); | |
| 72 | - call = factory()->NewCall(super_call_ref, args, pos); | ||
| 72 | + constexpr bool has_spread = true; | ||
| 73 | + call = factory()->NewCall(super_call_ref, args, pos, has_spread); | ||
| 73 | 74 | } | |
| 74 | 75 | body.Add(factory()->NewReturnStatement(call, pos)); | |
| 75 | 76 | } | |
@@ -3371,47 +3372,10 @@ ArrayLiteral* Parser::ArrayLiteralFromListWithSpread( | |||
| 3371 | 3372 | return factory()->NewArrayLiteral(list, first_spread, kNoSourcePosition); | |
| 3372 | 3373 | } | |
| 3373 | 3374 | ||
| 3374 | - Expression* Parser::SpreadCall(Expression* function, | ||
| 3375 | - const ScopedPtrList<Expression>& args_list, | ||
| 3376 | - int pos, Call::PossiblyEval is_possibly_eval, | ||
| 3377 | - bool optional_chain) { | ||
| 3378 | - // Handle this case in BytecodeGenerator. | ||
| 3379 | - if (OnlyLastArgIsSpread(args_list) || function->IsSuperCallReference()) { | ||
| 3380 | - return factory()->NewCall(function, args_list, pos, Call::NOT_EVAL, | ||
| 3381 | - optional_chain); | ||
| 3382 | - } | ||
| 3383 | - | ||
| 3384 | - ScopedPtrList<Expression> args(pointer_buffer()); | ||
| 3385 | - if (function->IsProperty()) { | ||
| 3386 | - // Method calls | ||
| 3387 | - if (function->AsProperty()->IsSuperAccess()) { | ||
| 3388 | - Expression* home = ThisExpression(); | ||
| 3389 | - args.Add(function); | ||
| 3390 | - args.Add(home); | ||
| 3391 | - } else { | ||
| 3392 | - Variable* temp = NewTemporary(ast_value_factory()->empty_string()); | ||
| 3393 | - VariableProxy* obj = factory()->NewVariableProxy(temp); | ||
| 3394 | - Assignment* assign_obj = factory()->NewAssignment( | ||
| 3395 | - Token::ASSIGN, obj, function->AsProperty()->obj(), kNoSourcePosition); | ||
| 3396 | - function = | ||
| 3397 | - factory()->NewProperty(assign_obj, function->AsProperty()->key(), | ||
| 3398 | - kNoSourcePosition, optional_chain); | ||
| 3399 | - args.Add(function); | ||
| 3400 | - obj = factory()->NewVariableProxy(temp); | ||
| 3401 | - args.Add(obj); | ||
| 3402 | - } | ||
| 3403 | - } else { | ||
| 3404 | - // Non-method calls | ||
| 3405 | - args.Add(function); | ||
| 3406 | - args.Add(factory()->NewUndefinedLiteral(kNoSourcePosition)); | ||
| 3407 | - } | ||
| 3408 | - args.Add(ArrayLiteralFromListWithSpread(args_list)); | ||
| 3409 | - return factory()->NewCallRuntime(Context::REFLECT_APPLY_INDEX, args, pos); | ||
| 3410 | - } | ||
| 3411 | - | ||
| 3412 | 3375 | Expression* Parser::SpreadCallNew(Expression* function, | |
| 3413 | 3376 | const ScopedPtrList<Expression>& args_list, | |
| 3414 | 3377 | int pos) { | |
| 3378 | + // TODO(syg): Handle all spread cases in BytecodeGenerator. | ||
| 3415 | 3379 | if (OnlyLastArgIsSpread(args_list)) { | |
| 3416 | 3380 | // Handle in BytecodeGenerator. | |
| 3417 | 3381 | return factory()->NewCallNew(function, args_list, pos); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -493,10 +493,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { | |||
| 493 | 493 | ||
| 494 | 494 | ArrayLiteral* ArrayLiteralFromListWithSpread( | |
| 495 | 495 | const ScopedPtrList<Expression>& list); | |
| 496 | - Expression* SpreadCall(Expression* function, | ||
| 497 | - const ScopedPtrList<Expression>& args, int pos, | ||
| 498 | - Call::PossiblyEval is_possibly_eval, | ||
| 499 | - bool optional_chain); | ||
| 500 | 496 | Expression* SpreadCallNew(Expression* function, | |
| 501 | 497 | const ScopedPtrList<Expression>& args, int pos); | |
| 502 | 498 | Expression* RewriteSuperCall(Expression* call_expression); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments