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

Side by Side Diff: src/builtins/builtins-async-iterator.cc

Issue 2645313003: [async-iteration] implement Async-from-Sync Iterator (Closed)
Patch Set: attempt #3 to fix merge conflicts 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/builtins/builtins-async.h ('k') | src/compiler/types.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins-async.h"
6 #include "src/builtins/builtins-utils.h"
7 #include "src/builtins/builtins.h"
8 #include "src/code-factory.h"
9 #include "src/code-stub-assembler.h"
10 #include "src/frames-inl.h"
11
12 namespace v8 {
13 namespace internal {
14
15 // Describe fields of Context associated with the AsyncIterator unwrap closure.
16 class ValueUnwrapContext {
17 public:
18 enum Fields { kDoneSlot = Context::MIN_CONTEXT_SLOTS, kLength };
19 };
20
21 // https://tc39.github.io/proposal-async-iteration/
22 // Section #sec-%asyncfromsynciteratorprototype%.next
23 TF_BUILTIN(AsyncFromSyncIteratorPrototypeNext, AsyncBuiltinsAssembler) {
24 const char* method_str = "[Async-from-Sync Iterator].prototype.next";
25 Handle<String> method_name = factory()->NewStringFromAsciiChecked(method_str);
26
27 Node* const iterator = Parameter(0);
28 Node* const value = Parameter(1);
29 Node* const context = Parameter(4);
30
31 Node* const native_context = LoadNativeContext(context);
32 Node* const promise = AllocateAndInitJSPromise(context);
33
34 Variable var_parent(this, MachineRepresentation::kTagged);
35 Variable var_exception(this, MachineRepresentation::kTagged);
36 var_exception.Bind(UndefinedConstant());
37 Label reject_promise(this, Label::kDeferred);
38 Label if_receiverisincompatible(this, Label::kDeferred);
39
40 GotoIf(TaggedIsSmi(iterator), &if_receiverisincompatible);
41 GotoUnless(HasInstanceType(iterator, JS_ASYNC_FROM_SYNC_ITERATOR_TYPE),
42 &if_receiverisincompatible);
43
44 Node* const sync_iterator =
45 LoadObjectField(iterator, JSAsyncFromSyncIterator::kSyncIteratorOffset);
46
47 // Let nextResult be IteratorNext(syncIterator, value).
48 // IfAbruptRejectPromise(nextResult, promiseCapability).
49 Node* next_method =
50 CallStub(CodeFactory::GetProperty(isolate()), context, sync_iterator,
51 HeapConstant(factory()->next_string()));
52 Node* const iter_result = CallJS(CodeFactory::Call(isolate()), context,
53 next_method, sync_iterator, value);
54 GotoIfException(iter_result, &reject_promise, &var_exception);
55
56 Label if_fastpath(this), if_slowpath(this), merge(this);
57 GotoIf(TaggedIsSmi(iter_result), &if_slowpath);
58
59 Node* const fast_iter_result_map =
jgruber 2017/01/24 16:48:39 This is used a couple of times in this file, can w
caitp 2017/02/15 22:18:00 I've moved the "Load IteratorResult properties" in
60 LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
61 Node* const iter_result_map = LoadMap(iter_result);
62
63 Variable var_value(this, MachineRepresentation::kTagged);
64 Variable var_done(this, MachineRepresentation::kTagged);
65 Branch(WordEqual(iter_result_map, fast_iter_result_map), &if_fastpath,
66 &if_slowpath);
67
68 Bind(&if_fastpath);
69 {
70 var_value.Bind(
71 LoadObjectField(iter_result, JSIteratorResult::kValueOffset));
72 var_done.Bind(LoadObjectField(iter_result, JSIteratorResult::kDoneOffset));
73 Goto(&merge);
74 }
75
76 Bind(&if_slowpath);
77 {
78 Label if_exception(this, Label::kDeferred);
79
80 // Let nextValue be IteratorValue(nextResult).
81 // IfAbruptRejectPromise(nextValue, promiseCapability).
82 Node* const value =
83 CallStub(CodeFactory::GetProperty(isolate()), context, iter_result,
84 HeapConstant(factory()->value_string()));
85 GotoIfException(value, &reject_promise, &var_exception);
86
87 // Let nextDone be IteratorComplete(nextResult).
88 // IfAbruptRejectPromise(nextDone, promiseCapability).
89 Node* const done =
90 CallStub(CodeFactory::GetProperty(isolate()), context, iter_result,
91 HeapConstant(factory()->done_string()));
92 GotoIfException(done, &reject_promise, &var_exception);
93
94 var_value.Bind(value);
95 var_done.Bind(done);
96 Goto(&merge);
97 }
98
99 Bind(&merge);
100
101 // Convert `done` status to a Boolean value if needed.
102 Label to_boolean(this, Label::kDeferred), wrap(this);
103 GotoIf(TaggedIsSmi(var_done.value()), &to_boolean);
jgruber 2017/01/24 16:48:39 Can this ever be needed for the fast path?
caitp 2017/01/24 16:58:36 I'm not sure. Does each ObjectLiteral in source co
caitp 2017/02/15 22:18:00 I'm pretty sure it's safe to trust that the map wi
104 Branch(IsBooleanMap(LoadMap(var_done.value())), &wrap, &to_boolean);
105
106 Bind(&to_boolean);
107 {
108 var_done.Bind(
109 CallStub(CodeFactory::ToBoolean(isolate()), context, var_done.value()));
110 Goto(&wrap);
111 }
112
113 Bind(&wrap);
114 {
115 Node* const value = var_value.value();
116 Node* const done = var_done.value();
117
118 // Let valueWrapperCapability be ! NewPromiseCapability(%Promise%).
119 Node* const wrapper = AllocateAndInitJSPromise(context);
120
121 // Perform ! Call(valueWrapperCapability.[[Resolve]], undefined,
122 // « nextValue »).
123 InternalResolvePromise(context, wrapper, value);
124
125 // Let onFulfilled be a new built-in function object as defined in
126 // Async Iterator Value Unwrap Functions.
127 // Set onFulfilled.[[Done]] to nextDone.
128 Node* const map = LoadContextElement(
jgruber 2017/01/24 16:48:39 Same here, can we extract creation of the closure?
caitp 2017/02/15 22:18:00 Done
129 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
130 Node* const on_resolve_shared = LoadContextElement(
131 native_context, Context::ASYNC_ITERATOR_VALUE_UNWRAP_SHARED_FUN);
132 CSA_ASSERT(this,
133 HasInstanceType(on_resolve_shared, SHARED_FUNCTION_INFO_TYPE));
134 Node* const closure_context =
135 AllocateAsyncIteratorValueUnwrapContext(native_context, done);
136 Node* const on_resolve = AllocateFunctionWithMapAndContext(
137 map, on_resolve_shared, closure_context);
138
139 // Perform ! PerformPromiseThen(valueWrapperCapability.[[Promise]],
140 // onFulfilled, undefined, promiseCapability).
141 Node* const undefined = UndefinedConstant();
142 InternalPerformPromiseThen(context, wrapper, on_resolve, undefined, promise,
143 undefined, undefined);
144
145 // TODO(caitp): Use TailCallStub once it's possible for a JS-linkage builtin
146 // to tailcall a CS-linkage builtin when an arguments adaptor frame is used.
147 Return(promise);
148 }
149
150 Bind(&if_receiverisincompatible);
151 {
152 // If Type(O) is not Object, or if O does not have a [[SyncIterator]]
153 // internal slot, then
154
155 // Let badIteratorError be a new TypeError exception.
156 Node* const make_type_error =
157 LoadContextElement(native_context, Context::MAKE_TYPE_ERROR_INDEX);
jgruber 2017/01/24 16:48:39 This is starting to pop up in several places, mayb
caitp 2017/02/15 22:18:00 I've added one to this CL, I don't think it's too
158 Node* const error =
159 CallJS(CodeFactory::Call(isolate()), context, make_type_error,
160 UndefinedConstant(),
161 SmiConstant(MessageTemplate::kIncompatibleMethodReceiver),
162 HeapConstant(method_name), iterator);
jgruber 2017/01/24 16:48:39 Maybe move method_name and method_str into this sc
caitp 2017/02/15 22:18:00 I'm keeping the c-string near the top of the funct
163
164 // Perform ! Call(promiseCapability.[[Reject]], undefined,
165 // « badIteratorError »).
166 var_exception.Bind(error);
167 Goto(&reject_promise);
168 }
169
170 Bind(&reject_promise);
171 {
172 Node* const promise = AllocateAndInitJSPromise(context);
173 Node* const exception = var_exception.value();
174 InternalPromiseReject(context, promise, exception, TrueConstant());
175
176 // Return promiseCapability.[[Promise]].
177 Return(promise);
178 }
179 }
180
181 // https://tc39.github.io/proposal-async-iteration/
182 // Section #sec-%asyncfromsynciteratorprototype%.return
183 TF_BUILTIN(AsyncFromSyncIteratorPrototypeReturn, AsyncBuiltinsAssembler) {
jgruber 2017/01/24 16:48:39 These 3 functions seem to have very similar struct
caitp 2017/02/15 22:18:00 Maybe, I've made them more concise with the helper
184 const char* method_str = "[Async-from-Sync Iterator].prototype.return";
185 Handle<String> method_name = factory()->NewStringFromAsciiChecked(method_str);
186
187 Node* const iterator = Parameter(0);
188 Node* const value = Parameter(1);
189 Node* const context = Parameter(4);
190
191 Node* const native_context = LoadNativeContext(context);
192 Node* const promise = AllocateAndInitJSPromise(context);
193
194 Variable var_exception(this, MachineRepresentation::kTagged);
195 var_exception.Bind(UndefinedConstant());
196 Label reject_promise(this, Label::kDeferred);
197 Label if_receiverisincompatible(this, Label::kDeferred);
198
199 GotoIf(TaggedIsSmi(iterator), &if_receiverisincompatible);
200 GotoUnless(HasInstanceType(iterator, JS_ASYNC_FROM_SYNC_ITERATOR_TYPE),
201 &if_receiverisincompatible);
202
203 Node* const sync_iterator =
204 LoadObjectField(iterator, JSAsyncFromSyncIterator::kSyncIteratorOffset);
205
206 // Let return be GetMethod(syncIterator, "return").
207 // IfAbruptRejectPromise(return, promiseCapability).
208 Node* const return_method =
209 CallStub(CodeFactory::GetProperty(isolate()), context, sync_iterator,
210 HeapConstant(factory()->return_string()));
211 GotoIfException(return_method, &reject_promise, &var_exception);
212
213 Variable var_value(this, MachineRepresentation::kTagged);
214 Variable var_done(this, MachineRepresentation::kTagged);
215
216 Label if_isundefined(this), if_isnotundefined(this), resolve_promise(this);
217
218 Branch(IsUndefined(return_method), &if_isundefined, &if_isnotundefined);
219 Bind(&if_isundefined);
220 {
221 // If return is undefined, then
222 // Let iterResult be ! CreateIterResultObject(value, true)
223 Node* const iter_result =
224 CallStub(CodeFactory::CreateIterResultObject(isolate()), context, value,
225 TrueConstant());
226
227 // Perform ! Call(promiseCapability.[[Resolve]], undefined, « iterResult »).
228 // IfAbruptRejectPromise(nextDone, promiseCapability).
229 // Return promiseCapability.[[Promise]].
230 PromiseFulfill(context, promise, iter_result, v8::Promise::kFulfilled);
231 Return(promise);
232 }
233
234 Bind(&if_isnotundefined);
235 {
236 // Let returnResult be Call(return, syncIterator, « value »).
237 Node* const iter_result = CallJS(CodeFactory::Call(isolate()), context,
238 return_method, sync_iterator, value);
239 // IfAbruptRejectPromise(returnResult, promiseCapability).
240 GotoIfException(iter_result, &reject_promise, &var_exception);
241 Label if_fastpath(this), if_slowpath(this), merge(this);
242
243 GotoIf(TaggedIsSmi(iter_result), &if_slowpath);
244
245 Node* const fast_iter_result_map =
246 LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
247 Node* const iter_result_map = LoadMap(iter_result);
248
249 Branch(WordEqual(iter_result_map, fast_iter_result_map), &if_fastpath,
250 &if_slowpath);
251
252 Bind(&if_fastpath);
253 {
254 var_value.Bind(
255 LoadObjectField(iter_result, JSIteratorResult::kValueOffset));
256 var_done.Bind(
257 LoadObjectField(iter_result, JSIteratorResult::kDoneOffset));
258 Goto(&merge);
259 }
260
261 Bind(&if_slowpath);
262 {
263 // Let returnValue be IteratorValue(nextResult).
264 // IfAbruptRejectPromise(returnValue, promiseCapability).
265 Node* const value =
266 CallStub(CodeFactory::GetProperty(isolate()), context, iter_result,
267 HeapConstant(factory()->value_string()));
268 GotoIfException(value, &reject_promise, &var_exception);
269
270 // Let returnDone be IteratorComplete(nextResult).
271 // IfAbruptRejectPromise(returnDone, promiseCapability).
272 Node* const done =
273 CallStub(CodeFactory::GetProperty(isolate()), context, iter_result,
274 HeapConstant(factory()->done_string()));
275 GotoIfException(done, &reject_promise, &var_exception);
276
277 var_value.Bind(value);
278 var_done.Bind(done);
279 Goto(&merge);
280 }
281
282 Bind(&merge);
283 {
284 Label to_boolean(this), done(this);
285 GotoIf(TaggedIsSmi(var_done.value()), &to_boolean);
286 Branch(IsBooleanMap(LoadMap(var_done.value())), &done, &to_boolean);
287
288 Bind(&to_boolean);
289 {
290 Node* const result = CallStub(CodeFactory::ToBoolean(isolate()),
291 context, var_done.value());
292 var_done.Bind(result);
293 Goto(&done);
294 }
295
296 Bind(&done);
297 Goto(&resolve_promise);
298 }
299 }
300
301 Bind(&resolve_promise);
302 {
303 // Let valueWrapperCapability be ! NewPromiseCapability(%Promise%).
304 Node* const wrapper = AllocateAndInitJSPromise(context);
305 Node* const value = var_value.value();
306 Node* const done = var_done.value();
307
308 // Perform ! Call(valueWrapperCapability.[[Resolve]], undefined,
309 // « nextValue »).
310 InternalResolvePromise(context, wrapper, value);
311
312 // Let onFulfilled be a new built-in function object as defined in
313 // Async Iterator Value Unwrap Functions.
314 // Set onFulfilled.[[Done]] to nextDone.
315 Node* const map = LoadContextElement(
316 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
317 Node* const on_resolve_shared = LoadContextElement(
318 native_context, Context::ASYNC_ITERATOR_VALUE_UNWRAP_SHARED_FUN);
319 CSA_ASSERT(this,
320 HasInstanceType(on_resolve_shared, SHARED_FUNCTION_INFO_TYPE));
321 Node* const closure_context =
322 AllocateAsyncIteratorValueUnwrapContext(native_context, done);
323 Node* const on_resolve = AllocateFunctionWithMapAndContext(
324 map, on_resolve_shared, closure_context);
325
326 // Perform ! PerformPromiseThen(valueWrapperCapability.[[Promise]],
327 // onFulfilled, undefined, promiseCapability).
328 Node* const undefined = UndefinedConstant();
329 InternalPerformPromiseThen(context, wrapper, on_resolve, undefined, promise,
330 undefined, undefined);
331 Return(promise);
332 }
333
334 Bind(&if_receiverisincompatible);
335 {
336 // If Type(O) is not Object, or if O does not have a [[SyncIterator]]
337 // internal slot, then
338
339 // Let badIteratorError be a new TypeError exception.
340 Node* const make_type_error =
341 LoadContextElement(native_context, Context::MAKE_TYPE_ERROR_INDEX);
342 Node* const error =
343 CallJS(CodeFactory::Call(isolate()), context, make_type_error,
344 UndefinedConstant(),
345 SmiConstant(MessageTemplate::kIncompatibleMethodReceiver),
346 HeapConstant(method_name), iterator);
347
348 // Perform ! Call(promiseCapability.[[Reject]], undefined,
349 // « badIteratorError »).
350 var_exception.Bind(error);
351 Goto(&reject_promise);
352 }
353
354 Bind(&reject_promise);
355 {
356 Node* const exception = var_exception.value();
357 InternalPromiseReject(context, promise, exception, TrueConstant());
358
359 // Return promiseCapability.[[Promise]].
360 Return(promise);
361 }
362 }
363
364 // https://tc39.github.io/proposal-async-iteration/
365 // Section #sec-%asyncfromsynciteratorprototype%.throw
366 TF_BUILTIN(AsyncFromSyncIteratorPrototypeThrow, AsyncBuiltinsAssembler) {
367 const char* method_str = "[Async-from-Sync Iterator].prototype.throw";
368 Handle<String> method_name = factory()->NewStringFromAsciiChecked(method_str);
369
370 Node* const iterator = Parameter(0);
371 Node* const value = Parameter(1);
372 Node* const context = Parameter(4);
373
374 Node* const native_context = LoadNativeContext(context);
375 Node* const promise = AllocateAndInitJSPromise(context);
376
377 Variable var_exception(this, MachineRepresentation::kTagged);
378 var_exception.Bind(value);
379 Variable var_value(this, MachineRepresentation::kTagged);
380 Variable var_done(this, MachineRepresentation::kTagged);
381 Label reject_promise(this, Label::kDeferred);
382 Label if_receiverisincompatible(this, Label::kDeferred);
383
384 GotoIf(TaggedIsSmi(iterator), &if_receiverisincompatible);
385 GotoUnless(HasInstanceType(iterator, JS_ASYNC_FROM_SYNC_ITERATOR_TYPE),
386 &if_receiverisincompatible);
387
388 Node* const sync_iterator =
389 LoadObjectField(iterator, JSAsyncFromSyncIterator::kSyncIteratorOffset);
390
391 // Let throw be GetMethod(syncIterator, "throw").
392 // IfAbruptRejectPromise(nextResult, promiseCapability).
393 // IfAbruptRejectPromise(throw, promiseCapability).
394 Node* const throw_method =
395 CallStub(CodeFactory::GetProperty(isolate()), context, sync_iterator,
396 HeapConstant(factory()->throw_string()));
397 GotoIfException(throw_method, &reject_promise, &var_exception);
398
399 Label if_isnotundefined(this), resolve_promise(this);
400
401 // If throw is undefined, then
402 // Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
403 Branch(IsUndefined(throw_method), &reject_promise, &if_isnotundefined);
404
405 Bind(&if_isnotundefined);
406 {
407 // Let throwResult be Call(throw, syncIterator, « value »).
408 Node* const iter_result = CallJS(CodeFactory::Call(isolate()), context,
409 throw_method, sync_iterator, value);
410 GotoIfException(iter_result, &reject_promise, &var_exception);
411
412 Label if_fastpath(this), if_slowpath(this), merge(this);
413
414 GotoIf(TaggedIsSmi(iter_result), &if_slowpath);
415
416 Node* const fast_iter_result_map =
417 LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
418 Node* const iter_result_map = LoadMap(iter_result);
419
420 Branch(WordEqual(iter_result_map, fast_iter_result_map), &if_fastpath,
421 &if_slowpath);
422
423 Bind(&if_fastpath);
424 {
425 var_value.Bind(
426 LoadObjectField(iter_result, JSIteratorResult::kValueOffset));
427 var_done.Bind(
428 LoadObjectField(iter_result, JSIteratorResult::kDoneOffset));
429 Goto(&merge);
430 }
431
432 Bind(&if_slowpath);
433 {
434 // Let throwValue be IteratorValue(nextResult).
435 // IfAbruptRejectPromise(throwValue, promiseCapability).
436 Node* const value =
437 CallStub(CodeFactory::GetProperty(isolate()), context, iter_result,
438 HeapConstant(factory()->value_string()));
439 GotoIfException(value, &reject_promise, &var_exception);
440
441 // Let throwDone be IteratorComplete(nextResult).
442 // IfAbruptRejectPromise(throwDone, promiseCapability).
443 Node* const done =
444 CallStub(CodeFactory::GetProperty(isolate()), context, iter_result,
445 HeapConstant(factory()->done_string()));
446 GotoIfException(done, &reject_promise, &var_exception);
447
448 var_value.Bind(value);
449 var_done.Bind(done);
450 Goto(&merge);
451 }
452
453 Bind(&merge);
454
455 // Convert `done` status to a Boolean value if needed.
456 Label to_boolean(this, Label::kDeferred), wrap(this);
457 GotoIf(TaggedIsSmi(var_done.value()), &to_boolean);
458 Branch(IsBooleanMap(LoadMap(var_done.value())), &wrap, &to_boolean);
459
460 Bind(&to_boolean);
461 {
462 var_done.Bind(CallStub(CodeFactory::ToBoolean(isolate()), context,
463 var_done.value()));
464 Goto(&wrap);
465 }
466
467 Bind(&wrap);
468 {
469 // Let valueWrapperCapability be ! NewPromiseCapability(%Promise%).
470 Node* const wrapper = AllocateAndInitJSPromise(context);
471 Node* const value = var_value.value();
472 Node* const done = var_done.value();
473
474 // Perform ! Call(valueWrapperCapability.[[Resolve]], undefined, «
475 // throwValue »).
476 InternalResolvePromise(context, wrapper, value);
477
478 // Let onFulfilled be a new built-in function object as defined in
479 // Async Iterator Value Unwrap Functions.
480 // Set onFulfilled.[[Done]] to throwDone.
481 Node* const map = LoadContextElement(
482 native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
483 Node* const on_resolve_shared = LoadContextElement(
484 native_context, Context::ASYNC_ITERATOR_VALUE_UNWRAP_SHARED_FUN);
485 CSA_ASSERT(this,
486 HasInstanceType(on_resolve_shared, SHARED_FUNCTION_INFO_TYPE));
487 Node* const closure_context =
488 AllocateAsyncIteratorValueUnwrapContext(native_context, done);
489 Node* const on_resolve = AllocateFunctionWithMapAndContext(
490 map, on_resolve_shared, closure_context);
491
492 // Perform ! PerformPromiseThen(valueWrapperCapability.[[Promise]],
493 // onFulfilled, undefined, promiseCapability).
494 Node* const undefined = UndefinedConstant();
495 InternalPerformPromiseThen(context, wrapper, on_resolve, undefined,
496 promise, undefined, undefined);
497 Return(promise);
498 }
499 }
500
501 Bind(&if_receiverisincompatible);
502 {
503 // If Type(O) is not Object, or if O does not have a [[SyncIterator]]
504 // internal slot, then
505
506 // Let badIteratorError be a new TypeError exception.
507 Node* const make_type_error =
508 LoadContextElement(native_context, Context::MAKE_TYPE_ERROR_INDEX);
509 Node* const error =
510 CallJS(CodeFactory::Call(isolate()), context, make_type_error,
511 UndefinedConstant(),
512 SmiConstant(MessageTemplate::kIncompatibleMethodReceiver),
513 HeapConstant(method_name), iterator);
514
515 // Perform ! Call(promiseCapability.[[Reject]], undefined,
516 // « badIteratorError »).
517 var_exception.Bind(error);
518 Goto(&reject_promise);
519 }
520
521 Bind(&reject_promise);
522 {
523 Node* const exception = var_exception.value();
524 InternalPromiseReject(context, promise, exception, TrueConstant());
525
526 // Return promiseCapability.[[Promise]].
527 Return(promise);
528 }
529 }
530
531 TF_BUILTIN(AsyncIteratorValueUnwrap, AsyncBuiltinsAssembler) {
532 Node* const value = Parameter(1);
533 Node* const context = Parameter(4);
534
535 Node* const done = LoadContextElement(context, ValueUnwrapContext::kDoneSlot);
536 Node* const unwrapped_value = CallStub(
537 CodeFactory::CreateIterResultObject(isolate()), context, value, done);
538
539 Return(unwrapped_value);
540 }
541
542 Node* AsyncBuiltinsAssembler::AllocateAsyncIteratorValueUnwrapContext(
543 Node* native_context, Node* done) {
544 Node* const context =
545 CreatePromiseContext(native_context, ValueUnwrapContext::kLength);
546 StoreContextElementNoWriteBarrier(context, ValueUnwrapContext::kDoneSlot,
547 done);
548 return context;
549 }
550
551 } // namespace internal
552 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-async.h ('k') | src/compiler/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698