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 2165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2176 if (FLAG_trace) { | 2176 if (FLAG_trace) { |
2177 RegisterAllocationScope register_scope(this); | 2177 RegisterAllocationScope register_scope(this); |
2178 Register result = register_allocator()->NewRegister(); | 2178 Register result = register_allocator()->NewRegister(); |
2179 // Runtime returns {result} value, preserving accumulator. | 2179 // Runtime returns {result} value, preserving accumulator. |
2180 builder()->StoreAccumulatorInRegister(result).CallRuntime( | 2180 builder()->StoreAccumulatorInRegister(result).CallRuntime( |
2181 Runtime::kTraceExit, result); | 2181 Runtime::kTraceExit, result); |
2182 } | 2182 } |
2183 if (info()->literal()->feedback_vector_spec()->HasTypeProfileSlot()) { | 2183 if (info()->literal()->feedback_vector_spec()->HasTypeProfileSlot()) { |
2184 builder()->CollectTypeProfile(info()->literal()->return_position()); | 2184 builder()->CollectTypeProfile(info()->literal()->return_position()); |
2185 } | 2185 } |
| 2186 |
| 2187 // For generators, wrap the result (for non-async generators) and |
| 2188 // close the generator. |
| 2189 if (IsGeneratorFunction(info()->literal()->kind())) { |
| 2190 if (!IsAsyncGeneratorFunction(info()->literal()->kind())) { |
| 2191 RegisterList args = register_allocator()->NewRegisterList(2); |
| 2192 builder() |
| 2193 ->StoreAccumulatorInRegister(args[0]) |
| 2194 .LoadTrue() |
| 2195 .StoreAccumulatorInRegister(args[1]) |
| 2196 .CallRuntime(Runtime::kInlineCreateIterResultObject, args); |
| 2197 } |
| 2198 // Mark the generator as closed (making sure we do not clobber |
| 2199 // the result). |
| 2200 Register result = register_allocator()->NewRegister(); |
| 2201 builder() |
| 2202 ->StoreAccumulatorInRegister(result) |
| 2203 .CallRuntime(Runtime::kInlineGeneratorClose, generator_object_) |
| 2204 .LoadAccumulatorWithRegister(result); |
| 2205 } |
2186 builder()->Return(); | 2206 builder()->Return(); |
2187 } | 2207 } |
2188 | 2208 |
2189 void BytecodeGenerator::BuildAsyncReturn() { | 2209 void BytecodeGenerator::BuildAsyncReturn() { |
2190 RegisterAllocationScope register_scope(this); | 2210 RegisterAllocationScope register_scope(this); |
2191 | 2211 |
2192 if (IsAsyncGeneratorFunction(info()->literal()->kind())) { | 2212 if (IsAsyncGeneratorFunction(info()->literal()->kind())) { |
2193 RegisterList args = register_allocator()->NewRegisterList(3); | 2213 RegisterList args = register_allocator()->NewRegisterList(3); |
2194 Register generator = args[0]; | 2214 Register generator = args[0]; |
2195 Register result = args[1]; | 2215 Register result = args[1]; |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2539 RegisterList args = register_allocator()->NewRegisterList(3); | 2559 RegisterList args = register_allocator()->NewRegisterList(3); |
2540 | 2560 |
2541 // AsyncGeneratorYield: | 2561 // AsyncGeneratorYield: |
2542 // perform AsyncGeneratorResolve(<generator>, <value>, false). | 2562 // perform AsyncGeneratorResolve(<generator>, <value>, false). |
2543 builder() | 2563 builder() |
2544 ->MoveRegister(generator, args[0]) | 2564 ->MoveRegister(generator, args[0]) |
2545 .MoveRegister(value, args[1]) | 2565 .MoveRegister(value, args[1]) |
2546 .LoadFalse() | 2566 .LoadFalse() |
2547 .StoreAccumulatorInRegister(args[2]) | 2567 .StoreAccumulatorInRegister(args[2]) |
2548 .CallRuntime(Runtime::kInlineAsyncGeneratorResolve, args); | 2568 .CallRuntime(Runtime::kInlineAsyncGeneratorResolve, args); |
| 2569 } else if (expr->IsNonInitialGeneratorYield()) { |
| 2570 // GeneratorYield: Wrap the value into IteratorResult. |
| 2571 RegisterList args = register_allocator()->NewRegisterList(2); |
| 2572 builder() |
| 2573 ->MoveRegister(value, args[0]) |
| 2574 .LoadFalse() |
| 2575 .StoreAccumulatorInRegister(args[1]) |
| 2576 .CallRuntime(Runtime::kInlineCreateIterResultObject, args); |
2549 } else { | 2577 } else { |
2550 builder()->LoadAccumulatorWithRegister(value); | 2578 builder()->LoadAccumulatorWithRegister(value); |
2551 } | 2579 } |
2552 builder()->Return(); // Hard return (ignore any finally blocks). | 2580 builder()->Return(); // Hard return (ignore any finally blocks). |
2553 } | 2581 } |
2554 | 2582 |
2555 void BytecodeGenerator::BuildGeneratorResume( | 2583 void BytecodeGenerator::BuildGeneratorResume( |
2556 Suspend* expr, Register generator, RegisterList registers_to_restore) { | 2584 Suspend* expr, Register generator, RegisterList registers_to_restore) { |
2557 RegisterAllocationScope register_scope(this); | 2585 RegisterAllocationScope register_scope(this); |
2558 | 2586 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2592 | 2620 |
2593 builder() | 2621 builder() |
2594 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext)) | 2622 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kNext)) |
2595 .CompareOperation(Token::EQ_STRICT, resume_mode) | 2623 .CompareOperation(Token::EQ_STRICT, resume_mode) |
2596 .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_next) | 2624 .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_next) |
2597 .LoadLiteral(Smi::FromInt(JSGeneratorObject::kThrow)) | 2625 .LoadLiteral(Smi::FromInt(JSGeneratorObject::kThrow)) |
2598 .CompareOperation(Token::EQ_STRICT, resume_mode) | 2626 .CompareOperation(Token::EQ_STRICT, resume_mode) |
2599 .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_throw); | 2627 .JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &resume_with_throw); |
2600 // Fall through for resuming with return. | 2628 // Fall through for resuming with return. |
2601 | 2629 |
| 2630 builder()->LoadAccumulatorWithRegister(input); |
2602 if (expr->is_async_generator()) { | 2631 if (expr->is_async_generator()) { |
2603 // Async generator methods will produce the iter result object. | 2632 // Async generator methods will produce the iter result object. |
2604 builder()->LoadAccumulatorWithRegister(input); | |
2605 execution_control()->AsyncReturnAccumulator(); | 2633 execution_control()->AsyncReturnAccumulator(); |
2606 } else { | 2634 } else { |
2607 RegisterList args = register_allocator()->NewRegisterList(2); | |
2608 builder() | |
2609 ->MoveRegister(input, args[0]) | |
2610 .LoadTrue() | |
2611 .StoreAccumulatorInRegister(args[1]) | |
2612 .CallRuntime(Runtime::kInlineCreateIterResultObject, args); | |
2613 execution_control()->ReturnAccumulator(); | 2635 execution_control()->ReturnAccumulator(); |
2614 } | 2636 } |
2615 | 2637 |
2616 builder()->Bind(&resume_with_throw); | 2638 builder()->Bind(&resume_with_throw); |
2617 builder()->SetExpressionPosition(expr); | 2639 builder()->SetExpressionPosition(expr); |
2618 builder()->LoadAccumulatorWithRegister(input); | 2640 builder()->LoadAccumulatorWithRegister(input); |
2619 if (expr->rethrow_on_exception()) { | 2641 if (expr->rethrow_on_exception()) { |
2620 builder()->ReThrow(); | 2642 builder()->ReThrow(); |
2621 } else { | 2643 } else { |
2622 builder()->Throw(); | 2644 builder()->Throw(); |
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3913 } | 3935 } |
3914 | 3936 |
3915 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3937 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3916 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3938 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3917 : Runtime::kStoreKeyedToSuper_Sloppy; | 3939 : Runtime::kStoreKeyedToSuper_Sloppy; |
3918 } | 3940 } |
3919 | 3941 |
3920 } // namespace interpreter | 3942 } // namespace interpreter |
3921 } // namespace internal | 3943 } // namespace internal |
3922 } // namespace v8 | 3944 } // namespace v8 |
OLD | NEW |