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 |