Revert "[torque] typed context slot access"

This reverts commit 408e7240d7.

Reason for revert: debug builds fail

is_component_build = true
is_debug = true
use_goma = true
v8_enable_backtrace = true
v8_enable_debugging_features = true
v8_enable_fast_mksnapshot = true
v8_enable_slow_dchecks = true
v8_enable_snapshot_code_comments = true
v8_enable_verify_csa = true
v8_optimized_debug = false
v8_use_multi_snapshots = false

# Fatal error in ../../src/compiler/backend/instruction-selector.cc, line 3088
# Expected Turbofan static assert to hold, but got non-true input:
  static_assert(nativeContext == LoadNativeContext(context)) at src/builtins/promise-resolve.tq:45:5


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}

TBR=tebbi@chromium.org,seth.brenith@microsoft.com

Change-Id: I90c014022a808449aca4a9b9b3c3b8e036beb28e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7793
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2340903
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69256}
This commit is contained in:
Jakob Gruber 2020-08-06 07:54:34 +00:00 committed by Commit Bot
parent fe850a8015
commit a55a2447fb
35 changed files with 467 additions and 599 deletions

View File

@ -1767,7 +1767,6 @@ v8_source_set("v8_initializers") {
"src/builtins/profile-data-reader.cc",
"src/builtins/profile-data-reader.h",
"src/builtins/setup-builtins-internal.cc",
"src/builtins/torque-csa-header-includes.h",
"src/codegen/code-stub-assembler.cc",
"src/codegen/code-stub-assembler.h",
"src/heap/setup-heap-internal.cc",

View File

@ -414,18 +414,17 @@ const kMinJoinStackSize:
constexpr int31 generates 'JSArray::kMinJoinStackSize';
macro LoadJoinStack(implicit context: Context)(): FixedArray
labels IfUninitialized {
typeswitch (*NativeContextSlot(ContextSlot::ARRAY_JOIN_STACK_INDEX)) {
case (Undefined): {
goto IfUninitialized;
}
case (stack: FixedArray): {
return stack;
}
}
const nativeContext: NativeContext = LoadNativeContext(context);
const stack: HeapObject = UnsafeCast<HeapObject>(
nativeContext.elements[NativeContextSlot::ARRAY_JOIN_STACK_INDEX]);
if (stack == Undefined) goto IfUninitialized;
assert(Is<FixedArray>(stack));
return UnsafeCast<FixedArray>(stack);
}
macro SetJoinStack(implicit context: Context)(stack: FixedArray): void {
*NativeContextSlot(ContextSlot::ARRAY_JOIN_STACK_INDEX) = stack;
const nativeContext: NativeContext = LoadNativeContext(context);
nativeContext.elements[NativeContextSlot::ARRAY_JOIN_STACK_INDEX] = stack;
}
// Adds a receiver to the stack. The FixedArray will automatically grow to

View File

@ -451,6 +451,8 @@ const UNSAFE_SKIP_WRITE_BARRIER:
extern transitioning macro AllocateJSIteratorResult(implicit context: Context)(
JSAny, Boolean): JSObject;
extern macro AllocateSyntheticFunctionContext(
NativeContext, constexpr int32): Context;
extern class Filler extends HeapObject generates 'TNode<HeapObject>';
@ -1100,47 +1102,74 @@ macro AllowNonNumberElements(kind: ElementsKind): ElementsKind {
}
macro GetObjectFunction(implicit context: Context)(): JSFunction {
return *NativeContextSlot(ContextSlot::OBJECT_FUNCTION_INDEX);
return UnsafeCast<JSFunction>(
LoadNativeContext(context)
.elements[NativeContextSlot::OBJECT_FUNCTION_INDEX]);
}
macro GetArrayFunction(implicit context: Context)(): JSFunction {
return *NativeContextSlot(ContextSlot::ARRAY_FUNCTION_INDEX);
return UnsafeCast<JSFunction>(
LoadNativeContext(context)
.elements[NativeContextSlot::ARRAY_FUNCTION_INDEX]);
}
macro GetArrayBufferFunction(implicit context: Context)(): Constructor {
return *NativeContextSlot(ContextSlot::ARRAY_BUFFER_FUN_INDEX);
return UnsafeCast<Constructor>(
LoadNativeContext(context)
.elements[NativeContextSlot::ARRAY_BUFFER_FUN_INDEX]);
}
macro GetArrayBufferNoInitFunction(implicit context: Context)(): JSFunction {
return *NativeContextSlot(ContextSlot::ARRAY_BUFFER_NOINIT_FUN_INDEX);
return UnsafeCast<JSFunction>(
LoadNativeContext(context)
.elements[NativeContextSlot::ARRAY_BUFFER_NOINIT_FUN_INDEX]);
}
macro GetFastPackedElementsJSArrayMap(implicit context: Context)(): Map {
return *NativeContextSlot(ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX);
return UnsafeCast<Map>(
LoadNativeContext(context)
.elements[NativeContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX]);
}
macro GetFastPackedSmiElementsJSArrayMap(implicit context: Context)(): Map {
return *NativeContextSlot(
ContextSlot::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX);
return UnsafeCast<Map>(
LoadNativeContext(context)
.elements[NativeContextSlot::JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX]);
}
macro GetProxyRevocableResultMap(implicit context: Context)(): Map {
return *NativeContextSlot(ContextSlot::PROXY_REVOCABLE_RESULT_MAP_INDEX);
return UnsafeCast<Map>(
LoadNativeContext(context)
.elements[NativeContextSlot::PROXY_REVOCABLE_RESULT_MAP_INDEX]);
}
macro GetIteratorResultMap(implicit context: Context)(): Map {
return *NativeContextSlot(ContextSlot::ITERATOR_RESULT_MAP_INDEX);
return UnsafeCast<Map>(
LoadNativeContext(context)
.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]);
}
macro GetInitialStringIteratorMap(implicit context: Context)(): Map {
return *NativeContextSlot(ContextSlot::INITIAL_STRING_ITERATOR_MAP_INDEX);
return UnsafeCast<Map>(
LoadNativeContext(context)
.elements[NativeContextSlot::INITIAL_STRING_ITERATOR_MAP_INDEX]);
}
macro GetReflectApply(implicit context: Context)(): Callable {
return *NativeContextSlot(ContextSlot::REFLECT_APPLY_INDEX);
return UnsafeCast<Callable>(
LoadNativeContext(context)
.elements[NativeContextSlot::REFLECT_APPLY_INDEX]);
}
macro GetRegExpLastMatchInfo(implicit context: Context)(): RegExpMatchInfo {
return *NativeContextSlot(ContextSlot::REGEXP_LAST_MATCH_INFO_INDEX);
return %RawDownCast<RegExpMatchInfo>(
LoadNativeContext(context)
.elements[NativeContextSlot::REGEXP_LAST_MATCH_INFO_INDEX]);
}
macro GetStrictArgumentsMap(implicit context: Context)(): Map {
return *NativeContextSlot(ContextSlot::STRICT_ARGUMENTS_MAP_INDEX);
return UnsafeCast<Map>(
LoadNativeContext(context)
.elements[NativeContextSlot::STRICT_ARGUMENTS_MAP_INDEX]);
}
macro GetSloppyArgumentsMap(implicit context: Context)(): Map {
return *NativeContextSlot(ContextSlot::SLOPPY_ARGUMENTS_MAP_INDEX);
return UnsafeCast<Map>(
LoadNativeContext(context)
.elements[NativeContextSlot::SLOPPY_ARGUMENTS_MAP_INDEX]);
}
macro GetFastAliasedArgumentsMap(implicit context: Context)(): Map {
return *NativeContextSlot(ContextSlot::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
return UnsafeCast<Map>(
LoadNativeContext(context)
.elements[NativeContextSlot::FAST_ALIASED_ARGUMENTS_MAP_INDEX]);
}
macro GetWeakCellMap(implicit context: Context)(): Map {
return %GetClassMapConstant<WeakCell>();

View File

@ -62,10 +62,9 @@ TNode<JSProxy> ProxiesCodeStubAssembler::AllocateProxy(
TNode<Context> ProxiesCodeStubAssembler::CreateProxyRevokeFunctionContext(
TNode<JSProxy> proxy, TNode<NativeContext> native_context) {
const TNode<Context> context = AllocateSyntheticFunctionContext(
native_context, ProxyRevokeFunctionContextSlot::kProxyContextLength);
StoreContextElementNoWriteBarrier(
context, ProxyRevokeFunctionContextSlot::kProxySlot, proxy);
const TNode<Context> context =
AllocateSyntheticFunctionContext(native_context, kProxyContextLength);
StoreContextElementNoWriteBarrier(context, kProxySlot, proxy);
return context;
}

View File

@ -33,6 +33,7 @@ class ProxiesCodeStubAssembler : public CodeStubAssembler {
void CheckDeleteTrapResult(TNode<Context> context, TNode<JSReceiver> target,
TNode<JSProxy> proxy, TNode<Name> name);
protected:
enum ProxyRevokeFunctionContextSlot {
kProxySlot = Context::MIN_CONTEXT_SLOTS,
kProxyContextLength,

View File

@ -611,35 +611,6 @@ 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>(
implicit context: Context)(o: B): bool {
Cast<A>(o) otherwise return false;

View File

@ -112,7 +112,7 @@ transitioning builtin ToObject(implicit context: Context)(input: JSAny):
try {
typeswitch (input) {
case (Smi): {
goto WrapPrimitive(ContextSlot::NUMBER_FUNCTION_INDEX);
goto WrapPrimitive(NativeContextSlot::NUMBER_FUNCTION_INDEX);
}
case (o: JSReceiver): {
return o;
@ -120,14 +120,14 @@ transitioning builtin ToObject(implicit context: Context)(input: JSAny):
case (o: JSAnyNotSmi): {
const index: intptr = Convert<intptr>(
o.map.in_object_properties_start_or_constructor_function_index);
if (index != kNoConstructorFunctionIndex)
goto WrapPrimitive(
%RawDownCast<Slot<NativeContext, JSFunction>>(index));
if (index != kNoConstructorFunctionIndex) goto WrapPrimitive(index);
ThrowTypeError(MessageTemplate::kUndefinedOrNullToObject, 'ToObject');
}
}
} label WrapPrimitive(constructorIndex: Slot<NativeContext, JSFunction>) {
const constructor = *NativeContextSlot(constructorIndex);
} label WrapPrimitive(constructorIndex: intptr) {
const nativeContext = LoadNativeContext(context);
const constructor =
UnsafeCast<JSFunction>(nativeContext.elements[constructorIndex]);
const map: Map = UnsafeCast<Map>(constructor.prototype_or_initial_map);
const wrapper =
UnsafeCast<JSPrimitiveWrapper>(AllocateFastOrSlowJSObjectFromMap(map));

View File

@ -66,12 +66,14 @@ FastFunctionPrototypeBind(
// Choose the right bound function map based on whether the target is
// constructable.
const boundFunctionMap: Map =
const boundFunctionMap: Map = UnsafeCast<Map>(
IsConstructor(fn) ?
*NativeContextSlot(
ContextSlot::BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX) :
*NativeContextSlot(ContextSlot::
BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX);
context
.elements[NativeContextSlot::
BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX] :
context.elements
[NativeContextSlot::
BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX]);
// Verify that prototype matches that of the target bound function.

View File

@ -437,16 +437,19 @@ extern macro RefillMathRandom(NativeContext): Smi;
transitioning javascript builtin
MathRandom(js-implicit context: NativeContext, receiver: JSAny)(): Number {
let smiIndex: Smi = *NativeContextSlot(ContextSlot::MATH_RANDOM_INDEX_INDEX);
let smiIndex: Smi =
Cast<Smi>(context.elements[NativeContextSlot::MATH_RANDOM_INDEX_INDEX])
otherwise unreachable;
if (smiIndex == 0) {
// refill math random.
smiIndex = RefillMathRandom(context);
}
const newSmiIndex: Smi = smiIndex - 1;
*NativeContextSlot(ContextSlot::MATH_RANDOM_INDEX_INDEX) = newSmiIndex;
context.elements[NativeContextSlot::MATH_RANDOM_INDEX_INDEX] = newSmiIndex;
const array: FixedDoubleArray =
*NativeContextSlot(ContextSlot::MATH_RANDOM_CACHE_INDEX);
const array: FixedDoubleArray = Cast<FixedDoubleArray>(
context.elements[NativeContextSlot::MATH_RANDOM_CACHE_INDEX])
otherwise unreachable;
const random: float64 =
array.floats[Convert<intptr>(newSmiIndex)].ValueUnsafeAssumeNotHole();
return AllocateHeapNumberWithValue(random);

View File

@ -92,19 +92,22 @@ ObjectSetPrototypeOfDontThrow(implicit context: Context)(
transitioning builtin CreateObjectWithoutProperties(implicit context: Context)(
prototype: JSAny): JSAny {
const nativeContext = LoadNativeContext(context);
try {
let map: Map;
let properties: NameDictionary|EmptyFixedArray;
typeswitch (prototype) {
case (Null): {
map = *NativeContextSlot(
ContextSlot::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP);
map = UnsafeCast<Map>(
nativeContext.elements
[NativeContextSlot::SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP]);
properties = AllocateNameDictionary(kNameDictionaryInitialCapacity);
}
case (prototype: JSReceiver): {
properties = kEmptyFixedArray;
const objectFunction =
*NativeContextSlot(ContextSlot::OBJECT_FUNCTION_INDEX);
const objectFunction = UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::OBJECT_FUNCTION_INDEX]);
map = UnsafeCast<Map>(objectFunction.prototype_or_initial_map);
if (prototype != map.prototype) {
const prototypeInfo = prototype.map.PrototypeInfo() otherwise Runtime;

View File

@ -35,7 +35,7 @@ const kResolveString: String = ResolveStringConstant();
extern macro IsPromiseResolveProtectorCellInvalid(): bool;
extern macro AllocateFunctionWithMapAndContext(
Map, SharedFunctionInfo, FunctionContext): JSFunction;
Map, SharedFunctionInfo, Context): JSFunction;
extern macro PromiseReactionMapConstant(): Map;
extern macro PromiseFulfillReactionJobTaskMapConstant(): Map;
@ -252,33 +252,24 @@ RejectPromise(implicit context: Context)(
const kPromiseCapabilitySize:
constexpr int31 generates 'PromiseCapability::kSize';
type PromiseResolvingFunctionContext extends FunctionContext;
extern enum PromiseResolvingFunctionContextSlot extends intptr
constexpr 'PromiseBuiltins::PromiseResolvingFunctionContextSlot' {
kPromiseSlot: Slot<PromiseResolvingFunctionContext, JSPromise>,
kAlreadyResolvedSlot: Slot<PromiseResolvingFunctionContext, Boolean>,
kDebugEventSlot: Slot<PromiseResolvingFunctionContext, Boolean>,
kPromiseContextLength
}
type PromiseCapabilitiesExecutorContext extends FunctionContext;
extern enum FunctionContextSlot extends intptr
constexpr 'PromiseBuiltins::FunctionContextSlot' {
kCapabilitySlot: Slot<PromiseCapabilitiesExecutorContext, PromiseCapability>,
kCapabilitiesContextLength
}
const kPromiseBuiltinsCapabilitiesContextLength: constexpr int31
generates 'PromiseBuiltins::kCapabilitiesContextLength';
const kPromiseBuiltinsCapabilitySlot: constexpr ContextSlot
generates 'PromiseBuiltins::kCapabilitySlot';
const kPromiseBuiltinsPromiseSlot: constexpr ContextSlot
generates 'PromiseBuiltins::kPromiseSlot';
const kPromiseBuiltinsAlreadyResolvedSlot: constexpr ContextSlot
generates 'PromiseBuiltins::kAlreadyResolvedSlot';
const kPromiseBuiltinsDebugEventSlot: constexpr ContextSlot
generates 'PromiseBuiltins::kDebugEventSlot';
@export
macro CreatePromiseCapabilitiesExecutorContext(
nativeContext: NativeContext, capability: PromiseCapability):
PromiseCapabilitiesExecutorContext {
const executorContext = %RawDownCast<PromiseCapabilitiesExecutorContext>(
AllocateSyntheticFunctionContext(
nativeContext, FunctionContextSlot::kCapabilitiesContextLength));
nativeContext: NativeContext, capability: PromiseCapability): Context {
const executorContext = AllocateSyntheticFunctionContext(
nativeContext, kPromiseBuiltinsCapabilitiesContextLength);
InitContextSlot(
executorContext, FunctionContextSlot::kCapabilitySlot, capability);
executorContext.elements[kPromiseBuiltinsCapabilitySlot] = capability;
return executorContext;
}
@ -302,12 +293,13 @@ struct PromiseResolvingFunctions {
@export
macro CreatePromiseResolvingFunctions(implicit context: Context)(
promise: JSPromise, debugEvent: Boolean, nativeContext: NativeContext):
promise: JSPromise, debugEvent: Object, nativeContext: NativeContext):
PromiseResolvingFunctions {
const promiseContext = CreatePromiseResolvingFunctionsContext(
promise, debugEvent, nativeContext);
const map = *NativeContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const map = UnsafeCast<Map>(
nativeContext.elements
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const resolveInfo = PromiseCapabilityDefaultResolveSharedFunConstant();
const resolve: JSFunction =
@ -320,10 +312,11 @@ macro CreatePromiseResolvingFunctions(implicit context: Context)(
transitioning macro
InnerNewPromiseCapability(implicit context: Context)(
constructor: HeapObject, debugEvent: Boolean): PromiseCapability {
constructor: HeapObject, debugEvent: Object): PromiseCapability {
const nativeContext = LoadNativeContext(context);
if (constructor ==
*NativeContextSlot(nativeContext, ContextSlot::PROMISE_FUNCTION_INDEX)) {
if (TaggedEqual(
constructor,
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX])) {
const promise = NewJSPromise();
const pair =
@ -338,10 +331,9 @@ InnerNewPromiseCapability(implicit context: Context)(
CreatePromiseCapabilitiesExecutorContext(nativeContext, capability);
const executorInfo = PromiseGetCapabilitiesExecutorSharedFunConstant();
const functionMap =
*NativeContextSlot(
nativeContext,
ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const functionMap = UnsafeCast<Map>(
nativeContext.elements
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const executor = AllocateFunctionWithMapAndContext(
functionMap, executorInfo, executorContext);
@ -359,7 +351,7 @@ InnerNewPromiseCapability(implicit context: Context)(
// https://tc39.es/ecma262/#sec-newpromisecapability
transitioning builtin
NewPromiseCapability(implicit context: Context)(
maybeConstructor: Object, debugEvent: Boolean): PromiseCapability {
maybeConstructor: Object, debugEvent: Object): PromiseCapability {
typeswitch (maybeConstructor) {
case (Smi): {
ThrowTypeError(MessageTemplate::kNotConstructor, maybeConstructor);
@ -376,15 +368,14 @@ NewPromiseCapability(implicit context: Context)(
// https://tc39.es/ecma262/#sec-promise-reject-functions
transitioning javascript builtin
PromiseCapabilityDefaultReject(
js-implicit context: Context, receiver: JSAny)(reason: JSAny): JSAny {
const context = %RawDownCast<PromiseResolvingFunctionContext>(context);
js-implicit context: NativeContext, receiver: JSAny)(reason: JSAny): JSAny {
// 2. Let promise be F.[[Promise]].
const promise =
*ContextSlot(context, PromiseResolvingFunctionContextSlot::kPromiseSlot);
UnsafeCast<JSPromise>(context.elements[kPromiseBuiltinsPromiseSlot]);
// 3. Let alreadyResolved be F.[[AlreadyResolved]].
const alreadyResolved = *ContextSlot(
context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot);
const alreadyResolved = UnsafeCast<Boolean>(
context.elements[kPromiseBuiltinsAlreadyResolvedSlot]);
// 4. If alreadyResolved.[[Value]] is true, return undefined.
if (alreadyResolved == True) {
@ -392,28 +383,26 @@ PromiseCapabilityDefaultReject(
}
// 5. Set alreadyResolved.[[Value]] to true.
*ContextSlot(
context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot) =
True;
context.elements[kPromiseBuiltinsAlreadyResolvedSlot] = True;
// 6. Return RejectPromise(promise, reason).
const debugEvent = *ContextSlot(
context, PromiseResolvingFunctionContextSlot::kDebugEventSlot);
const debugEvent =
UnsafeCast<Boolean>(context.elements[kPromiseBuiltinsDebugEventSlot]);
return RejectPromise(promise, reason, debugEvent);
}
// https://tc39.es/ecma262/#sec-promise-resolve-functions
transitioning javascript builtin
PromiseCapabilityDefaultResolve(
js-implicit context: Context, receiver: JSAny)(resolution: JSAny): JSAny {
const context = %RawDownCast<PromiseResolvingFunctionContext>(context);
js-implicit context: NativeContext,
receiver: JSAny)(resolution: JSAny): JSAny {
// 2. Let promise be F.[[Promise]].
const promise: JSPromise =
*ContextSlot(context, PromiseResolvingFunctionContextSlot::kPromiseSlot);
const promise =
UnsafeCast<JSPromise>(context.elements[kPromiseBuiltinsPromiseSlot]);
// 3. Let alreadyResolved be F.[[AlreadyResolved]].
const alreadyResolved: Boolean = *ContextSlot(
context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot);
const alreadyResolved = UnsafeCast<Boolean>(
context.elements[kPromiseBuiltinsAlreadyResolvedSlot]);
// 4. If alreadyResolved.[[Value]] is true, return undefined.
if (alreadyResolved == True) {
@ -421,9 +410,7 @@ PromiseCapabilityDefaultResolve(
}
// 5. Set alreadyResolved.[[Value]] to true.
*ContextSlot(
context, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot) =
True;
context.elements[kPromiseBuiltinsAlreadyResolvedSlot] = True;
// The rest of the logic (and the catch prediction) is
// encapsulated in the dedicated ResolvePromise builtin.
@ -490,7 +477,8 @@ PromiseReject(
const receiver = Cast<JSReceiver>(receiver) otherwise
ThrowTypeError(MessageTemplate::kCalledOnNonObject, 'PromiseReject');
const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
const promiseFun =
context.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX];
if (promiseFun == receiver) {
const promise = NewJSPromise(PromiseState::kRejected, reason);
runtime::PromiseRejectEventFromStack(promise, reason);
@ -513,11 +501,11 @@ const kPromiseExecutorAlreadyInvoked: constexpr MessageTemplate
// https://tc39.es/ecma262/#sec-getcapabilitiesexecutor-functions
transitioning javascript builtin
PromiseGetCapabilitiesExecutor(js-implicit context: Context, receiver: JSAny)(
PromiseGetCapabilitiesExecutor(
js-implicit context: NativeContext, receiver: JSAny)(
resolve: JSAny, reject: JSAny): JSAny {
const context = %RawDownCast<PromiseCapabilitiesExecutorContext>(context);
const capability: PromiseCapability =
*ContextSlot(context, FunctionContextSlot::kCapabilitySlot);
const capability = UnsafeCast<PromiseCapability>(
context.elements[kPromiseBuiltinsCapabilitySlot]);
if (capability.resolve != Undefined || capability.reject != Undefined)
deferred {
ThrowTypeError(kPromiseExecutorAlreadyInvoked);
@ -531,8 +519,8 @@ PromiseGetCapabilitiesExecutor(js-implicit context: Context, receiver: JSAny)(
macro IsPromiseResolveLookupChainIntact(implicit context: Context)(
nativeContext: NativeContext, constructor: JSReceiver): bool {
if (IsForceSlowPath()) return false;
const promiseFun =
*NativeContextSlot(nativeContext, ContextSlot::PROMISE_FUNCTION_INDEX);
const promiseFun = UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
return promiseFun == constructor && !IsPromiseResolveProtectorCellInvalid();
}

View File

@ -21,8 +21,8 @@ struct PromiseAllSettledWrapResultAsFulfilledFunctor {
// TODO(gsathya): Optimize the creation using a cached map to
// prevent transitions here.
// 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
const objectFunction =
*NativeContextSlot(nativeContext, ContextSlot::OBJECT_FUNCTION_INDEX);
const objectFunction = UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::OBJECT_FUNCTION_INDEX]);
const objectFunctionMap =
UnsafeCast<Map>(objectFunction.prototype_or_initial_map);
const obj = AllocateJSObjectFromMap(objectFunctionMap);
@ -44,8 +44,8 @@ struct PromiseAllSettledWrapResultAsRejectedFunctor {
// TODO(gsathya): Optimize the creation using a cached map to
// prevent transitions here.
// 9. Let obj be ! ObjectCreate(%ObjectPrototype%).
const objectFunction =
*NativeContextSlot(nativeContext, ContextSlot::OBJECT_FUNCTION_INDEX);
const objectFunction = UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::OBJECT_FUNCTION_INDEX]);
const objectFunctionMap =
UnsafeCast<Map>(objectFunction.prototype_or_initial_map);
const obj = AllocateJSObjectFromMap(objectFunctionMap);
@ -62,15 +62,11 @@ struct PromiseAllSettledWrapResultAsRejectedFunctor {
extern macro LoadJSReceiverIdentityHash(Object): intptr labels IfNoHash;
type PromiseAllResolveElementContext extends FunctionContext;
extern enum PromiseAllResolveElementContextSlots extends intptr
extern enum PromiseAllResolveElementContextSlots extends int31
constexpr 'PromiseBuiltins::PromiseAllResolveElementContextSlots' {
kPromiseAllResolveElementRemainingSlot:
Slot<PromiseAllResolveElementContext, Smi>,
kPromiseAllResolveElementCapabilitySlot:
Slot<PromiseAllResolveElementContext, PromiseCapability>,
kPromiseAllResolveElementValuesSlot:
Slot<PromiseAllResolveElementContext, FixedArray>,
kPromiseAllResolveElementRemainingSlot,
kPromiseAllResolveElementCapabilitySlot,
kPromiseAllResolveElementValuesSlot,
kPromiseAllResolveElementLength
}
extern operator '[]=' macro StoreContextElement(
@ -85,7 +81,7 @@ const kPropertyArrayHashFieldMax: constexpr int31
generates 'PropertyArray::HashField::kMax';
transitioning macro PromiseAllResolveElementClosure<F: type>(
implicit context: PromiseAllResolveElementContext|NativeContext)(
implicit context: Context)(
value: JSAny, function: JSFunction, wrapResultFunctor: F,
hasResolveAndRejectClosures: constexpr bool): JSAny {
// We use the {function}s context as the marker to remember whether this
@ -93,21 +89,14 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
// 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
// to mark this resolve element closure as done.
let promiseContext: PromiseAllResolveElementContext;
typeswitch (context) {
case (NativeContext): deferred {
if (IsNativeContext(context)) deferred {
return Undefined;
}
case (context: PromiseAllResolveElementContext): {
promiseContext = context;
}
}
assert(
promiseContext.length ==
SmiTag(PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementLength));
const nativeContext = LoadNativeContext(promiseContext);
context.length ==
PromiseAllResolveElementContextSlots::kPromiseAllResolveElementLength);
const nativeContext = LoadNativeContext(context);
function.context = nativeContext;
// Determine the index from the {function}.
@ -117,23 +106,19 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
assert(identityHash > 0);
const index = identityHash - 1;
let remainingElementsCount = *ContextSlot(
promiseContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot);
let remainingElementsCount = UnsafeCast<Smi>(
context.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot]);
let values = *ContextSlot(
promiseContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot);
let values = UnsafeCast<FixedArray>(
context.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot]);
const newCapacity = index + 1;
if (newCapacity > values.length_intptr) deferred {
// This happens only when the promises are resolved during iteration.
values = ExtractFixedArray(values, 0, values.length_intptr, newCapacity);
*ContextSlot(
promiseContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot) = values;
context.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot] = values;
}
// Promise.allSettled, for each input element, has both a resolve and a reject
@ -159,21 +144,19 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
values.objects[index] = updatedValue;
remainingElementsCount = remainingElementsCount - 1;
*ContextSlot(
promiseContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot) = remainingElementsCount;
context.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot] =
remainingElementsCount;
if (remainingElementsCount == 0) {
const capability = *ContextSlot(
promiseContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementCapabilitySlot);
const capability = UnsafeCast<PromiseCapability>(
context.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementCapabilitySlot]);
const resolve = UnsafeCast<JSAny>(capability.resolve);
const arrayMap =
*NativeContextSlot(
nativeContext, ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX);
const arrayMap = UnsafeCast<Map>(
nativeContext
.elements[NativeContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX]);
const valuesArray = NewJSArray(arrayMap, values);
Call(promiseContext, resolve, Undefined, valuesArray);
Call(context, resolve, Undefined, valuesArray);
}
return Undefined;
}
@ -182,8 +165,6 @@ transitioning javascript builtin
PromiseAllResolveElementClosure(
js-implicit context: Context, receiver: JSAny,
target: JSFunction)(value: JSAny): JSAny {
const context =
%RawDownCast<PromiseAllResolveElementContext|NativeContext>(context);
return PromiseAllResolveElementClosure(
value, target, PromiseAllWrapResultAsFulfilledFunctor{}, false);
}
@ -192,8 +173,6 @@ transitioning javascript builtin
PromiseAllSettledResolveElementClosure(
js-implicit context: Context, receiver: JSAny,
target: JSFunction)(value: JSAny): JSAny {
const context =
%RawDownCast<PromiseAllResolveElementContext|NativeContext>(context);
return PromiseAllResolveElementClosure(
value, target, PromiseAllSettledWrapResultAsFulfilledFunctor{}, true);
}
@ -202,8 +181,6 @@ transitioning javascript builtin
PromiseAllSettledRejectElementClosure(
js-implicit context: Context, receiver: JSAny,
target: JSFunction)(value: JSAny): JSAny {
const context =
%RawDownCast<PromiseAllResolveElementContext|NativeContext>(context);
return PromiseAllResolveElementClosure(
value, target, PromiseAllSettledWrapResultAsRejectedFunctor{}, true);
}

View File

@ -17,38 +17,31 @@ const kPromiseBuiltinsPromiseContextLength: constexpr int31
// was called already (we slap the native context onto the closure in that
// case to mark it's done).
macro CreatePromiseAllResolveElementContext(implicit context: Context)(
capability: PromiseCapability,
nativeContext: NativeContext): PromiseAllResolveElementContext {
const resolveContext = %RawDownCast<
PromiseAllResolveElementContext>(AllocateSyntheticFunctionContext(
capability: PromiseCapability, nativeContext: NativeContext): Context {
const resolveContext = AllocateSyntheticFunctionContext(
nativeContext,
PromiseAllResolveElementContextSlots::kPromiseAllResolveElementLength));
InitContextSlot(
resolveContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot,
1);
InitContextSlot(
resolveContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementCapabilitySlot,
capability);
InitContextSlot(
resolveContext,
PromiseAllResolveElementContextSlots::kPromiseAllResolveElementValuesSlot,
kEmptyFixedArray);
PromiseAllResolveElementContextSlots::kPromiseAllResolveElementLength);
resolveContext.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot] =
SmiConstant(1);
resolveContext.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementCapabilitySlot] =
capability;
resolveContext.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot] =
kEmptyFixedArray;
return resolveContext;
}
macro CreatePromiseAllResolveElementFunction(implicit context: Context)(
resolveElementContext: PromiseAllResolveElementContext, index: Smi,
nativeContext: NativeContext,
resolveElementContext: Context, index: Smi, nativeContext: NativeContext,
resolveFunction: SharedFunctionInfo): JSFunction {
assert(index > 0);
assert(index < kPropertyArrayHashFieldMax);
const map = *ContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const map = UnsafeCast<Map>(
nativeContext.elements
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const resolve = AllocateFunctionWithMapAndContext(
map, resolveFunction, resolveElementContext);
@ -59,24 +52,13 @@ macro CreatePromiseAllResolveElementFunction(implicit context: Context)(
@export
macro CreatePromiseResolvingFunctionsContext(implicit context: Context)(
promise: JSPromise, debugEvent: Boolean, nativeContext: NativeContext):
PromiseResolvingFunctionContext {
const resolveContext = %RawDownCast<PromiseResolvingFunctionContext>(
AllocateSyntheticFunctionContext(
nativeContext,
PromiseResolvingFunctionContextSlot::kPromiseContextLength));
InitContextSlot(
resolveContext, PromiseResolvingFunctionContextSlot::kPromiseSlot,
promise);
InitContextSlot(
resolveContext, PromiseResolvingFunctionContextSlot::kAlreadyResolvedSlot,
False);
InitContextSlot(
resolveContext, PromiseResolvingFunctionContextSlot::kDebugEventSlot,
debugEvent);
static_assert(
PromiseResolvingFunctionContextSlot::kPromiseContextLength ==
ContextSlot::MIN_CONTEXT_SLOTS + 3);
promise: JSPromise, debugEvent: Object, nativeContext: NativeContext):
Context {
const resolveContext = AllocateSyntheticFunctionContext(
nativeContext, kPromiseBuiltinsPromiseContextLength);
resolveContext.elements[kPromiseBuiltinsPromiseSlot] = promise;
resolveContext.elements[kPromiseBuiltinsAlreadyResolvedSlot] = False;
resolveContext.elements[kPromiseBuiltinsDebugEventSlot] = debugEvent;
return resolveContext;
}
@ -84,17 +66,15 @@ macro IsPromiseThenLookupChainIntact(implicit context: Context)(
nativeContext: NativeContext, receiverMap: Map): bool {
if (IsForceSlowPath()) return false;
if (!IsJSPromiseMap(receiverMap)) return false;
if (receiverMap.prototype != *NativeContextSlot(
nativeContext, ContextSlot::PROMISE_PROTOTYPE_INDEX)) {
if (receiverMap.prototype !=
nativeContext.elements[NativeContextSlot::PROMISE_PROTOTYPE_INDEX])
return false;
}
return !IsPromiseThenProtectorCellInvalid();
}
struct PromiseAllResolveElementFunctor {
macro Call(implicit context: Context)(
resolveElementContext: PromiseAllResolveElementContext,
nativeContext: NativeContext, index: Smi,
resolveElementContext: Context, nativeContext: NativeContext, index: Smi,
_capability: PromiseCapability): Callable {
return CreatePromiseAllResolveElementFunction(
resolveElementContext, index, nativeContext,
@ -104,17 +84,15 @@ struct PromiseAllResolveElementFunctor {
struct PromiseAllRejectElementFunctor {
macro Call(implicit context: Context)(
_resolveElementContext: PromiseAllResolveElementContext,
_nativeContext: NativeContext, _index: Smi,
capability: PromiseCapability): Callable {
_resolveElementContext: Context, _nativeContext: NativeContext,
_index: Smi, capability: PromiseCapability): Callable {
return UnsafeCast<Callable>(capability.reject);
}
}
struct PromiseAllSettledResolveElementFunctor {
macro Call(implicit context: Context)(
resolveElementContext: PromiseAllResolveElementContext,
nativeContext: NativeContext, index: Smi,
resolveElementContext: Context, nativeContext: NativeContext, index: Smi,
_capability: PromiseCapability): Callable {
return CreatePromiseAllResolveElementFunction(
resolveElementContext, index, nativeContext,
@ -124,8 +102,7 @@ struct PromiseAllSettledResolveElementFunctor {
struct PromiseAllSettledRejectElementFunctor {
macro Call(implicit context: Context)(
resolveElementContext: PromiseAllResolveElementContext,
nativeContext: NativeContext, index: Smi,
resolveElementContext: Context, nativeContext: NativeContext, index: Smi,
_capability: PromiseCapability): Callable {
return CreatePromiseAllResolveElementFunction(
resolveElementContext, index, nativeContext,
@ -156,8 +133,8 @@ Reject(Object) {
let index: Smi = 1;
try {
const fastIteratorResultMap = *NativeContextSlot(
nativeContext, ContextSlot::ITERATOR_RESULT_MAP_INDEX);
const fastIteratorResultMap = UnsafeCast<Map>(
nativeContext.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]);
while (true) {
let nextValue: JSAny;
try {
@ -192,10 +169,14 @@ Reject(Object) {
// Set remainingElementsCount.[[Value]] to
// remainingElementsCount.[[Value]] + 1.
*ContextSlot(
resolveElementContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot) += 1;
const remainingElementsCount = UnsafeCast<Smi>(
resolveElementContext
.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot]);
resolveElementContext
.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot] =
remainingElementsCount + 1;
// Let resolveElement be CreateBuiltinFunction(steps,
// « [[AlreadyCalled]],
@ -271,27 +252,32 @@ Reject(Object) {
// Set iteratorRecord.[[Done]] to true.
// Set remainingElementsCount.[[Value]] to
// remainingElementsCount.[[Value]] - 1.
const remainingElementsCount = -- *ContextSlot(
resolveElementContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot);
let remainingElementsCount = UnsafeCast<Smi>(
resolveElementContext
.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot]);
remainingElementsCount -= 1;
resolveElementContext.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementRemainingSlot] =
remainingElementsCount;
if (remainingElementsCount > 0) {
// Pre-allocate the backing store for the {values} to the desired
// capacity. We may already have elements in "values" - this happens
// when the Thenable calls the resolve callback immediately.
const valuesRef:&FixedArray = ContextSlot(
resolveElementContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot);
const values = *valuesRef;
let values = UnsafeCast<FixedArray>(
resolveElementContext
.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot]);
// 'index' is a 1-based index and incremented after every Promise. Later we
// use 'values' as a 0-based array, so capacity 'index - 1' is enough.
const newCapacity = SmiUntag(index) - 1;
const oldCapacity = values.length_intptr;
if (oldCapacity < newCapacity) {
*valuesRef = ExtractFixedArray(values, 0, oldCapacity, newCapacity);
values = ExtractFixedArray(values, 0, oldCapacity, newCapacity);
resolveElementContext.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot] =
values;
}
} else
deferred {
@ -301,13 +287,13 @@ Reject(Object) {
// Perform ? Call(resultCapability.[[Resolve]], undefined,
// « valuesArray »).
const values: FixedArray = *ContextSlot(
resolveElementContext,
PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot);
const arrayMap =
*NativeContextSlot(
nativeContext, ContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX);
const values = UnsafeCast<FixedArray>(
resolveElementContext
.elements[PromiseAllResolveElementContextSlots::
kPromiseAllResolveElementValuesSlot]);
const arrayMap = UnsafeCast<Map>(
nativeContext
.elements[NativeContextSlot::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX]);
const valuesArray = NewJSArray(arrayMap, values);
Call(nativeContext, UnsafeCast<JSAny>(resolve), Undefined, valuesArray);
}

View File

@ -5,15 +5,11 @@
#include 'src/builtins/builtins-promise-gen.h'
namespace promise {
type PromiseAnyRejectElementContext extends FunctionContext;
extern enum PromiseAnyRejectElementContextSlots extends intptr
extern enum PromiseAnyRejectElementContextSlots extends int31
constexpr 'PromiseBuiltins::PromiseAnyRejectElementContextSlots' {
kPromiseAnyRejectElementRemainingSlot:
Slot<PromiseAnyRejectElementContext, Smi>,
kPromiseAnyRejectElementCapabilitySlot:
Slot<PromiseAnyRejectElementContext, PromiseCapability>,
kPromiseAnyRejectElementErrorsSlot:
Slot<PromiseAnyRejectElementContext, FixedArray>,
kPromiseAnyRejectElementRemainingSlot,
kPromiseAnyRejectElementCapabilitySlot,
kPromiseAnyRejectElementErrorsSlot,
kPromiseAnyRejectElementLength
}
@ -31,36 +27,30 @@ extern operator '[]' macro LoadContextElement(
// case to mark it's done). See Promise.all which uses the same approach.
transitioning macro CreatePromiseAnyRejectElementContext(
implicit context: Context)(
capability: PromiseCapability,
nativeContext: NativeContext): PromiseAnyRejectElementContext {
const rejectContext = %RawDownCast<PromiseAnyRejectElementContext>(
AllocateSyntheticFunctionContext(
nativeContext,
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength));
InitContextSlot(
rejectContext,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot,
1);
InitContextSlot(
rejectContext,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementCapabilitySlot,
capability);
InitContextSlot(
rejectContext,
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementErrorsSlot,
kEmptyFixedArray);
capability: PromiseCapability, nativeContext: NativeContext): Context {
const rejectContext = AllocateSyntheticFunctionContext(
nativeContext,
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength);
rejectContext.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot] =
SmiConstant(1);
rejectContext.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementCapabilitySlot] =
capability;
rejectContext.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot] =
kEmptyFixedArray;
return rejectContext;
}
macro CreatePromiseAnyRejectElementFunction(implicit context: Context)(
rejectElementContext: PromiseAnyRejectElementContext, index: Smi,
rejectElementContext: Context, index: Smi,
nativeContext: NativeContext): JSFunction {
assert(index > 0);
assert(index < kPropertyArrayHashFieldMax);
const map = *ContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const map = UnsafeCast<Map>(
nativeContext.elements
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const rejectInfo = PromiseAnyRejectElementSharedFunConstant();
const reject =
AllocateFunctionWithMapAndContext(map, rejectInfo, rejectElementContext);
@ -91,9 +81,7 @@ PromiseAnyRejectElementClosure(
assert(
context.length ==
SmiTag(
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength));
const context = %RawDownCast<PromiseAnyRejectElementContext>(context);
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength);
// 4. Set alreadyCalled.[[Value]] to true.
const nativeContext = LoadNativeContext(context);
@ -106,36 +94,32 @@ PromiseAnyRejectElementClosure(
const index = identityHash - 1;
// 6. Let errors be F.[[Errors]].
let errors = *ContextSlot(
context,
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementErrorsSlot);
let errors = UnsafeCast<FixedArray>(
context.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot]);
// 7. Let promiseCapability be F.[[Capability]].
// 8. Let remainingElementsCount be F.[[RemainingElements]].
let remainingElementsCount = *ContextSlot(
context,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot);
let remainingElementsCount = UnsafeCast<Smi>(
context.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot]);
// 9. Set errors[index] to x.
const newCapacity = IntPtrMax(SmiUntag(remainingElementsCount), index + 1);
if (newCapacity > errors.length_intptr) deferred {
errors = ExtractFixedArray(errors, 0, errors.length_intptr, newCapacity);
*ContextSlot(
context,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot) = errors;
context.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot] = errors;
}
errors.objects[index] = value;
// 10. Set remainingElementsCount.[[Value]] to
// remainingElementsCount.[[Value]] - 1.
remainingElementsCount = remainingElementsCount - 1;
*ContextSlot(
context,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot) = remainingElementsCount;
context.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot] =
remainingElementsCount;
// 11. If remainingElementsCount.[[Value]] is 0, then
if (remainingElementsCount == 0) {
@ -144,10 +128,9 @@ PromiseAnyRejectElementClosure(
// b. Set error.[[AggregateErrors]] to errors.
const error = ConstructAggregateError(errors);
// c. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
const capability = *ContextSlot(
context,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementCapabilitySlot);
const capability = UnsafeCast<PromiseCapability>(
context.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementCapabilitySlot]);
Call(context, UnsafeCast<Callable>(capability.reject), Undefined, error);
}
@ -175,8 +158,8 @@ Reject(Object) {
let index: Smi = 1;
try {
const fastIteratorResultMap = *NativeContextSlot(
nativeContext, ContextSlot::ITERATOR_RESULT_MAP_INDEX);
const fastIteratorResultMap = UnsafeCast<Map>(
nativeContext.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]);
// 8. Repeat,
while (true) {
let nextValue: JSAny;
@ -248,14 +231,12 @@ Reject(Object) {
rejectElementContext, index, nativeContext);
// q. Set remainingElementsCount.[[Value]] to
// remainingElementsCount.[[Value]] + 1.
const remainingElementsCount = *ContextSlot(
rejectElementContext,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot);
*ContextSlot(
rejectElementContext,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot) =
const remainingElementsCount = UnsafeCast<Smi>(
rejectElementContext
.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot]);
rejectElementContext.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot] =
remainingElementsCount + 1;
// r. Perform ? Invoke(nextPromise, "then", «
@ -289,10 +270,13 @@ Reject(Object) {
// i. Set iteratorRecord.[[Done]] to true.
// ii. Set remainingElementsCount.[[Value]] to
// remainingElementsCount.[[Value]] - 1.
const remainingElementsCount = -- *ContextSlot(
rejectElementContext,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot);
let remainingElementsCount = UnsafeCast<Smi>(
rejectElementContext.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot]);
remainingElementsCount -= 1;
rejectElementContext.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementRemainingSlot] =
remainingElementsCount;
// iii. If remainingElementsCount.[[Value]] is 0, then
if (remainingElementsCount == 0) deferred {
@ -301,10 +285,10 @@ Reject(Object) {
// We may already have elements in "errors" - this happens when the
// Thenable calls the reject callback immediately.
const errors: FixedArray = *ContextSlot(
rejectElementContext,
PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot);
const errors = UnsafeCast<FixedArray>(
rejectElementContext
.elements[PromiseAnyRejectElementContextSlots::
kPromiseAnyRejectElementErrorsSlot]);
const error = ConstructAggregateError(errors);
// 3. Return ThrowCompletion(error).

View File

@ -57,7 +57,8 @@ PromiseConstructor(
ThrowTypeError(MessageTemplate::kResolverNotAFunction, executor);
}
const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
const promiseFun = UnsafeCast<JSFunction>(
context.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
// Silently fail if the stack looks fishy.
if (HasAccessCheckFailed(context, promiseFun, executor)) {

View File

@ -7,48 +7,41 @@
namespace promise {
type PromiseValueThunkOrReasonContext extends FunctionContext;
extern enum PromiseValueThunkOrReasonContextSlot extends intptr
constexpr 'PromiseBuiltins::PromiseValueThunkOrReasonContextSlot' {
kValueSlot: Slot<PromiseValueThunkOrReasonContext, JSAny>,
kPromiseValueThunkOrReasonContextLength
}
type PromiseFinallyContext extends FunctionContext;
extern enum PromiseFinallyContextSlot extends intptr
constexpr 'PromiseBuiltins::PromiseFinallyContextSlot' {
kOnFinallySlot: Slot<PromiseFinallyContext, Callable>,
kConstructorSlot: Slot<PromiseFinallyContext, Constructor>,
kPromiseFinallyContextLength
}
// TODO(joshualitt): The below ContextSlots are only available on synthetic
// contexts created by the promise pipeline for use in the promise pipeline.
// However, with Torque we should type the context and its slots to prevent
// accidentially using these slots on contexts which don't support them.
const kPromiseBuiltinsValueSlot: constexpr ContextSlot
generates 'PromiseBuiltins::kValueSlot';
const kPromiseBuiltinsOnFinallySlot: constexpr ContextSlot
generates 'PromiseBuiltins::kOnFinallySlot';
const kPromiseBuiltinsConstructorSlot: constexpr ContextSlot
generates 'PromiseBuiltins::kConstructorSlot';
const kPromiseBuiltinsPromiseValueThunkOrReasonContextLength: constexpr int31
generates 'PromiseBuiltins::kPromiseValueThunkOrReasonContextLength';
const kPromiseBuiltinsPromiseFinallyContextLength: constexpr int31
generates 'PromiseBuiltins::kPromiseFinallyContextLength';
transitioning javascript builtin
PromiseValueThunkFinally(
js-implicit context: Context, receiver: JSAny)(): JSAny {
const context = %RawDownCast<PromiseValueThunkOrReasonContext>(context);
return *ContextSlot(
context, PromiseValueThunkOrReasonContextSlot::kValueSlot);
return UnsafeCast<JSAny>(context.elements[kPromiseBuiltinsValueSlot]);
}
transitioning javascript builtin
PromiseThrowerFinally(js-implicit context: Context, receiver: JSAny)(): never {
const context = %RawDownCast<PromiseValueThunkOrReasonContext>(context);
const reason =
*ContextSlot(context, PromiseValueThunkOrReasonContextSlot::kValueSlot);
const reason = UnsafeCast<JSAny>(context.elements[kPromiseBuiltinsValueSlot]);
Throw(reason);
}
macro CreateThrowerFunction(implicit context: Context)(
nativeContext: NativeContext, reason: JSAny): JSFunction {
const throwerContext = %RawDownCast<PromiseValueThunkOrReasonContext>(
AllocateSyntheticFunctionContext(
nativeContext,
PromiseValueThunkOrReasonContextSlot::
kPromiseValueThunkOrReasonContextLength));
InitContextSlot(
throwerContext, PromiseValueThunkOrReasonContextSlot::kValueSlot, reason);
const map = *ContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const throwerContext = AllocateSyntheticFunctionContext(
nativeContext, kPromiseBuiltinsPromiseValueThunkOrReasonContextLength);
throwerContext.elements[kPromiseBuiltinsValueSlot] = reason;
const map = UnsafeCast<Map>(
nativeContext.elements
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const throwerInfo = PromiseThrowerFinallySharedFunConstant();
return AllocateFunctionWithMapAndContext(map, throwerInfo, throwerContext);
}
@ -56,18 +49,17 @@ macro CreateThrowerFunction(implicit context: Context)(
transitioning javascript builtin
PromiseCatchFinally(
js-implicit context: Context, receiver: JSAny)(reason: JSAny): JSAny {
const context = %RawDownCast<PromiseFinallyContext>(context);
// 1. Let onFinally be F.[[OnFinally]].
// 2. Assert: IsCallable(onFinally) is true.
const onFinally: Callable =
*ContextSlot(context, PromiseFinallyContextSlot::kOnFinallySlot);
const onFinally =
UnsafeCast<Callable>(context.elements[kPromiseBuiltinsOnFinallySlot]);
// 3. Let result be ? Call(onFinally).
const result = Call(context, onFinally, Undefined);
// 4. Let C be F.[[Constructor]].
const constructor: Constructor =
*ContextSlot(context, PromiseFinallyContextSlot::kConstructorSlot);
const constructor =
UnsafeCast<JSFunction>(context.elements[kPromiseBuiltinsConstructorSlot]);
// 5. Assert: IsConstructor(C) is true.
assert(IsConstructor(constructor));
@ -85,16 +77,12 @@ PromiseCatchFinally(
macro CreateValueThunkFunction(implicit context: Context)(
nativeContext: NativeContext, value: JSAny): JSFunction {
const valueThunkContext = %RawDownCast<PromiseValueThunkOrReasonContext>(
AllocateSyntheticFunctionContext(
nativeContext,
PromiseValueThunkOrReasonContextSlot::
kPromiseValueThunkOrReasonContextLength));
InitContextSlot(
valueThunkContext, PromiseValueThunkOrReasonContextSlot::kValueSlot,
value);
const map = *ContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
const valueThunkContext = AllocateSyntheticFunctionContext(
nativeContext, kPromiseBuiltinsPromiseValueThunkOrReasonContextLength);
valueThunkContext.elements[kPromiseBuiltinsValueSlot] = value;
const map = UnsafeCast<Map>(
nativeContext.elements
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const valueThunkInfo = PromiseValueThunkFinallySharedFunConstant();
return AllocateFunctionWithMapAndContext(
map, valueThunkInfo, valueThunkContext);
@ -103,18 +91,17 @@ macro CreateValueThunkFunction(implicit context: Context)(
transitioning javascript builtin
PromiseThenFinally(
js-implicit context: Context, receiver: JSAny)(value: JSAny): JSAny {
const context = %RawDownCast<PromiseFinallyContext>(context);
// 1. Let onFinally be F.[[OnFinally]].
// 2. Assert: IsCallable(onFinally) is true.
const onFinally =
*ContextSlot(context, PromiseFinallyContextSlot::kOnFinallySlot);
UnsafeCast<Callable>(context.elements[kPromiseBuiltinsOnFinallySlot]);
// 3. Let result be ? Call(onFinally).
const result = Call(context, onFinally, Undefined);
// 4. Let C be F.[[Constructor]].
const constructor =
*ContextSlot(context, PromiseFinallyContextSlot::kConstructorSlot);
UnsafeCast<JSFunction>(context.elements[kPromiseBuiltinsConstructorSlot]);
// 5. Assert: IsConstructor(C) is true.
assert(IsConstructor(constructor));
@ -137,17 +124,14 @@ struct PromiseFinallyFunctions {
macro CreatePromiseFinallyFunctions(implicit context: Context)(
nativeContext: NativeContext, onFinally: Callable,
constructor: Constructor): PromiseFinallyFunctions {
const promiseContext =
%RawDownCast<PromiseFinallyContext>(AllocateSyntheticFunctionContext(
nativeContext,
PromiseFinallyContextSlot::kPromiseFinallyContextLength));
InitContextSlot(
promiseContext, PromiseFinallyContextSlot::kOnFinallySlot, onFinally);
InitContextSlot(
promiseContext, PromiseFinallyContextSlot::kConstructorSlot, constructor);
const map = *ContextSlot(
nativeContext, ContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
constructor: JSReceiver): PromiseFinallyFunctions {
const promiseContext = AllocateSyntheticFunctionContext(
nativeContext, kPromiseBuiltinsPromiseFinallyContextLength);
promiseContext.elements[kPromiseBuiltinsOnFinallySlot] = onFinally;
promiseContext.elements[kPromiseBuiltinsConstructorSlot] = constructor;
const map = UnsafeCast<Map>(
nativeContext.elements
[NativeContextSlot::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX]);
const thenFinallyInfo = PromiseThenFinallySharedFunConstant();
const thenFinally =
AllocateFunctionWithMapAndContext(map, thenFinallyInfo, promiseContext);
@ -170,15 +154,15 @@ PromisePrototypeFinally(
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
const nativeContext = LoadNativeContext(context);
const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
const promiseFun = UnsafeCast<Callable>(
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
let constructor: Constructor = UnsafeCast<Constructor>(promiseFun);
let constructor: JSReceiver = promiseFun;
const receiverMap = jsReceiver.map;
if (!IsJSPromiseMap(receiverMap) ||
!IsPromiseSpeciesLookupChainIntact(nativeContext, receiverMap))
deferred {
constructor =
UnsafeCast<Constructor>(SpeciesConstructor(jsReceiver, promiseFun));
constructor = SpeciesConstructor(jsReceiver, promiseFun);
}
// 4. Assert: IsConstructor(C) is true.

View File

@ -22,7 +22,8 @@ PromiseResolveThenableJob(implicit context: Context)(
// We take the generic (slow-)path if a PromiseHook is enabled or the
// debugger is active, to make sure we expose spec compliant behavior.
const nativeContext = LoadNativeContext(context);
const promiseThen = *NativeContextSlot(ContextSlot::PROMISE_THEN_INDEX);
const promiseThen =
nativeContext.elements[NativeContextSlot::PROMISE_THEN_INDEX];
const thenableMap = thenable.map;
if (TaggedEqual(then, promiseThen) && IsJSPromiseMap(thenableMap) &&
!IsPromiseHookEnabledOrDebugIsActiveOrHasAsyncEventDelegate() &&

View File

@ -38,7 +38,9 @@ macro PromiseInit(promise: JSPromise): void {
}
macro InnerNewJSPromise(implicit context: Context)(): JSPromise {
const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
const nativeContext = LoadNativeContext(context);
const promiseFun = UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
assert(IsFunctionWithPrototypeSlotMap(promiseFun.map));
const promiseMap = UnsafeCast<Map>(promiseFun.prototype_or_initial_map);
const promiseHeapObject = promise_internal::AllocateJSPromise(context);
@ -68,8 +70,8 @@ macro NewPromiseFulfillReactionJobTask(implicit context: Context)(
handler,
promise_or_capability: promiseOrCapability,
continuation_preserved_embedder_data:
*ContextSlot(
nativeContext, ContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX)
nativeContext.elements
[NativeContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX]
};
}
@ -85,8 +87,8 @@ macro NewPromiseRejectReactionJobTask(implicit context: Context)(
handler,
promise_or_capability: promiseOrCapability,
continuation_preserved_embedder_data:
*ContextSlot(
nativeContext, ContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX)
nativeContext.elements
[NativeContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX]
};
}
@ -144,8 +146,8 @@ macro NewPromiseReaction(implicit context: Context)(
fulfill_handler: fulfillHandler,
promise_or_capability: promiseOrCapability,
continuation_preserved_embedder_data:
*ContextSlot(
nativeContext, ContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX)
nativeContext.elements
[NativeContextSlot::CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX]
};
}
@ -208,8 +210,8 @@ macro InvokeThen<F: type>(implicit context: Context)(
if (!Is<Smi>(receiver) &&
IsPromiseThenLookupChainIntact(
nativeContext, UnsafeCast<HeapObject>(receiver).map)) {
const then =
*NativeContextSlot(nativeContext, ContextSlot::PROMISE_THEN_INDEX);
const then = UnsafeCast<JSAny>(
nativeContext.elements[NativeContextSlot::PROMISE_THEN_INDEX]);
return callFunctor.Call(nativeContext, then, receiver, arg1, arg2);
} else
deferred {

View File

@ -50,8 +50,8 @@ PromiseRace(
// Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).
try {
const fastIteratorResultMap = *NativeContextSlot(
nativeContext, ContextSlot::ITERATOR_RESULT_MAP_INDEX);
const fastIteratorResultMap = UnsafeCast<Map>(
nativeContext.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]);
while (true) {
let nextValue: JSAny;
try {

View File

@ -30,7 +30,8 @@ transitioning builtin
PromiseResolve(implicit context: Context)(
constructor: JSReceiver, value: JSAny): JSAny {
const nativeContext = LoadNativeContext(context);
const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
const promiseFun =
nativeContext.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX];
try {
// Check if {value} is a JSPromise.
const value = Cast<JSPromise>(value) otherwise NeedToAllocate;
@ -40,9 +41,7 @@ PromiseResolve(implicit context: Context)(
// intact, as that guards the lookup path for "constructor" on
// JSPromise instances which have the (initial) Promise.prototype.
const promisePrototype =
*NativeContextSlot(ContextSlot::PROMISE_PROTOTYPE_INDEX);
// Check that Torque load elimination works.
static_assert(nativeContext == LoadNativeContext(context));
nativeContext.elements[NativeContextSlot::PROMISE_PROTOTYPE_INDEX];
if (value.map.prototype != promisePrototype) {
goto SlowConstructor;
}
@ -139,7 +138,8 @@ ResolvePromise(implicit context: Context)(
assert(IsJSReceiverMap(resolutionMap));
assert(!IsPromiseThenProtectorCellInvalid());
if (resolutionMap ==
*NativeContextSlot(ContextSlot::ITERATOR_RESULT_MAP_INDEX)) {
nativeContext
.elements[NativeContextSlot::ITERATOR_RESULT_MAP_INDEX]) {
return FulfillPromise(promise, resolution);
} else {
goto Slow;
@ -147,12 +147,10 @@ ResolvePromise(implicit context: Context)(
}
const promisePrototype =
*NativeContextSlot(ContextSlot::PROMISE_PROTOTYPE_INDEX);
nativeContext.elements[NativeContextSlot::PROMISE_PROTOTYPE_INDEX];
if (resolutionMap.prototype == promisePrototype) {
// The {resolution} is a native Promise in this case.
then = *NativeContextSlot(ContextSlot::PROMISE_THEN_INDEX);
// Check that Torque load elimination works.
static_assert(nativeContext == LoadNativeContext(context));
then = nativeContext.elements[NativeContextSlot::PROMISE_THEN_INDEX];
goto Enqueue;
}
goto Slow;

View File

@ -10,7 +10,7 @@ macro
IsPromiseSpeciesLookupChainIntact(
nativeContext: NativeContext, promiseMap: Map): bool {
const promisePrototype =
*NativeContextSlot(nativeContext, ContextSlot::PROMISE_PROTOTYPE_INDEX);
nativeContext.elements[NativeContextSlot::PROMISE_PROTOTYPE_INDEX];
if (IsForceSlowPath()) return false;
if (promiseMap.prototype != promisePrototype) return false;
return !IsPromiseSpeciesProtectorCellInvalid();
@ -27,7 +27,8 @@ PromisePrototypeThen(js-implicit context: NativeContext, receiver: JSAny)(
receiver);
// 3. Let C be ? SpeciesConstructor(promise, %Promise%).
const promiseFun = *NativeContextSlot(ContextSlot::PROMISE_FUNCTION_INDEX);
const promiseFun = UnsafeCast<JSFunction>(
context.elements[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
// 4. Let resultCapability be ? NewPromiseCapability(C).
let resultPromiseOrCapability: JSPromise|PromiseCapability;

View File

@ -9,34 +9,28 @@ namespace proxy {
// Proxy Revocation Functions
// https://tc39.github.io/ecma262/#sec-proxy-revocation-functions
transitioning javascript builtin
ProxyRevoke(js-implicit context: Context)(): Undefined {
const context = %RawDownCast<ProxyRevokeFunctionContext>(context);
ProxyRevoke(js-implicit context: NativeContext)(): Undefined {
// 1. Let p be F.[[RevocableProxy]].
const proxySlot:&(JSProxy | Null) =
ContextSlot(context, ProxyRevokeFunctionContextSlot::kProxySlot);
const proxyObject: Object = context.elements[PROXY_SLOT];
typeswitch (*proxySlot) {
case (Null): {
// 2. If p is null, return undefined
return Undefined;
}
case (proxy: JSProxy): {
// 3. Set F.[[RevocableProxy]] to null.
*proxySlot = Null;
// 4. Assert: p is a Proxy object.
assert(Is<JSProxy>(proxy));
// 5. Set p.[[ProxyTarget]] to null.
proxy.target = Null;
// 6. Set p.[[ProxyHandler]] to null.
proxy.handler = Null;
// 7. Return undefined.
return Undefined;
}
// 2. If p is null, return undefined
if (proxyObject == Null) {
return Undefined;
}
// 3. Set F.[[RevocableProxy]] to null.
context.elements[PROXY_SLOT] = Null;
// 4. Assert: p is a Proxy object.
const proxy: JSProxy = UnsafeCast<JSProxy>(proxyObject);
// 5. Set p.[[ProxyTarget]] to null.
proxy.target = Null;
// 6. Set p.[[ProxyHandler]] to null.
proxy.handler = Null;
// 7. Return undefined.
return Undefined;
}
}

View File

@ -23,11 +23,4 @@ const kProxyGet: constexpr int31
generates 'JSProxy::AccessKind::kGet';
const kProxySet: constexpr int31
generates 'JSProxy::AccessKind::kSet';
type ProxyRevokeFunctionContext extends FunctionContext;
extern enum ProxyRevokeFunctionContextSlot extends intptr
constexpr 'ProxiesCodeStubAssembler::ProxyRevokeFunctionContextSlot' {
kProxySlot: Slot<ProxyRevokeFunctionContext, JSProxy|Null>,
kProxyContextLength
}
}

View File

@ -155,8 +155,10 @@ transitioning macro RegExpPrototypeExecBody(implicit context: Context)(
regexp, matchIndices, string, lastIndex);
}
macro LoadRegExpFunction(nativeContext: NativeContext): JSFunction {
return *NativeContextSlot(nativeContext, ContextSlot::REGEXP_FUNCTION_INDEX);
macro LoadRegExpFunction(implicit context: Context)(
nativeContext: NativeContext): JSFunction {
return UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::REGEXP_FUNCTION_INDEX]);
}
// Note this doesn't guarantee const-ness of object properties, just

View File

@ -1,19 +0,0 @@
// 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_

View File

@ -25,11 +25,6 @@ macro NewReference<T: type>(object: HeapObject, offset: intptr):&T {
return %RawDownCast<&T>(
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
struct Slice<T: type> {

View File

@ -13037,6 +13037,34 @@ void CodeStubAssembler::PerformStackCheck(TNode<Context> context) {
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> context, TNode<RawPtrT> callback, TNode<IntPtrT> argc,
TNode<Object> data, TNode<Object> holder, TNode<Object> receiver) {

View File

@ -128,7 +128,6 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(default_string, default_string, DefaultString) \
V(EmptyByteArray, empty_byte_array, EmptyByteArray) \
V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray) \
V(EmptyScopeInfo, empty_scope_info, EmptyScopeInfo) \
V(EmptyPropertyDictionary, empty_property_dictionary, \
EmptyPropertyDictionary) \
V(EmptySlowElementDictionary, empty_slow_element_dictionary, \
@ -3709,6 +3708,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<IntPtrT> TryToIntptr(SloppyTNode<Object> key, Label* if_not_intptr,
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);
// Allocate a clone of a mutable primitive, if {object} is a mutable

View File

@ -150,7 +150,7 @@ macro NewParameterMapIterator(
context: Context, formalParameterCount: intptr,
mappedCount: intptr): ParameterMapIterator {
const flags = context.GetScopeInfo().flags;
let contextHeaderSize: intptr = ContextSlot::MIN_CONTEXT_SLOTS;
let contextHeaderSize: intptr = MIN_CONTEXT_SLOTS;
if (flags.has_context_extension_slot) ++contextHeaderSize;
// Copy the parameter slots and the holes in the arguments.
// We need to fill in mapped_count slots. They index the context,

View File

@ -5,7 +5,7 @@
@abstract
extern class Context extends HeapObject {
macro GetScopeInfo(): ScopeInfo {
return *ContextSlot(this, ContextSlot::SCOPE_INFO_INDEX);
return UnsafeCast<ScopeInfo>(this.elements[0]);
}
const length: Smi;
elements[length]: Object;
@ -17,117 +17,57 @@ extern class CatchContext extends Context generates 'TNode<Context>';
extern class DebugEvaluateContext 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 NativeContext extends Context;
extern class ScriptContext extends Context generates 'TNode<Context>';
extern class WithContext extends Context generates 'TNode<Context>';
extern class FunctionContext extends Context generates 'TNode<Context>';
const MIN_CONTEXT_SLOTS: constexpr int31
generates 'Context::MIN_CONTEXT_SLOTS';
const kInitialContextSlotValue: Smi = 0;
extern enum NativeContextSlot extends intptr constexpr 'Context::Field' {
AGGREGATE_ERROR_FUNCTION_INDEX,
ARRAY_BUFFER_FUN_INDEX,
ARRAY_BUFFER_NOINIT_FUN_INDEX,
ARRAY_BUFFER_MAP_INDEX,
ARRAY_FUNCTION_INDEX,
ARRAY_JOIN_STACK_INDEX,
OBJECT_FUNCTION_INDEX,
ITERATOR_RESULT_MAP_INDEX,
JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX,
JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX,
MATH_RANDOM_CACHE_INDEX,
MATH_RANDOM_INDEX_INDEX,
NUMBER_FUNCTION_INDEX,
PROXY_REVOCABLE_RESULT_MAP_INDEX,
REFLECT_APPLY_INDEX,
REGEXP_FUNCTION_INDEX,
REGEXP_LAST_MATCH_INFO_INDEX,
INITIAL_STRING_ITERATOR_MAP_INDEX,
INITIAL_ARRAY_ITERATOR_MAP_INDEX,
SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP,
STRICT_ARGUMENTS_MAP_INDEX,
SLOPPY_ARGUMENTS_MAP_INDEX,
FAST_ALIASED_ARGUMENTS_MAP_INDEX,
@export
macro AllocateSyntheticFunctionContext(
nativeContext: NativeContext, slots: constexpr int31): FunctionContext {
return AllocateSyntheticFunctionContext(
nativeContext, Convert<intptr>(slots));
}
PROMISE_FUNCTION_INDEX,
PROMISE_THEN_INDEX,
PROMISE_PROTOTYPE_INDEX,
STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX,
macro AllocateSyntheticFunctionContext(
nativeContext: NativeContext, slots: intptr): FunctionContext {
static_assert(slots >= ContextSlot::MIN_CONTEXT_SLOTS);
const map =
*ContextSlot(nativeContext, ContextSlot::FUNCTION_CONTEXT_MAP_INDEX);
const result = new FunctionContext{
map,
length: Convert<Smi>(slots),
elements: ...ConstantIterator<Smi>(kInitialContextSlotValue)
};
InitContextSlot(result, ContextSlot::SCOPE_INFO_INDEX, kEmptyScopeInfo);
InitContextSlot(result, ContextSlot::PREVIOUS_INDEX, Undefined);
return result;
}
CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX,
extern class NativeContext extends Context;
type Slot<Container : type extends Context, T : type extends Object> extends
intptr;
// We cannot use ContextSlot() for initialization since that one asserts the
// slot has the right type already.
macro InitContextSlot<
ArgumentContext: type, AnnotatedContext: type, T: type, U: type>(
context: ArgumentContext, index: Slot<AnnotatedContext, T>, value: U) {
// 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;
}
macro ContextSlot<ArgumentContext: type, AnnotatedContext: type, T: type>(
context: ArgumentContext, index: Slot<AnnotatedContext, T>):&T {
const context: AnnotatedContext = context;
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,
BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX,
BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX,
...
}
type ContextSlot extends intptr
generates 'TNode<IntPtrT>' constexpr 'int32_t';
const PROXY_SLOT: constexpr ContextSlot
generates 'Context::MIN_CONTEXT_SLOTS';
@export
macro LoadContextElement(c: Context, i: intptr): Object {
return c.elements[i];

View File

@ -16,7 +16,8 @@ extern class JSArrayIterator extends JSObject {
macro CreateArrayIterator(implicit context: NativeContext)(
array: JSReceiver, kind: constexpr IterationKind): JSArrayIterator {
return new JSArrayIterator{
map: *NativeContextSlot(ContextSlot::INITIAL_ARRAY_ITERATOR_MAP_INDEX),
map: UnsafeCast<Map>(
context.elements[NativeContextSlot::INITIAL_ARRAY_ITERATOR_MAP_INDEX]),
properties_or_hash: kEmptyFixedArray,
elements: kEmptyFixedArray,
iterated_object: array,

View File

@ -4,9 +4,6 @@
extern class ScopeInfo extends FixedArray;
extern macro EmptyScopeInfoConstant(): ScopeInfo;
const kEmptyScopeInfo: ScopeInfo = EmptyScopeInfoConstant();
const kScopeInfoFlagsIndex:
constexpr int32 generates 'ScopeInfo::Fields::kFlags';

View File

@ -374,10 +374,8 @@ Callable* DeclarationVisitor::Specialize(
}
void PredeclarationVisitor::ResolvePredeclarations() {
const auto& all_declarables = GlobalContext::AllDeclarables();
for (size_t i = 0; i < all_declarables.size(); ++i) {
Declarable* declarable = all_declarables[i].get();
if (const TypeAlias* alias = TypeAlias::DynamicCast(declarable)) {
for (auto& p : GlobalContext::AllDeclarables()) {
if (const TypeAlias* alias = TypeAlias::DynamicCast(p.get())) {
CurrentScope::Scope scope_activator(alias->ParentScope());
CurrentSourcePosition::Scope position_activator(alias->Position());
alias->Resolve();

View File

@ -81,7 +81,12 @@ void ImplementationVisitor::BeginCSAFiles() {
UnderlinifyPath(SourceFileMap::PathFromV8Root(file)) + "_H_";
header << "#ifndef " << headerDefine << "\n";
header << "#define " << headerDefine << "\n\n";
header << "#include \"src/builtins/torque-csa-header-includes.h\"\n";
header << "#include \"src/builtins/builtins-promise.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 << "namespace v8 {\n"

View File

@ -1306,8 +1306,9 @@ macro TestGeneratedCastOperators(implicit context: Context)() {
assert(!Is<ExportedSubClass>(cO));
assert(Is<ExportedSubClass2>(cO));
const jsf: JSFunction =
*NativeContextSlot(ContextSlot::REGEXP_FUNCTION_INDEX);
const nativeContext = LoadNativeContext(context);
const jsf: JSFunction = UnsafeCast<JSFunction>(
nativeContext.elements[NativeContextSlot::REGEXP_FUNCTION_INDEX]);
assert(!Is<JSSloppyArgumentsObject>(jsf));
const parameterValues = NewFixedArray(0, ConstantIterator(TheHole));