| // 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(); |