blob: a246b2177b8830f92ae323de66b52148d4227b0c [file] [log] [blame]
// Copyright 2019 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.
@abstract
extern class Context extends HeapObject {
macro GetScopeInfo(): ScopeInfo {
return *ContextSlot(this, ContextSlot::SCOPE_INFO_INDEX);
}
const length: Smi;
elements[length]: Object;
}
extern class AwaitContext extends Context generates 'TNode<Context>';
extern class BlockContext extends Context generates 'TNode<Context>';
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 ModuleContext extends Context generates 'TNode<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 kInitialContextSlotValue: Smi = 0;
@export
macro AllocateSyntheticFunctionContext(
nativeContext: NativeContext, slots: constexpr int31): FunctionContext {
return AllocateSyntheticFunctionContext(
nativeContext, Convert<intptr>(slots));
}
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;
}
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,
...
}
@export
macro LoadContextElement(c: Context, i: intptr): Object {
return c.elements[i];
}
@export
macro LoadContextElement(c: Context, i: Smi): Object {
return c.elements[i];
}
@export
macro LoadContextElement(c: Context, i: constexpr int32): Object {
return c.elements[i];
}
@export
macro StoreContextElement(c: Context, i: intptr, o: Object) {
c.elements[i] = o;
}
@export
macro StoreContextElement(c: Context, i: Smi, o: Object) {
c.elements[i] = o;
}
@export
macro StoreContextElement(c: Context, i: constexpr int32, o: Object) {
c.elements[i] = o;
}
// A dummy used instead of a context constant for runtime calls that don't need
// a context.
type NoContext extends Smi;
extern macro NoContextConstant(): NoContext;
const kNoContext: NoContext = NoContextConstant();