Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: src/interpreter/bytecode-generator.cc

Issue 2622833002: WIP [esnext] implement async iteration proposal (Closed)
Patch Set: simplify AsyncIteratorValueUnwrap Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 function_literals_(0, info->zone()), 578 function_literals_(0, info->zone()),
579 native_function_literals_(0, info->zone()), 579 native_function_literals_(0, info->zone()),
580 execution_control_(nullptr), 580 execution_control_(nullptr),
581 execution_context_(nullptr), 581 execution_context_(nullptr),
582 execution_result_(nullptr), 582 execution_result_(nullptr),
583 generator_resume_points_(info->literal()->yield_count(), info->zone()), 583 generator_resume_points_(info->literal()->yield_count(), info->zone()),
584 generator_state_(), 584 generator_state_(),
585 loop_depth_(0), 585 loop_depth_(0),
586 home_object_symbol_(info->isolate()->factory()->home_object_symbol()), 586 home_object_symbol_(info->isolate()->factory()->home_object_symbol()),
587 iterator_symbol_(info->isolate()->factory()->iterator_symbol()), 587 iterator_symbol_(info->isolate()->factory()->iterator_symbol()),
588 async_iterator_symbol_(
589 info->isolate()->factory()->async_iterator_symbol()),
588 empty_fixed_array_(info->isolate()->factory()->empty_fixed_array()) { 590 empty_fixed_array_(info->isolate()->factory()->empty_fixed_array()) {
589 AstValueFactory* ast_value_factory = info->parse_info()->ast_value_factory(); 591 AstValueFactory* ast_value_factory = info->parse_info()->ast_value_factory();
590 const AstRawString* prototype_string = ast_value_factory->prototype_string(); 592 const AstRawString* prototype_string = ast_value_factory->prototype_string();
591 ast_value_factory->Internalize(info->isolate()); 593 ast_value_factory->Internalize(info->isolate());
592 prototype_string_ = prototype_string->string(); 594 prototype_string_ = prototype_string->string();
593 undefined_string_ = ast_value_factory->undefined_string(); 595 undefined_string_ = ast_value_factory->undefined_string();
594 } 596 }
595 597
596 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) { 598 Handle<BytecodeArray> BytecodeGenerator::FinalizeBytecode(Isolate* isolate) {
597 AllocateDeferredConstants(); 599 AllocateDeferredConstants();
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 } 2239 }
2238 } 2240 }
2239 } 2241 }
2240 2242
2241 void BytecodeGenerator::VisitYield(Yield* expr) { 2243 void BytecodeGenerator::VisitYield(Yield* expr) {
2242 builder()->SetExpressionPosition(expr); 2244 builder()->SetExpressionPosition(expr);
2243 Register value = VisitForRegisterValue(expr->expression()); 2245 Register value = VisitForRegisterValue(expr->expression());
2244 2246
2245 Register generator = VisitForRegisterValue(expr->generator_object()); 2247 Register generator = VisitForRegisterValue(expr->generator_object());
2246 2248
2247 // Save context, registers, and state. Then return. 2249 const bool kIsAsyncGenerator =
2248 builder() 2250 IsAsyncGeneratorFunction(scope()->function_kind());
2249 ->LoadLiteral(Smi::FromInt(expr->yield_id())) 2251
2250 .SuspendGenerator(generator) 2252 if (kIsAsyncGenerator && expr->yield_id() > 0 &&
2251 .LoadAccumulatorWithRegister(value) 2253 expr->yield_type() != Yield::kAwait) {
2252 .Return(); // Hard return (ignore any finally blocks). 2254 RegisterList args = register_allocator()->NewRegisterList(2);
2255
2256 int context_index = Context::ASYNC_GENERATOR_YIELD;
2257 if (expr->yield_type() == Yield::kDelegate) {
2258 // Avoid wrapping in iterator result for yield* yields
2259 context_index = Context::ASYNC_GENERATOR_RAW_YIELD;
2260 }
2261
2262 builder()
2263 ->LoadLiteral(Smi::FromInt(expr->yield_id()))
2264 .SuspendGenerator(generator, expr->yield_type())
2265 .MoveRegister(generator, args[0])
2266 .MoveRegister(value, args[1])
2267 .CallJSRuntime(context_index, args)
2268 .Return(); // Hard return (ignore any finally blocks).
2269 } else {
2270 // Save context, registers, and state. Then return.
2271 builder()
2272 ->LoadLiteral(Smi::FromInt(expr->yield_id()))
2273 .SuspendGenerator(generator, expr->yield_type())
2274 .LoadAccumulatorWithRegister(value)
2275 .Return(); // Hard return (ignore any finally blocks).
2276 }
2253 2277
2254 builder()->Bind(&(generator_resume_points_[expr->yield_id()])); 2278 builder()->Bind(&(generator_resume_points_[expr->yield_id()]));
2255 // Upon resume, we continue here. 2279 // Upon resume, we continue here.
2256 2280
2257 { 2281 {
2258 RegisterAllocationScope register_scope(this); 2282 RegisterAllocationScope register_scope(this);
2259 2283
2260 // Update state to indicate that we have finished resuming. Loop headers 2284 // Update state to indicate that we have finished resuming. Loop headers
2261 // rely on this. 2285 // rely on this.
2262 builder() 2286 builder()
2263 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)) 2287 ->LoadLiteral(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))
2264 .StoreAccumulatorInRegister(generator_state_); 2288 .StoreAccumulatorInRegister(generator_state_);
2265 2289
2266 Register input = register_allocator()->NewRegister(); 2290 Register input = register_allocator()->NewRegister();
2267 builder() 2291 if (!kIsAsyncGenerator || expr->yield_type() != Yield::kAwait) {
2268 ->CallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, generator) 2292 builder()
2269 .StoreAccumulatorInRegister(input); 2293 ->CallRuntime(Runtime::kInlineGeneratorGetInputOrDebugPos, generator)
2294 .StoreAccumulatorInRegister(input);
2295 } else {
2296 // When resuming from an Await expression, the sent value is in the
2297 // await input slot.
2298 builder()
2299 ->CallRuntime(Runtime::kInlineAsyncGeneratorGetAwaitInput, generator)
2300 .StoreAccumulatorInRegister(input);
2301 }
2270 2302
2271 Register resume_mode = register_allocator()->NewRegister(); 2303 Register resume_mode = register_allocator()->NewRegister();
2272 builder() 2304 builder()
2273 ->CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator) 2305 ->CallRuntime(Runtime::kInlineGeneratorGetResumeMode, generator)
2274 .StoreAccumulatorInRegister(resume_mode); 2306 .StoreAccumulatorInRegister(resume_mode);
2275 2307
2276 // Now dispatch on resume mode. 2308 // Now dispatch on resume mode.
2277 2309
2278 BytecodeLabel resume_with_next; 2310 BytecodeLabel resume_with_next;
2279 BytecodeLabel resume_with_return; 2311 BytecodeLabel resume_with_return;
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
2881 void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { 2913 void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
2882 FeedbackVectorSlot load_slot = expr->IteratorPropertyFeedbackSlot(); 2914 FeedbackVectorSlot load_slot = expr->IteratorPropertyFeedbackSlot();
2883 FeedbackVectorSlot call_slot = expr->IteratorCallFeedbackSlot(); 2915 FeedbackVectorSlot call_slot = expr->IteratorCallFeedbackSlot();
2884 2916
2885 RegisterList args = register_allocator()->NewRegisterList(1); 2917 RegisterList args = register_allocator()->NewRegisterList(1);
2886 Register method = register_allocator()->NewRegister(); 2918 Register method = register_allocator()->NewRegister();
2887 Register obj = args[0]; 2919 Register obj = args[0];
2888 2920
2889 VisitForAccumulatorValue(expr->iterable()); 2921 VisitForAccumulatorValue(expr->iterable());
2890 2922
2891 // Let method be GetMethod(obj, @@iterator). 2923 if (expr->hint() == GetIterator::kAsync) {
2892 builder() 2924 FeedbackVectorSlot load_slot2 = expr->AsyncIteratorPropertyFeedbackSlot();
2893 ->StoreAccumulatorInRegister(obj) 2925 FeedbackVectorSlot call_slot2 = expr->AsyncIteratorCallFeedbackSlot();
2894 .LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot)) 2926 Register tmp = register_allocator()->NewRegister();
2895 .StoreAccumulatorInRegister(method); 2927 // Set method to GetMethod(obj, @@asyncIterator)
2928 builder()->StoreAccumulatorInRegister(obj).LoadNamedProperty(
2929 obj, async_iterator_symbol(), feedback_index(load_slot2));
2896 2930
2897 // Let iterator be Call(method, obj). 2931 BytecodeLabel async_iterator_undefined, async_iterator_null, done;
2898 builder()->Call(method, args, feedback_index(call_slot), 2932 builder()->JumpIfUndefined(&async_iterator_undefined);
2899 Call::NAMED_PROPERTY_CALL); 2933 builder()->JumpIfNull(&async_iterator_null);
2900 2934
2901 // If Type(iterator) is not Object, throw a TypeError exception. 2935 // Let iterator be Call(method, obj)
2902 BytecodeLabel no_type_error; 2936 builder()->StoreAccumulatorInRegister(method).Call(
2903 builder()->JumpIfJSReceiver(&no_type_error); 2937 method, args, feedback_index(call_slot), Call::NAMED_PROPERTY_CALL);
2904 builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid); 2938
2905 builder()->Bind(&no_type_error); 2939 // If Type(iterator) is not Object, throw a TypeError exception.
2940 builder()->JumpIfJSReceiver(&done);
2941 builder()->CallRuntime(Runtime::kThrowSymbolAsyncIteratorInvalid);
2942
2943 builder()->Bind(&async_iterator_undefined);
2944 builder()->Bind(&async_iterator_null);
2945 // If method is undefined,
2946 // Let syncMethod be GetMethod(obj, @@iterator)
2947 builder()
2948 ->LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot))
2949 .StoreAccumulatorInRegister(method);
2950
2951 // Let syncIterator be Call(syncMethod, obj)
2952 builder()->Call(method, args, feedback_index(call_slot2),
2953 Call::NAMED_PROPERTY_CALL);
2954
2955 // Return CreateAsyncFromSyncIterator(syncIterator)
2956 RegisterList args = register_allocator()->NewRegisterList(1);
2957 Register sync_iterator = args[0];
2958 builder()
2959 ->StoreAccumulatorInRegister(sync_iterator)
2960 .CallRuntime(Runtime::kInlineCreateAsyncFromSyncIterator, args);
2961
2962 builder()->Bind(&done);
2963 } else {
2964 // Let method be GetMethod(obj, @@iterator).
2965 builder()
2966 ->StoreAccumulatorInRegister(obj)
2967 .LoadNamedProperty(obj, iterator_symbol(), feedback_index(load_slot))
2968 .StoreAccumulatorInRegister(method);
2969
2970 // Let iterator be Call(method, obj).
2971 builder()->Call(method, args, feedback_index(call_slot),
2972 Call::NAMED_PROPERTY_CALL);
2973
2974 // If Type(iterator) is not Object, throw a TypeError exception.
2975 BytecodeLabel no_type_error;
2976 builder()->JumpIfJSReceiver(&no_type_error);
2977 builder()->CallRuntime(Runtime::kThrowSymbolIteratorInvalid);
2978 builder()->Bind(&no_type_error);
2979 }
2906 } 2980 }
2907 2981
2908 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { 2982 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) {
2909 builder()->LoadAccumulatorWithRegister(Register::function_closure()); 2983 builder()->LoadAccumulatorWithRegister(Register::function_closure());
2910 } 2984 }
2911 2985
2912 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { 2986 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) {
2913 // Handled by VisitCall(). 2987 // Handled by VisitCall().
2914 UNREACHABLE(); 2988 UNREACHABLE();
2915 } 2989 }
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
3321 } 3395 }
3322 3396
3323 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { 3397 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() {
3324 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict 3398 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
3325 : Runtime::kStoreKeyedToSuper_Sloppy; 3399 : Runtime::kStoreKeyedToSuper_Sloppy;
3326 } 3400 }
3327 3401
3328 } // namespace interpreter 3402 } // namespace interpreter
3329 } // namespace internal 3403 } // namespace internal
3330 } // namespace v8 3404 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-generator.h ('k') | src/interpreter/bytecodes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698