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