 Chromium Code Reviews
 Chromium Code Reviews Issue 2622833002:
  WIP [esnext] implement async iteration proposal  (Closed)
    
  
    Issue 2622833002:
  WIP [esnext] implement async iteration proposal  (Closed) 
  | Index: src/bootstrapper.cc | 
| diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc | 
| index c99cadc481d0718e3bda6ee5b55c836e68392063..f60ad55d31dc722e89869ff6551f54e1b5c58083 100644 | 
| --- a/src/bootstrapper.cc | 
| +++ b/src/bootstrapper.cc | 
| @@ -169,6 +169,7 @@ class Genesis BASE_EMBEDDED { | 
| void CreateStrictModeFunctionMaps(Handle<JSFunction> empty); | 
| void CreateIteratorMaps(Handle<JSFunction> empty); | 
| + void CreateAsyncIteratorMaps(Handle<JSFunction> empty); | 
| void CreateAsyncFunctionMaps(Handle<JSFunction> empty); | 
| void CreateJSProxyMaps(); | 
| @@ -781,6 +782,129 @@ void Genesis::CreateIteratorMaps(Handle<JSFunction> empty) { | 
| *generator_object_prototype_map); | 
| } | 
| +static void InstallWithIntrinsicDefaultProto(Isolate* isolate, | 
| + Handle<JSFunction> function, | 
| + int context_index) { | 
| + Handle<Smi> index(Smi::FromInt(context_index), isolate); | 
| + JSObject::AddProperty( | 
| + function, isolate->factory()->native_context_index_symbol(), index, NONE); | 
| + isolate->native_context()->set(context_index, *function); | 
| +} | 
| + | 
| +void Genesis::CreateAsyncIteratorMaps(Handle<JSFunction> empty) { | 
| + // Create iterator-related meta-objects. | 
| + Handle<JSObject> async_iterator_prototype = | 
| + factory()->NewJSObject(isolate()->object_function(), TENURED); | 
| + | 
| + Handle<JSFunction> async_iterator_prototype_iterator = SimpleCreateFunction( | 
| + isolate(), factory()->NewStringFromAsciiChecked("[Symbol.asyncIterator]"), | 
| + Builtins::kReturnReceiver, 0, true); | 
| + async_iterator_prototype_iterator->shared()->set_native(true); | 
| + | 
| + JSObject::AddProperty(async_iterator_prototype, | 
| + factory()->async_iterator_symbol(), | 
| + async_iterator_prototype_iterator, DONT_ENUM); | 
| + | 
| + Handle<JSObject> async_from_sync_iterator_prototype = | 
| + factory()->NewJSObject(isolate()->object_function(), TENURED); | 
| + SimpleInstallFunction(async_from_sync_iterator_prototype, | 
| + factory()->next_string(), | 
| + Builtins::kAsyncFromSyncIteratorPrototypeNext, 1, true); | 
| + SimpleInstallFunction( | 
| + async_from_sync_iterator_prototype, factory()->return_string(), | 
| + Builtins::kAsyncFromSyncIteratorPrototypeReturn, 1, true); | 
| + SimpleInstallFunction( | 
| + async_from_sync_iterator_prototype, factory()->throw_string(), | 
| + Builtins::kAsyncFromSyncIteratorPrototypeThrow, 1, true); | 
| + | 
| + JSObject::AddProperty( | 
| + async_from_sync_iterator_prototype, factory()->to_string_tag_symbol(), | 
| + factory()->NewStringFromAsciiChecked("Async-from-Sync Iterator"), | 
| + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); | 
| + | 
| + JSObject::ForceSetPrototype(async_from_sync_iterator_prototype, | 
| + async_iterator_prototype); | 
| + | 
| + Handle<Map> async_from_sync_iterator_map = factory()->NewMap( | 
| + JS_ASYNC_FROM_SYNC_ITERATOR_TYPE, JSAsyncFromSyncIterator::kSize); | 
| + Map::SetPrototype(async_from_sync_iterator_map, | 
| + async_from_sync_iterator_prototype); | 
| + native_context()->set_initial_async_from_sync_iterator_map( | 
| + *async_from_sync_iterator_map); | 
| + | 
| + Handle<String> AsyncGeneratorFunction_string = | 
| + factory()->NewStringFromAsciiChecked("AsyncGeneratorFunction", TENURED); | 
| + | 
| + static const bool kUseStrictFunctionMap = true; | 
| + Handle<JSObject> async_generator_object_prototype = | 
| + factory()->NewJSObject(isolate()->object_function(), TENURED); | 
| + Handle<JSObject> async_generator_function_prototype = | 
| + factory()->NewJSObject(isolate()->object_function(), TENURED); | 
| + | 
| + Handle<JSFunction> async_generator_function = SimpleCreateFunction( | 
| + isolate(), AsyncGeneratorFunction_string, | 
| + Builtins::kAsyncGeneratorFunctionConstructor, 1, false); | 
| + InstallWithIntrinsicDefaultProto( | 
| + isolate(), async_generator_function, | 
| + Context::ASYNC_GENERATOR_FUNCTION_FUNCTION_INDEX); | 
| + | 
| + // %AsyncGenerator% / %AsyncGeneratorFunction%.prototype | 
| + JSObject::ForceSetPrototype(async_generator_function_prototype, empty); | 
| + JSObject::AddProperty(async_generator_function_prototype, | 
| + factory()->constructor_string(), | 
| + async_generator_function, | 
| + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); | 
| + JSObject::AddProperty(async_generator_function_prototype, | 
| + factory()->prototype_string(), | 
| + async_generator_object_prototype, | 
| + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); | 
| + JSObject::AddProperty(async_generator_function_prototype, | 
| + factory()->to_string_tag_symbol(), | 
| + AsyncGeneratorFunction_string, | 
| + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); | 
| + | 
| + // %AsyncGeneratorPrototype% | 
| + JSObject::ForceSetPrototype(async_generator_object_prototype, | 
| + async_iterator_prototype); | 
| + | 
| + JSObject::AddProperty(async_generator_object_prototype, | 
| + factory()->constructor_string(), | 
| + async_generator_function, | 
| + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); | 
| + JSObject::AddProperty(async_generator_object_prototype, | 
| + factory()->to_string_tag_symbol(), | 
| + factory()->NewStringFromAsciiChecked("AsyncGenerator"), | 
| + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY)); | 
| + SimpleInstallFunction(async_generator_object_prototype, "next", | 
| + Builtins::kAsyncGeneratorPrototypeNext, 1, true); | 
| + SimpleInstallFunction(async_generator_object_prototype, "return", | 
| + Builtins::kAsyncGeneratorPrototypeReturn, 1, true); | 
| + SimpleInstallFunction(async_generator_object_prototype, "throw", | 
| + Builtins::kAsyncGeneratorPrototypeThrow, 1, true); | 
| + | 
| + // Create maps for async generator functions and their prototypes. Store those | 
| + // maps in the native context. The "prototype" property descriptor is | 
| + // writable, non-enumerable, and non-configurable. | 
| + Handle<Map> strict_function_map(strict_function_map_writable_prototype_); | 
| + | 
| + // Async Generator functions do not have "caller" or "arguments" accessors in | 
| + // either sloppy mode or strict mode. | 
| + Handle<Map> async_generator_function_map = | 
| + Map::Copy(strict_function_map, "AsyncGeneratorFunction"); | 
| + async_generator_function_map->set_is_constructor(false); | 
| + Map::SetPrototype(async_generator_function_map, | 
| + async_generator_function_prototype); | 
| + native_context()->set_async_generator_function_map( | 
| + *async_generator_function_map); | 
| + | 
| + Handle<JSFunction> object_function(native_context()->object_function()); | 
| + Handle<Map> async_generator_object_prototype_map = Map::Create(isolate(), 0); | 
| + Map::SetPrototype(async_generator_object_prototype_map, | 
| + async_generator_object_prototype); | 
| + native_context()->set_async_generator_object_prototype_map( | 
| + *async_generator_object_prototype_map); | 
| +} | 
| + | 
| void Genesis::CreateAsyncFunctionMaps(Handle<JSFunction> empty) { | 
| // %AsyncFunctionPrototype% intrinsic | 
| Handle<JSObject> async_function_prototype = | 
| @@ -1034,15 +1158,6 @@ void Genesis::HookUpGlobalObject(Handle<JSGlobalObject> global_object) { | 
| TransferIndexedProperties(global_object_from_snapshot, global_object); | 
| } | 
| -static void InstallWithIntrinsicDefaultProto(Isolate* isolate, | 
| - Handle<JSFunction> function, | 
| - int context_index) { | 
| - Handle<Smi> index(Smi::FromInt(context_index), isolate); | 
| - JSObject::AddProperty( | 
| - function, isolate->factory()->native_context_index_symbol(), index, NONE); | 
| - isolate->native_context()->set(context_index, *function); | 
| -} | 
| - | 
| static void InstallError(Isolate* isolate, Handle<JSObject> global, | 
| Handle<String> name, int context_index) { | 
| Factory* factory = isolate->factory(); | 
| @@ -1291,6 +1406,69 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, | 
| class_function_map_->SetConstructor(*function_fun); | 
| } | 
| + { | 
| + // --- A s y n c F r o m S y n c I t e r a t o r | 
| + Handle<Code> code = handle( | 
| + isolate->builtins()->builtin(Builtins::kAsyncIteratorValueUnwrap), | 
| 
jgruber
2017/01/13 13:34:34
Nit: isolate->builtins()->AsyncIteratorValueUnwrap
 
caitp
2017/01/13 14:36:03
Acknowledged.
 
caitp
2017/01/17 19:23:11
Done.
 | 
| + isolate); | 
| + Handle<SharedFunctionInfo> info = | 
| + factory->NewSharedFunctionInfo(factory->empty_string(), code, false); | 
| + info->set_internal_formal_parameter_count(1); | 
| + info->set_length(1); | 
| + native_context()->set_async_iterator_value_unwrap_shared_fun(*info); | 
| + } | 
| + | 
| + { // --- A s y n c G e n e r a t o r --- | 
| + Handle<JSFunction> async_generator_function( | 
| + native_context()->async_generator_function_function(), isolate); | 
| + Handle<JSFunction> function_fun(native_context()->function_function(), | 
| + isolate); | 
| + JSObject::ForceSetPrototype(async_generator_function, function_fun); | 
| + | 
| + async_generator_function->set_prototype_or_initial_map( | 
| + native_context()->async_generator_function_map()); | 
| + async_generator_function->shared()->SetConstructStub( | 
| + *isolate->builtins()->AsyncGeneratorFunctionConstructor()); | 
| + native_context()->async_generator_function_map()->SetConstructor( | 
| + *async_generator_function); | 
| + | 
| + Handle<JSFunction> await_caught = | 
| + SimpleCreateFunction(isolate, factory->empty_string(), | 
| + Builtins::kAsyncGeneratorAwaitCaught, 2, false); | 
| + InstallWithIntrinsicDefaultProto(isolate, await_caught, | 
| + Context::ASYNC_GENERATOR_AWAIT_CAUGHT); | 
| + | 
| + Handle<JSFunction> await_uncaught = | 
| + SimpleCreateFunction(isolate, factory->empty_string(), | 
| + Builtins::kAsyncGeneratorAwaitUncaught, 2, false); | 
| + InstallWithIntrinsicDefaultProto(isolate, await_uncaught, | 
| + Context::ASYNC_GENERATOR_AWAIT_UNCAUGHT); | 
| + | 
| + Handle<JSFunction> yield = | 
| + SimpleCreateFunction(isolate, factory->empty_string(), | 
| + Builtins::kAsyncGeneratorYield, 2, false); | 
| + InstallWithIntrinsicDefaultProto(isolate, yield, | 
| + Context::ASYNC_GENERATOR_YIELD); | 
| + | 
| + Handle<Code> code = | 
| + handle(isolate->builtins()->builtin( | 
| + Builtins::kAsyncGeneratorAwaitResolveClosure), | 
| 
jgruber
2017/01/13 13:34:33
Same here and below.
 
caitp
2017/01/17 19:23:11
Done.
 | 
| + isolate); | 
| + Handle<SharedFunctionInfo> info = | 
| + factory->NewSharedFunctionInfo(factory->empty_string(), code, false); | 
| + info->set_internal_formal_parameter_count(1); | 
| + info->set_length(1); | 
| + native_context()->set_async_generator_await_resolve_shared_fun(*info); | 
| + | 
| + code = handle(isolate->builtins()->builtin( | 
| + Builtins::kAsyncGeneratorAwaitRejectClosure), | 
| + isolate); | 
| + info = factory->NewSharedFunctionInfo(factory->empty_string(), code, false); | 
| + info->set_internal_formal_parameter_count(1); | 
| + info->set_length(1); | 
| + native_context()->set_async_generator_await_reject_shared_fun(*info); | 
| + } | 
| + | 
| { // --- A r r a y --- | 
| Handle<JSFunction> array_function = | 
| InstallFunction(global, "Array", JS_ARRAY_TYPE, JSArray::kSize, | 
| @@ -3446,6 +3624,7 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrictive_generators) | 
| EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_trailing_commas) | 
| EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_class_fields) | 
| EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_spread) | 
| +EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_async_iteration) | 
| void InstallPublicSymbol(Factory* factory, Handle<Context> native_context, | 
| const char* name, Handle<Symbol> value) { | 
| @@ -4006,6 +4185,7 @@ bool Genesis::InstallExperimentalNatives() { | 
| static const char* harmony_trailing_commas_natives[] = {nullptr}; | 
| static const char* harmony_class_fields_natives[] = {nullptr}; | 
| static const char* harmony_object_spread_natives[] = {nullptr}; | 
| + static const char* harmony_async_iteration_natives[] = {nullptr}; | 
| for (int i = ExperimentalNatives::GetDebuggerCount(); | 
| i < ExperimentalNatives::GetBuiltinsCount(); i++) { | 
| @@ -4607,6 +4787,7 @@ Genesis::Genesis( | 
| Handle<JSFunction> empty_function = CreateEmptyFunction(isolate); | 
| CreateStrictModeFunctionMaps(empty_function); | 
| CreateIteratorMaps(empty_function); | 
| + CreateAsyncIteratorMaps(empty_function); | 
| CreateAsyncFunctionMaps(empty_function); | 
| Handle<JSGlobalObject> global_object = | 
| CreateNewGlobals(global_proxy_template, global_proxy); |