| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
| 6 | 6 |
| 7 #include "src/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/builtins/builtins-constructor.h" | 9 #include "src/builtins/builtins-constructor.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 2431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2442 Call::CallType call_type = expr->GetCallType(); | 2442 Call::CallType call_type = expr->GetCallType(); |
| 2443 | 2443 |
| 2444 if (call_type == Call::SUPER_CALL) { | 2444 if (call_type == Call::SUPER_CALL) { |
| 2445 return VisitCallSuper(expr); | 2445 return VisitCallSuper(expr); |
| 2446 } | 2446 } |
| 2447 | 2447 |
| 2448 // Grow the args list as we visit receiver / arguments to avoid allocating all | 2448 // Grow the args list as we visit receiver / arguments to avoid allocating all |
| 2449 // the registers up-front. Otherwise these registers are unavailable during | 2449 // the registers up-front. Otherwise these registers are unavailable during |
| 2450 // receiver / argument visiting and we can end up with memory leaks due to | 2450 // receiver / argument visiting and we can end up with memory leaks due to |
| 2451 // registers keeping objects alive. | 2451 // registers keeping objects alive. |
| 2452 RegisterList args; | 2452 Register callee = register_allocator()->NewRegister(); |
| 2453 Register callee; | 2453 RegisterList args = register_allocator()->NewGrowableRegisterList(); |
| 2454 // The CallWithSpread bytecode takes all arguments in a register list so that | |
| 2455 // it can easily call into a runtime function for its implementation. This | |
| 2456 // will change once CallWithSpread has an implementation in ASM. | |
| 2457 // TODO(petermarshall): Remove this special path when CallWithSpread is done. | |
| 2458 if (expr->only_last_arg_is_spread()) { | |
| 2459 args = register_allocator()->NewGrowableRegisterList(); | |
| 2460 callee = register_allocator()->GrowRegisterList(&args); | |
| 2461 } else { | |
| 2462 callee = register_allocator()->NewRegister(); | |
| 2463 args = register_allocator()->NewGrowableRegisterList(); | |
| 2464 } | |
| 2465 | 2454 |
| 2466 // TODO(petermarshall): We have a lot of call bytecodes that are very similar, | 2455 // TODO(petermarshall): We have a lot of call bytecodes that are very similar, |
| 2467 // see if we can reduce the number by adding a separate argument which | 2456 // see if we can reduce the number by adding a separate argument which |
| 2468 // specifies the call type (e.g., property, spread, tailcall, etc.). | 2457 // specifies the call type (e.g., property, spread, tailcall, etc.). |
| 2469 | 2458 |
| 2470 // Prepare the callee and the receiver to the function call. This depends on | 2459 // Prepare the callee and the receiver to the function call. This depends on |
| 2471 // the semantics of the underlying call type. | 2460 // the semantics of the underlying call type. |
| 2472 switch (call_type) { | 2461 switch (call_type) { |
| 2473 case Call::NAMED_PROPERTY_CALL: | 2462 case Call::NAMED_PROPERTY_CALL: |
| 2474 case Call::KEYED_PROPERTY_CALL: { | 2463 case Call::KEYED_PROPERTY_CALL: { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2528 break; | 2517 break; |
| 2529 } | 2518 } |
| 2530 case Call::SUPER_CALL: | 2519 case Call::SUPER_CALL: |
| 2531 UNREACHABLE(); | 2520 UNREACHABLE(); |
| 2532 break; | 2521 break; |
| 2533 } | 2522 } |
| 2534 | 2523 |
| 2535 // Evaluate all arguments to the function call and store in sequential args | 2524 // Evaluate all arguments to the function call and store in sequential args |
| 2536 // registers. | 2525 // registers. |
| 2537 VisitArguments(expr->arguments(), &args); | 2526 VisitArguments(expr->arguments(), &args); |
| 2538 // TODO(petermarshall): Check this for spread calls as well when | 2527 CHECK_EQ(expr->arguments()->length() + 1, args.register_count()); |
| 2539 // CallWithSpread is done. | |
| 2540 if (!expr->only_last_arg_is_spread()) { | |
| 2541 CHECK_EQ(expr->arguments()->length() + 1, args.register_count()); | |
| 2542 } | |
| 2543 | 2528 |
| 2544 // Resolve callee for a potential direct eval call. This block will mutate the | 2529 // Resolve callee for a potential direct eval call. This block will mutate the |
| 2545 // callee value. | 2530 // callee value. |
| 2546 if (expr->is_possibly_eval() && expr->arguments()->length() > 0) { | 2531 if (expr->is_possibly_eval() && expr->arguments()->length() > 0) { |
| 2547 RegisterAllocationScope inner_register_scope(this); | 2532 RegisterAllocationScope inner_register_scope(this); |
| 2548 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source | 2533 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source |
| 2549 // strings and function closure, and loading language and | 2534 // strings and function closure, and loading language and |
| 2550 // position. | 2535 // position. |
| 2551 RegisterList runtime_call_args = register_allocator()->NewRegisterList(6); | 2536 RegisterList runtime_call_args = register_allocator()->NewRegisterList(6); |
| 2552 builder() | 2537 builder() |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2565 builder() | 2550 builder() |
| 2566 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args) | 2551 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, runtime_call_args) |
| 2567 .StoreAccumulatorInRegister(callee); | 2552 .StoreAccumulatorInRegister(callee); |
| 2568 } | 2553 } |
| 2569 | 2554 |
| 2570 builder()->SetExpressionPosition(expr); | 2555 builder()->SetExpressionPosition(expr); |
| 2571 | 2556 |
| 2572 // When a call contains a spread, a Call AST node is only created if there is | 2557 // When a call contains a spread, a Call AST node is only created if there is |
| 2573 // exactly one spread, and it is the last argument. | 2558 // exactly one spread, and it is the last argument. |
| 2574 if (expr->only_last_arg_is_spread()) { | 2559 if (expr->only_last_arg_is_spread()) { |
| 2575 CHECK_EQ(expr->arguments()->length() + 2, args.register_count()); | |
| 2576 DCHECK_EQ(TailCallMode::kDisallow, expr->tail_call_mode()); | 2560 DCHECK_EQ(TailCallMode::kDisallow, expr->tail_call_mode()); |
| 2577 builder()->CallWithSpread(args); | 2561 builder()->CallWithSpread(callee, args); |
| 2578 } else { | 2562 } else { |
| 2579 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); | 2563 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); |
| 2580 builder()->Call(callee, args, feedback_slot_index, call_type, | 2564 builder()->Call(callee, args, feedback_slot_index, call_type, |
| 2581 expr->tail_call_mode()); | 2565 expr->tail_call_mode()); |
| 2582 } | 2566 } |
| 2583 } | 2567 } |
| 2584 | 2568 |
| 2585 void BytecodeGenerator::VisitCallSuper(Call* expr) { | 2569 void BytecodeGenerator::VisitCallSuper(Call* expr) { |
| 2586 RegisterAllocationScope register_scope(this); | 2570 RegisterAllocationScope register_scope(this); |
| 2587 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | 2571 SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3374 } | 3358 } |
| 3375 | 3359 |
| 3376 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3360 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
| 3377 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3361 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
| 3378 : Runtime::kStoreKeyedToSuper_Sloppy; | 3362 : Runtime::kStoreKeyedToSuper_Sloppy; |
| 3379 } | 3363 } |
| 3380 | 3364 |
| 3381 } // namespace interpreter | 3365 } // namespace interpreter |
| 3382 } // namespace internal | 3366 } // namespace internal |
| 3383 } // namespace v8 | 3367 } // namespace v8 |
| OLD | NEW |