Skip to content

Commit f22c213

Browse files
joshualittCommit Bot
authored andcommitted
[promises] Port remaining promise code to Torque.
Bug: v8:9838 Change-Id: Idc6bda122354a54dd24e39b0356f35b0f54ef089 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2012596 Commit-Queue: Joshua Litt <[email protected]> Reviewed-by: Jakob Gruber <[email protected]> Cr-Commit-Position: refs/heads/master@{#66031}
1 parent 01646bc commit f22c213

15 files changed

+297
-391
lines changed

BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,7 @@ torque_files = [
987987
"src/builtins/promise-all-element-closure.tq",
988988
"src/builtins/promise-constructor.tq",
989989
"src/builtins/promise-finally.tq",
990+
"src/builtins/promise-misc.tq",
990991
"src/builtins/promise-race.tq",
991992
"src/builtins/promise-reaction-job.tq",
992993
"src/builtins/promise-resolve.tq",

src/builtins/builtins-async-generator-gen.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ void AsyncGeneratorBuiltinsAssembler::AsyncGeneratorEnqueue(
148148
// presently executing, then this method will loop through, processing each
149149
// request from front to back.
150150
// This loop resides in AsyncGeneratorResumeNext.
151-
TNode<JSPromise> promise = AllocateAndInitJSPromise(context);
151+
TNode<JSPromise> promise = NewJSPromise(context);
152152

153153
Label if_receiverisincompatible(this, Label::kDeferred);
154154
GotoIf(TaggedIsSmi(receiver), &if_receiverisincompatible);

src/builtins/builtins-async-iterator-gen.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void AsyncFromSyncBuiltinsAssembler::Generate_AsyncFromSyncIteratorMethod(
105105
const char* operation_name, Label::Type reject_label_type,
106106
base::Optional<TNode<Object>> initial_exception_value) {
107107
const TNode<NativeContext> native_context = LoadNativeContext(context);
108-
const TNode<JSPromise> promise = AllocateAndInitJSPromise(context);
108+
const TNode<JSPromise> promise = NewJSPromise(context);
109109

110110
TVARIABLE(
111111
Object, var_exception,

src/builtins/builtins-promise-gen.cc

Lines changed: 7 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -20,234 +20,22 @@
2020
namespace v8 {
2121
namespace internal {
2222

23-
using Node = compiler::Node;
24-
using IteratorRecord = TorqueStructIteratorRecord;
25-
using PromiseResolvingFunctions = TorqueStructPromiseResolvingFunctions;
26-
27-
TNode<JSPromise> PromiseBuiltinsAssembler::AllocateJSPromise(
28-
TNode<Context> context) {
29-
const TNode<NativeContext> native_context = LoadNativeContext(context);
30-
const TNode<JSFunction> promise_fun =
31-
CAST(LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX));
32-
CSA_ASSERT(this, IsFunctionWithPrototypeSlotMap(LoadMap(promise_fun)));
33-
const TNode<Map> promise_map = LoadObjectField<Map>(
34-
promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
35-
const TNode<HeapObject> promise =
36-
Allocate(JSPromise::kSizeWithEmbedderFields);
37-
StoreMapNoWriteBarrier(promise, promise_map);
38-
StoreObjectFieldRoot(promise, JSPromise::kPropertiesOrHashOffset,
39-
RootIndex::kEmptyFixedArray);
40-
StoreObjectFieldRoot(promise, JSPromise::kElementsOffset,
41-
RootIndex::kEmptyFixedArray);
42-
return CAST(promise);
43-
}
44-
45-
void PromiseBuiltinsAssembler::PromiseInit(TNode<JSPromise> promise) {
46-
STATIC_ASSERT(v8::Promise::kPending == 0);
47-
StoreObjectFieldNoWriteBarrier(promise, JSPromise::kReactionsOrResultOffset,
48-
SmiConstant(Smi::zero()));
49-
StoreObjectFieldNoWriteBarrier(promise, JSPromise::kFlagsOffset,
50-
SmiConstant(Smi::zero()));
23+
void PromiseBuiltinsAssembler::ZeroOutEmbedderOffsets(
24+
TNode<JSPromise> promise) {
5125
for (int offset = JSPromise::kHeaderSize;
5226
offset < JSPromise::kSizeWithEmbedderFields; offset += kTaggedSize) {
5327
StoreObjectFieldNoWriteBarrier(promise, offset, SmiConstant(Smi::zero()));
5428
}
5529
}
5630

57-
TNode<JSPromise> PromiseBuiltinsAssembler::AllocateAndInitJSPromise(
31+
TNode<HeapObject> PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
5832
TNode<Context> context) {
59-
return AllocateAndInitJSPromise(context, UndefinedConstant());
60-
}
61-
62-
TNode<JSPromise> PromiseBuiltinsAssembler::AllocateAndInitJSPromise(
63-
TNode<Context> context, TNode<Object> parent) {
64-
const TNode<JSPromise> instance = AllocateJSPromise(context);
65-
PromiseInit(instance);
66-
67-
Label out(this);
68-
GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &out);
69-
CallRuntime(Runtime::kPromiseHookInit, context, instance, parent);
70-
Goto(&out);
71-
72-
BIND(&out);
73-
return instance;
74-
}
75-
76-
TNode<JSPromise> PromiseBuiltinsAssembler::AllocateAndSetJSPromise(
77-
TNode<Context> context, v8::Promise::PromiseState status,
78-
TNode<Object> result) {
79-
DCHECK_NE(Promise::kPending, status);
80-
81-
const TNode<JSPromise> instance = AllocateJSPromise(context);
82-
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kReactionsOrResultOffset,
83-
result);
84-
STATIC_ASSERT(JSPromise::kStatusShift == 0);
85-
StoreObjectFieldNoWriteBarrier(instance, JSPromise::kFlagsOffset,
86-
SmiConstant(status));
87-
for (int offset = JSPromise::kHeaderSize;
88-
offset < JSPromise::kSizeWithEmbedderFields; offset += kTaggedSize) {
89-
StoreObjectFieldNoWriteBarrier(instance, offset, SmiConstant(0));
90-
}
91-
92-
Label out(this);
93-
GotoIfNot(IsPromiseHookEnabledOrHasAsyncEventDelegate(), &out);
94-
CallRuntime(Runtime::kPromiseHookInit, context, instance,
95-
UndefinedConstant());
96-
Goto(&out);
97-
98-
BIND(&out);
99-
return instance;
100-
}
101-
102-
TNode<BoolT> PromiseBuiltinsAssembler::PromiseHasHandler(
103-
TNode<JSPromise> promise) {
104-
const TNode<Smi> flags =
105-
LoadObjectField<Smi>(promise, JSPromise::kFlagsOffset);
106-
return IsSetWord(SmiUntag(flags), 1 << JSPromise::kHasHandlerBit);
107-
}
108-
109-
TNode<PromiseReaction> PromiseBuiltinsAssembler::AllocatePromiseReaction(
110-
TNode<Object> next, TNode<HeapObject> promise_or_capability,
111-
TNode<HeapObject> fulfill_handler, TNode<HeapObject> reject_handler) {
112-
const TNode<HeapObject> reaction = Allocate(PromiseReaction::kSize);
113-
StoreMapNoWriteBarrier(reaction, RootIndex::kPromiseReactionMap);
114-
StoreObjectFieldNoWriteBarrier(reaction, PromiseReaction::kNextOffset, next);
115-
StoreObjectFieldNoWriteBarrier(reaction,
116-
PromiseReaction::kPromiseOrCapabilityOffset,
117-
promise_or_capability);
118-
StoreObjectFieldNoWriteBarrier(
119-
reaction, PromiseReaction::kFulfillHandlerOffset, fulfill_handler);
120-
StoreObjectFieldNoWriteBarrier(
121-
reaction, PromiseReaction::kRejectHandlerOffset, reject_handler);
122-
return CAST(reaction);
123-
}
124-
125-
TNode<PromiseReactionJobTask>
126-
PromiseBuiltinsAssembler::AllocatePromiseReactionJobTask(
127-
TNode<Map> map, TNode<Context> context, TNode<Object> argument,
128-
TNode<HeapObject> handler, TNode<HeapObject> promise_or_capability) {
129-
const TNode<HeapObject> microtask =
130-
Allocate(PromiseReactionJobTask::kSizeOfAllPromiseReactionJobTasks);
131-
StoreMapNoWriteBarrier(microtask, map);
132-
StoreObjectFieldNoWriteBarrier(
133-
microtask, PromiseReactionJobTask::kArgumentOffset, argument);
134-
StoreObjectFieldNoWriteBarrier(
135-
microtask, PromiseReactionJobTask::kContextOffset, context);
136-
StoreObjectFieldNoWriteBarrier(
137-
microtask, PromiseReactionJobTask::kHandlerOffset, handler);
138-
StoreObjectFieldNoWriteBarrier(
139-
microtask, PromiseReactionJobTask::kPromiseOrCapabilityOffset,
140-
promise_or_capability);
141-
return CAST(microtask);
142-
}
143-
144-
TNode<PromiseResolveThenableJobTask>
145-
PromiseBuiltinsAssembler::AllocatePromiseResolveThenableJobTask(
146-
TNode<JSPromise> promise_to_resolve, TNode<JSReceiver> then,
147-
TNode<JSReceiver> thenable, TNode<Context> context) {
148-
const TNode<HeapObject> microtask =
149-
Allocate(PromiseResolveThenableJobTask::kSize);
150-
StoreMapNoWriteBarrier(microtask,
151-
RootIndex::kPromiseResolveThenableJobTaskMap);
152-
StoreObjectFieldNoWriteBarrier(
153-
microtask, PromiseResolveThenableJobTask::kContextOffset, context);
154-
StoreObjectFieldNoWriteBarrier(
155-
microtask, PromiseResolveThenableJobTask::kPromiseToResolveOffset,
156-
promise_to_resolve);
157-
StoreObjectFieldNoWriteBarrier(
158-
microtask, PromiseResolveThenableJobTask::kThenOffset, then);
159-
StoreObjectFieldNoWriteBarrier(
160-
microtask, PromiseResolveThenableJobTask::kThenableOffset, thenable);
161-
return CAST(microtask);
162-
}
163-
164-
void PromiseBuiltinsAssembler::BranchIfPromiseResolveLookupChainIntact(
165-
TNode<NativeContext> native_context, TNode<Object> constructor,
166-
Label* if_fast, Label* if_slow) {
167-
GotoIfForceSlowPath(if_slow);
168-
TNode<Object> promise_fun =
169-
LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
170-
GotoIfNot(TaggedEqual(promise_fun, constructor), if_slow);
171-
Branch(IsPromiseResolveProtectorCellInvalid(), if_slow, if_fast);
172-
}
173-
174-
void PromiseBuiltinsAssembler::GotoIfNotPromiseResolveLookupChainIntact(
175-
TNode<NativeContext> native_context, TNode<Object> constructor,
176-
Label* if_slow) {
177-
Label if_fast(this);
178-
BranchIfPromiseResolveLookupChainIntact(native_context, constructor, &if_fast,
179-
if_slow);
180-
BIND(&if_fast);
181-
}
182-
183-
void PromiseBuiltinsAssembler::BranchIfPromiseSpeciesLookupChainIntact(
184-
TNode<NativeContext> native_context, TNode<Map> promise_map, Label* if_fast,
185-
Label* if_slow) {
186-
TNode<Object> promise_prototype =
187-
LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
188-
GotoIfForceSlowPath(if_slow);
189-
GotoIfNot(TaggedEqual(LoadMapPrototype(promise_map), promise_prototype),
190-
if_slow);
191-
Branch(IsPromiseSpeciesProtectorCellInvalid(), if_slow, if_fast);
33+
return Allocate(PromiseReactionJobTask::kSizeOfAllPromiseReactionJobTasks);
19234
}
19335

194-
void PromiseBuiltinsAssembler::BranchIfPromiseThenLookupChainIntact(
195-
TNode<NativeContext> native_context, TNode<Map> receiver_map,
196-
Label* if_fast, Label* if_slow) {
197-
GotoIfForceSlowPath(if_slow);
198-
GotoIfNot(IsJSPromiseMap(receiver_map), if_slow);
199-
const TNode<Object> promise_prototype =
200-
LoadContextElement(native_context, Context::PROMISE_PROTOTYPE_INDEX);
201-
GotoIfNot(TaggedEqual(LoadMapPrototype(receiver_map), promise_prototype),
202-
if_slow);
203-
Branch(IsPromiseThenProtectorCellInvalid(), if_slow, if_fast);
204-
}
205-
206-
void PromiseBuiltinsAssembler::BranchIfAccessCheckFailed(
207-
TNode<Context> context, TNode<Context> native_context,
208-
TNode<Object> promise_constructor, TNode<Object> executor,
209-
Label* if_noaccess) {
210-
TVARIABLE(HeapObject, var_executor);
211-
var_executor = CAST(executor);
212-
Label has_access(this), call_runtime(this, Label::kDeferred);
213-
214-
// If executor is a bound function, load the bound function until we've
215-
// reached an actual function.
216-
Label found_function(this), loop_over_bound_function(this, &var_executor);
217-
Goto(&loop_over_bound_function);
218-
BIND(&loop_over_bound_function);
219-
{
220-
TNode<Uint16T> executor_type = LoadInstanceType(var_executor.value());
221-
GotoIf(InstanceTypeEqual(executor_type, JS_FUNCTION_TYPE), &found_function);
222-
GotoIfNot(InstanceTypeEqual(executor_type, JS_BOUND_FUNCTION_TYPE),
223-
&call_runtime);
224-
var_executor = LoadObjectField<HeapObject>(
225-
var_executor.value(), JSBoundFunction::kBoundTargetFunctionOffset);
226-
Goto(&loop_over_bound_function);
227-
}
228-
229-
// Load the context from the function and compare it to the Promise
230-
// constructor's context. If they match, everything is fine, otherwise, bail
231-
// out to the runtime.
232-
BIND(&found_function);
233-
{
234-
TNode<Context> function_context = LoadObjectField<Context>(
235-
var_executor.value(), JSFunction::kContextOffset);
236-
TNode<NativeContext> native_function_context =
237-
LoadNativeContext(function_context);
238-
Branch(TaggedEqual(native_context, native_function_context), &has_access,
239-
&call_runtime);
240-
}
241-
242-
BIND(&call_runtime);
243-
{
244-
Branch(TaggedEqual(CallRuntime(Runtime::kAllowDynamicFunction, context,
245-
promise_constructor),
246-
TrueConstant()),
247-
&has_access, if_noaccess);
248-
}
249-
250-
BIND(&has_access);
36+
TNode<HeapObject> PromiseBuiltinsAssembler::AllocateJSPromise(
37+
TNode<Context> context) {
38+
return Allocate(JSPromise::kSizeWithEmbedderFields);
25139
}
25240

25341
} // namespace internal

src/builtins/builtins-promise-gen.h

Lines changed: 3 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -17,112 +17,11 @@ class V8_EXPORT_PRIVATE PromiseBuiltinsAssembler : public CodeStubAssembler {
1717
public:
1818
explicit PromiseBuiltinsAssembler(compiler::CodeAssemblerState* state)
1919
: CodeStubAssembler(state) {}
20-
// These allocate and initialize a promise with pending state and
21-
// undefined fields.
22-
//
23-
// This uses undefined as the parent promise for the promise init
24-
// hook.
25-
TNode<JSPromise> AllocateAndInitJSPromise(TNode<Context> context);
26-
// This uses the given parent as the parent promise for the promise
27-
// init hook.
28-
TNode<JSPromise> AllocateAndInitJSPromise(TNode<Context> context,
29-
TNode<Object> parent);
20+
void ZeroOutEmbedderOffsets(TNode<JSPromise> promise);
3021

31-
// This allocates and initializes a promise with the given state and
32-
// fields.
33-
TNode<JSPromise> AllocateAndSetJSPromise(TNode<Context> context,
34-
v8::Promise::PromiseState status,
35-
TNode<Object> result);
22+
TNode<HeapObject> AllocateJSPromise(TNode<Context> context);
3623

37-
TNode<PromiseReaction> AllocatePromiseReaction(
38-
TNode<Object> next, TNode<HeapObject> promise_or_capability,
39-
TNode<HeapObject> fulfill_handler, TNode<HeapObject> reject_handler);
40-
41-
TNode<PromiseReactionJobTask> AllocatePromiseReactionJobTask(
42-
TNode<Map> map, TNode<Context> context, TNode<Object> argument,
43-
TNode<HeapObject> handler, TNode<HeapObject> promise_or_capability);
44-
45-
TNode<PromiseResolveThenableJobTask> AllocatePromiseResolveThenableJobTask(
46-
TNode<JSPromise> promise_to_resolve, TNode<JSReceiver> then,
47-
TNode<JSReceiver> thenable, TNode<Context> context);
48-
TNode<BoolT> PromiseHasHandler(TNode<JSPromise> promise);
49-
50-
void BranchIfAccessCheckFailed(TNode<Context> context,
51-
TNode<Context> native_context,
52-
TNode<Object> promise_constructor,
53-
TNode<Object> executor, Label* if_noaccess);
54-
void PromiseInit(TNode<JSPromise> promise);
55-
56-
// We can shortcut the SpeciesConstructor on {promise_map} if it's
57-
// [[Prototype]] is the (initial) Promise.prototype and the @@species
58-
// protector is intact, as that guards the lookup path for the "constructor"
59-
// property on JSPromise instances which have the %PromisePrototype%.
60-
void BranchIfPromiseSpeciesLookupChainIntact(
61-
TNode<NativeContext> native_context, TNode<Map> promise_map,
62-
Label* if_fast, Label* if_slow);
63-
64-
template <typename... TArgs>
65-
TNode<Object> InvokeThen(TNode<NativeContext> native_context,
66-
TNode<Object> receiver, TArgs... args) {
67-
TVARIABLE(Object, var_result);
68-
Label if_fast(this), if_slow(this, Label::kDeferred),
69-
done(this, &var_result);
70-
GotoIf(TaggedIsSmi(receiver), &if_slow);
71-
const TNode<Map> receiver_map = LoadMap(CAST(receiver));
72-
// We can skip the "then" lookup on {receiver} if it's [[Prototype]]
73-
// is the (initial) Promise.prototype and the Promise#then protector
74-
// is intact, as that guards the lookup path for the "then" property
75-
// on JSPromise instances which have the (initial) %PromisePrototype%.
76-
BranchIfPromiseThenLookupChainIntact(native_context, receiver_map, &if_fast,
77-
&if_slow);
78-
79-
BIND(&if_fast);
80-
{
81-
const TNode<Object> then =
82-
LoadContextElement(native_context, Context::PROMISE_THEN_INDEX);
83-
var_result =
84-
CallJS(CodeFactory::CallFunction(
85-
isolate(), ConvertReceiverMode::kNotNullOrUndefined),
86-
native_context, then, receiver, args...);
87-
Goto(&done);
88-
}
89-
90-
BIND(&if_slow);
91-
{
92-
const TNode<Object> then = GetProperty(
93-
native_context, receiver, isolate()->factory()->then_string());
94-
var_result =
95-
CallJS(CodeFactory::Call(isolate(),
96-
ConvertReceiverMode::kNotNullOrUndefined),
97-
native_context, then, receiver, args...);
98-
Goto(&done);
99-
}
100-
101-
BIND(&done);
102-
return var_result.value();
103-
}
104-
105-
protected:
106-
// We can skip the "resolve" lookup on {constructor} if it's the (initial)
107-
// Promise constructor and the Promise.resolve() protector is intact, as
108-
// that guards the lookup path for the "resolve" property on the %Promise%
109-
// intrinsic object.
110-
void BranchIfPromiseResolveLookupChainIntact(
111-
TNode<NativeContext> native_context, TNode<Object> constructor,
112-
Label* if_fast, Label* if_slow);
113-
void GotoIfNotPromiseResolveLookupChainIntact(
114-
TNode<NativeContext> native_context, TNode<Object> constructor,
115-
Label* if_slow);
116-
117-
// We can skip the "then" lookup on {receiver_map} if it's [[Prototype]]
118-
// is the (initial) Promise.prototype and the Promise#then() protector
119-
// is intact, as that guards the lookup path for the "then" property
120-
// on JSPromise instances which have the (initial) %PromisePrototype%.
121-
void BranchIfPromiseThenLookupChainIntact(TNode<NativeContext> native_context,
122-
TNode<Map> receiver_map,
123-
Label* if_fast, Label* if_slow);
124-
125-
TNode<JSPromise> AllocateJSPromise(TNode<Context> context);
24+
TNode<HeapObject> AllocatePromiseReactionJobTask(TNode<Context> context);
12625
};
12726

12827
} // namespace internal

0 commit comments

Comments
 (0)