// 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 @export @customCppClass // We normally don't generate a BodyDescriptor for an abstact class, but here we // do since all context classes share the same BodyDescriptor. @generateBodyDescriptor 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'; extern class BlockContext extends Context generates 'TNode'; extern class CatchContext extends Context generates 'TNode'; extern class DebugEvaluateContext extends Context generates 'TNode'; extern class EvalContext extends Context generates 'TNode'; extern class ModuleContext extends Context generates 'TNode'; extern class ScriptContext extends Context generates 'TNode'; extern class WithContext extends Context generates 'TNode'; extern class FunctionContext extends Context generates 'TNode'; const kInitialContextSlotValue: Smi = 0; @export macro AllocateSyntheticFunctionContext( nativeContext: NativeContext, slots: constexpr int31): FunctionContext { return AllocateSyntheticFunctionContext( nativeContext, Convert(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(slots), elements: ...ConstantIterator(kInitialContextSlotValue) }; InitContextSlot(result, ContextSlot::SCOPE_INFO_INDEX, kEmptyScopeInfo); InitContextSlot(result, ContextSlot::PREVIOUS_INDEX, Undefined); return result; } extern class NativeContext extends Context; type Slot 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, 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( context: ArgumentContext, index: Slot):&T { const context: AnnotatedContext = context; return torque_internal::unsafe::ReferenceCast(&context.elements[index]); } macro NativeContextSlot( context: NativeContext, index: Slot):&T { return ContextSlot(context, index); } macro NativeContextSlot( context: Context, index: Slot):&T { return ContextSlot(LoadNativeContext(context), index); } macro NativeContextSlot(implicit context: C)( index: Slot):&T { return NativeContextSlot(context, index); } extern enum ContextSlot extends intptr constexpr 'Context::Field' { SCOPE_INFO_INDEX: Slot, // Zero is used for the NativeContext, Undefined is used for synthetic // function contexts. PREVIOUS_INDEX: Slot, AGGREGATE_ERROR_FUNCTION_INDEX: Slot, ARRAY_BUFFER_FUN_INDEX: Slot, ARRAY_BUFFER_NOINIT_FUN_INDEX: Slot, ARRAY_BUFFER_MAP_INDEX: Slot, ARRAY_FUNCTION_INDEX: Slot, ARRAY_JOIN_STACK_INDEX: Slot, OBJECT_FUNCTION_INDEX: Slot, ITERATOR_RESULT_MAP_INDEX: Slot, JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX: Slot, JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX: Slot, MATH_RANDOM_CACHE_INDEX: Slot, MATH_RANDOM_INDEX_INDEX: Slot, NUMBER_FUNCTION_INDEX: Slot, PROXY_REVOCABLE_RESULT_MAP_INDEX: Slot, REFLECT_APPLY_INDEX: Slot, REGEXP_FUNCTION_INDEX: Slot, REGEXP_LAST_MATCH_INFO_INDEX: Slot, INITIAL_STRING_ITERATOR_MAP_INDEX: Slot, INITIAL_ARRAY_ITERATOR_MAP_INDEX: Slot, SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP: Slot, STRICT_ARGUMENTS_MAP_INDEX: Slot, SLOPPY_ARGUMENTS_MAP_INDEX: Slot, FAST_ALIASED_ARGUMENTS_MAP_INDEX: Slot, FUNCTION_CONTEXT_MAP_INDEX: Slot, FUNCTION_PROTOTYPE_APPLY_INDEX: Slot, UINT8_ARRAY_FUN_INDEX: Slot, INT8_ARRAY_FUN_INDEX: Slot, UINT16_ARRAY_FUN_INDEX: Slot, INT16_ARRAY_FUN_INDEX: Slot, UINT32_ARRAY_FUN_INDEX: Slot, INT32_ARRAY_FUN_INDEX: Slot, FLOAT32_ARRAY_FUN_INDEX: Slot, FLOAT64_ARRAY_FUN_INDEX: Slot, UINT8_CLAMPED_ARRAY_FUN_INDEX: Slot, BIGUINT64_ARRAY_FUN_INDEX: Slot, BIGINT64_ARRAY_FUN_INDEX: Slot, RAB_GSAB_UINT8_ARRAY_MAP_INDEX: Slot, RAB_GSAB_INT8_ARRAY_MAP_INDEX: Slot, RAB_GSAB_UINT16_ARRAY_MAP_INDEX: Slot, RAB_GSAB_INT16_ARRAY_MAP_INDEX: Slot, RAB_GSAB_UINT32_ARRAY_MAP_INDEX: Slot, RAB_GSAB_INT32_ARRAY_MAP_INDEX: Slot, RAB_GSAB_FLOAT32_ARRAY_MAP_INDEX: Slot, RAB_GSAB_FLOAT64_ARRAY_MAP_INDEX: Slot, RAB_GSAB_UINT8_CLAMPED_ARRAY_MAP_INDEX: Slot, RAB_GSAB_BIGUINT64_ARRAY_MAP_INDEX: Slot, RAB_GSAB_BIGINT64_ARRAY_MAP_INDEX: Slot, PROMISE_FUNCTION_INDEX: Slot, PROMISE_THEN_INDEX: Slot, PROMISE_PROTOTYPE_INDEX: Slot, STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX: Slot, PROMISE_HOOK_INIT_FUNCTION_INDEX: Slot, PROMISE_HOOK_BEFORE_FUNCTION_INDEX: Slot, PROMISE_HOOK_AFTER_FUNCTION_INDEX: Slot, PROMISE_HOOK_RESOLVE_FUNCTION_INDEX: Slot, CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX: Slot, BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX: Slot, BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX: Slot, 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();