| 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 |