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 Register result = register_allocator()->NewRegister(); | |
adamk
2017/06/05 18:37:36
Should there be a RegisterAllocationScope here?
rmcilroy
2017/06/05 19:28:42
Each statement is in its own RegisterAllocationSco
| |
2192 builder() | |
2193 ->StoreAccumulatorInRegister(result) | |
2194 .CallRuntime(Runtime::kInlineGeneratorClose, generator_object_) | |
2195 .LoadAccumulatorWithRegister(result); | |
2196 } | |
2186 builder()->Return(); | 2197 builder()->Return(); |
2187 } | 2198 } |
2188 | 2199 |
2189 void BytecodeGenerator::BuildAsyncReturn() { | 2200 void BytecodeGenerator::BuildAsyncReturn() { |
2190 RegisterAllocationScope register_scope(this); | 2201 RegisterAllocationScope register_scope(this); |
2191 | 2202 |
2192 if (IsAsyncGeneratorFunction(info()->literal()->kind())) { | 2203 if (IsAsyncGeneratorFunction(info()->literal()->kind())) { |
2193 RegisterList args = register_allocator()->NewRegisterList(3); | 2204 RegisterList args = register_allocator()->NewRegisterList(3); |
2194 Register generator = args[0]; | 2205 Register generator = args[0]; |
2195 Register result = args[1]; | 2206 Register result = args[1]; |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2526 RegisterAllocationScope register_scope(this); | 2537 RegisterAllocationScope register_scope(this); |
2527 | 2538 |
2528 builder()->SetExpressionPosition(expr); | 2539 builder()->SetExpressionPosition(expr); |
2529 Register value = VisitForRegisterValue(expr->expression()); | 2540 Register value = VisitForRegisterValue(expr->expression()); |
2530 | 2541 |
2531 // Save context, registers, and state. Then return. | 2542 // Save context, registers, and state. Then return. |
2532 builder() | 2543 builder() |
2533 ->LoadLiteral(Smi::FromInt(expr->suspend_id())) | 2544 ->LoadLiteral(Smi::FromInt(expr->suspend_id())) |
2534 .SuspendGenerator(generator, registers_to_save, expr->flags()); | 2545 .SuspendGenerator(generator, registers_to_save, expr->flags()); |
2535 | 2546 |
2536 if (expr->IsNonInitialAsyncGeneratorYield()) { | 2547 if (expr->IsNonInitialGeneratorYield()) { |
2548 // GeneratorYield: Wrap the value into IteratorResult. | |
2549 RegisterList args = register_allocator()->NewRegisterList(2); | |
2550 builder() | |
2551 ->MoveRegister(value, args[0]) | |
2552 .LoadFalse() | |
2553 .StoreAccumulatorInRegister(args[1]) | |
2554 .CallRuntime(Runtime::kInlineCreateIterResultObject, args); | |
2555 } else if (expr->IsNonInitialAsyncGeneratorYield()) { | |
2537 // AsyncGenerator yields (with the exception of the initial yield) delegate | 2556 // AsyncGenerator yields (with the exception of the initial yield) delegate |
2538 // to AsyncGeneratorResolve(), implemented via the runtime call below. | 2557 // to AsyncGeneratorResolve(), implemented via the runtime call below. |
2539 RegisterList args = register_allocator()->NewRegisterList(3); | 2558 RegisterList args = register_allocator()->NewRegisterList(3); |
2540 | 2559 |
2541 // AsyncGeneratorYield: | 2560 // AsyncGeneratorYield: |
2542 // perform AsyncGeneratorResolve(<generator>, <value>, false). | 2561 // perform AsyncGeneratorResolve(<generator>, <value>, false). |
2543 builder() | 2562 builder() |
2544 ->MoveRegister(generator, args[0]) | 2563 ->MoveRegister(generator, args[0]) |
2545 .MoveRegister(value, args[1]) | 2564 .MoveRegister(value, args[1]) |
2546 .LoadFalse() | 2565 .LoadFalse() |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2599 if (expr->rethrow_on_exception()) { | 2618 if (expr->rethrow_on_exception()) { |
2600 builder()->ReThrow(); | 2619 builder()->ReThrow(); |
2601 } else { | 2620 } else { |
2602 builder()->Throw(); | 2621 builder()->Throw(); |
2603 } | 2622 } |
2604 } | 2623 } |
2605 | 2624 |
2606 { | 2625 { |
2607 // Resume with return. | 2626 // Resume with return. |
2608 builder()->Bind(jump_table, JSGeneratorObject::kReturn); | 2627 builder()->Bind(jump_table, JSGeneratorObject::kReturn); |
2628 builder()->LoadAccumulatorWithRegister(input); | |
2609 if (expr->is_async_generator()) { | 2629 if (expr->is_async_generator()) { |
2610 // Async generator methods will produce the iter result object. | 2630 // Async generator methods will produce the iter result object. |
2611 builder()->LoadAccumulatorWithRegister(input); | |
2612 execution_control()->AsyncReturnAccumulator(); | 2631 execution_control()->AsyncReturnAccumulator(); |
2613 } else { | 2632 } 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(); | 2633 execution_control()->ReturnAccumulator(); |
2621 } | 2634 } |
2622 } | 2635 } |
2623 | 2636 |
2624 { | 2637 { |
2625 // Resume with next. | 2638 // Resume with next. |
2626 builder()->Bind(jump_table, JSGeneratorObject::kNext); | 2639 builder()->Bind(jump_table, JSGeneratorObject::kNext); |
2627 builder()->LoadAccumulatorWithRegister(input); | 2640 builder()->LoadAccumulatorWithRegister(input); |
2628 } | 2641 } |
2629 } | 2642 } |
(...skipping 1285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3915 } | 3928 } |
3916 | 3929 |
3917 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3930 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3918 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3931 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3919 : Runtime::kStoreKeyedToSuper_Sloppy; | 3932 : Runtime::kStoreKeyedToSuper_Sloppy; |
3920 } | 3933 } |
3921 | 3934 |
3922 } // namespace interpreter | 3935 } // namespace interpreter |
3923 } // namespace internal | 3936 } // namespace internal |
3924 } // namespace v8 | 3937 } // namespace v8 |
OLD | NEW |