Chromium Code Reviews| 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 1638 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2241 } | 2243 } |
| 2242 } | 2244 } |
| 2243 } | 2245 } |
| 2244 | 2246 |
| 2245 void BytecodeGenerator::VisitYield(Yield* expr) { | 2247 void BytecodeGenerator::VisitYield(Yield* expr) { |
| 2246 builder()->SetExpressionPosition(expr); | 2248 builder()->SetExpressionPosition(expr); |
| 2247 Register value = VisitForRegisterValue(expr->expression()); | 2249 Register value = VisitForRegisterValue(expr->expression()); |
| 2248 | 2250 |
| 2249 Register generator = VisitForRegisterValue(expr->generator_object()); | 2251 Register generator = VisitForRegisterValue(expr->generator_object()); |
| 2250 | 2252 |
| 2251 // Save context, registers, and state. Then return. | 2253 if (IsAsyncGeneratorFunction(scope()->function_kind()) && |
| 2252 builder() | 2254 expr->yield_id() > 0 && expr->yield_type() == Yield::kNormal) { |
| 2253 ->LoadLiteral(Smi::FromInt(expr->yield_id())) | 2255 Expression* yield_value = expr->expression(); |
| 2254 .SuspendGenerator(generator) | 2256 int context_index = Context::ASYNC_GENERATOR_YIELD; |
| 2255 .LoadAccumulatorWithRegister(value) | 2257 |
| 2256 .Return(); // Hard return (ignore any finally blocks). | 2258 RegisterList args = register_allocator()->NewRegisterList(2); |
| 2259 builder() | |
| 2260 ->LoadLiteral(Smi::FromInt(expr->yield_id())) | |
| 2261 .SuspendGenerator(generator) | |
| 2262 .MoveRegister(generator, args[0]) | |
| 2263 .MoveRegister(value, args[1]) | |
| 2264 .CallJSRuntime(context_index, args) | |
| 2265 .Return(); // Hard return (ignore any finally blocks). | |
| 2266 } else { | |
| 2267 // Save context, registers, and state. Then return. | |
| 2268 builder() | |
|
caitp
2017/01/10 04:13:42
AwaitExpressions are still desugared in the parser
| |
| 2269 ->LoadLiteral(Smi::FromInt(expr->yield_id())) | |
| 2270 .SuspendGenerator(generator) | |
| 2271 .LoadAccumulatorWithRegister(value) | |
| 2272 .Return(); // Hard return (ignore any finally blocks). | |
| 2273 } | |
| 2257 | 2274 |
| 2258 builder()->Bind(&(generator_resume_points_[expr->yield_id()])); | 2275 builder()->Bind(&(generator_resume_points_[expr->yield_id()])); |
| 2259 // Upon resume, we continue here. | 2276 // Upon resume, we continue here. |
| 2260 | 2277 |
| 2261 { | 2278 { |
| 2262 RegisterAllocationScope register_scope(this); | 2279 RegisterAllocationScope register_scope(this); |
| 2263 | 2280 |
| 2264 // Update state to indicate that we have finished resuming. Loop headers | 2281 // Update state to indicate that we have finished resuming. Loop headers |
| 2265 // rely on this. | 2282 // rely on this. |
| 2266 builder() | 2283 builder() |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2885 void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { | 2902 void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { |
| 2886 FeedbackVectorSlot load_slot = expr->IteratorPropertyFeedbackSlot(); | 2903 FeedbackVectorSlot load_slot = expr->IteratorPropertyFeedbackSlot(); |
| 2887 FeedbackVectorSlot call_slot = expr->IteratorCallFeedbackSlot(); | 2904 FeedbackVectorSlot call_slot = expr->IteratorCallFeedbackSlot(); |
| 2888 | 2905 |
| 2889 RegisterList args = register_allocator()->NewRegisterList(1); | 2906 RegisterList args = register_allocator()->NewRegisterList(1); |
| 2890 Register method = register_allocator()->NewRegister(); | 2907 Register method = register_allocator()->NewRegister(); |
| 2891 Register obj = args[0]; | 2908 Register obj = args[0]; |
| 2892 | 2909 |
| 2893 VisitForAccumulatorValue(expr->iterable()); | 2910 VisitForAccumulatorValue(expr->iterable()); |
| 2894 | 2911 |
| 2895 // Let method be GetMethod(obj, @@iterator). | 2912 if (expr->hint() == GetIterator::kAsync) { |
| 2896 builder() | 2913 FeedbackVectorSlot load_slot2 = expr->AsyncIteratorPropertyFeedbackSlot(); |
| 2897 ->StoreAccumulatorInRegister(obj) | 2914 FeedbackVectorSlot call_slot2 = expr->AsyncIteratorCallFeedbackSlot(); |
| 2898 .LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot)) | |
| 2899 .StoreAccumulatorInRegister(method); | |
| 2900 | 2915 |
| 2901 // Let iterator be Call(method, obj). | 2916 // Set method to GetMethod(obj, @@asyncIterator) |
| 2902 builder()->Call(method, args, feedback_index(call_slot), | 2917 builder()->StoreAccumulatorInRegister(obj).LoadNamedProperty( |
| 2903 Call::NAMED_PROPERTY_CALL); | 2918 obj, async_iterator_symbol(), feedback_index(load_slot2)); |
| 2904 | 2919 |
| 2905 // If Type(iterator) is not Object, throw a TypeError exception. | 2920 BytecodeLabel create_async_from_sync, done; |
| 2906 BytecodeLabel no_type_error; | 2921 builder()->JumpIfUndefined(&create_async_from_sync); |
| 2907 builder()->JumpIfJSReceiver(&no_type_error); | 2922 |
| 2908 builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid); | 2923 // Let iterator be Call(method, obj) |
| 2909 builder()->Bind(&no_type_error); | 2924 builder()->StoreAccumulatorInRegister(method).Call( |
| 2925 method, args, feedback_index(call_slot), Call::NAMED_PROPERTY_CALL); | |
| 2926 | |
| 2927 // If Type(iterator) is not Object, throw a TypeError exception. | |
| 2928 builder()->JumpIfJSReceiver(&done); | |
| 2929 builder()->CallRuntime(Runtime::kThrowSymbolAsyncIteratorInvalid); | |
| 2930 | |
| 2931 builder()->Bind(&create_async_from_sync); | |
| 2932 // If method is undefined, | |
| 2933 // Let syncMethod be GetMethod(obj, @@iterator) | |
| 2934 builder() | |
| 2935 ->LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot)) | |
| 2936 .StoreAccumulatorInRegister(method); | |
| 2937 | |
| 2938 // Let syncIterator be Call(syncMethod, obj) | |
| 2939 builder()->Call(method, args, feedback_index(call_slot2), | |
| 2940 Call::NAMED_PROPERTY_CALL); | |
| 2941 | |
| 2942 // Return CreateAsyncFromSyncIterator(syncIterator) | |
| 2943 RegisterList args = register_allocator()->NewRegisterList(1); | |
| 2944 Register sync_iterator = args[0]; | |
| 2945 builder() | |
| 2946 ->StoreAccumulatorInRegister(sync_iterator) | |
| 2947 .CallRuntime(Runtime::kInlineCreateAsyncFromSyncIterator, args); | |
| 2948 | |
| 2949 builder()->Bind(&done); | |
| 2950 } else { | |
| 2951 // Let method be GetMethod(obj, @@iterator). | |
| 2952 builder() | |
| 2953 ->StoreAccumulatorInRegister(obj) | |
| 2954 .LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot)) | |
| 2955 .StoreAccumulatorInRegister(method); | |
| 2956 | |
| 2957 // Let iterator be Call(method, obj). | |
| 2958 builder()->Call(method, args, feedback_index(call_slot), | |
| 2959 Call::NAMED_PROPERTY_CALL); | |
| 2960 | |
| 2961 // If Type(iterator) is not Object, throw a TypeError exception. | |
| 2962 BytecodeLabel no_type_error; | |
| 2963 builder()->JumpIfJSReceiver(&no_type_error); | |
| 2964 builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid); | |
| 2965 builder()->Bind(&no_type_error); | |
| 2966 } | |
| 2910 } | 2967 } |
| 2911 | 2968 |
| 2912 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { | 2969 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 2913 builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 2970 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
| 2914 } | 2971 } |
| 2915 | 2972 |
| 2916 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { | 2973 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { |
| 2917 // Handled by VisitCall(). | 2974 // Handled by VisitCall(). |
| 2918 UNREACHABLE(); | 2975 UNREACHABLE(); |
| 2919 } | 2976 } |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3325 } | 3382 } |
| 3326 | 3383 |
| 3327 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3384 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
| 3328 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3385 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
| 3329 : Runtime::kStoreKeyedToSuper_Sloppy; | 3386 : Runtime::kStoreKeyedToSuper_Sloppy; |
| 3330 } | 3387 } |
| 3331 | 3388 |
| 3332 } // namespace interpreter | 3389 } // namespace interpreter |
| 3333 } // namespace internal | 3390 } // namespace internal |
| 3334 } // namespace v8 | 3391 } // namespace v8 |
| OLD | NEW |