Chromium Code Reviews| 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 |