OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 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 | 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/builtins/builtins-promise.h" | 5 #include "src/builtins/builtins-promise.h" |
6 #include "src/builtins/builtins-constructor.h" | 6 #include "src/builtins/builtins-constructor.h" |
7 #include "src/builtins/builtins-utils.h" | 7 #include "src/builtins/builtins-utils.h" |
8 #include "src/builtins/builtins.h" | 8 #include "src/builtins/builtins.h" |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stub-assembler.h" | 10 #include "src/code-stub-assembler.h" |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset, new_flags); | 273 StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset, new_flags); |
274 } | 274 } |
275 | 275 |
276 Node* PromiseBuiltinsAssembler::SpeciesConstructor(Node* context, Node* object, | 276 Node* PromiseBuiltinsAssembler::SpeciesConstructor(Node* context, Node* object, |
277 Node* default_constructor) { | 277 Node* default_constructor) { |
278 Isolate* isolate = this->isolate(); | 278 Isolate* isolate = this->isolate(); |
279 Variable var_result(this, MachineRepresentation::kTagged); | 279 Variable var_result(this, MachineRepresentation::kTagged); |
280 var_result.Bind(default_constructor); | 280 var_result.Bind(default_constructor); |
281 | 281 |
282 // 2. Let C be ? Get(O, "constructor"). | 282 // 2. Let C be ? Get(O, "constructor"). |
283 Node* const constructor_str = | |
284 HeapConstant(isolate->factory()->constructor_string()); | |
285 Callable getproperty_callable = CodeFactory::GetProperty(isolate); | |
286 Node* const constructor = | 283 Node* const constructor = |
287 CallStub(getproperty_callable, context, object, constructor_str); | 284 GetProperty(context, object, isolate->factory()->constructor_string()); |
288 | 285 |
289 // 3. If C is undefined, return defaultConstructor. | 286 // 3. If C is undefined, return defaultConstructor. |
290 Label out(this); | 287 Label out(this); |
291 GotoIf(IsUndefined(constructor), &out); | 288 GotoIf(IsUndefined(constructor), &out); |
292 | 289 |
293 // 4. If Type(C) is not Object, throw a TypeError exception. | 290 // 4. If Type(C) is not Object, throw a TypeError exception. |
294 ThrowIfNotJSReceiver(context, constructor, | 291 ThrowIfNotJSReceiver(context, constructor, |
295 MessageTemplate::kConstructorNotReceiver); | 292 MessageTemplate::kConstructorNotReceiver); |
296 | 293 |
297 // 5. Let S be ? Get(C, @@species). | 294 // 5. Let S be ? Get(C, @@species). |
298 Node* const species_symbol = | |
299 HeapConstant(isolate->factory()->species_symbol()); | |
300 Node* const species = | 295 Node* const species = |
301 CallStub(getproperty_callable, context, constructor, species_symbol); | 296 GetProperty(context, constructor, isolate->factory()->species_symbol()); |
302 | 297 |
303 // 6. If S is either undefined or null, return defaultConstructor. | 298 // 6. If S is either undefined or null, return defaultConstructor. |
304 GotoIf(IsUndefined(species), &out); | 299 GotoIf(IsUndefined(species), &out); |
305 GotoIf(WordEqual(species, NullConstant()), &out); | 300 GotoIf(WordEqual(species, NullConstant()), &out); |
306 | 301 |
307 // 7. If IsConstructor(S) is true, return S. | 302 // 7. If IsConstructor(S) is true, return S. |
308 Label throw_error(this); | 303 Label throw_error(this); |
309 Node* species_bitfield = LoadMapBitField(LoadMap(species)); | 304 Node* species_bitfield = LoadMapBitField(LoadMap(species)); |
310 GotoIfNot(Word32Equal(Word32And(species_bitfield, | 305 GotoIfNot(Word32Equal(Word32And(species_bitfield, |
311 Int32Constant((1 << Map::kIsConstructor))), | 306 Int32Constant((1 << Map::kIsConstructor))), |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 InternalPromiseReject(context, promise, thenable_value, false); | 741 InternalPromiseReject(context, promise, thenable_value, false); |
747 PromiseSetHasHandler(result); | 742 PromiseSetHasHandler(result); |
748 Goto(&out); | 743 Goto(&out); |
749 } | 744 } |
750 } | 745 } |
751 } | 746 } |
752 | 747 |
753 Bind(&if_notnativepromise); | 748 Bind(&if_notnativepromise); |
754 { | 749 { |
755 // 8. Let then be Get(resolution, "then"). | 750 // 8. Let then be Get(resolution, "then"). |
756 Node* const then_str = HeapConstant(isolate->factory()->then_string()); | |
757 Callable getproperty_callable = CodeFactory::GetProperty(isolate); | |
758 Node* const then = | 751 Node* const then = |
759 CallStub(getproperty_callable, context, result, then_str); | 752 GetProperty(context, result, isolate->factory()->then_string()); |
760 | 753 |
761 // 9. If then is an abrupt completion, then | 754 // 9. If then is an abrupt completion, then |
762 GotoIfException(then, &if_rejectpromise, &var_reason); | 755 GotoIfException(then, &if_rejectpromise, &var_reason); |
763 | 756 |
764 // 11. If IsCallable(thenAction) is false, then | 757 // 11. If IsCallable(thenAction) is false, then |
765 GotoIf(TaggedIsSmi(then), &fulfill); | 758 GotoIf(TaggedIsSmi(then), &fulfill); |
766 Node* const then_map = LoadMap(then); | 759 Node* const then_map = LoadMap(then); |
767 GotoIfNot(IsCallableMap(then_map), &fulfill); | 760 GotoIfNot(IsCallableMap(then_map), &fulfill); |
768 var_then.Bind(then); | 761 var_then.Bind(then); |
769 Goto(&do_enqueue); | 762 Goto(&do_enqueue); |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 | 1353 |
1361 Bind(&if_internalthen); | 1354 Bind(&if_internalthen); |
1362 { | 1355 { |
1363 Node* const result = | 1356 Node* const result = |
1364 InternalPromiseThen(context, promise, on_resolve, on_reject); | 1357 InternalPromiseThen(context, promise, on_resolve, on_reject); |
1365 Return(result); | 1358 Return(result); |
1366 } | 1359 } |
1367 | 1360 |
1368 Bind(&if_customthen); | 1361 Bind(&if_customthen); |
1369 { | 1362 { |
1370 Isolate* isolate = this->isolate(); | |
1371 Node* const then_str = HeapConstant(isolate->factory()->then_string()); | |
1372 Callable getproperty_callable = CodeFactory::GetProperty(isolate); | |
1373 Node* const then = | 1363 Node* const then = |
1374 CallStub(getproperty_callable, context, promise, then_str); | 1364 GetProperty(context, promise, isolate()->factory()->then_string()); |
1375 Callable call_callable = CodeFactory::Call(isolate); | 1365 Callable call_callable = CodeFactory::Call(isolate()); |
1376 Node* const result = | 1366 Node* const result = |
1377 CallJS(call_callable, context, then, promise, on_resolve, on_reject); | 1367 CallJS(call_callable, context, then, promise, on_resolve, on_reject); |
1378 Return(result); | 1368 Return(result); |
1379 } | 1369 } |
1380 } | 1370 } |
1381 | 1371 |
1382 TF_BUILTIN(PromiseResolve, PromiseBuiltinsAssembler) { | 1372 TF_BUILTIN(PromiseResolve, PromiseBuiltinsAssembler) { |
1383 // 1. Let C be the this value. | 1373 // 1. Let C be the this value. |
1384 Node* receiver = Parameter(0); | 1374 Node* receiver = Parameter(0); |
1385 Node* value = Parameter(1); | 1375 Node* value = Parameter(1); |
(...skipping 27 matching lines...) Expand all Loading... |
1413 GotoIfNot(WordEqual(promise_fun, receiver), &if_valueisnotnativepromise); | 1403 GotoIfNot(WordEqual(promise_fun, receiver), &if_valueisnotnativepromise); |
1414 Return(value); | 1404 Return(value); |
1415 } | 1405 } |
1416 | 1406 |
1417 // At this point, value or/and receiver are not native promises, but | 1407 // At this point, value or/and receiver are not native promises, but |
1418 // they could be of the same subclass. | 1408 // they could be of the same subclass. |
1419 Bind(&if_valueisnotnativepromise); | 1409 Bind(&if_valueisnotnativepromise); |
1420 { | 1410 { |
1421 // 3.a Let xConstructor be ? Get(x, "constructor"). | 1411 // 3.a Let xConstructor be ? Get(x, "constructor"). |
1422 // The constructor lookup is observable. | 1412 // The constructor lookup is observable. |
1423 Node* const constructor_str = | |
1424 HeapConstant(isolate->factory()->constructor_string()); | |
1425 Callable getproperty_callable = CodeFactory::GetProperty(isolate); | |
1426 Node* const constructor = | 1413 Node* const constructor = |
1427 CallStub(getproperty_callable, context, value, constructor_str); | 1414 GetProperty(context, value, isolate->factory()->constructor_string()); |
1428 | 1415 |
1429 // 3.b If SameValue(xConstructor, C) is true, return x. | 1416 // 3.b If SameValue(xConstructor, C) is true, return x. |
1430 GotoIfNot(SameValue(constructor, receiver), &if_valueisnotpromise); | 1417 GotoIfNot(SameValue(constructor, receiver), &if_valueisnotpromise); |
1431 | 1418 |
1432 Return(value); | 1419 Return(value); |
1433 } | 1420 } |
1434 | 1421 |
1435 Bind(&if_valueisnotpromise); | 1422 Bind(&if_valueisnotpromise); |
1436 { | 1423 { |
1437 Label if_nativepromise(this), if_notnativepromise(this); | 1424 Label if_nativepromise(this), if_notnativepromise(this); |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1753 { | 1740 { |
1754 Node* deferred_promise = AllocateAndInitJSPromise(context, promise); | 1741 Node* deferred_promise = AllocateAndInitJSPromise(context, promise); |
1755 InternalPerformPromiseThen(context, promise, var_then_finally.value(), | 1742 InternalPerformPromiseThen(context, promise, var_then_finally.value(), |
1756 var_catch_finally.value(), deferred_promise, | 1743 var_catch_finally.value(), deferred_promise, |
1757 UndefinedConstant(), UndefinedConstant()); | 1744 UndefinedConstant(), UndefinedConstant()); |
1758 Return(deferred_promise); | 1745 Return(deferred_promise); |
1759 } | 1746 } |
1760 | 1747 |
1761 Bind(&if_custompromise); | 1748 Bind(&if_custompromise); |
1762 { | 1749 { |
1763 Isolate* isolate = this->isolate(); | |
1764 Node* const then_str = HeapConstant(isolate->factory()->then_string()); | |
1765 Callable getproperty_callable = CodeFactory::GetProperty(isolate); | |
1766 Node* const then = | 1750 Node* const then = |
1767 CallStub(getproperty_callable, context, promise, then_str); | 1751 GetProperty(context, promise, isolate()->factory()->then_string()); |
1768 Callable call_callable = CodeFactory::Call(isolate); | 1752 Callable call_callable = CodeFactory::Call(isolate()); |
1769 // 5. Return ? Invoke(promise, "then", « thenFinally, catchFinally »). | 1753 // 5. Return ? Invoke(promise, "then", « thenFinally, catchFinally »). |
1770 Node* const result = | 1754 Node* const result = |
1771 CallJS(call_callable, context, then, promise, var_then_finally.value(), | 1755 CallJS(call_callable, context, then, promise, var_then_finally.value(), |
1772 var_catch_finally.value()); | 1756 var_catch_finally.value()); |
1773 Return(result); | 1757 Return(result); |
1774 } | 1758 } |
1775 } | 1759 } |
1776 | 1760 |
1777 } // namespace internal | 1761 } // namespace internal |
1778 } // namespace v8 | 1762 } // namespace v8 |
OLD | NEW |