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 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
846 Heap::kUndefinedValueRootIndex); | 846 Heap::kUndefinedValueRootIndex); |
847 StoreObjectFieldRoot(promise, JSPromise::kFulfillReactionsOffset, | 847 StoreObjectFieldRoot(promise, JSPromise::kFulfillReactionsOffset, |
848 Heap::kUndefinedValueRootIndex); | 848 Heap::kUndefinedValueRootIndex); |
849 StoreObjectFieldRoot(promise, JSPromise::kRejectReactionsOffset, | 849 StoreObjectFieldRoot(promise, JSPromise::kRejectReactionsOffset, |
850 Heap::kUndefinedValueRootIndex); | 850 Heap::kUndefinedValueRootIndex); |
851 } | 851 } |
852 } | 852 } |
853 | 853 |
854 // ES#sec-promise-reject-functions | 854 // ES#sec-promise-reject-functions |
855 // Promise Reject Functions | 855 // Promise Reject Functions |
856 BUILTIN(PromiseRejectClosure) { | 856 TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) { |
857 HandleScope scope(isolate); | 857 Node* const value = Parameter(1); |
858 Node* const context = Parameter(4); | |
858 | 859 |
859 Handle<Context> context(isolate->context(), isolate); | 860 Label out(this); |
860 | 861 |
861 if (PromiseUtils::HasAlreadyVisited(context)) { | 862 // 3. Let alreadyResolved be F.[[AlreadyResolved]]. |
862 return isolate->heap()->undefined_value(); | 863 Node* const has_already_visited_slot = |
863 } | 864 IntPtrConstant(PromiseUtils::kAlreadyVisitedSlot); |
864 | 865 |
865 PromiseUtils::SetAlreadyVisited(context); | 866 Node* const has_already_visited = |
866 Handle<Object> value = args.atOrUndefined(isolate, 1); | 867 LoadFixedArrayElement(context, has_already_visited_slot); |
Igor Sheludko
2017/01/06 17:26:25
LoadContextElement
gsathya
2017/01/06 19:20:49
Done.
| |
867 Handle<JSObject> promise = handle(PromiseUtils::GetPromise(context), isolate); | 868 |
868 Handle<Object> debug_event = | 869 // 4. If alreadyResolved.[[Value]] is true, return undefined. |
869 handle(PromiseUtils::GetDebugEvent(context), isolate); | 870 GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out); |
Igor Sheludko
2017/01/06 17:26:25
Nit: this should be
GotoUnless(SmiEqual(..., Sm
gsathya
2017/01/06 19:20:49
Leaving as such to match PromiseResolveClosure imp
| |
870 MaybeHandle<Object> maybe_result; | 871 |
871 Handle<Object> argv[] = {promise, value, debug_event}; | 872 // 5.Set alreadyResolved.[[Value]] to true. |
872 RETURN_FAILURE_ON_EXCEPTION( | 873 StoreFixedArrayElement(context, has_already_visited_slot, SmiConstant(1)); |
Igor Sheludko
2017/01/06 17:26:25
StoreContextElementNoWriteBarrier
gsathya
2017/01/06 19:20:49
Done.
| |
873 isolate, Execution::Call(isolate, isolate->promise_internal_reject(), | 874 |
874 isolate->factory()->undefined_value(), | 875 // 2. Let promise be F.[[Promise]]. |
875 arraysize(argv), argv)); | 876 Node* const promise = LoadFixedArrayElement( |
Igor Sheludko
2017/01/06 17:26:25
LoadContextElement
gsathya
2017/01/06 19:20:49
Done.
| |
876 return isolate->heap()->undefined_value(); | 877 context, IntPtrConstant(PromiseUtils::kPromiseSlot)); |
878 Node* const debug_event = LoadFixedArrayElement( | |
Igor Sheludko
2017/01/06 17:26:25
Same here.
gsathya
2017/01/06 19:20:49
Done.
| |
879 context, IntPtrConstant(PromiseUtils::kDebugEventSlot)); | |
880 | |
881 CallRuntime(Runtime::kPromiseReject, context, promise, value, debug_event); | |
882 Return(UndefinedConstant()); | |
883 | |
884 Bind(&out); | |
885 Return(UndefinedConstant()); | |
877 } | 886 } |
878 | 887 |
879 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { | 888 TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) { |
880 Node* const executor = Parameter(1); | 889 Node* const executor = Parameter(1); |
881 Node* const new_target = Parameter(2); | 890 Node* const new_target = Parameter(2); |
882 Node* const context = Parameter(4); | 891 Node* const context = Parameter(4); |
883 Isolate* isolate = this->isolate(); | 892 Isolate* isolate = this->isolate(); |
884 | 893 |
885 Label if_targetisundefined(this, Label::kDeferred); | 894 Label if_targetisundefined(this, Label::kDeferred); |
886 | 895 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
985 Return(UndefinedConstant()); // Never reached. | 994 Return(UndefinedConstant()); // Never reached. |
986 } | 995 } |
987 } | 996 } |
988 | 997 |
989 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { | 998 TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) { |
990 Node* const parent = Parameter(1); | 999 Node* const parent = Parameter(1); |
991 Node* const context = Parameter(4); | 1000 Node* const context = Parameter(4); |
992 Return(AllocateAndInitJSPromise(context, parent)); | 1001 Return(AllocateAndInitJSPromise(context, parent)); |
993 } | 1002 } |
994 | 1003 |
995 TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) { | |
996 Node* const status = Parameter(1); | |
997 Node* const result = Parameter(2); | |
998 Node* const context = Parameter(5); | |
999 | |
1000 Node* const instance = AllocateAndSetJSPromise(context, status, result); | |
1001 Return(instance); | |
1002 } | |
1003 | |
1004 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { | 1004 TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) { |
1005 Node* const maybe_promise = Parameter(1); | 1005 Node* const maybe_promise = Parameter(1); |
1006 Label if_notpromise(this, Label::kDeferred); | 1006 Label if_notpromise(this, Label::kDeferred); |
1007 | 1007 |
1008 GotoIf(TaggedIsSmi(maybe_promise), &if_notpromise); | 1008 GotoIf(TaggedIsSmi(maybe_promise), &if_notpromise); |
1009 | 1009 |
1010 Node* const result = | 1010 Node* const result = |
1011 SelectBooleanConstant(HasInstanceType(maybe_promise, JS_PROMISE_TYPE)); | 1011 SelectBooleanConstant(HasInstanceType(maybe_promise, JS_PROMISE_TYPE)); |
1012 Return(result); | 1012 Return(result); |
1013 | 1013 |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1350 TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) { | 1350 TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) { |
1351 Node* constructor = Parameter(1); | 1351 Node* constructor = Parameter(1); |
1352 Node* debug_event = Parameter(2); | 1352 Node* debug_event = Parameter(2); |
1353 Node* context = Parameter(5); | 1353 Node* context = Parameter(5); |
1354 | 1354 |
1355 CSA_ASSERT_JS_ARGC_EQ(this, 2); | 1355 CSA_ASSERT_JS_ARGC_EQ(this, 2); |
1356 | 1356 |
1357 Return(NewPromiseCapability(context, constructor, debug_event)); | 1357 Return(NewPromiseCapability(context, constructor, debug_event)); |
1358 } | 1358 } |
1359 | 1359 |
1360 TF_BUILTIN(PromiseReject, PromiseBuiltinsAssembler) { | |
1361 // 1. Let C be the this value. | |
1362 Node* const receiver = Parameter(0); | |
1363 Node* const reason = Parameter(1); | |
1364 Node* const context = Parameter(4); | |
1365 | |
1366 // 2. If Type(C) is not Object, throw a TypeError exception. | |
1367 ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject, | |
1368 "PromiseReject"); | |
1369 | |
1370 Label if_nativepromise(this), if_custompromise(this, Label::kDeferred); | |
1371 Node* const native_context = LoadNativeContext(context); | |
1372 Node* const promise_fun = | |
1373 LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); | |
1374 Branch(WordEqual(promise_fun, receiver), &if_nativepromise, | |
1375 &if_custompromise); | |
1376 | |
1377 Bind(&if_nativepromise); | |
1378 { | |
1379 Node* const promise = AllocateAndSetJSPromise( | |
1380 context, SmiConstant(v8::Promise::kRejected), reason); | |
1381 CallRuntime(Runtime::kPromiseRejectEventFromStack, context, promise, | |
1382 reason); | |
1383 Return(promise); | |
1384 } | |
1385 | |
1386 Bind(&if_custompromise); | |
1387 { | |
1388 // 3. Let promiseCapability be ? NewPromiseCapability(C). | |
1389 Node* const capability = NewPromiseCapability(context, receiver); | |
1390 | |
1391 // 4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »). | |
1392 Node* const reject = | |
1393 LoadObjectField(capability, JSPromiseCapability::kRejectOffset); | |
1394 Callable call_callable = CodeFactory::Call(isolate()); | |
1395 CallJS(call_callable, context, reject, UndefinedConstant(), reason); | |
1396 | |
1397 // 5. Return promiseCapability.[[Promise]]. | |
1398 Node* const promise = | |
1399 LoadObjectField(capability, JSPromiseCapability::kPromiseOffset); | |
1400 Return(promise); | |
1401 } | |
1402 } | |
1403 | |
1360 } // namespace internal | 1404 } // namespace internal |
1361 } // namespace v8 | 1405 } // namespace v8 |
OLD | NEW |