Commit 6647f292 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

Reland "[torque] typed context slot access"

This is a reland of 408e7240
Change: Allow CSA load elimination accross code comments

Original change's description:
> [torque] typed context slot access
>
> This introduces a new type Slot<ContextType, SlotType> that is used
> for enum values used to access context slots.
> Together with new types for the various custom contexts used in
> Torque, this results in fairly type-safe access to context slots,
> including the NativeContext's slots.
>
> Drive-by changes:
> - Introduce a new header file to specify headers needed for
>   generated CSA headers, to reduce the amount of includes specified
>   in implementation-visitor.cc
> - Port AllocateSyntheticFunctionContext to Torque.
>
> Bug: v8:7793
> Change-Id: I509a128916ca408eeeb636a9bcc376b2cc868532
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2335064
> Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> Reviewed-by: Seth Brenith <seth.brenith@microsoft.com>
> Cr-Commit-Position: refs/heads/master@{#69249}

Bug: v8:7793
Change-Id: I1fe100d8d62e8220524eddb8ecc4faa85219748d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2339462Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69264}
parent 54fd0626
...@@ -1767,6 +1767,7 @@ v8_source_set("v8_initializers") { ...@@ -1767,6 +1767,7 @@ v8_source_set("v8_initializers") {
"src/builtins/profile-data-reader.cc", "src/builtins/profile-data-reader.cc",
"src/builtins/profile-data-reader.h", "src/builtins/profile-data-reader.h",
"src/builtins/setup-builtins-internal.cc", "src/builtins/setup-builtins-internal.cc",
"src/builtins/torque-csa-header-includes.h",
"src/codegen/code-stub-assembler.cc", "src/codegen/code-stub-assembler.cc",
"src/codegen/code-stub-assembler.h", "src/codegen/code-stub-assembler.h",
"src/heap/setup-heap-internal.cc", "src/heap/setup-heap-internal.cc",
......
...@@ -414,17 +414,18 @@ const kMinJoinStackSize: ...@@ -414,17 +414,18 @@ const kMinJoinStackSize:
constexpr int31 generates 'JSArray::kMinJoinStackSize'; constexpr int31 generates 'JSArray::kMinJoinStackSize';
macro LoadJoinStack(implicit context: Context)(): FixedArray macro LoadJoinStack(implicit context: Context)(): FixedArray
labels IfUninitialized { labels IfUninitialized {
const nativeContext: NativeContext = LoadNativeContext(context); typeswitch (*NativeContextSlot(ContextSlot::ARRAY_JOIN_STACK_INDEX)) {
const stack: HeapObject = UnsafeCast<HeapObject>( case (Undefined): {
nativeContext.elements[NativeContextSlot::ARRAY_JOIN_STACK_INDEX]); goto IfUninitialized;
if (stack == Undefined) goto IfUninitialized; }
assert(Is<FixedArray>(stack)); case (stack: FixedArray): {
return UnsafeCast<FixedArray>(stack); return stack;
}
}
} }
macro SetJoinStack(implicit context: Context)(stack: FixedArray): void { macro SetJoinStack(implicit context: Context)(stack: FixedArray): void {
const nativeContext: NativeContext = LoadNativeContext(context); *NativeContextSlot(ContextSlot::ARRAY_JOIN_STACK_INDEX) = stack;
nativeContext.elements[NativeContextSlot::ARRAY_JOIN_STACK_INDEX] = stack;
} }
// Adds a receiver to the stack. The FixedArray will automatically grow to // Adds a receiver to the stack. The FixedArray will automatically grow to
......
...@@ -451,8 +451,6 @@ const UNSAFE_SKIP_WRITE_BARRIER: ...@@ -451,8 +451,6 @@ const UNSAFE_SKIP_WRITE_BARRIER:
extern transitioning macro AllocateJSIteratorResult(implicit context: Context)( extern transitioning macro AllocateJSIteratorResult(implicit context: Context)(
JSAny, Boolean): JSObject; JSAny, Boolean): JSObject;
extern macro AllocateSyntheticFunctionContext(
NativeContext, constexpr int32): Context;
extern class Filler extends HeapObject generates 'TNode<HeapObject>'; extern class Filler extends HeapObject generates 'TNode<HeapObject>';
...@@ -1102,74 +1100,47 @@ macro AllowNonNumberElements(kind: ElementsKind): ElementsKind { ...@@ -1102,74 +1100,47 @@ macro AllowNonNumberElements(kind: ElementsKind): ElementsKind {
} }
macro GetObjectFunction(implicit context: Context)(): JSFunction { macro GetObjectFunction(implicit context: Context)(): JSFunction {
return UnsafeCast<JSFunction>( return *NativeContextSlot(ContextSlot::OBJECT_FUNCTION_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::OBJECT_FUNCTION_INDEX]);
} }
macro GetArrayFunction(implicit context: Context)(): JSFunction { macro GetArrayFunction(implicit context: Context)(): JSFunction {
return UnsafeCast<JSFunction>( return *NativeContextSlot(ContextSlot::ARRAY_FUNCTION_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::ARRAY_FUNCTION_INDEX]);
} }
macro GetArrayBufferFunction(implicit context: Context)(): Constructor { macro GetArrayBufferFunction(implicit context: Context)(): Constructor {
return UnsafeCast<Constructor>( return *NativeContextSlot(ContextSlot::ARRAY_BUFFER_FUN_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::ARRAY_BUFFER_FUN_INDEX]);
} }
macro GetArrayBufferNoInitFunction(implicit context: Context)(): JSFunction { macro GetArrayBufferNoInitFunction(implicit context: Context)(): JSFunction {
return UnsafeCast<JSFunction>( return *NativeContextSlot(ContextSlot::ARRAY_BUFFER_NOINIT_FUN_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::ARRAY_BUFFER_NOINIT_FUN_INDEX]);
} }
macro GetFastPackedElementsJSArrayMap(implicit context: Context)(): Map { macro GetFastPackedElementsJSArrayMap(implicit context: Context)(): Map {
return UnsafeCast<Map>( return *NativeContextSlot(ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX]);
} }
macro GetFastPackedSmiElementsJSArrayMap(implicit context: Context)(): Map { macro GetFastPackedSmiElementsJSArrayMap(implicit context: Context)(): Map {
return UnsafeCast<Map>( return *NativeContextSlot(
LoadNativeContext(context) ContextSlot::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX);
.elements[NativeContextSlot::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX]);
} }
macro GetProxyRevocableResultMap(implicit context: Context)(): Map { macro GetProxyRevocableResultMap(implicit context: Context)(): Map {
return UnsafeCast<Map>( return *NativeContextSlot(ContextSlot::PROXY_REVOCABLE_RESULT_MAP_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::PROXY_REVOCABLE_RESULT_MAP_INDEX]);
} }
macro GetIteratorResultMap(implicit context: Context)(): Map { macro GetIteratorResultMap(implicit context: Context)(): Map {
return UnsafeCast<Map>( return *NativeContextSlot(ContextSlot::ITERATOR_RESULT_MAP_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]);
} }
macro GetInitialStringIteratorMap(implicit context: Context)(): Map { macro GetInitialStringIteratorMap(implicit context: Context)(): Map {
return UnsafeCast<Map>( return *NativeContextSlot(ContextSlot::INITIAL_STRING_ITERATOR_MAP_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::INITIAL_STRING_ITERATOR_MAP_INDEX]);
} }
macro GetReflectApply(implicit context: Context)(): Callable { macro GetReflectApply(implicit context: Context)(): Callable {
return UnsafeCast<Callable>( return *NativeContextSlot(ContextSlot::REFLECT_APPLY_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::REFLECT_APPLY_INDEX]);
} }
macro GetRegExpLastMatchInfo(implicit context: Context)(): RegExpMatchInfo { macro GetRegExpLastMatchInfo(implicit context: Context)(): RegExpMatchInfo {
return %RawDownCast<RegExpMatchInfo>( return *NativeContextSlot(ContextSlot::REGEXP_LAST_MATCH_INFO_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::REGEXP_LAST_MATCH_INFO_INDEX]);
} }
macro GetStrictArgumentsMap(implicit context: Context)(): Map { macro GetStrictArgumentsMap(implicit context: Context)(): Map {
return UnsafeCast<Map>( return *NativeContextSlot(ContextSlot::STRICT_ARGUMENTS_MAP_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::STRICT_ARGUMENTS_MAP_INDEX]);
} }
macro GetSloppyArgumentsMap(implicit context: Context)(): Map { macro GetSloppyArgumentsMap(implicit context: Context)(): Map {
return UnsafeCast<Map>( return *NativeContextSlot(ContextSlot::SLOPPY_ARGUMENTS_MAP_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::SLOPPY_ARGUMENTS_MAP_INDEX]);
} }
macro GetFastAliasedArgumentsMap(implicit context: Context)(): Map { macro GetFastAliasedArgumentsMap(implicit context: Context)(): Map {
return UnsafeCast<Map>( return *NativeContextSlot(ContextSlot::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
LoadNativeContext(context)
.elements[NativeContextSlot::FAST_ALIASED_ARGUMENTS_MAP_INDEX]);
} }
macro GetWeakCellMap(implicit context: Context)(): Map { macro GetWeakCellMap(implicit context: Context)(): Map {
return %GetClassMapConstant<WeakCell>(); return %GetClassMapConstant<WeakCell>();
......
...@@ -62,9 +62,10 @@ TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy( ...@@ -62,9 +62,10 @@ TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy(
TNode<Context> ProxiesCodeStubAssembler::CreateProxyRevokeFunctionContext( TNode<Context> ProxiesCodeStubAssembler::CreateProxyRevokeFunctionContext(
TNode<JSProxy> proxy, TNode<NativeContext> native_context) { TNode<JSProxy> proxy, TNode<NativeContext> native_context) {
const TNode<Context> context = const TNode<Context> context = AllocateSyntheticFunctionContext(
AllocateSyntheticFunctionContext(native_context, kProxyContextLength); native_context, ProxyRevokeFunctionContextSlot::kProxyContextLength);
StoreContextElementNoWriteBarrier(context, kProxySlot, proxy); StoreContextElementNoWriteBarrier(
context, ProxyRevokeFunctionContextSlot::kProxySlot, proxy);
return context; return context;
} }
......
...@@ -33,7 +33,6 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler { ...@@ -33,7 +33,6 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
void CheckDeleteTrapResult(TNode<Context> context, TNode<JSReceiver> target, void CheckDeleteTrapResult(TNode<Context> context, TNode<JSReceiver> target,
TNode<JSProxy> proxy, TNode<Name> name); TNode<JSProxy> proxy, TNode<Name> name);
protected:
enum ProxyRevokeFunctionContextSlot { enum ProxyRevokeFunctionContextSlot {
kProxySlot = Context::MIN_CONTEXT_SLOTS, kProxySlot = Context::MIN_CONTEXT_SLOTS,
kProxyContextLength, kProxyContextLength,
......
...@@ -611,6 +611,35 @@ Cast<JSFunction|JSBoundFunction>(implicit context: Context)(o: Object): ...@@ -611,6 +611,35 @@ Cast<JSFunction|JSBoundFunction>(implicit context: Context)(o: Object):
} }
} }
Cast<FixedArray|Undefined>(o: HeapObject): FixedArray|
Undefined labels CastError {
typeswitch (o) {
case (o: Undefined): {
return o;
}
case (o: FixedArray): {
return o;
}
case (Object): {
goto CastError;
}
}
}
Cast<JSProxy|Null>(o: HeapObject): JSProxy|Null labels CastError {
typeswitch (o) {
case (o: Null): {
return o;
}
case (o: JSProxy): {
return o;
}
case (Object): {
goto CastError;
}
}
}
macro Is<A : type extends Object, B : type extends Object>( macro Is<A : type extends Object, B : type extends Object>(
implicit context: Context)(o: B): bool { implicit context: Context)(o: B): bool {
Cast<A>(o) otherwise return false; Cast<A>(o) otherwise return false;
......
...@@ -112,7 +112,7 @@ transitioning builtin ToObject(implicit context: Context)(input: JSAny): ...@@ -112,7 +112,7 @@ transitioning builtin ToObject(implicit context: Context)(input: JSAny):
try { try {
typeswitch (input) { typeswitch (input) {
case (Smi): { case (Smi): {
goto WrapPrimitive(NativeContextSlot::NUMBER_FUNCTION_INDEX); goto WrapPrimitive(ContextSlot::NUMBER_FUNCTION_INDEX);
} }
case (o: JSReceiver): { case (o: JSReceiver): {
return o; return o;
...@@ -120,14 +120,14 @@ transitioning builtin ToObject(implicit context: Context)(input: JSAny): ...@@ -120,14 +120,14 @@ transitioning builtin ToObject(implicit context: Context)(input: JSAny):
case (o: JSAnyNotSmi): { case (o: JSAnyNotSmi): {
const index: intptr = Convert<intptr>( const index: intptr = Convert<intptr>(
o.map.in_object_properties_start_or_constructor_function_index); o.map.in_object_properties_start_or_constructor_function_index);
if (index != kNoConstructorFunctionIndex) goto WrapPrimitive(index); if (index != kNoConstructorFunctionIndex)
goto WrapPrimitive(
%RawDownCast<Slot<NativeContext, JSFunction>>(index));
ThrowTypeError(MessageTemplate::kUndefinedOrNullToObject, 'ToObject'); ThrowTypeError(MessageTemplate::kUndefinedOrNullToObject, 'ToObject');
} }
} }
} label WrapPrimitive(constructorIndex: intptr) { } label WrapPrimitive(constructorIndex: Slot<NativeContext, JSFunction>) {
const nativeContext = LoadNativeContext(context); const constructor = *NativeContextSlot(constructorIndex);
const constructor =
UnsafeCast<JSFunction>(nativeContext.elements[constructorIndex]);
const map: Map = UnsafeCast<Map>(constructor.prototype_or_initial_map); const map: Map = UnsafeCast<Map>(constructor.prototype_or_initial_map);
const wrapper = const wrapper =
UnsafeCast<JSPrimitiveWrapper>(AllocateFastOrSlowJSObjectFromMap(map)); UnsafeCast<JSPrimitiveWrapper>(AllocateFastOrSlowJSObjectFromMap(map));
......
...@@ -66,14 +66,12 @@ FastFunctionPrototypeBind( ...@@ -66,14 +66,12 @@ FastFunctionPrototypeBind(
// Choose the right bound function map based on whether the target is // Choose the right bound function map based on whether the target is
// constructable. // constructable.
const boundFunctionMap: Map = UnsafeCast<Map>( const boundFunctionMap: Map =
IsConstructor(fn) ? IsConstructor(fn) ?
context *NativeContextSlot(
.elements[NativeContextSlot:: ContextSlot::BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX) :
BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX] : *NativeContextSlot(ContextSlot::
context.elements BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX);
[NativeContextSlot::
BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX]);
// Verify that prototype matches that of the target bound function. // Verify that prototype matches that of the target bound function.
......
...@@ -437,19 +437,16 @@ extern macro RefillMathRandom(NativeContext): Smi; ...@@ -437,19 +437,16 @@ extern macro RefillMathRandom(NativeContext): Smi;
transitioning javascript builtin transitioning javascript builtin
MathRandom(js-implicit context: NativeContext, receiver: JSAny)(): Number { MathRandom(js-implicit context: NativeContext, receiver: JSAny)(): Number {
let smiIndex: Smi = let smiIndex: Smi = *NativeContextSlot(ContextSlot::MATH_RANDOM_INDEX_INDEX);
Cast<Smi>(context.elements[NativeContextSlot::MATH_RANDOM_INDEX_INDEX])
otherwise unreachable;
if (smiIndex == 0) { if (smiIndex == 0) {
// refill math random. // refill math random.
smiIndex = RefillMathRandom(context); smiIndex = RefillMathRandom(context);
} }
const newSmiIndex: Smi = smiIndex - 1; const newSmiIndex: Smi = smiIndex - 1;
context.elements[NativeContextSlot::MATH_RANDOM_INDEX_INDEX] = newSmiIndex; *NativeContextSlot(ContextSlot::MATH_RANDOM_INDEX_INDEX) = newSmiIndex;
const array: FixedDoubleArray = Cast<FixedDoubleArray>( const array: FixedDoubleArray =
context.elements[NativeContextSlot::MATH_RANDOM_CACHE_INDEX]) *NativeContextSlot(ContextSlot::MATH_RANDOM_CACHE_INDEX);
otherwise unreachable;
const random: float64 = const random: float64 =
array.floats[Convert<intptr>(newSmiIndex)].ValueUnsafeAssumeNotHole(); array.floats[Convert<intptr>(newSmiIndex)].ValueUnsafeAssumeNotHole();
return AllocateHeapNumberWithValue(random); return AllocateHeapNumberWithValue(random);
......
...@@ -92,22 +92,19 @@ ObjectSetPrototypeOfDontThrow(implicit context: Context)( ...@@ -92,22 +92,19 @@ ObjectSetPrototypeOfDontThrow(implicit context: Context)(
transitioning builtin CreateObjectWithoutProperties(implicit context: Context)( transitioning builtin CreateObjectWithoutProperties(implicit context: Context)(
prototype: JSAny): JSAny { prototype: JSAny): JSAny {
const nativeContext = LoadNativeContext(context);
try { try {
let map: Map; let map: Map;
let properties: NameDictionary|EmptyFixedArray; let properties: NameDictionary|EmptyFixedArray;
typeswitch (prototype) { typeswitch (prototype) {
case (Null): { case (Null): {
map = UnsafeCast<Map>( map = *NativeContextSlot(
nativeContext.elements ContextSlot::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP);
[NativeContextSlot::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP]);
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity); properties = AllocateNameDictionary(kNameDictionaryInitialCapacity);
} }
case (prototype: JSReceiver): { case (prototype: JSReceiver): {
properties = kEmptyFixedArray; properties = kEmptyFixedArray;
const objectFunction = UnsafeCast<JSFunction>( const objectFunction =
nativeContext.elements[NativeContextSlot::OBJECT_FUNCTION_INDEX]); *NativeContextSlot(ContextSlot::OBJECT_FUNCTION_INDEX);
map = UnsafeCast<Map>(objectFunction.prototype_or_initial_map); map = UnsafeCast<Map>(objectFunction.prototype_or_initial_map);
if (prototype != map.prototype) { if (prototype != map.prototype) {
const prototypeInfo = prototype.map.PrototypeInfo() otherwise Runtime; const prototypeInfo = prototype.map.PrototypeInfo() otherwise Runtime;
......
...@@ -35,7 +35,7 @@ const kResolveString: String = ResolveStringConstant(); ...@@ -35,7 +35,7 @@ const kResolveString: String = ResolveStringConstant();
extern macro IsPromiseResolveProtectorCellInvalid(): bool; extern macro IsPromiseResolveProtectorCellInvalid(): bool;
extern macro AllocateFunctionWithMapAndContext( extern macro AllocateFunctionWithMapAndContext(
Map, SharedFunctionInfo, Context): JSFunction; Map, SharedFunctionInfo, FunctionContext): JSFunction;
extern macro PromiseReactionMapConstant(): Map; extern macro PromiseReactionMapConstant(): Map;
extern macro PromiseFulfillReactionJobTaskMapConstant(): Map; extern macro PromiseFulfillReactionJobTaskMapConstant(): Map;
...@@ -252,24 +252,33 @@ RejectPromise(implicit context: Context)( ...@@ -252,24 +252,33 @@ RejectPromise(implicit context: Context)(
const kPromiseCapabilitySize: const kPromiseCapabilitySize:
constexpr int31 generates 'PromiseCapability::kSize'; constexpr int31 generates 'PromiseCapability::kSize';
const kPromiseBuiltinsCapabilitiesContextLength: constexpr int31
generates 'PromiseBuiltins::kCapabilitiesContextLength'; type PromiseResolvingFunctionContext extends FunctionContext;
const kPromiseBuiltinsCapabilitySlot: constexpr ContextSlot extern enum PromiseResolvingFunctionContextSlot extends intptr
generates 'PromiseBuiltins::kCapabilitySlot'; constexpr 'PromiseBuiltins::PromiseResolvingFunctionContextSlot' {
const kPromiseBuiltinsPromiseSlot: constexpr ContextSlot kPromiseSlot: Slot<PromiseResolvingFunctionContext, JSPromise>,
generates 'PromiseBuiltins::kPromiseSlot'; kAlreadyResolvedSlot: Slot<PromiseResolvingFunctionContext, Boolean>,
const kPromiseBuiltinsAlreadyResolvedSlot: constexpr ContextSlot kDebugEventSlot: Slot<PromiseResolvingFunctionContext, Boolean>,
generates 'PromiseBuiltins::kAlreadyResolvedSlot'; kPromiseContextLength
const kPromiseBuiltinsDebugEventSlot: constexpr ContextSlot }
generates 'PromiseBuiltins::kDebugEventSlot';
type PromiseCapabilitiesExecutorContext extends FunctionContext;
extern enum FunctionContextSlot extends intptr
constexpr 'PromiseBuiltins::FunctionContextSlot' {
kCapabilitySlot: Slot<PromiseCapabilitiesExecutorContext, PromiseCapability>,
kCapabilitiesContextLength
}
@export @export
macro CreatePromiseCapabilitiesExecutorContext( macro CreatePromiseCapabilitiesExecutorContext(
nativeContext: NativeContext, capability: PromiseCapability): Context { nativeContext: NativeContext, capability: PromiseCapability):
const executorContext = AllocateSyntheticFunctionContext( PromiseCapabilitiesExecutorContext {
nativeContext, kPromiseBuiltinsCapabilitiesContextLength); const executorContext = %RawDownCast<PromiseCapabilitiesExecutorContext>(
AllocateSyntheticFunctionContext(
executorContext.elements[kPromiseBuiltinsCapabilitySlot] = capability; nativeContext, FunctionContextSlot::kCapabilitiesContextLength));
InitContextSlot(
executorContext, FunctionContextSlot::kCapabilitySlot, capability);
return executorContext; return executorContext;
} }
...@@ -293,13 +302,12 @@ struct PromiseResolvingFunctions { ...@@ -293,13 +302,12 @@ struct PromiseResolvingFunctions {
@export @export
macro CreatePromiseResolvingFunctions(implicit context: Context)( macro CreatePromiseResolvingFunctions(implicit context: Context)(
promise: JSPromise, debugEvent: Object, nativeContext: NativeContext): promise: JSPromise, debugEvent: Boolean, nativeContext: NativeContext):
PromiseResolvingFunctions { PromiseResolvingFunctions {
const promiseContext = CreatePromiseResolvingFunctionsContext( const promiseContext = CreatePromiseResolvingFunctionsContext(
promise, debugEvent, nativeContext); promise, debugEvent, nativeContext);
const map = UnsafeCast<Map>( const map = *NativeContextSlot(
nativeContext.elements nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const resolveInfo = PromiseCapabilityDefaultResolveSharedFunConstant(); const resolveInfo = PromiseCapabilityDefaultResolveSharedFunConstant();
const resolve: JSFunction = const resolve: JSFunction =
...@@ -312,11 +320,10 @@ macro CreatePromiseResolvingFunctions(implicit context: Context)( ...@@ -312,11 +320,10 @@ macro CreatePromiseResolvingFunctions(implicit context: Context)(
transitioning macro transitioning macro
InnerNewPromiseCapability(implicit context: Context)( InnerNewPromiseCapability(implicit context: Context)(
constructor: HeapObject, debugEvent: Object): PromiseCapability { constructor: HeapObject, debugEvent: Boolean): PromiseCapability {
const nativeContext = LoadNativeContext(context); const nativeContext = LoadNativeContext(context);
if (TaggedEqual( if (constructor ==
constructor, *NativeContextSlot(nativeContext, ContextSlot::PROMISE_FUNCTION_INDEX)) {
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX])) {
const promise = NewJSPromise(); const promise = NewJSPromise();
const pair = const pair =
...@@ -331,9 +338,10 @@ InnerNewPromiseCapability(implicit context: Context)( ...@@ -331,9 +338,10 @@ InnerNewPromiseCapability(implicit context: Context)(
CreatePromiseCapabilitiesExecutorContext(nativeContext, capability); CreatePromiseCapabilitiesExecutorContext(nativeContext, capability);
const executorInfo = PromiseGetCapabilitiesExecutorSharedFunConstant(); const executorInfo = PromiseGetCapabilitiesExecutorSharedFunConstant();
const functionMap = UnsafeCast<Map>( const functionMap =
nativeContext.elements *NativeContextSlot(
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]); nativeContext,
ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const executor = AllocateFunctionWithMapAndContext( const executor = AllocateFunctionWithMapAndContext(
functionMap, executorInfo, executorContext); functionMap, executorInfo, executorContext);
...@@ -351,7 +359,7 @@ InnerNewPromiseCapability(implicit context: Context)( ...@@ -351,7 +359,7 @@ InnerNewPromiseCapability(implicit context: Context)(
// https://tc39.es/ecma262/#sec-newpromisecapability // https://tc39.es/ecma262/#sec-newpromisecapability
transitioning builtin transitioning builtin
NewPromiseCapability(implicit context: Context)( NewPromiseCapability(implicit context: Context)(
maybeConstructor: Object, debugEvent: Object): PromiseCapability { maybeConstructor: Object, debugEvent: Boolean): PromiseCapability {
typeswitch (maybeConstructor) { typeswitch (maybeConstructor) {
case (Smi): { case (Smi): {
ThrowTypeError(MessageTemplate::kNotConstructor, maybeConstructor); ThrowTypeError(MessageTemplate::kNotConstructor, maybeConstructor);
...@@ -368,14 +376,15 @@ NewPromiseCapability(implicit context: Context)( ...@@ -368,14 +376,15 @@ NewPromiseCapability(implicit context: Context)(
// https://tc39.es/ecma262/#sec-promise-reject-functions // https://tc39.es/ecma262/#sec-promise-reject-functions
transitioning javascript builtin transitioning javascript builtin
PromiseCapabilityDefaultReject( PromiseCapabilityDefaultReject(
js-implicit context: NativeContext, receiver: JSAny)(reason: JSAny): JSAny { js-implicit context: Context, receiver: JSAny)(reason: JSAny): JSAny {
const context = %RawDownCast<PromiseResolvingFunctionContext>(context);
// 2. Let promise be F.[[Promise]]. // 2. Let promise be F.[[Promise]].
const promise = const promise =
UnsafeCast<JSPromise>(context.elements[kPromiseBuiltinsPromiseSlot]); *ContextSlot(context, PromiseResolvingFunctionContextSlot::kPromiseSlot);
// 3. Let alreadyResolved be F.[[AlreadyResolved]]. // 3. Let alreadyResolved be F.[[AlreadyResolved]].
const alreadyResolved = UnsafeCast<Boolean>( const alreadyResolved = *ContextSlot(
context.elements[kPromiseBuiltinsAlreadyResolvedSlot]); context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot);
// 4. If alreadyResolved.[[Value]] is true, return undefined. // 4. If alreadyResolved.[[Value]] is true, return undefined.
if (alreadyResolved == True) { if (alreadyResolved == True) {
...@@ -383,26 +392,28 @@ PromiseCapabilityDefaultReject( ...@@ -383,26 +392,28 @@ PromiseCapabilityDefaultReject(
} }
// 5. Set alreadyResolved.[[Value]] to true. // 5. Set alreadyResolved.[[Value]] to true.
context.elements[kPromiseBuiltinsAlreadyResolvedSlot] = True; *ContextSlot(
context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot) =
True;
// 6. Return RejectPromise(promise, reason). // 6. Return RejectPromise(promise, reason).
const debugEvent = const debugEvent = *ContextSlot(
UnsafeCast<Boolean>(context.elements[kPromiseBuiltinsDebugEventSlot]); context, PromiseResolvingFunctionContextSlot::kDebugEventSlot);
return RejectPromise(promise, reason, debugEvent); return RejectPromise(promise, reason, debugEvent);
} }
// https://tc39.es/ecma262/#sec-promise-resolve-functions // https://tc39.es/ecma262/#sec-promise-resolve-functions
transitioning javascript builtin transitioning javascript builtin
PromiseCapabilityDefaultResolve( PromiseCapabilityDefaultResolve(
js-implicit context: NativeContext, js-implicit context: Context, receiver: JSAny)(resolution: JSAny): JSAny {
receiver: JSAny)(resolution: JSAny): JSAny { const context = %RawDownCast<PromiseResolvingFunctionContext>(context);
// 2. Let promise be F.[[Promise]]. // 2. Let promise be F.[[Promise]].
const promise = const promise: JSPromise =
UnsafeCast<JSPromise>(context.elements[kPromiseBuiltinsPromiseSlot]); *ContextSlot(context, PromiseResolvingFunctionContextSlot::kPromiseSlot);
// 3. Let alreadyResolved be F.[[AlreadyResolved]]. // 3. Let alreadyResolved be F.[[AlreadyResolved]].
const alreadyResolved = UnsafeCast<Boolean>( const alreadyResolved: Boolean = *ContextSlot(
context.elements[kPromiseBuiltinsAlreadyResolvedSlot]); context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot);
// 4. If alreadyResolved.[[Value]] is true, return undefined. // 4. If alreadyResolved.[[Value]] is true, return undefined.
if (alreadyResolved == True) { if (alreadyResolved == True) {
...@@ -410,7 +421,9 @@ PromiseCapabilityDefaultResolve( ...@@ -410,7 +421,9 @@ PromiseCapabilityDefaultResolve(
} }
// 5. Set alreadyResolved.[[Value]] to true. // 5. Set alreadyResolved.[[Value]] to true.
context.elements[kPromiseBuiltinsAlreadyResolvedSlot] = True; *ContextSlot(
context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot) =
True;
// The rest of the logic (and the catch prediction) is // The rest of the logic (and the catch prediction) is
// encapsulated in the dedicated ResolvePromise builtin. // encapsulated in the dedicated ResolvePromise builtin.
...@@ -477,8 +490,7 @@ PromiseReject( ...@@ -477,8 +490,7 @@ PromiseReject(
const receiver = Cast<JSReceiver>(receiver) otherwise const receiver = Cast<JSReceiver>(receiver) otherwise
ThrowTypeError(MessageTemplate::kCalledOnNonObject, 'PromiseReject'); ThrowTypeError(MessageTemplate::kCalledOnNonObject, 'PromiseReject');
const promiseFun = const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
context.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX];
if (promiseFun == receiver) { if (promiseFun == receiver) {
const promise = NewJSPromise(PromiseState::kRejected, reason); const promise = NewJSPromise(PromiseState::kRejected, reason);
runtime::PromiseRejectEventFromStack(promise, reason); runtime::PromiseRejectEventFromStack(promise, reason);
...@@ -501,11 +513,11 @@ const kPromiseExecutorAlreadyInvoked: constexpr MessageTemplate ...@@ -501,11 +513,11 @@ const kPromiseExecutorAlreadyInvoked: constexpr MessageTemplate
// https://tc39.es/ecma262/#sec-getcapabilitiesexecutor-functions // https://tc39.es/ecma262/#sec-getcapabilitiesexecutor-functions
transitioning javascript builtin transitioning javascript builtin
PromiseGetCapabilitiesExecutor( PromiseGetCapabilitiesExecutor(js-implicit context: Context, receiver: JSAny)(
js-implicit context: NativeContext, receiver: JSAny)(
resolve: JSAny, reject: JSAny): JSAny { resolve: JSAny, reject: JSAny): JSAny {
const capability = UnsafeCast<PromiseCapability>( const context = %RawDownCast<PromiseCapabilitiesExecutorContext>(context);
context.elements[kPromiseBuiltinsCapabilitySlot]); const capability: PromiseCapability =
*ContextSlot(context, FunctionContextSlot::kCapabilitySlot);
if (capability.resolve != Undefined || capability.reject != Undefined) if (capability.resolve != Undefined || capability.reject != Undefined)
deferred { deferred {
ThrowTypeError(kPromiseExecutorAlreadyInvoked); ThrowTypeError(kPromiseExecutorAlreadyInvoked);
...@@ -519,8 +531,8 @@ PromiseGetCapabilitiesExecutor( ...@@ -519,8 +531,8 @@ PromiseGetCapabilitiesExecutor(
macro IsPromiseResolveLookupChainIntact(implicit context: Context)( macro IsPromiseResolveLookupChainIntact(implicit context: Context)(
nativeContext: NativeContext, constructor: JSReceiver): bool { nativeContext: NativeContext, constructor: JSReceiver): bool {
if (IsForceSlowPath()) return false; if (IsForceSlowPath()) return false;
const promiseFun = UnsafeCast<JSFunction>( const promiseFun =
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]); *NativeContextSlot(nativeContext, ContextSlot::PROMISE_FUNCTION_INDEX);
return promiseFun == constructor && !IsPromiseResolveProtectorCellInvalid(); return promiseFun == constructor && !IsPromiseResolveProtectorCellInvalid();
} }
......
...@@ -21,8 +21,8 @@ struct PromiseAllSettledWrapResultAsFulfilledFunctor { ...@@ -21,8 +21,8 @@ struct PromiseAllSettledWrapResultAsFulfilledFunctor {
// TODO(gsathya): Optimize the creation using a cached map to // TODO(gsathya): Optimize the creation using a cached map to
// prevent transitions here. // prevent transitions here.
// 9. Let obj be ! ObjectCreate(%ObjectPrototype%). // 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
const objectFunction = UnsafeCast<JSFunction>( const objectFunction =
nativeContext.elements[NativeContextSlot::OBJECT_FUNCTION_INDEX]); *NativeContextSlot(nativeContext, ContextSlot::OBJECT_FUNCTION_INDEX);
const objectFunctionMap = const objectFunctionMap =
UnsafeCast<Map>(objectFunction.prototype_or_initial_map); UnsafeCast<Map>(objectFunction.prototype_or_initial_map);
const obj = AllocateJSObjectFromMap(objectFunctionMap); const obj = AllocateJSObjectFromMap(objectFunctionMap);
...@@ -44,8 +44,8 @@ struct PromiseAllSettledWrapResultAsRejectedFunctor { ...@@ -44,8 +44,8 @@ struct PromiseAllSettledWrapResultAsRejectedFunctor {
// TODO(gsathya): Optimize the creation using a cached map to // TODO(gsathya): Optimize the creation using a cached map to
// prevent transitions here. // prevent transitions here.
// 9. Let obj be ! ObjectCreate(%ObjectPrototype%). // 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
const objectFunction = UnsafeCast<JSFunction>( const objectFunction =
nativeContext.elements[NativeContextSlot::OBJECT_FUNCTION_INDEX]); *NativeContextSlot(nativeContext, ContextSlot::OBJECT_FUNCTION_INDEX);
const objectFunctionMap = const objectFunctionMap =
UnsafeCast<Map>(objectFunction.prototype_or_initial_map); UnsafeCast<Map>(objectFunction.prototype_or_initial_map);
const obj = AllocateJSObjectFromMap(objectFunctionMap); const obj = AllocateJSObjectFromMap(objectFunctionMap);
...@@ -62,11 +62,15 @@ struct PromiseAllSettledWrapResultAsRejectedFunctor { ...@@ -62,11 +62,15 @@ struct PromiseAllSettledWrapResultAsRejectedFunctor {
extern macro LoadJSReceiverIdentityHash(Object): intptr labels IfNoHash; extern macro LoadJSReceiverIdentityHash(Object): intptr labels IfNoHash;
extern enum PromiseAllResolveElementContextSlots extends int31 type PromiseAllResolveElementContext extends FunctionContext;
extern enum PromiseAllResolveElementContextSlots extends intptr
constexpr 'PromiseBuiltins::PromiseAllResolveElementContextSlots' { constexpr 'PromiseBuiltins::PromiseAllResolveElementContextSlots' {
kPromiseAllResolveElementRemainingSlot, kPromiseAllResolveElementRemainingSlot:
kPromiseAllResolveElementCapabilitySlot, Slot<PromiseAllResolveElementContext, Smi>,
kPromiseAllResolveElementValuesSlot, kPromiseAllResolveElementCapabilitySlot:
Slot<PromiseAllResolveElementContext, PromiseCapability>,
kPromiseAllResolveElementValuesSlot:
Slot<PromiseAllResolveElementContext, FixedArray>,
kPromiseAllResolveElementLength kPromiseAllResolveElementLength
} }
extern operator '[]=' macro StoreContextElement( extern operator '[]=' macro StoreContextElement(
...@@ -81,7 +85,7 @@ const kPropertyArrayHashFieldMax: constexpr int31 ...@@ -81,7 +85,7 @@ const kPropertyArrayHashFieldMax: constexpr int31
generates 'PropertyArray::HashField::kMax'; generates 'PropertyArray::HashField::kMax';
transitioning macro PromiseAllResolveElementClosure<F: type>( transitioning macro PromiseAllResolveElementClosure<F: type>(
implicit context: Context)( implicit context: PromiseAllResolveElementContext|NativeContext)(
value: JSAny, function: JSFunction, wrapResultFunctor: F, value: JSAny, function: JSFunction, wrapResultFunctor: F,
hasResolveAndRejectClosures: constexpr bool): JSAny { hasResolveAndRejectClosures: constexpr bool): JSAny {
// We use the {function}s context as the marker to remember whether this // We use the {function}s context as the marker to remember whether this
...@@ -89,14 +93,21 @@ transitioning macro PromiseAllResolveElementClosure<F: type>( ...@@ -89,14 +93,21 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
// element context (which is a FunctionContext) until it was called the // element context (which is a FunctionContext) until it was called the
// first time, in which case we make it point to the native context here // first time, in which case we make it point to the native context here
// to mark this resolve element closure as done. // to mark this resolve element closure as done.
if (IsNativeContext(context)) deferred { let promiseContext: PromiseAllResolveElementContext;
typeswitch (context) {
case (NativeContext): deferred {
return Undefined; return Undefined;
} }
case (context: PromiseAllResolveElementContext): {
promiseContext = context;
}
}
assert( assert(
context.length == promiseContext.length ==
PromiseAllResolveElementContextSlots::kPromiseAllResolveElementLength); SmiTag(PromiseAllResolveElementContextSlots::
const nativeContext = LoadNativeContext(context); kPromiseAllResolveElementLength));
const nativeContext = LoadNativeContext(promiseContext);
function.context = nativeContext; function.context = nativeContext;
// Determine the index from the {function}. // Determine the index from the {function}.
...@@ -106,19 +117,23 @@ transitioning macro PromiseAllResolveElementClosure<F: type>( ...@@ -106,19 +117,23 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
assert(identityHash > 0); assert(identityHash > 0);
const index = identityHash - 1; const index = identityHash - 1;
let remainingElementsCount = UnsafeCast<Smi>( let remainingElementsCount = *ContextSlot(
context.elements[PromiseAllResolveElementContextSlots:: promiseContext,
kPromiseAllResolveElementRemainingSlot]); PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot);
let values = UnsafeCast<FixedArray>( let values = *ContextSlot(
context.elements[PromiseAllResolveElementContextSlots:: promiseContext,
kPromiseAllResolveElementValuesSlot]); PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot);
const newCapacity = index + 1; const newCapacity = index + 1;
if (newCapacity > values.length_intptr) deferred { if (newCapacity > values.length_intptr) deferred {
// This happens only when the promises are resolved during iteration. // This happens only when the promises are resolved during iteration.
values = ExtractFixedArray(values, 0, values.length_intptr, newCapacity); values = ExtractFixedArray(values, 0, values.length_intptr, newCapacity);
context.elements[PromiseAllResolveElementContextSlots:: *ContextSlot(
kPromiseAllResolveElementValuesSlot] = values; promiseContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot) = values;
} }
// Promise.allSettled, for each input element, has both a resolve and a reject // Promise.allSettled, for each input element, has both a resolve and a reject
...@@ -144,19 +159,21 @@ transitioning macro PromiseAllResolveElementClosure<F: type>( ...@@ -144,19 +159,21 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
values.objects[index] = updatedValue; values.objects[index] = updatedValue;
remainingElementsCount = remainingElementsCount - 1; remainingElementsCount = remainingElementsCount - 1;
context.elements[PromiseAllResolveElementContextSlots:: *ContextSlot(
kPromiseAllResolveElementRemainingSlot] = promiseContext,
remainingElementsCount; PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot) = remainingElementsCount;
if (remainingElementsCount == 0) { if (remainingElementsCount == 0) {
const capability = UnsafeCast<PromiseCapability>( const capability = *ContextSlot(
context.elements[PromiseAllResolveElementContextSlots:: promiseContext,
kPromiseAllResolveElementCapabilitySlot]); PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementCapabilitySlot);
const resolve = UnsafeCast<JSAny>(capability.resolve); const resolve = UnsafeCast<JSAny>(capability.resolve);
const arrayMap = UnsafeCast<Map>( const arrayMap =
nativeContext *NativeContextSlot(
.elements[NativeContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX]); nativeContext, ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX);
const valuesArray = NewJSArray(arrayMap, values); const valuesArray = NewJSArray(arrayMap, values);
Call(context, resolve, Undefined, valuesArray); Call(promiseContext, resolve, Undefined, valuesArray);
} }
return Undefined; return Undefined;
} }
...@@ -165,6 +182,8 @@ transitioning javascript builtin ...@@ -165,6 +182,8 @@ transitioning javascript builtin
PromiseAllResolveElementClosure( PromiseAllResolveElementClosure(
js-implicit context: Context, receiver: JSAny, js-implicit context: Context, receiver: JSAny,
target: JSFunction)(value: JSAny): JSAny { target: JSFunction)(value: JSAny): JSAny {
const context =
%RawDownCast<PromiseAllResolveElementContext|NativeContext>(context);
return PromiseAllResolveElementClosure( return PromiseAllResolveElementClosure(
value, target, PromiseAllWrapResultAsFulfilledFunctor{}, false); value, target, PromiseAllWrapResultAsFulfilledFunctor{}, false);
} }
...@@ -173,6 +192,8 @@ transitioning javascript builtin ...@@ -173,6 +192,8 @@ transitioning javascript builtin
PromiseAllSettledResolveElementClosure( PromiseAllSettledResolveElementClosure(
js-implicit context: Context, receiver: JSAny, js-implicit context: Context, receiver: JSAny,
target: JSFunction)(value: JSAny): JSAny { target: JSFunction)(value: JSAny): JSAny {
const context =
%RawDownCast<PromiseAllResolveElementContext|NativeContext>(context);
return PromiseAllResolveElementClosure( return PromiseAllResolveElementClosure(
value, target, PromiseAllSettledWrapResultAsFulfilledFunctor{}, true); value, target, PromiseAllSettledWrapResultAsFulfilledFunctor{}, true);
} }
...@@ -181,6 +202,8 @@ transitioning javascript builtin ...@@ -181,6 +202,8 @@ transitioning javascript builtin
PromiseAllSettledRejectElementClosure( PromiseAllSettledRejectElementClosure(
js-implicit context: Context, receiver: JSAny, js-implicit context: Context, receiver: JSAny,
target: JSFunction)(value: JSAny): JSAny { target: JSFunction)(value: JSAny): JSAny {
const context =
%RawDownCast<PromiseAllResolveElementContext|NativeContext>(context);
return PromiseAllResolveElementClosure( return PromiseAllResolveElementClosure(
value, target, PromiseAllSettledWrapResultAsRejectedFunctor{}, true); value, target, PromiseAllSettledWrapResultAsRejectedFunctor{}, true);
} }
......
This diff is collapsed.
...@@ -5,11 +5,15 @@ ...@@ -5,11 +5,15 @@
#include 'src/builtins/builtins-promise-gen.h' #include 'src/builtins/builtins-promise-gen.h'
namespace promise { namespace promise {
extern enum PromiseAnyRejectElementContextSlots extends int31 type PromiseAnyRejectElementContext extends FunctionContext;
extern enum PromiseAnyRejectElementContextSlots extends intptr
constexpr 'PromiseBuiltins::PromiseAnyRejectElementContextSlots' { constexpr 'PromiseBuiltins::PromiseAnyRejectElementContextSlots' {
kPromiseAnyRejectElementRemainingSlot, kPromiseAnyRejectElementRemainingSlot:
kPromiseAnyRejectElementCapabilitySlot, Slot<PromiseAnyRejectElementContext, Smi>,
kPromiseAnyRejectElementErrorsSlot, kPromiseAnyRejectElementCapabilitySlot:
Slot<PromiseAnyRejectElementContext, PromiseCapability>,
kPromiseAnyRejectElementErrorsSlot:
Slot<PromiseAnyRejectElementContext, FixedArray>,
kPromiseAnyRejectElementLength kPromiseAnyRejectElementLength
} }
...@@ -27,30 +31,36 @@ extern operator '[]' macro LoadContextElement( ...@@ -27,30 +31,36 @@ extern operator '[]' macro LoadContextElement(
// case to mark it's done). See Promise.all which uses the same approach. // case to mark it's done). See Promise.all which uses the same approach.
transitioning macro CreatePromiseAnyRejectElementContext( transitioning macro CreatePromiseAnyRejectElementContext(
implicit context: Context)( implicit context: Context)(
capability: PromiseCapability, nativeContext: NativeContext): Context { capability: PromiseCapability,
const rejectContext = AllocateSyntheticFunctionContext( nativeContext: NativeContext): PromiseAnyRejectElementContext {
const rejectContext = %RawDownCast<PromiseAnyRejectElementContext>(
AllocateSyntheticFunctionContext(
nativeContext, nativeContext,
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength); PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength));
rejectContext.elements[PromiseAnyRejectElementContextSlots:: InitContextSlot(
kPromiseAnyRejectElementRemainingSlot] = rejectContext,
SmiConstant(1); PromiseAnyRejectElementContextSlots::
rejectContext.elements[PromiseAnyRejectElementContextSlots:: kPromiseAnyRejectElementRemainingSlot,
kPromiseAnyRejectElementCapabilitySlot] = 1);
capability; InitContextSlot(
rejectContext.elements[PromiseAnyRejectElementContextSlots:: rejectContext,
kPromiseAnyRejectElementErrorsSlot] = PromiseAnyRejectElementContextSlots::
kEmptyFixedArray; kPromiseAnyRejectElementCapabilitySlot,
capability);
InitContextSlot(
rejectContext,
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementErrorsSlot,
kEmptyFixedArray);
return rejectContext; return rejectContext;
} }
macro CreatePromiseAnyRejectElementFunction(implicit context: Context)( macro CreatePromiseAnyRejectElementFunction(implicit context: Context)(
rejectElementContext: Context, index: Smi, rejectElementContext: PromiseAnyRejectElementContext, index: Smi,
nativeContext: NativeContext): JSFunction { nativeContext: NativeContext): JSFunction {
assert(index > 0); assert(index > 0);
assert(index < kPropertyArrayHashFieldMax); assert(index < kPropertyArrayHashFieldMax);
const map = UnsafeCast<Map>( const map = *ContextSlot(
nativeContext.elements nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const rejectInfo = PromiseAnyRejectElementSharedFunConstant(); const rejectInfo = PromiseAnyRejectElementSharedFunConstant();
const reject = const reject =
AllocateFunctionWithMapAndContext(map, rejectInfo, rejectElementContext); AllocateFunctionWithMapAndContext(map, rejectInfo, rejectElementContext);
...@@ -81,7 +91,9 @@ PromiseAnyRejectElementClosure( ...@@ -81,7 +91,9 @@ PromiseAnyRejectElementClosure(
assert( assert(
context.length == context.length ==
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength); SmiTag(
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength));
const context = %RawDownCast<PromiseAnyRejectElementContext>(context);
// 4. Set alreadyCalled.[[Value]] to true. // 4. Set alreadyCalled.[[Value]] to true.
const nativeContext = LoadNativeContext(context); const nativeContext = LoadNativeContext(context);
...@@ -94,32 +106,36 @@ PromiseAnyRejectElementClosure( ...@@ -94,32 +106,36 @@ PromiseAnyRejectElementClosure(
const index = identityHash - 1; const index = identityHash - 1;
// 6. Let errors be F.[[Errors]]. // 6. Let errors be F.[[Errors]].
let errors = UnsafeCast<FixedArray>( let errors = *ContextSlot(
context.elements[PromiseAnyRejectElementContextSlots:: context,
kPromiseAnyRejectElementErrorsSlot]); PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementErrorsSlot);
// 7. Let promiseCapability be F.[[Capability]]. // 7. Let promiseCapability be F.[[Capability]].
// 8. Let remainingElementsCount be F.[[RemainingElements]]. // 8. Let remainingElementsCount be F.[[RemainingElements]].
let remainingElementsCount = UnsafeCast<Smi>( let remainingElementsCount = *ContextSlot(
context.elements[PromiseAnyRejectElementContextSlots:: context,
kPromiseAnyRejectElementRemainingSlot]); PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot);
// 9. Set errors[index] to x. // 9. Set errors[index] to x.
const newCapacity = IntPtrMax(SmiUntag(remainingElementsCount), index + 1); const newCapacity = IntPtrMax(SmiUntag(remainingElementsCount), index + 1);
if (newCapacity > errors.length_intptr) deferred { if (newCapacity > errors.length_intptr) deferred {
errors = ExtractFixedArray(errors, 0, errors.length_intptr, newCapacity); errors = ExtractFixedArray(errors, 0, errors.length_intptr, newCapacity);
context.elements[PromiseAnyRejectElementContextSlots:: *ContextSlot(
kPromiseAnyRejectElementErrorsSlot] = errors; context,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot) = errors;
} }
errors.objects[index] = value; errors.objects[index] = value;
// 10. Set remainingElementsCount.[[Value]] to // 10. Set remainingElementsCount.[[Value]] to
// remainingElementsCount.[[Value]] - 1. // remainingElementsCount.[[Value]] - 1.
remainingElementsCount = remainingElementsCount - 1; remainingElementsCount = remainingElementsCount - 1;
context.elements[PromiseAnyRejectElementContextSlots:: *ContextSlot(
kPromiseAnyRejectElementRemainingSlot] = context,
remainingElementsCount; PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot) = remainingElementsCount;
// 11. If remainingElementsCount.[[Value]] is 0, then // 11. If remainingElementsCount.[[Value]] is 0, then
if (remainingElementsCount == 0) { if (remainingElementsCount == 0) {
...@@ -128,9 +144,10 @@ PromiseAnyRejectElementClosure( ...@@ -128,9 +144,10 @@ PromiseAnyRejectElementClosure(
// b. Set error.[[AggregateErrors]] to errors. // b. Set error.[[AggregateErrors]] to errors.
const error = ConstructAggregateError(errors); const error = ConstructAggregateError(errors);
// c. Return ? Call(promiseCapability.[[Reject]], undefined, « error »). // c. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
const capability = UnsafeCast<PromiseCapability>( const capability = *ContextSlot(
context.elements[PromiseAnyRejectElementContextSlots:: context,
kPromiseAnyRejectElementCapabilitySlot]); PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementCapabilitySlot);
Call(context, UnsafeCast<Callable>(capability.reject), Undefined, error); Call(context, UnsafeCast<Callable>(capability.reject), Undefined, error);
} }
...@@ -158,8 +175,8 @@ Reject(Object) { ...@@ -158,8 +175,8 @@ Reject(Object) {
let index: Smi = 1; let index: Smi = 1;
try { try {
const fastIteratorResultMap = UnsafeCast<Map>( const fastIteratorResultMap = *NativeContextSlot(
nativeContext.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]); nativeContext, ContextSlot::ITERATOR_RESULT_MAP_INDEX);
// 8. Repeat, // 8. Repeat,
while (true) { while (true) {
let nextValue: JSAny; let nextValue: JSAny;
...@@ -231,12 +248,14 @@ Reject(Object) { ...@@ -231,12 +248,14 @@ Reject(Object) {
rejectElementContext, index, nativeContext); rejectElementContext, index, nativeContext);
// q. Set remainingElementsCount.[[Value]] to // q. Set remainingElementsCount.[[Value]] to
// remainingElementsCount.[[Value]] + 1. // remainingElementsCount.[[Value]] + 1.
const remainingElementsCount = UnsafeCast<Smi>( const remainingElementsCount = *ContextSlot(
rejectElementContext rejectElementContext,
.elements[PromiseAnyRejectElementContextSlots:: PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot]); kPromiseAnyRejectElementRemainingSlot);
rejectElementContext.elements[PromiseAnyRejectElementContextSlots:: *ContextSlot(
kPromiseAnyRejectElementRemainingSlot] = rejectElementContext,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot) =
remainingElementsCount + 1; remainingElementsCount + 1;
// r. Perform ? Invoke(nextPromise, "then", « // r. Perform ? Invoke(nextPromise, "then", «
...@@ -270,13 +289,10 @@ Reject(Object) { ...@@ -270,13 +289,10 @@ Reject(Object) {
// i. Set iteratorRecord.[[Done]] to true. // i. Set iteratorRecord.[[Done]] to true.
// ii. Set remainingElementsCount.[[Value]] to // ii. Set remainingElementsCount.[[Value]] to
// remainingElementsCount.[[Value]] - 1. // remainingElementsCount.[[Value]] - 1.
let remainingElementsCount = UnsafeCast<Smi>( const remainingElementsCount = -- *ContextSlot(
rejectElementContext.elements[PromiseAnyRejectElementContextSlots:: rejectElementContext,
kPromiseAnyRejectElementRemainingSlot]); PromiseAnyRejectElementContextSlots::
remainingElementsCount -= 1; kPromiseAnyRejectElementRemainingSlot);
rejectElementContext.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot] =
remainingElementsCount;
// iii. If remainingElementsCount.[[Value]] is 0, then // iii. If remainingElementsCount.[[Value]] is 0, then
if (remainingElementsCount == 0) deferred { if (remainingElementsCount == 0) deferred {
...@@ -285,10 +301,10 @@ Reject(Object) { ...@@ -285,10 +301,10 @@ Reject(Object) {
// We may already have elements in "errors" - this happens when the // We may already have elements in "errors" - this happens when the
// Thenable calls the reject callback immediately. // Thenable calls the reject callback immediately.
const errors = UnsafeCast<FixedArray>( const errors: FixedArray = *ContextSlot(
rejectElementContext rejectElementContext,
.elements[PromiseAnyRejectElementContextSlots:: PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot]); kPromiseAnyRejectElementErrorsSlot);
const error = ConstructAggregateError(errors); const error = ConstructAggregateError(errors);
// 3. Return ThrowCompletion(error). // 3. Return ThrowCompletion(error).
......
...@@ -57,8 +57,7 @@ PromiseConstructor( ...@@ -57,8 +57,7 @@ PromiseConstructor(
ThrowTypeError(MessageTemplate::kResolverNotAFunction, executor); ThrowTypeError(MessageTemplate::kResolverNotAFunction, executor);
} }
const promiseFun = UnsafeCast<JSFunction>( const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
context.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
// Silently fail if the stack looks fishy. // Silently fail if the stack looks fishy.
if (HasAccessCheckFailed(context, promiseFun, executor)) { if (HasAccessCheckFailed(context, promiseFun, executor)) {
......
...@@ -7,41 +7,48 @@ ...@@ -7,41 +7,48 @@
namespace promise { namespace promise {
// TODO(joshualitt): The below ContextSlots are only available on synthetic type PromiseValueThunkOrReasonContext extends FunctionContext;
// contexts created by the promise pipeline for use in the promise pipeline. extern enum PromiseValueThunkOrReasonContextSlot extends intptr
// However, with Torque we should type the context and its slots to prevent constexpr 'PromiseBuiltins::PromiseValueThunkOrReasonContextSlot' {
// accidentially using these slots on contexts which don't support them. kValueSlot: Slot<PromiseValueThunkOrReasonContext, JSAny>,
const kPromiseBuiltinsValueSlot: constexpr ContextSlot kPromiseValueThunkOrReasonContextLength
generates 'PromiseBuiltins::kValueSlot'; }
const kPromiseBuiltinsOnFinallySlot: constexpr ContextSlot
generates 'PromiseBuiltins::kOnFinallySlot'; type PromiseFinallyContext extends FunctionContext;
const kPromiseBuiltinsConstructorSlot: constexpr ContextSlot extern enum PromiseFinallyContextSlot extends intptr
generates 'PromiseBuiltins::kConstructorSlot'; constexpr 'PromiseBuiltins::PromiseFinallyContextSlot' {
const kPromiseBuiltinsPromiseValueThunkOrReasonContextLength: constexpr int31 kOnFinallySlot: Slot<PromiseFinallyContext, Callable>,
generates 'PromiseBuiltins::kPromiseValueThunkOrReasonContextLength'; kConstructorSlot: Slot<PromiseFinallyContext, Constructor>,
const kPromiseBuiltinsPromiseFinallyContextLength: constexpr int31 kPromiseFinallyContextLength
generates 'PromiseBuiltins::kPromiseFinallyContextLength'; }
transitioning javascript builtin transitioning javascript builtin
PromiseValueThunkFinally( PromiseValueThunkFinally(
js-implicit context: Context, receiver: JSAny)(): JSAny { js-implicit context: Context, receiver: JSAny)(): JSAny {
return UnsafeCast<JSAny>(context.elements[kPromiseBuiltinsValueSlot]); const context = %RawDownCast<PromiseValueThunkOrReasonContext>(context);
return *ContextSlot(
context, PromiseValueThunkOrReasonContextSlot::kValueSlot);
} }
transitioning javascript builtin transitioning javascript builtin
PromiseThrowerFinally(js-implicit context: Context, receiver: JSAny)(): never { PromiseThrowerFinally(js-implicit context: Context, receiver: JSAny)(): never {
const reason = UnsafeCast<JSAny>(context.elements[kPromiseBuiltinsValueSlot]); const context = %RawDownCast<PromiseValueThunkOrReasonContext>(context);
const reason =
*ContextSlot(context, PromiseValueThunkOrReasonContextSlot::kValueSlot);
Throw(reason); Throw(reason);
} }
macro CreateThrowerFunction(implicit context: Context)( macro CreateThrowerFunction(implicit context: Context)(
nativeContext: NativeContext, reason: JSAny): JSFunction { nativeContext: NativeContext, reason: JSAny): JSFunction {
const throwerContext = AllocateSyntheticFunctionContext( const throwerContext = %RawDownCast<PromiseValueThunkOrReasonContext>(
nativeContext, kPromiseBuiltinsPromiseValueThunkOrReasonContextLength); AllocateSyntheticFunctionContext(
throwerContext.elements[kPromiseBuiltinsValueSlot] = reason; nativeContext,
const map = UnsafeCast<Map>( PromiseValueThunkOrReasonContextSlot::
nativeContext.elements kPromiseValueThunkOrReasonContextLength));
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]); InitContextSlot(
throwerContext, PromiseValueThunkOrReasonContextSlot::kValueSlot, reason);
const map = *ContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const throwerInfo = PromiseThrowerFinallySharedFunConstant(); const throwerInfo = PromiseThrowerFinallySharedFunConstant();
return AllocateFunctionWithMapAndContext(map, throwerInfo, throwerContext); return AllocateFunctionWithMapAndContext(map, throwerInfo, throwerContext);
} }
...@@ -49,17 +56,18 @@ macro CreateThrowerFunction(implicit context: Context)( ...@@ -49,17 +56,18 @@ macro CreateThrowerFunction(implicit context: Context)(
transitioning javascript builtin transitioning javascript builtin
PromiseCatchFinally( PromiseCatchFinally(
js-implicit context: Context, receiver: JSAny)(reason: JSAny): JSAny { js-implicit context: Context, receiver: JSAny)(reason: JSAny): JSAny {
const context = %RawDownCast<PromiseFinallyContext>(context);
// 1. Let onFinally be F.[[OnFinally]]. // 1. Let onFinally be F.[[OnFinally]].
// 2. Assert: IsCallable(onFinally) is true. // 2. Assert: IsCallable(onFinally) is true.
const onFinally = const onFinally: Callable =
UnsafeCast<Callable>(context.elements[kPromiseBuiltinsOnFinallySlot]); *ContextSlot(context, PromiseFinallyContextSlot::kOnFinallySlot);
// 3. Let result be ? Call(onFinally). // 3. Let result be ? Call(onFinally).
const result = Call(context, onFinally, Undefined); const result = Call(context, onFinally, Undefined);
// 4. Let C be F.[[Constructor]]. // 4. Let C be F.[[Constructor]].
const constructor = const constructor: Constructor =
UnsafeCast<JSFunction>(context.elements[kPromiseBuiltinsConstructorSlot]); *ContextSlot(context, PromiseFinallyContextSlot::kConstructorSlot);
// 5. Assert: IsConstructor(C) is true. // 5. Assert: IsConstructor(C) is true.
assert(IsConstructor(constructor)); assert(IsConstructor(constructor));
...@@ -77,12 +85,16 @@ PromiseCatchFinally( ...@@ -77,12 +85,16 @@ PromiseCatchFinally(
macro CreateValueThunkFunction(implicit context: Context)( macro CreateValueThunkFunction(implicit context: Context)(
nativeContext: NativeContext, value: JSAny): JSFunction { nativeContext: NativeContext, value: JSAny): JSFunction {
const valueThunkContext = AllocateSyntheticFunctionContext( const valueThunkContext = %RawDownCast<PromiseValueThunkOrReasonContext>(
nativeContext, kPromiseBuiltinsPromiseValueThunkOrReasonContextLength); AllocateSyntheticFunctionContext(
valueThunkContext.elements[kPromiseBuiltinsValueSlot] = value; nativeContext,
const map = UnsafeCast<Map>( PromiseValueThunkOrReasonContextSlot::
nativeContext.elements kPromiseValueThunkOrReasonContextLength));
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]); InitContextSlot(
valueThunkContext, PromiseValueThunkOrReasonContextSlot::kValueSlot,
value);
const map = *ContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const valueThunkInfo = PromiseValueThunkFinallySharedFunConstant(); const valueThunkInfo = PromiseValueThunkFinallySharedFunConstant();
return AllocateFunctionWithMapAndContext( return AllocateFunctionWithMapAndContext(
map, valueThunkInfo, valueThunkContext); map, valueThunkInfo, valueThunkContext);
...@@ -91,17 +103,18 @@ macro CreateValueThunkFunction(implicit context: Context)( ...@@ -91,17 +103,18 @@ macro CreateValueThunkFunction(implicit context: Context)(
transitioning javascript builtin transitioning javascript builtin
PromiseThenFinally( PromiseThenFinally(
js-implicit context: Context, receiver: JSAny)(value: JSAny): JSAny { js-implicit context: Context, receiver: JSAny)(value: JSAny): JSAny {
const context = %RawDownCast<PromiseFinallyContext>(context);
// 1. Let onFinally be F.[[OnFinally]]. // 1. Let onFinally be F.[[OnFinally]].
// 2. Assert: IsCallable(onFinally) is true. // 2. Assert: IsCallable(onFinally) is true.
const onFinally = const onFinally =
UnsafeCast<Callable>(context.elements[kPromiseBuiltinsOnFinallySlot]); *ContextSlot(context, PromiseFinallyContextSlot::kOnFinallySlot);
// 3. Let result be ? Call(onFinally). // 3. Let result be ? Call(onFinally).
const result = Call(context, onFinally, Undefined); const result = Call(context, onFinally, Undefined);
// 4. Let C be F.[[Constructor]]. // 4. Let C be F.[[Constructor]].
const constructor = const constructor =
UnsafeCast<JSFunction>(context.elements[kPromiseBuiltinsConstructorSlot]); *ContextSlot(context, PromiseFinallyContextSlot::kConstructorSlot);
// 5. Assert: IsConstructor(C) is true. // 5. Assert: IsConstructor(C) is true.
assert(IsConstructor(constructor)); assert(IsConstructor(constructor));
...@@ -124,14 +137,17 @@ struct PromiseFinallyFunctions { ...@@ -124,14 +137,17 @@ struct PromiseFinallyFunctions {
macro CreatePromiseFinallyFunctions(implicit context: Context)( macro CreatePromiseFinallyFunctions(implicit context: Context)(
nativeContext: NativeContext, onFinally: Callable, nativeContext: NativeContext, onFinally: Callable,
constructor: JSReceiver): PromiseFinallyFunctions { constructor: Constructor): PromiseFinallyFunctions {
const promiseContext = AllocateSyntheticFunctionContext( const promiseContext =
nativeContext, kPromiseBuiltinsPromiseFinallyContextLength); %RawDownCast<PromiseFinallyContext>(AllocateSyntheticFunctionContext(
promiseContext.elements[kPromiseBuiltinsOnFinallySlot] = onFinally; nativeContext,
promiseContext.elements[kPromiseBuiltinsConstructorSlot] = constructor; PromiseFinallyContextSlot::kPromiseFinallyContextLength));
const map = UnsafeCast<Map>( InitContextSlot(
nativeContext.elements promiseContext, PromiseFinallyContextSlot::kOnFinallySlot, onFinally);
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]); InitContextSlot(
promiseContext, PromiseFinallyContextSlot::kConstructorSlot, constructor);
const map = *ContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const thenFinallyInfo = PromiseThenFinallySharedFunConstant(); const thenFinallyInfo = PromiseThenFinallySharedFunConstant();
const thenFinally = const thenFinally =
AllocateFunctionWithMapAndContext(map, thenFinallyInfo, promiseContext); AllocateFunctionWithMapAndContext(map, thenFinallyInfo, promiseContext);
...@@ -154,15 +170,15 @@ PromisePrototypeFinally( ...@@ -154,15 +170,15 @@ PromisePrototypeFinally(
// 3. Let C be ? SpeciesConstructor(promise, %Promise%). // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
const nativeContext = LoadNativeContext(context); const nativeContext = LoadNativeContext(context);
const promiseFun = UnsafeCast<Callable>( const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
let constructor: JSReceiver = promiseFun; let constructor: Constructor = UnsafeCast<Constructor>(promiseFun);
const receiverMap = jsReceiver.map; const receiverMap = jsReceiver.map;
if (!IsJSPromiseMap(receiverMap) || if (!IsJSPromiseMap(receiverMap) ||
!IsPromiseSpeciesLookupChainIntact(nativeContext, receiverMap)) !IsPromiseSpeciesLookupChainIntact(nativeContext, receiverMap))
deferred { deferred {
constructor = SpeciesConstructor(jsReceiver, promiseFun); constructor =
UnsafeCast<Constructor>(SpeciesConstructor(jsReceiver, promiseFun));
} }
// 4. Assert: IsConstructor(C) is true. // 4. Assert: IsConstructor(C) is true.
......
...@@ -22,8 +22,7 @@ PromiseResolveThenableJob(implicit context: Context)( ...@@ -22,8 +22,7 @@ PromiseResolveThenableJob(implicit context: Context)(
// We take the generic (slow-)path if a PromiseHook is enabled or the // We take the generic (slow-)path if a PromiseHook is enabled or the
// debugger is active, to make sure we expose spec compliant behavior. // debugger is active, to make sure we expose spec compliant behavior.
const nativeContext = LoadNativeContext(context); const nativeContext = LoadNativeContext(context);
const promiseThen = const promiseThen = *NativeContextSlot(ContextSlot::PROMISE_THEN_INDEX);
nativeContext.elements[NativeContextSlot::PROMISE_THEN_INDEX];
const thenableMap = thenable.map; const thenableMap = thenable.map;
if (TaggedEqual(then, promiseThen) && IsJSPromiseMap(thenableMap) && if (TaggedEqual(then, promiseThen) && IsJSPromiseMap(thenableMap) &&
!IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() && !IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() &&
......
...@@ -38,9 +38,7 @@ macro PromiseInit(promise: JSPromise): void { ...@@ -38,9 +38,7 @@ macro PromiseInit(promise: JSPromise): void {
} }
macro InnerNewJSPromise(implicit context: Context)(): JSPromise { macro InnerNewJSPromise(implicit context: Context)(): JSPromise {
const nativeContext = LoadNativeContext(context); const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
const promiseFun = UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
assert(IsFunctionWithPrototypeSlotMap(promiseFun.map)); assert(IsFunctionWithPrototypeSlotMap(promiseFun.map));
const promiseMap = UnsafeCast<Map>(promiseFun.prototype_or_initial_map); const promiseMap = UnsafeCast<Map>(promiseFun.prototype_or_initial_map);
const promiseHeapObject = promise_internal::AllocateJSPromise(context); const promiseHeapObject = promise_internal::AllocateJSPromise(context);
...@@ -70,8 +68,8 @@ macro NewPromiseFulfillReactionJobTask(implicit context: Context)( ...@@ -70,8 +68,8 @@ macro NewPromiseFulfillReactionJobTask(implicit context: Context)(
handler, handler,
promise_or_capability: promiseOrCapability, promise_or_capability: promiseOrCapability,
continuation_preserved_embedder_data: continuation_preserved_embedder_data:
nativeContext.elements *ContextSlot(
[NativeContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX] nativeContext, ContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX)
}; };
} }
...@@ -87,8 +85,8 @@ macro NewPromiseRejectReactionJobTask(implicit context: Context)( ...@@ -87,8 +85,8 @@ macro NewPromiseRejectReactionJobTask(implicit context: Context)(
handler, handler,
promise_or_capability: promiseOrCapability, promise_or_capability: promiseOrCapability,
continuation_preserved_embedder_data: continuation_preserved_embedder_data:
nativeContext.elements *ContextSlot(
[NativeContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX] nativeContext, ContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX)
}; };
} }
...@@ -146,8 +144,8 @@ macro NewPromiseReaction(implicit context: Context)( ...@@ -146,8 +144,8 @@ macro NewPromiseReaction(implicit context: Context)(
fulfill_handler: fulfillHandler, fulfill_handler: fulfillHandler,
promise_or_capability: promiseOrCapability, promise_or_capability: promiseOrCapability,
continuation_preserved_embedder_data: continuation_preserved_embedder_data:
nativeContext.elements *ContextSlot(
[NativeContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX] nativeContext, ContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX)
}; };
} }
...@@ -210,8 +208,8 @@ macro InvokeThen<F: type>(implicit context: Context)( ...@@ -210,8 +208,8 @@ macro InvokeThen<F: type>(implicit context: Context)(
if (!Is<Smi>(receiver) && if (!Is<Smi>(receiver) &&
IsPromiseThenLookupChainIntact( IsPromiseThenLookupChainIntact(
nativeContext, UnsafeCast<HeapObject>(receiver).map)) { nativeContext, UnsafeCast<HeapObject>(receiver).map)) {
const then = UnsafeCast<JSAny>( const then =
nativeContext.elements[NativeContextSlot::PROMISE_THEN_INDEX]); *NativeContextSlot(nativeContext, ContextSlot::PROMISE_THEN_INDEX);
return callFunctor.Call(nativeContext, then, receiver, arg1, arg2); return callFunctor.Call(nativeContext, then, receiver, arg1, arg2);
} else } else
deferred { deferred {
......
...@@ -50,8 +50,8 @@ PromiseRace( ...@@ -50,8 +50,8 @@ PromiseRace(
// Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability). // Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
try { try {
const fastIteratorResultMap = UnsafeCast<Map>( const fastIteratorResultMap = *NativeContextSlot(
nativeContext.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]); nativeContext, ContextSlot::ITERATOR_RESULT_MAP_INDEX);
while (true) { while (true) {
let nextValue: JSAny; let nextValue: JSAny;
try { try {
......
...@@ -30,8 +30,7 @@ transitioning builtin ...@@ -30,8 +30,7 @@ transitioning builtin
PromiseResolve(implicit context: Context)( PromiseResolve(implicit context: Context)(
constructor: JSReceiver, value: JSAny): JSAny { constructor: JSReceiver, value: JSAny): JSAny {
const nativeContext = LoadNativeContext(context); const nativeContext = LoadNativeContext(context);
const promiseFun = const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX];
try { try {
// Check if {value} is a JSPromise. // Check if {value} is a JSPromise.
const value = Cast<JSPromise>(value) otherwise NeedToAllocate; const value = Cast<JSPromise>(value) otherwise NeedToAllocate;
...@@ -41,7 +40,9 @@ PromiseResolve(implicit context: Context)( ...@@ -41,7 +40,9 @@ PromiseResolve(implicit context: Context)(
// intact, as that guards the lookup path for "constructor" on // intact, as that guards the lookup path for "constructor" on
// JSPromise instances which have the (initial) Promise.prototype. // JSPromise instances which have the (initial) Promise.prototype.
const promisePrototype = const promisePrototype =
nativeContext.elements[NativeContextSlot::PROMISE_PROTOTYPE_INDEX]; *NativeContextSlot(ContextSlot::PROMISE_PROTOTYPE_INDEX);
// Check that Torque load elimination works.
static_assert(nativeContext == LoadNativeContext(context));
if (value.map.prototype != promisePrototype) { if (value.map.prototype != promisePrototype) {
goto SlowConstructor; goto SlowConstructor;
} }
...@@ -138,8 +139,7 @@ ResolvePromise(implicit context: Context)( ...@@ -138,8 +139,7 @@ ResolvePromise(implicit context: Context)(
assert(IsJSReceiverMap(resolutionMap)); assert(IsJSReceiverMap(resolutionMap));
assert(!IsPromiseThenProtectorCellInvalid()); assert(!IsPromiseThenProtectorCellInvalid());
if (resolutionMap == if (resolutionMap ==
nativeContext *NativeContextSlot(ContextSlot::ITERATOR_RESULT_MAP_INDEX)) {
.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]) {
return FulfillPromise(promise, resolution); return FulfillPromise(promise, resolution);
} else { } else {
goto Slow; goto Slow;
...@@ -147,10 +147,12 @@ ResolvePromise(implicit context: Context)( ...@@ -147,10 +147,12 @@ ResolvePromise(implicit context: Context)(
} }
const promisePrototype = const promisePrototype =
nativeContext.elements[NativeContextSlot::PROMISE_PROTOTYPE_INDEX]; *NativeContextSlot(ContextSlot::PROMISE_PROTOTYPE_INDEX);
if (resolutionMap.prototype == promisePrototype) { if (resolutionMap.prototype == promisePrototype) {
// The {resolution} is a native Promise in this case. // The {resolution} is a native Promise in this case.
then = nativeContext.elements[NativeContextSlot::PROMISE_THEN_INDEX]; then = *NativeContextSlot(ContextSlot::PROMISE_THEN_INDEX);
// Check that Torque load elimination works.
static_assert(nativeContext == LoadNativeContext(context));
goto Enqueue; goto Enqueue;
} }
goto Slow; goto Slow;
......
...@@ -10,7 +10,7 @@ macro ...@@ -10,7 +10,7 @@ macro
IsPromiseSpeciesLookupChainIntact( IsPromiseSpeciesLookupChainIntact(
nativeContext: NativeContext, promiseMap: Map): bool { nativeContext: NativeContext, promiseMap: Map): bool {
const promisePrototype = const promisePrototype =
nativeContext.elements[NativeContextSlot::PROMISE_PROTOTYPE_INDEX]; *NativeContextSlot(nativeContext, ContextSlot::PROMISE_PROTOTYPE_INDEX);
if (IsForceSlowPath()) return false; if (IsForceSlowPath()) return false;
if (promiseMap.prototype != promisePrototype) return false; if (promiseMap.prototype != promisePrototype) return false;
return !IsPromiseSpeciesProtectorCellInvalid(); return !IsPromiseSpeciesProtectorCellInvalid();
...@@ -27,8 +27,7 @@ PromisePrototypeThen(js-implicit context: NativeContext, receiver: JSAny)( ...@@ -27,8 +27,7 @@ PromisePrototypeThen(js-implicit context: NativeContext, receiver: JSAny)(
receiver); receiver);
// 3. Let C be ? SpeciesConstructor(promise, %Promise%). // 3. Let C be ? SpeciesConstructor(promise, %Promise%).
const promiseFun = UnsafeCast<JSFunction>( const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
context.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
// 4. Let resultCapability be ? NewPromiseCapability(C). // 4. Let resultCapability be ? NewPromiseCapability(C).
let resultPromiseOrCapability: JSPromise|PromiseCapability; let resultPromiseOrCapability: JSPromise|PromiseCapability;
......
...@@ -9,20 +9,24 @@ namespace proxy { ...@@ -9,20 +9,24 @@ namespace proxy {
// Proxy Revocation Functions // Proxy Revocation Functions
// https://tc39.github.io/ecma262/#sec-proxy-revocation-functions // https://tc39.github.io/ecma262/#sec-proxy-revocation-functions
transitioning javascript builtin transitioning javascript builtin
ProxyRevoke(js-implicit context: NativeContext)(): Undefined { ProxyRevoke(js-implicit context: Context)(): Undefined {
const context = %RawDownCast<ProxyRevokeFunctionContext>(context);
// 1. Let p be F.[[RevocableProxy]]. // 1. Let p be F.[[RevocableProxy]].
const proxyObject: Object = context.elements[PROXY_SLOT]; const proxySlot:&(JSProxy | Null) =
ContextSlot(context, ProxyRevokeFunctionContextSlot::kProxySlot);
typeswitch (*proxySlot) {
case (Null): {
// 2. If p is null, return undefined // 2. If p is null, return undefined
if (proxyObject == Null) {
return Undefined; return Undefined;
} }
case (proxy: JSProxy): {
// 3. Set F.[[RevocableProxy]] to null. // 3. Set F.[[RevocableProxy]] to null.
context.elements[PROXY_SLOT] = Null; *proxySlot = Null;
// 4. Assert: p is a Proxy object. // 4. Assert: p is a Proxy object.
const proxy: JSProxy = UnsafeCast<JSProxy>(proxyObject); assert(Is<JSProxy>(proxy));
// 5. Set p.[[ProxyTarget]] to null. // 5. Set p.[[ProxyTarget]] to null.
proxy.target = Null; proxy.target = Null;
...@@ -32,5 +36,7 @@ ProxyRevoke(js-implicit context: NativeContext)(): Undefined { ...@@ -32,5 +36,7 @@ ProxyRevoke(js-implicit context: NativeContext)(): Undefined {
// 7. Return undefined. // 7. Return undefined.
return Undefined; return Undefined;
}
}
} }
} }
...@@ -23,4 +23,11 @@ const kProxyGet: constexpr int31 ...@@ -23,4 +23,11 @@ const kProxyGet: constexpr int31
generates 'JSProxy::AccessKind::kGet'; generates 'JSProxy::AccessKind::kGet';
const kProxySet: constexpr int31 const kProxySet: constexpr int31
generates 'JSProxy::AccessKind::kSet'; generates 'JSProxy::AccessKind::kSet';
type ProxyRevokeFunctionContext extends FunctionContext;
extern enum ProxyRevokeFunctionContextSlot extends intptr
constexpr 'ProxiesCodeStubAssembler::ProxyRevokeFunctionContextSlot' {
kProxySlot: Slot<ProxyRevokeFunctionContext, JSProxy|Null>,
kProxyContextLength
}
} }
...@@ -155,10 +155,8 @@ transitioning macro RegExpPrototypeExecBody(implicit context: Context)( ...@@ -155,10 +155,8 @@ transitioning macro RegExpPrototypeExecBody(implicit context: Context)(
regexp, matchIndices, string, lastIndex); regexp, matchIndices, string, lastIndex);
} }
macro LoadRegExpFunction(implicit context: Context)( macro LoadRegExpFunction(nativeContext: NativeContext): JSFunction {
nativeContext: NativeContext): JSFunction { return *NativeContextSlot(nativeContext, ContextSlot::REGEXP_FUNCTION_INDEX);
return UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::REGEXP_FUNCTION_INDEX]);
} }
// Note this doesn't guarantee const-ness of object properties, just // Note this doesn't guarantee const-ness of object properties, just
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_BUILTINS_TORQUE_CSA_HEADER_INCLUDES_H_
#define V8_BUILTINS_TORQUE_CSA_HEADER_INCLUDES_H_
// This file is included by Torque-generated CSA headers and contains
// includes necessary for these headers.
#include "src/builtins/builtins-promise.h"
#include "src/builtins/builtins-proxy-gen.h"
#include "src/codegen/code-stub-assembler.h"
#include "src/compiler/code-assembler.h"
#include "src/utils/utils.h"
#include "torque-generated/csa-types-tq.h"
#include "torque-generated/field-offsets-tq.h"
#endif // V8_BUILTINS_TORQUE_CSA_HEADER_INCLUDES_H_
...@@ -25,6 +25,11 @@ macro NewReference<T: type>(object: HeapObject, offset: intptr):&T { ...@@ -25,6 +25,11 @@ macro NewReference<T: type>(object: HeapObject, offset: intptr):&T {
return %RawDownCast<&T>( return %RawDownCast<&T>(
Reference<T>{object: object, offset: offset, unsafeMarker: Unsafe {}}); Reference<T>{object: object, offset: offset, unsafeMarker: Unsafe {}});
} }
macro ReferenceCast<T: type, U: type>(ref:&U):&T {
const ref = NewReference<T>(ref.object, ref.offset);
UnsafeCast<T>(*ref);
return ref;
}
} // namespace unsafe } // namespace unsafe
struct Slice<T: type> { struct Slice<T: type> {
......
...@@ -13037,34 +13037,6 @@ void CodeStubAssembler::PerformStackCheck(TNode<Context> context) { ...@@ -13037,34 +13037,6 @@ void CodeStubAssembler::PerformStackCheck(TNode<Context> context) {
BIND(&ok); BIND(&ok);
} }
TNode<Context> CodeStubAssembler::AllocateSyntheticFunctionContext(
TNode<NativeContext> native_context, int slots) {
DCHECK_GE(slots, Context::MIN_CONTEXT_SLOTS);
TNode<HeapObject> context_heap_object =
AllocateInNewSpace(FixedArray::SizeFor(slots));
InitializeSyntheticFunctionContext(native_context, context_heap_object,
slots);
return CAST(context_heap_object);
}
void CodeStubAssembler::InitializeSyntheticFunctionContext(
TNode<NativeContext> native_context, TNode<HeapObject> context_heap_object,
int slots) {
DCHECK_GE(slots, Context::MIN_CONTEXT_SLOTS);
TNode<Map> map = CAST(
LoadContextElement(native_context, Context::FUNCTION_CONTEXT_MAP_INDEX));
StoreMapNoWriteBarrier(context_heap_object, map);
StoreObjectFieldNoWriteBarrier(context_heap_object, FixedArray::kLengthOffset,
SmiConstant(slots));
TNode<Context> context = CAST(context_heap_object);
const TNode<Object> empty_scope_info = LoadRoot(RootIndex::kEmptyScopeInfo);
StoreContextElementNoWriteBarrier(context, Context::SCOPE_INFO_INDEX,
empty_scope_info);
StoreContextElementNoWriteBarrier(context, Context::PREVIOUS_INDEX,
UndefinedConstant());
}
TNode<Object> CodeStubAssembler::CallApiCallback( TNode<Object> CodeStubAssembler::CallApiCallback(
TNode<Object> context, TNode<RawPtrT> callback, TNode<IntPtrT> argc, TNode<Object> context, TNode<RawPtrT> callback, TNode<IntPtrT> argc,
TNode<Object> data, TNode<Object> holder, TNode<Object> receiver) { TNode<Object> data, TNode<Object> holder, TNode<Object> receiver) {
......
...@@ -128,6 +128,7 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol }; ...@@ -128,6 +128,7 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(default_string, default_string, DefaultString) \ V(default_string, default_string, DefaultString) \
V(EmptyByteArray, empty_byte_array, EmptyByteArray) \ V(EmptyByteArray, empty_byte_array, EmptyByteArray) \
V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray) \ V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray) \
V(EmptyScopeInfo, empty_scope_info, EmptyScopeInfo) \
V(EmptyPropertyDictionary, empty_property_dictionary, \ V(EmptyPropertyDictionary, empty_property_dictionary, \
EmptyPropertyDictionary) \ EmptyPropertyDictionary) \
V(EmptySlowElementDictionary, empty_slow_element_dictionary, \ V(EmptySlowElementDictionary, empty_slow_element_dictionary, \
...@@ -3708,12 +3709,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3708,12 +3709,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<IntPtrT> TryToIntptr(SloppyTNode<Object> key, Label* if_not_intptr, TNode<IntPtrT> TryToIntptr(SloppyTNode<Object> key, Label* if_not_intptr,
TVariable<Int32T>* var_instance_type = nullptr); TVariable<Int32T>* var_instance_type = nullptr);
TNode<Context> AllocateSyntheticFunctionContext(
TNode<NativeContext> native_context, int slots);
void InitializeSyntheticFunctionContext(TNode<NativeContext> native_context,
TNode<HeapObject> context_heap_object,
int slots);
TNode<JSArray> ArrayCreate(TNode<Context> context, TNode<Number> length); TNode<JSArray> ArrayCreate(TNode<Context> context, TNode<Number> length);
// Allocate a clone of a mutable primitive, if {object} is a mutable // Allocate a clone of a mutable primitive, if {object} is a mutable
......
...@@ -969,8 +969,8 @@ struct StackPointerGreaterThanOperator : public Operator1<StackCheckKind> { ...@@ -969,8 +969,8 @@ struct StackPointerGreaterThanOperator : public Operator1<StackCheckKind> {
struct CommentOperator : public Operator1<const char*> { struct CommentOperator : public Operator1<const char*> {
explicit CommentOperator(const char* msg) explicit CommentOperator(const char* msg)
: Operator1(IrOpcode::kComment, Operator::kNoThrow, "Comment", 0, 1, 1, 0, : Operator1(IrOpcode::kComment, Operator::kNoThrow | Operator::kNoWrite,
1, 0, msg) {} "Comment", 0, 1, 1, 0, 1, 0, msg) {}
}; };
MachineOperatorBuilder::MachineOperatorBuilder( MachineOperatorBuilder::MachineOperatorBuilder(
......
...@@ -150,7 +150,7 @@ macro NewParameterMapIterator( ...@@ -150,7 +150,7 @@ macro NewParameterMapIterator(
context: Context, formalParameterCount: intptr, context: Context, formalParameterCount: intptr,
mappedCount: intptr): ParameterMapIterator { mappedCount: intptr): ParameterMapIterator {
const flags = context.GetScopeInfo().flags; const flags = context.GetScopeInfo().flags;
let contextHeaderSize: intptr = MIN_CONTEXT_SLOTS; let contextHeaderSize: intptr = ContextSlot::MIN_CONTEXT_SLOTS;
if (flags.has_context_extension_slot) ++contextHeaderSize; if (flags.has_context_extension_slot) ++contextHeaderSize;
// Copy the parameter slots and the holes in the arguments. // Copy the parameter slots and the holes in the arguments.
// We need to fill in mapped_count slots. They index the context, // We need to fill in mapped_count slots. They index the context,
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
@abstract @abstract
extern class Context extends HeapObject { extern class Context extends HeapObject {
macro GetScopeInfo(): ScopeInfo { macro GetScopeInfo(): ScopeInfo {
return UnsafeCast<ScopeInfo>(this.elements[0]); return *ContextSlot(this, ContextSlot::SCOPE_INFO_INDEX);
} }
const length: Smi; const length: Smi;
elements[length]: Object; elements[length]: Object;
...@@ -17,56 +17,116 @@ extern class CatchContext extends Context generates 'TNode<Context>'; ...@@ -17,56 +17,116 @@ extern class CatchContext extends Context generates 'TNode<Context>';
extern class DebugEvaluateContext extends Context extern class DebugEvaluateContext extends Context
generates 'TNode<Context>'; generates 'TNode<Context>';
extern class EvalContext extends Context generates 'TNode<Context>'; extern class EvalContext extends Context generates 'TNode<Context>';
extern class FunctionContext extends Context generates 'TNode<Context>';
extern class ModuleContext extends Context generates 'TNode<Context>'; extern class ModuleContext extends Context generates 'TNode<Context>';
extern class NativeContext extends Context;
extern class ScriptContext extends Context generates 'TNode<Context>'; extern class ScriptContext extends Context generates 'TNode<Context>';
extern class WithContext extends Context generates 'TNode<Context>'; extern class WithContext extends Context generates 'TNode<Context>';
const MIN_CONTEXT_SLOTS: constexpr int31 extern class FunctionContext extends Context generates 'TNode<Context>';
generates 'Context::MIN_CONTEXT_SLOTS';
const kInitialContextSlotValue: Smi = 0;
extern enum NativeContextSlot extends intptr constexpr 'Context::Field' {
AGGREGATE_ERROR_FUNCTION_INDEX, @export
ARRAY_BUFFER_FUN_INDEX, macro AllocateSyntheticFunctionContext(
ARRAY_BUFFER_NOINIT_FUN_INDEX, nativeContext: NativeContext, slots: constexpr int31): FunctionContext {
ARRAY_BUFFER_MAP_INDEX, return AllocateSyntheticFunctionContext(
ARRAY_FUNCTION_INDEX, nativeContext, Convert<intptr>(slots));
ARRAY_JOIN_STACK_INDEX, }
OBJECT_FUNCTION_INDEX,
ITERATOR_RESULT_MAP_INDEX, macro AllocateSyntheticFunctionContext(
JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX, nativeContext: NativeContext, slots: intptr): FunctionContext {
JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX, static_assert(slots >= ContextSlot::MIN_CONTEXT_SLOTS);
MATH_RANDOM_CACHE_INDEX, const map =
MATH_RANDOM_INDEX_INDEX, *ContextSlot(nativeContext, ContextSlot::FUNCTION_CONTEXT_MAP_INDEX);
NUMBER_FUNCTION_INDEX, const result = new FunctionContext{
PROXY_REVOCABLE_RESULT_MAP_INDEX, map,
REFLECT_APPLY_INDEX, length: Convert<Smi>(slots),
REGEXP_FUNCTION_INDEX, elements: ...ConstantIterator<Smi>(kInitialContextSlotValue)
REGEXP_LAST_MATCH_INFO_INDEX, };
INITIAL_STRING_ITERATOR_MAP_INDEX, InitContextSlot(result, ContextSlot::SCOPE_INFO_INDEX, kEmptyScopeInfo);
INITIAL_ARRAY_ITERATOR_MAP_INDEX, InitContextSlot(result, ContextSlot::PREVIOUS_INDEX, Undefined);
SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP, return result;
STRICT_ARGUMENTS_MAP_INDEX, }
SLOPPY_ARGUMENTS_MAP_INDEX,
FAST_ALIASED_ARGUMENTS_MAP_INDEX, extern class NativeContext extends Context;
PROMISE_FUNCTION_INDEX, type Slot<Container : type extends Context, T : type extends Object> extends
PROMISE_THEN_INDEX, intptr;
PROMISE_PROTOTYPE_INDEX,
STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX, // We cannot use ContextSlot() for initialization since that one asserts the
// slot has the right type already.
CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX, macro InitContextSlot<
ArgumentContext: type, AnnotatedContext: type, T: type, U: type>(
BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX, context: ArgumentContext, index: Slot<AnnotatedContext, T>, value: U) {
BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX, // Make sure the arguments have the right type.
... const context: AnnotatedContext = context;
const value: T = value;
assert(TaggedEqual(context.elements[index], kInitialContextSlotValue));
context.elements[index] = value;
} }
type ContextSlot extends intptr macro ContextSlot<ArgumentContext: type, AnnotatedContext: type, T: type>(
generates 'TNode<IntPtrT>' constexpr 'int32_t'; context: ArgumentContext, index: Slot<AnnotatedContext, T>):&T {
const PROXY_SLOT: constexpr ContextSlot const context: AnnotatedContext = context;
generates 'Context::MIN_CONTEXT_SLOTS'; return torque_internal::unsafe::ReferenceCast<T>(&context.elements[index]);
}
macro NativeContextSlot<T: type>(
context: NativeContext, index: Slot<NativeContext, T>):&T {
return ContextSlot(context, index);
}
macro NativeContextSlot<T: type>(
context: Context, index: Slot<NativeContext, T>):&T {
return ContextSlot(LoadNativeContext(context), index);
}
macro NativeContextSlot<C: type, T: type>(implicit context: C)(
index: Slot<NativeContext, T>):&T {
return NativeContextSlot(context, index);
}
extern enum ContextSlot extends intptr constexpr 'Context::Field' {
SCOPE_INFO_INDEX: Slot<Context, ScopeInfo>,
// Zero is used for the NativeContext, Undefined is used for synthetic
// function contexts.
PREVIOUS_INDEX: Slot<Context, Context|Zero|Undefined>,
AGGREGATE_ERROR_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
ARRAY_BUFFER_FUN_INDEX: Slot<NativeContext, Constructor>,
ARRAY_BUFFER_NOINIT_FUN_INDEX: Slot<NativeContext, JSFunction>,
ARRAY_BUFFER_MAP_INDEX: Slot<NativeContext, Map>,
ARRAY_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
ARRAY_JOIN_STACK_INDEX: Slot<NativeContext, Undefined|FixedArray>,
OBJECT_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
ITERATOR_RESULT_MAP_INDEX: Slot<NativeContext, Map>,
JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX: Slot<NativeContext, Map>,
JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX: Slot<NativeContext, Map>,
MATH_RANDOM_CACHE_INDEX: Slot<NativeContext, FixedDoubleArray>,
MATH_RANDOM_INDEX_INDEX: Slot<NativeContext, Smi>,
NUMBER_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
PROXY_REVOCABLE_RESULT_MAP_INDEX: Slot<NativeContext, Map>,
REFLECT_APPLY_INDEX: Slot<NativeContext, Callable>,
REGEXP_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
REGEXP_LAST_MATCH_INFO_INDEX: Slot<NativeContext, RegExpMatchInfo>,
INITIAL_STRING_ITERATOR_MAP_INDEX: Slot<NativeContext, Map>,
INITIAL_ARRAY_ITERATOR_MAP_INDEX: Slot<NativeContext, Map>,
SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP: Slot<NativeContext, Map>,
STRICT_ARGUMENTS_MAP_INDEX: Slot<NativeContext, Map>,
SLOPPY_ARGUMENTS_MAP_INDEX: Slot<NativeContext, Map>,
FAST_ALIASED_ARGUMENTS_MAP_INDEX: Slot<NativeContext, Map>,
FUNCTION_CONTEXT_MAP_INDEX: Slot<NativeContext, Map>,
PROMISE_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
PROMISE_THEN_INDEX: Slot<NativeContext, JSFunction>,
PROMISE_PROTOTYPE_INDEX: Slot<NativeContext, JSObject>,
STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX: Slot<NativeContext, Map>,
CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX: Slot<NativeContext, HeapObject>,
BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX: Slot<NativeContext, Map>,
BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX: Slot<NativeContext, Map>,
MIN_CONTEXT_SLOTS,
...
}
@export @export
macro LoadContextElement(c: Context, i: intptr): Object { macro LoadContextElement(c: Context, i: intptr): Object {
......
...@@ -16,8 +16,7 @@ extern class JSArrayIterator extends JSObject { ...@@ -16,8 +16,7 @@ extern class JSArrayIterator extends JSObject {
macro CreateArrayIterator(implicit context: NativeContext)( macro CreateArrayIterator(implicit context: NativeContext)(
array: JSReceiver, kind: constexpr IterationKind): JSArrayIterator { array: JSReceiver, kind: constexpr IterationKind): JSArrayIterator {
return new JSArrayIterator{ return new JSArrayIterator{
map: UnsafeCast<Map>( map: *NativeContextSlot(ContextSlot::INITIAL_ARRAY_ITERATOR_MAP_INDEX),
context.elements[NativeContextSlot::INITIAL_ARRAY_ITERATOR_MAP_INDEX]),
properties_or_hash: kEmptyFixedArray, properties_or_hash: kEmptyFixedArray,
elements: kEmptyFixedArray, elements: kEmptyFixedArray,
iterated_object: array, iterated_object: array,
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
extern class ScopeInfo extends FixedArray; extern class ScopeInfo extends FixedArray;
extern macro EmptyScopeInfoConstant(): ScopeInfo;
const kEmptyScopeInfo: ScopeInfo = EmptyScopeInfoConstant();
const kScopeInfoFlagsIndex: const kScopeInfoFlagsIndex:
constexpr int32 generates 'ScopeInfo::Fields::kFlags'; constexpr int32 generates 'ScopeInfo::Fields::kFlags';
......
...@@ -374,8 +374,10 @@ Callable* DeclarationVisitor::Specialize( ...@@ -374,8 +374,10 @@ Callable* DeclarationVisitor::Specialize(
} }
void PredeclarationVisitor::ResolvePredeclarations() { void PredeclarationVisitor::ResolvePredeclarations() {
for (auto& p : GlobalContext::AllDeclarables()) { const auto& all_declarables = GlobalContext::AllDeclarables();
if (const TypeAlias* alias = TypeAlias::DynamicCast(p.get())) { for (size_t i = 0; i < all_declarables.size(); ++i) {
Declarable* declarable = all_declarables[i].get();
if (const TypeAlias* alias = TypeAlias::DynamicCast(declarable)) {
CurrentScope::Scope scope_activator(alias->ParentScope()); CurrentScope::Scope scope_activator(alias->ParentScope());
CurrentSourcePosition::Scope position_activator(alias->Position()); CurrentSourcePosition::Scope position_activator(alias->Position());
alias->Resolve(); alias->Resolve();
......
...@@ -81,12 +81,7 @@ void ImplementationVisitor::BeginCSAFiles() { ...@@ -81,12 +81,7 @@ void ImplementationVisitor::BeginCSAFiles() {
UnderlinifyPath(SourceFileMap::PathFromV8Root(file)) + "_H_"; UnderlinifyPath(SourceFileMap::PathFromV8Root(file)) + "_H_";
header << "#ifndef " << headerDefine << "\n"; header << "#ifndef " << headerDefine << "\n";
header << "#define " << headerDefine << "\n\n"; header << "#define " << headerDefine << "\n\n";
header << "#include \"src/builtins/builtins-promise.h\"\n"; header << "#include \"src/builtins/torque-csa-header-includes.h\"\n";
header << "#include \"src/compiler/code-assembler.h\"\n";
header << "#include \"src/codegen/code-stub-assembler.h\"\n";
header << "#include \"src/utils/utils.h\"\n";
header << "#include \"torque-generated/field-offsets-tq.h\"\n";
header << "#include \"torque-generated/csa-types-tq.h\"\n";
header << "\n"; header << "\n";
header << "namespace v8 {\n" header << "namespace v8 {\n"
......
...@@ -1306,9 +1306,8 @@ macro TestGeneratedCastOperators(implicit context: Context)() { ...@@ -1306,9 +1306,8 @@ macro TestGeneratedCastOperators(implicit context: Context)() {
assert(!Is<ExportedSubClass>(cO)); assert(!Is<ExportedSubClass>(cO));
assert(Is<ExportedSubClass2>(cO)); assert(Is<ExportedSubClass2>(cO));
const nativeContext = LoadNativeContext(context); const jsf: JSFunction =
const jsf: JSFunction = UnsafeCast<JSFunction>( *NativeContextSlot(ContextSlot::REGEXP_FUNCTION_INDEX);
nativeContext.elements[NativeContextSlot::REGEXP_FUNCTION_INDEX]);
assert(!Is<JSSloppyArgumentsObject>(jsf)); assert(!Is<JSSloppyArgumentsObject>(jsf));
const parameterValues = NewFixedArray(0, ConstantIterator(TheHole)); const parameterValues = NewFixedArray(0, ConstantIterator(TheHole));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment