| 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 |