Index: src/builtins/builtins-promise.cc |
diff --git a/src/builtins/builtins-promise.cc b/src/builtins/builtins-promise.cc |
index 9f5d7c88d7885e8bfbcefe65fdc80c729301b305..106674dd33f2f3f9e6f6d2987fb412c567561b32 100644 |
--- a/src/builtins/builtins-promise.cc |
+++ b/src/builtins/builtins-promise.cc |
@@ -5,6 +5,7 @@ |
#include "src/builtins/builtins-utils.h" |
#include "src/builtins/builtins.h" |
+#include "src/code-factory.h" |
#include "src/promise-utils.h" |
namespace v8 { |
@@ -68,7 +69,6 @@ BUILTIN(CreateResolvingFunctions) { |
Handle<JSObject> promise = args.at<JSObject>(1); |
Handle<Object> debug_event = args.at<Object>(2); |
Handle<JSFunction> resolve, reject; |
- |
PromiseUtils::CreateResolvingFunctions(isolate, promise, debug_event, |
&resolve, &reject); |
@@ -80,5 +80,88 @@ BUILTIN(CreateResolvingFunctions) { |
NOT_TENURED); |
} |
+// TODO(gsathya): Set up catch prediction |
+void Builtins::Generate_PromiseConstructor(CodeStubAssembler* a) { |
+ typedef CodeStubAssembler::Variable Variable; |
+ typedef CodeStubAssembler::Label Label; |
+ typedef compiler::Node Node; |
+ |
+ Node* const executor = a->Parameter(1); |
+ Node* const new_target = a->Parameter(2); |
+ Node* const context = a->Parameter(4); |
+ Isolate* isolate = a->isolate(); |
+ |
+ Variable result(a, MachineRepresentation::kTagged), |
jgruber
2016/11/11 08:05:19
Nit: The naming convention used elsewhere is to pr
gsathya
2016/11/22 04:31:43
Done.
|
+ reason(a, MachineRepresentation::kTagged); |
+ Label if_targetisnotundefined(a), if_targetisundefined(a, Label::kDeferred); |
+ |
+ a->Branch(a->WordEqual(new_target, a->UndefinedConstant()), |
Benedikt Meurer
2016/11/11 06:50:31
Instead of dynamically checking that new.target is
gsathya
2016/11/22 04:31:43
The asm wrapper is set as the construct stub, whic
|
+ &if_targetisundefined, &if_targetisnotundefined); |
+ |
+ // 1. If NewTarget is undefined, throw a TypeError exception. |
+ a->Bind(&if_targetisundefined); |
+ { |
+ Node* const message_id = |
+ a->SmiConstant(Smi::FromInt(MessageTemplate::kNotAPromise)); |
+ Callable callable = CodeFactory::ToString(isolate); |
+ // calling toString on UndefinedConstant? |
jgruber
2016/11/11 08:05:19
You probably don't need to call ToString here, jus
gsathya
2016/11/22 04:31:43
Done.
|
+ Node* const undefined_str = a->CallStub(callable, context, new_target); |
+ |
+ a->CallRuntime(Runtime::kThrowTypeError, context, message_id, |
+ undefined_str); |
+ a->Return(a->UndefinedConstant()); // Never reached. |
+ } |
+ |
+ a->Bind(&if_targetisnotundefined); |
+ { |
+ Node* const executor_map = a->LoadMap(executor); |
+ Label if_iscallable(a), if_notcallable(a, Label::kDeferred), |
+ if_rejectpromise(a, Label::kDeferred); |
+ a->Branch(a->IsCallableMap(executor_map), &if_iscallable, &if_notcallable); |
+ |
+ // 2. If IsCallable(executor) is false, throw a TypeError exception. |
+ a->Bind(&if_notcallable); |
+ { |
+ Node* const message_id = |
+ a->SmiConstant(Smi::FromInt(MessageTemplate::kResolverNotAFunction)); |
+ Callable callable = CodeFactory::ToString(isolate); |
jgruber
2016/11/11 09:25:43
Danno added ToString to CSA recently, so all CodeF
gsathya
2016/11/22 04:31:43
Done.
|
+ Node* const executor_str = a->CallStub(callable, context, executor); |
+ |
+ a->CallRuntime(Runtime::kThrowTypeError, context, message_id, |
+ executor_str); |
+ a->Return(a->UndefinedConstant()); // Never reached. |
+ } |
+ |
+ a->Bind(&if_iscallable); |
+ { |
+ Node* const native_context = a->LoadNativeContext(context); |
+ Node* const promise_fun = a->LoadContextElement( |
+ native_context, Context::PROMISE_FUNCTION_INDEX); |
+ Node* const initial_map = a->LoadObjectField( |
+ promise_fun, JSFunction::kPrototypeOrInitialMapOffset); |
+ |
+ // TODO(gsathya): check if target != new_target |
+ Node* const instance = a->AllocateJSObjectFromMap(initial_map); |
+ result.Bind(instance); |
+ |
+ Node* const resolving_functions = |
+ a->CallRuntime(Runtime::kCreateResolvingFunctions, context, instance); |
gsathya
2016/11/11 02:48:18
Is there a way to call a C++ builtin from TFJ? Set
Benedikt Meurer
2016/11/11 06:50:31
The runtime function is the correct approach here.
|
+ |
+ Callable call_callable = CodeFactory::Call(isolate); |
+ |
+ // TODO(gsathya): Extract resolving functions from JSArray |
jgruber
2016/11/11 08:05:19
Once all calls to CreateResolvingFunctions are in
gsathya
2016/11/22 04:31:43
Moved to a FixedArray for now. Next step is to mov
|
+ Node* const maybe_exception = |
+ a->CallJS(call_callable, context, executor, a->UndefinedConstant(), |
+ resolving_functions); |
+ |
+ a->GotoIfException(maybe_exception, &if_rejectpromise, &reason); |
+ a->Return(result.value()); |
+ } |
+ |
+ // TODO(gsathya): Reject the promise |
+ a->Bind(&if_rejectpromise); |
+ { a->Return(result.value()); } |
jgruber
2016/11/11 08:05:19
Nit: You can remove these braces.
gsathya
2016/11/22 04:31:43
Done.
|
+ } |
+} |
} // namespace internal |
} // namespace v8 |