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 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 function_literals_(0, info->zone()), | 583 function_literals_(0, info->zone()), |
584 native_function_literals_(0, info->zone()), | 584 native_function_literals_(0, info->zone()), |
585 execution_control_(nullptr), | 585 execution_control_(nullptr), |
586 execution_context_(nullptr), | 586 execution_context_(nullptr), |
587 execution_result_(nullptr), | 587 execution_result_(nullptr), |
588 generator_resume_points_(info->literal()->yield_count(), info->zone()), | 588 generator_resume_points_(info->literal()->yield_count(), info->zone()), |
589 generator_state_(), | 589 generator_state_(), |
590 loop_depth_(0), | 590 loop_depth_(0), |
591 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), | 591 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), |
592 iterator_symbol_(info->isolate()->factory()->iterator_symbol()), | 592 iterator_symbol_(info->isolate()->factory()->iterator_symbol()), |
| 593 async_iterator_symbol_( |
| 594 info->isolate()->factory()->async_iterator_symbol()), |
593 empty_fixed_array_(info->isolate()->factory()->empty_fixed_array()) { | 595 empty_fixed_array_(info->isolate()->factory()->empty_fixed_array()) { |
594 AstValueFactory* ast_value_factory = info->parse_info()->ast_value_factory(); | 596 AstValueFactory* ast_value_factory = info->parse_info()->ast_value_factory(); |
595 const AstRawString* prototype_string = ast_value_factory->prototype_string(); | 597 const AstRawString* prototype_string = ast_value_factory->prototype_string(); |
596 ast_value_factory->Internalize(info->isolate()); | 598 ast_value_factory->Internalize(info->isolate()); |
597 prototype_string_ = prototype_string->string(); | 599 prototype_string_ = prototype_string->string(); |
598 undefined_string_ = ast_value_factory->undefined_string(); | 600 undefined_string_ = ast_value_factory->undefined_string(); |
599 } | 601 } |
600 | 602 |
601 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { | 603 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { |
602 AllocateDeferredConstants(); | 604 AllocateDeferredConstants(); |
(...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2243 } | 2245 } |
2244 } | 2246 } |
2245 } | 2247 } |
2246 | 2248 |
2247 void BytecodeGenerator::VisitYield(Yield* expr) { | 2249 void BytecodeGenerator::VisitYield(Yield* expr) { |
2248 builder()->SetExpressionPosition(expr); | 2250 builder()->SetExpressionPosition(expr); |
2249 Register value = VisitForRegisterValue(expr->expression()); | 2251 Register value = VisitForRegisterValue(expr->expression()); |
2250 | 2252 |
2251 Register generator = VisitForRegisterValue(expr->generator_object()); | 2253 Register generator = VisitForRegisterValue(expr->generator_object()); |
2252 | 2254 |
2253 // Save context, registers, and state. Then return. | 2255 if (IsAsyncGeneratorFunction(scope()->function_kind()) && |
2254 builder() | 2256 expr->yield_id() > 0 && expr->yield_type() == Yield::kNormal) { |
2255 ->LoadLiteral(Smi::FromInt(expr->yield_id())) | 2257 Expression* yield_value = expr->expression(); |
2256 .SuspendGenerator(generator) | 2258 |
2257 .LoadAccumulatorWithRegister(value) | 2259 RegisterList args = register_allocator()->NewRegisterList(2); |
2258 .Return(); // Hard return (ignore any finally blocks). | 2260 builder() |
| 2261 ->LoadLiteral(Smi::FromInt(expr->yield_id())) |
| 2262 .SuspendGenerator(generator) |
| 2263 .MoveRegister(generator, args[0]) |
| 2264 .MoveRegister(value, args[1]) |
| 2265 .CallJSRuntime(Context::ASYNC_GENERATOR_YIELD, args) |
| 2266 .Return(); // Hard return (ignore any finally blocks). |
| 2267 } else { |
| 2268 // Save context, registers, and state. Then return. |
| 2269 builder() |
| 2270 ->LoadLiteral(Smi::FromInt(expr->yield_id())) |
| 2271 .SuspendGenerator(generator) |
| 2272 .LoadAccumulatorWithRegister(value) |
| 2273 .Return(); // Hard return (ignore any finally blocks). |
| 2274 } |
2259 | 2275 |
2260 builder()->Bind(&(generator_resume_points_[expr->yield_id()])); | 2276 builder()->Bind(&(generator_resume_points_[expr->yield_id()])); |
2261 // Upon resume, we continue here. | 2277 // Upon resume, we continue here. |
2262 | 2278 |
2263 { | 2279 { |
2264 RegisterAllocationScope register_scope(this); | 2280 RegisterAllocationScope register_scope(this); |
2265 | 2281 |
2266 // Update state to indicate that we have finished resuming. Loop headers | 2282 // Update state to indicate that we have finished resuming. Loop headers |
2267 // rely on this. | 2283 // rely on this. |
2268 builder() | 2284 builder() |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2887 void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { | 2903 void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { |
2888 FeedbackVectorSlot load_slot = expr->IteratorPropertyFeedbackSlot(); | 2904 FeedbackVectorSlot load_slot = expr->IteratorPropertyFeedbackSlot(); |
2889 FeedbackVectorSlot call_slot = expr->IteratorCallFeedbackSlot(); | 2905 FeedbackVectorSlot call_slot = expr->IteratorCallFeedbackSlot(); |
2890 | 2906 |
2891 RegisterList args = register_allocator()->NewRegisterList(1); | 2907 RegisterList args = register_allocator()->NewRegisterList(1); |
2892 Register method = register_allocator()->NewRegister(); | 2908 Register method = register_allocator()->NewRegister(); |
2893 Register obj = args[0]; | 2909 Register obj = args[0]; |
2894 | 2910 |
2895 VisitForAccumulatorValue(expr->iterable()); | 2911 VisitForAccumulatorValue(expr->iterable()); |
2896 | 2912 |
2897 // Let method be GetMethod(obj, @@iterator). | 2913 if (expr->hint() == GetIterator::kAsync) { |
2898 builder() | 2914 FeedbackVectorSlot load_slot2 = expr->AsyncIteratorPropertyFeedbackSlot(); |
2899 ->StoreAccumulatorInRegister(obj) | 2915 FeedbackVectorSlot call_slot2 = expr->AsyncIteratorCallFeedbackSlot(); |
2900 .LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot)) | |
2901 .StoreAccumulatorInRegister(method); | |
2902 | 2916 |
2903 // Let iterator be Call(method, obj). | 2917 // Set method to GetMethod(obj, @@asyncIterator) |
2904 builder()->Call(method, args, feedback_index(call_slot), | 2918 builder()->StoreAccumulatorInRegister(obj).LoadNamedProperty( |
2905 Call::NAMED_PROPERTY_CALL); | 2919 obj, async_iterator_symbol(), feedback_index(load_slot2)); |
2906 | 2920 |
2907 // If Type(iterator) is not Object, throw a TypeError exception. | 2921 BytecodeLabel create_async_from_sync, done; |
2908 BytecodeLabel no_type_error; | 2922 builder()->JumpIfUndefined(&create_async_from_sync); |
2909 builder()->JumpIfJSReceiver(&no_type_error); | 2923 |
2910 builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid); | 2924 // Let iterator be Call(method, obj) |
2911 builder()->Bind(&no_type_error); | 2925 builder()->StoreAccumulatorInRegister(method).Call( |
| 2926 method, args, feedback_index(call_slot), Call::NAMED_PROPERTY_CALL); |
| 2927 |
| 2928 // If Type(iterator) is not Object, throw a TypeError exception. |
| 2929 builder()->JumpIfJSReceiver(&done); |
| 2930 builder()->CallRuntime(Runtime::kThrowSymbolAsyncIteratorInvalid); |
| 2931 |
| 2932 builder()->Bind(&create_async_from_sync); |
| 2933 // If method is undefined, |
| 2934 // Let syncMethod be GetMethod(obj, @@iterator) |
| 2935 builder() |
| 2936 ->LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot)) |
| 2937 .StoreAccumulatorInRegister(method); |
| 2938 |
| 2939 // Let syncIterator be Call(syncMethod, obj) |
| 2940 builder()->Call(method, args, feedback_index(call_slot2), |
| 2941 Call::NAMED_PROPERTY_CALL); |
| 2942 |
| 2943 // Return CreateAsyncFromSyncIterator(syncIterator) |
| 2944 RegisterList args = register_allocator()->NewRegisterList(1); |
| 2945 Register sync_iterator = args[0]; |
| 2946 builder() |
| 2947 ->StoreAccumulatorInRegister(sync_iterator) |
| 2948 .CallRuntime(Runtime::kInlineCreateAsyncFromSyncIterator, args); |
| 2949 |
| 2950 builder()->Bind(&done); |
| 2951 } else { |
| 2952 // Let method be GetMethod(obj, @@iterator). |
| 2953 builder() |
| 2954 ->StoreAccumulatorInRegister(obj) |
| 2955 .LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot)) |
| 2956 .StoreAccumulatorInRegister(method); |
| 2957 |
| 2958 // Let iterator be Call(method, obj). |
| 2959 builder()->Call(method, args, feedback_index(call_slot), |
| 2960 Call::NAMED_PROPERTY_CALL); |
| 2961 |
| 2962 // If Type(iterator) is not Object, throw a TypeError exception. |
| 2963 BytecodeLabel no_type_error; |
| 2964 builder()->JumpIfJSReceiver(&no_type_error); |
| 2965 builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid); |
| 2966 builder()->Bind(&no_type_error); |
| 2967 } |
2912 } | 2968 } |
2913 | 2969 |
2914 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { | 2970 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { |
2915 builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 2971 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
2916 } | 2972 } |
2917 | 2973 |
2918 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { | 2974 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { |
2919 // Handled by VisitCall(). | 2975 // Handled by VisitCall(). |
2920 UNREACHABLE(); | 2976 UNREACHABLE(); |
2921 } | 2977 } |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3327 } | 3383 } |
3328 | 3384 |
3329 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3385 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
3330 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3386 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
3331 : Runtime::kStoreKeyedToSuper_Sloppy; | 3387 : Runtime::kStoreKeyedToSuper_Sloppy; |
3332 } | 3388 } |
3333 | 3389 |
3334 } // namespace interpreter | 3390 } // namespace interpreter |
3335 } // namespace internal | 3391 } // namespace internal |
3336 } // namespace v8 | 3392 } // namespace v8 |
OLD | NEW |