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 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 // functions are non-constructable. | 974 // functions are non-constructable. |
975 builder()->MoveRegister(Register::new_target(), generator_object_); | 975 builder()->MoveRegister(Register::new_target(), generator_object_); |
976 | 976 |
977 BytecodeLabel regular_call; | 977 BytecodeLabel regular_call; |
978 builder() | 978 builder() |
979 ->LoadAccumulatorWithRegister(generator_object_) | 979 ->LoadAccumulatorWithRegister(generator_object_) |
980 .JumpIfUndefined(®ular_call); | 980 .JumpIfUndefined(®ular_call); |
981 | 981 |
982 // This is a resume call. Restore the current context and the registers, | 982 // This is a resume call. Restore the current context and the registers, |
983 // then perform state dispatch. | 983 // then perform state dispatch. |
984 Register generator_context = register_allocator()->NewRegister(); | 984 { |
985 builder() | 985 RegisterAllocationScope register_scope(this); |
986 ->CallRuntime(Runtime::kInlineGeneratorGetContext, generator_object_) | 986 Register generator_context = register_allocator()->NewRegister(); |
987 .PushContext(generator_context) | 987 builder() |
988 .RestoreGeneratorState(generator_object_) | 988 ->CallRuntime(Runtime::kInlineGeneratorGetContext, generator_object_) |
989 .StoreAccumulatorInRegister(generator_state_) | 989 .PushContext(generator_context) |
990 .SwitchOnSmiNoFeedback(generator_jump_table_); | 990 .RestoreGeneratorState(generator_object_) |
| 991 .StoreAccumulatorInRegister(generator_state_) |
| 992 .SwitchOnSmiNoFeedback(generator_jump_table_); |
| 993 } |
991 // We fall through when the generator state is not in the jump table. | 994 // We fall through when the generator state is not in the jump table. |
992 // TODO(leszeks): Only generate this for debug builds. | 995 // TODO(leszeks): Only generate this for debug builds. |
993 BuildAbort(BailoutReason::kInvalidJumpTableIndex); | 996 BuildAbort(BailoutReason::kInvalidJumpTableIndex); |
994 | 997 |
995 // This is a regular call. | 998 // This is a regular call. |
996 builder() | 999 builder() |
997 ->Bind(®ular_call) | 1000 ->Bind(®ular_call) |
998 .LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)) | 1001 .LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)) |
999 .StoreAccumulatorInRegister(generator_state_); | 1002 .StoreAccumulatorInRegister(generator_state_); |
1000 // Now fall through to the ordinary function prologue, after which we will run | 1003 // Now fall through to the ordinary function prologue, after which we will run |
(...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2176 if (FLAG_trace) { | 2179 if (FLAG_trace) { |
2177 RegisterAllocationScope register_scope(this); | 2180 RegisterAllocationScope register_scope(this); |
2178 Register result = register_allocator()->NewRegister(); | 2181 Register result = register_allocator()->NewRegister(); |
2179 // Runtime returns {result} value, preserving accumulator. | 2182 // Runtime returns {result} value, preserving accumulator. |
2180 builder()->StoreAccumulatorInRegister(result).CallRuntime( | 2183 builder()->StoreAccumulatorInRegister(result).CallRuntime( |
2181 Runtime::kTraceExit, result); | 2184 Runtime::kTraceExit, result); |
2182 } | 2185 } |
2183 if (info()->literal()->feedback_vector_spec()->HasTypeProfileSlot()) { | 2186 if (info()->literal()->feedback_vector_spec()->HasTypeProfileSlot()) { |
2184 builder()->CollectTypeProfile(info()->literal()->return_position()); | 2187 builder()->CollectTypeProfile(info()->literal()->return_position()); |
2185 } | 2188 } |
| 2189 if (IsGeneratorFunction(info()->literal()->kind())) { |
| 2190 // Mark the generator as closed if returning from a generator function. |
| 2191 RegisterAllocationScope register_scope(this); |
| 2192 Register result = register_allocator()->NewRegister(); |
| 2193 builder() |
| 2194 ->StoreAccumulatorInRegister(result) |
| 2195 .CallRuntime(Runtime::kInlineGeneratorClose, generator_object_) |
| 2196 .LoadAccumulatorWithRegister(result); |
| 2197 } |
2186 builder()->Return(); | 2198 builder()->Return(); |
2187 } | 2199 } |
2188 | 2200 |
2189 void BytecodeGenerator::BuildAsyncReturn() { | 2201 void BytecodeGenerator::BuildAsyncReturn() { |
2190 RegisterAllocationScope register_scope(this); | 2202 RegisterAllocationScope register_scope(this); |
2191 | 2203 |
2192 if (IsAsyncGeneratorFunction(info()->literal()->kind())) { | 2204 if (IsAsyncGeneratorFunction(info()->literal()->kind())) { |
2193 RegisterList args = register_allocator()->NewRegisterList(3); | 2205 RegisterList args = register_allocator()->NewRegisterList(3); |
2194 Register generator = args[0]; | 2206 Register generator = args[0]; |
2195 Register result = args[1]; | 2207 Register result = args[1]; |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2526 RegisterAllocationScope register_scope(this); | 2538 RegisterAllocationScope register_scope(this); |
2527 | 2539 |
2528 builder()->SetExpressionPosition(expr); | 2540 builder()->SetExpressionPosition(expr); |
2529 Register value = VisitForRegisterValue(expr->expression()); | 2541 Register value = VisitForRegisterValue(expr->expression()); |
2530 | 2542 |
2531 // Save context, registers, and state. Then return. | 2543 // Save context, registers, and state. Then return. |
2532 builder() | 2544 builder() |
2533 ->LoadLiteral(Smi::FromInt(expr->suspend_id())) | 2545 ->LoadLiteral(Smi::FromInt(expr->suspend_id())) |
2534 .SuspendGenerator(generator_object_, registers_to_save, expr->flags()); | 2546 .SuspendGenerator(generator_object_, registers_to_save, expr->flags()); |
2535 | 2547 |
2536 if (expr->IsNonInitialAsyncGeneratorYield()) { | 2548 if (expr->IsNonInitialGeneratorYield()) { |
| 2549 // GeneratorYield: Wrap the value into IteratorResult. |
| 2550 RegisterList args = register_allocator()->NewRegisterList(2); |
| 2551 builder() |
| 2552 ->MoveRegister(value, args[0]) |
| 2553 .LoadFalse() |
| 2554 .StoreAccumulatorInRegister(args[1]) |
| 2555 .CallRuntime(Runtime::kInlineCreateIterResultObject, args); |
| 2556 } else if (expr->IsNonInitialAsyncGeneratorYield()) { |
2537 // AsyncGenerator yields (with the exception of the initial yield) delegate | 2557 // AsyncGenerator yields (with the exception of the initial yield) delegate |
2538 // to AsyncGeneratorResolve(), implemented via the runtime call below. | 2558 // to AsyncGeneratorResolve(), implemented via the runtime call below. |
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_object_, args[0]) | 2564 ->MoveRegister(generator_object_, args[0]) |
2545 .MoveRegister(value, args[1]) | 2565 .MoveRegister(value, args[1]) |
2546 .LoadFalse() | 2566 .LoadFalse() |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2599 if (expr->rethrow_on_exception()) { | 2619 if (expr->rethrow_on_exception()) { |
2600 builder()->ReThrow(); | 2620 builder()->ReThrow(); |
2601 } else { | 2621 } else { |
2602 builder()->Throw(); | 2622 builder()->Throw(); |
2603 } | 2623 } |
2604 } | 2624 } |
2605 | 2625 |
2606 { | 2626 { |
2607 // Resume with return. | 2627 // Resume with return. |
2608 builder()->Bind(jump_table, JSGeneratorObject::kReturn); | 2628 builder()->Bind(jump_table, JSGeneratorObject::kReturn); |
| 2629 builder()->LoadAccumulatorWithRegister(input); |
2609 if (expr->is_async_generator()) { | 2630 if (expr->is_async_generator()) { |
2610 // Async generator methods will produce the iter result object. | 2631 // Async generator methods will produce the iter result object. |
2611 builder()->LoadAccumulatorWithRegister(input); | |
2612 execution_control()->AsyncReturnAccumulator(); | 2632 execution_control()->AsyncReturnAccumulator(); |
2613 } else { | 2633 } else { |
2614 RegisterList args = register_allocator()->NewRegisterList(2); | |
2615 builder() | |
2616 ->MoveRegister(input, args[0]) | |
2617 .LoadTrue() | |
2618 .StoreAccumulatorInRegister(args[1]) | |
2619 .CallRuntime(Runtime::kInlineCreateIterResultObject, args); | |
2620 execution_control()->ReturnAccumulator(); | 2634 execution_control()->ReturnAccumulator(); |
2621 } | 2635 } |
2622 } | 2636 } |
2623 | 2637 |
2624 { | 2638 { |
2625 // Resume with next. | 2639 // Resume with next. |
2626 builder()->Bind(jump_table, JSGeneratorObject::kNext); | 2640 builder()->Bind(jump_table, JSGeneratorObject::kNext); |
2627 builder()->LoadAccumulatorWithRegister(input); | 2641 builder()->LoadAccumulatorWithRegister(input); |
2628 } | 2642 } |
2629 } | 2643 } |
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3914 } | 3928 } |
3915 | 3929 |
3916 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3930 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3917 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3931 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3918 : Runtime::kStoreKeyedToSuper_Sloppy; | 3932 : Runtime::kStoreKeyedToSuper_Sloppy; |
3919 } | 3933 } |
3920 | 3934 |
3921 } // namespace interpreter | 3935 } // namespace interpreter |
3922 } // namespace internal | 3936 } // namespace internal |
3923 } // namespace v8 | 3937 } // namespace v8 |
OLD | NEW |