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-utils.h" | 5 #include "src/builtins/builtins-utils.h" |
| 6 #include "src/builtins/builtins.h" | 6 #include "src/builtins/builtins.h" |
| 7 | 7 |
| 8 #include "src/code-factory.h" | |
| 8 #include "src/promise-utils.h" | 9 #include "src/promise-utils.h" |
| 9 | 10 |
| 10 namespace v8 { | 11 namespace v8 { |
| 11 namespace internal { | 12 namespace internal { |
| 12 | 13 |
| 13 // ES#sec-promise-resolve-functions | 14 // ES#sec-promise-resolve-functions |
| 14 // Promise Resolve Functions | 15 // Promise Resolve Functions |
| 15 BUILTIN(PromiseResolveClosure) { | 16 BUILTIN(PromiseResolveClosure) { |
| 16 HandleScope scope(isolate); | 17 HandleScope scope(isolate); |
| 17 | 18 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 | 62 |
| 62 // ES#sec-createresolvingfunctions | 63 // ES#sec-createresolvingfunctions |
| 63 // CreateResolvingFunctions ( promise ) | 64 // CreateResolvingFunctions ( promise ) |
| 64 BUILTIN(CreateResolvingFunctions) { | 65 BUILTIN(CreateResolvingFunctions) { |
| 65 HandleScope scope(isolate); | 66 HandleScope scope(isolate); |
| 66 DCHECK_EQ(3, args.length()); | 67 DCHECK_EQ(3, args.length()); |
| 67 | 68 |
| 68 Handle<JSObject> promise = args.at<JSObject>(1); | 69 Handle<JSObject> promise = args.at<JSObject>(1); |
| 69 Handle<Object> debug_event = args.at<Object>(2); | 70 Handle<Object> debug_event = args.at<Object>(2); |
| 70 Handle<JSFunction> resolve, reject; | 71 Handle<JSFunction> resolve, reject; |
| 71 | |
| 72 PromiseUtils::CreateResolvingFunctions(isolate, promise, debug_event, | 72 PromiseUtils::CreateResolvingFunctions(isolate, promise, debug_event, |
| 73 &resolve, &reject); | 73 &resolve, &reject); |
| 74 | 74 |
| 75 Handle<FixedArray> result = isolate->factory()->NewFixedArray(2); | 75 Handle<FixedArray> result = isolate->factory()->NewFixedArray(2); |
| 76 result->set(0, *resolve); | 76 result->set(0, *resolve); |
| 77 result->set(1, *reject); | 77 result->set(1, *reject); |
| 78 | 78 |
| 79 return *isolate->factory()->NewJSArrayWithElements(result, FAST_ELEMENTS, 2, | 79 return *isolate->factory()->NewJSArrayWithElements(result, FAST_ELEMENTS, 2, |
| 80 NOT_TENURED); | 80 NOT_TENURED); |
| 81 } | 81 } |
| 82 | 82 |
| 83 // TODO(gsathya): Set up catch prediction | |
| 84 void Builtins::Generate_PromiseConstructor(CodeStubAssembler* a) { | |
| 85 typedef CodeStubAssembler::Variable Variable; | |
| 86 typedef CodeStubAssembler::Label Label; | |
| 87 typedef compiler::Node Node; | |
| 88 | |
| 89 Node* const executor = a->Parameter(1); | |
| 90 Node* const new_target = a->Parameter(2); | |
| 91 Node* const context = a->Parameter(4); | |
| 92 Isolate* isolate = a->isolate(); | |
| 93 | |
| 94 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.
| |
| 95 reason(a, MachineRepresentation::kTagged); | |
| 96 Label if_targetisnotundefined(a), if_targetisundefined(a, Label::kDeferred); | |
| 97 | |
| 98 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
| |
| 99 &if_targetisundefined, &if_targetisnotundefined); | |
| 100 | |
| 101 // 1. If NewTarget is undefined, throw a TypeError exception. | |
| 102 a->Bind(&if_targetisundefined); | |
| 103 { | |
| 104 Node* const message_id = | |
| 105 a->SmiConstant(Smi::FromInt(MessageTemplate::kNotAPromise)); | |
| 106 Callable callable = CodeFactory::ToString(isolate); | |
| 107 // 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.
| |
| 108 Node* const undefined_str = a->CallStub(callable, context, new_target); | |
| 109 | |
| 110 a->CallRuntime(Runtime::kThrowTypeError, context, message_id, | |
| 111 undefined_str); | |
| 112 a->Return(a->UndefinedConstant()); // Never reached. | |
| 113 } | |
| 114 | |
| 115 a->Bind(&if_targetisnotundefined); | |
| 116 { | |
| 117 Node* const executor_map = a->LoadMap(executor); | |
| 118 Label if_iscallable(a), if_notcallable(a, Label::kDeferred), | |
| 119 if_rejectpromise(a, Label::kDeferred); | |
| 120 a->Branch(a->IsCallableMap(executor_map), &if_iscallable, &if_notcallable); | |
| 121 | |
| 122 // 2. If IsCallable(executor) is false, throw a TypeError exception. | |
| 123 a->Bind(&if_notcallable); | |
| 124 { | |
| 125 Node* const message_id = | |
| 126 a->SmiConstant(Smi::FromInt(MessageTemplate::kResolverNotAFunction)); | |
| 127 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.
| |
| 128 Node* const executor_str = a->CallStub(callable, context, executor); | |
| 129 | |
| 130 a->CallRuntime(Runtime::kThrowTypeError, context, message_id, | |
| 131 executor_str); | |
| 132 a->Return(a->UndefinedConstant()); // Never reached. | |
| 133 } | |
| 134 | |
| 135 a->Bind(&if_iscallable); | |
| 136 { | |
| 137 Node* const native_context = a->LoadNativeContext(context); | |
| 138 Node* const promise_fun = a->LoadContextElement( | |
| 139 native_context, Context::PROMISE_FUNCTION_INDEX); | |
| 140 Node* const initial_map = a->LoadObjectField( | |
| 141 promise_fun, JSFunction::kPrototypeOrInitialMapOffset); | |
| 142 | |
| 143 // TODO(gsathya): check if target != new_target | |
| 144 Node* const instance = a->AllocateJSObjectFromMap(initial_map); | |
| 145 result.Bind(instance); | |
| 146 | |
| 147 Node* const resolving_functions = | |
| 148 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.
| |
| 149 | |
| 150 Callable call_callable = CodeFactory::Call(isolate); | |
| 151 | |
| 152 // 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
| |
| 153 Node* const maybe_exception = | |
| 154 a->CallJS(call_callable, context, executor, a->UndefinedConstant(), | |
| 155 resolving_functions); | |
| 156 | |
| 157 a->GotoIfException(maybe_exception, &if_rejectpromise, &reason); | |
| 158 a->Return(result.value()); | |
| 159 } | |
| 160 | |
| 161 // TODO(gsathya): Reject the promise | |
| 162 a->Bind(&if_rejectpromise); | |
| 163 { 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.
| |
| 164 } | |
| 165 } | |
| 83 } // namespace internal | 166 } // namespace internal |
| 84 } // namespace v8 | 167 } // namespace v8 |
| OLD | NEW |