1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5@abstract
6@export
7@customCppClass
8// We normally don't generate a BodyDescriptor for an abstact class, but here we
9// do since all context classes share the same BodyDescriptor.
10@generateBodyDescriptor
11class Context extends HeapObject {
12  macro GetScopeInfo(): ScopeInfo {
13    return *ContextSlot(this, ContextSlot::SCOPE_INFO_INDEX);
14  }
15  const length: Smi;
16  elements[length]: Object;
17}
18
19extern class AwaitContext extends Context generates 'TNode<Context>';
20extern class BlockContext extends Context generates 'TNode<Context>';
21extern class CatchContext extends Context generates 'TNode<Context>';
22extern class DebugEvaluateContext extends Context
23    generates 'TNode<Context>';
24extern class EvalContext extends Context generates 'TNode<Context>';
25extern class ModuleContext extends Context generates 'TNode<Context>';
26extern class ScriptContext extends Context generates 'TNode<Context>';
27extern class WithContext extends Context generates 'TNode<Context>';
28
29extern class FunctionContext extends Context generates 'TNode<Context>';
30
31const kInitialContextSlotValue: Smi = 0;
32
33@export
34macro AllocateSyntheticFunctionContext(
35    nativeContext: NativeContext, slots: constexpr int31): FunctionContext {
36  return AllocateSyntheticFunctionContext(
37      nativeContext, Convert<intptr>(slots));
38}
39
40macro AllocateSyntheticFunctionContext(
41    nativeContext: NativeContext, slots: intptr): FunctionContext {
42  static_assert(slots >= ContextSlot::MIN_CONTEXT_SLOTS);
43  const map =
44      *ContextSlot(nativeContext, ContextSlot::FUNCTION_CONTEXT_MAP_INDEX);
45  const result = new FunctionContext{
46    map,
47    length: Convert<Smi>(slots),
48    elements: ...ConstantIterator<Smi>(kInitialContextSlotValue)
49  };
50  InitContextSlot(result, ContextSlot::SCOPE_INFO_INDEX, kEmptyScopeInfo);
51  InitContextSlot(result, ContextSlot::PREVIOUS_INDEX, Undefined);
52  return result;
53}
54
55extern class NativeContext extends Context;
56
57type Slot<Container : type extends Context, T : type extends Object> extends
58    intptr;
59
60// We cannot use ContextSlot() for initialization since that one asserts the
61// slot has the right type already.
62macro InitContextSlot<
63    ArgumentContext: type, AnnotatedContext: type, T: type, U: type>(
64    context: ArgumentContext, index: Slot<AnnotatedContext, T>,
65    value: U): void {
66  // Make sure the arguments have the right type.
67  const context: AnnotatedContext = context;
68  const value: T = value;
69  dcheck(TaggedEqual(context.elements[index], kInitialContextSlotValue));
70  context.elements[index] = value;
71}
72
73macro ContextSlot<ArgumentContext: type, AnnotatedContext: type, T: type>(
74    context: ArgumentContext, index: Slot<AnnotatedContext, T>):&T {
75  const context: AnnotatedContext = context;
76  return torque_internal::unsafe::ReferenceCast<T>(&context.elements[index]);
77}
78
79macro NativeContextSlot<T: type>(
80    context: NativeContext, index: Slot<NativeContext, T>):&T {
81  return ContextSlot(context, index);
82}
83macro NativeContextSlot<T: type>(
84    context: Context, index: Slot<NativeContext, T>):&T {
85  return ContextSlot(LoadNativeContext(context), index);
86}
87macro NativeContextSlot<C: type, T: type>(implicit context: C)(
88    index: Slot<NativeContext, T>):&T {
89  return NativeContextSlot(context, index);
90}
91
92extern enum ContextSlot extends intptr constexpr 'Context::Field' {
93  SCOPE_INFO_INDEX: Slot<Context, ScopeInfo>,
94  // Zero is used for the NativeContext, Undefined is used for synthetic
95  // function contexts.
96  PREVIOUS_INDEX: Slot<Context, Context|Zero|Undefined>,
97
98  AGGREGATE_ERROR_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
99  ARRAY_BUFFER_FUN_INDEX: Slot<NativeContext, Constructor>,
100  ARRAY_BUFFER_NOINIT_FUN_INDEX: Slot<NativeContext, JSFunction>,
101  ARRAY_BUFFER_MAP_INDEX: Slot<NativeContext, Map>,
102  ARRAY_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
103  ARRAY_JOIN_STACK_INDEX: Slot<NativeContext, Undefined|FixedArray>,
104  OBJECT_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
105  ITERATOR_RESULT_MAP_INDEX: Slot<NativeContext, Map>,
106  JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX: Slot<NativeContext, Map>,
107  JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX: Slot<NativeContext, Map>,
108  MATH_RANDOM_CACHE_INDEX: Slot<NativeContext, FixedDoubleArray>,
109  MATH_RANDOM_INDEX_INDEX: Slot<NativeContext, Smi>,
110  NUMBER_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
111  PROXY_REVOCABLE_RESULT_MAP_INDEX: Slot<NativeContext, Map>,
112  REFLECT_APPLY_INDEX: Slot<NativeContext, Callable>,
113  REGEXP_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
114  REGEXP_LAST_MATCH_INFO_INDEX: Slot<NativeContext, RegExpMatchInfo>,
115  INITIAL_STRING_ITERATOR_MAP_INDEX: Slot<NativeContext, Map>,
116  INITIAL_ARRAY_ITERATOR_MAP_INDEX: Slot<NativeContext, Map>,
117  SLOW_OBJECT_WITH_NULL_PROTOTYPE_MAP: Slot<NativeContext, Map>,
118  STRICT_ARGUMENTS_MAP_INDEX: Slot<NativeContext, Map>,
119  SLOPPY_ARGUMENTS_MAP_INDEX: Slot<NativeContext, Map>,
120  FAST_ALIASED_ARGUMENTS_MAP_INDEX: Slot<NativeContext, Map>,
121  FUNCTION_CONTEXT_MAP_INDEX: Slot<NativeContext, Map>,
122  FUNCTION_PROTOTYPE_APPLY_INDEX: Slot<NativeContext, JSFunction>,
123
124  UINT8_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
125  INT8_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
126  UINT16_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
127  INT16_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
128  UINT32_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
129  INT32_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
130  FLOAT32_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
131  FLOAT64_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
132  UINT8_CLAMPED_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
133  BIGUINT64_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
134  BIGINT64_ARRAY_FUN_INDEX: Slot<NativeContext, JSFunction>,
135
136  RAB_GSAB_UINT8_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
137  RAB_GSAB_INT8_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
138  RAB_GSAB_UINT16_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
139  RAB_GSAB_INT16_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
140  RAB_GSAB_UINT32_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
141  RAB_GSAB_INT32_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
142  RAB_GSAB_FLOAT32_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
143  RAB_GSAB_FLOAT64_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
144  RAB_GSAB_UINT8_CLAMPED_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
145  RAB_GSAB_BIGUINT64_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
146  RAB_GSAB_BIGINT64_ARRAY_MAP_INDEX: Slot<NativeContext, Map>,
147
148  PROMISE_FUNCTION_INDEX: Slot<NativeContext, JSFunction>,
149  PROMISE_THEN_INDEX: Slot<NativeContext, JSFunction>,
150  PROMISE_PROTOTYPE_INDEX: Slot<NativeContext, JSObject>,
151  STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX: Slot<NativeContext, Map>,
152
153  PROMISE_HOOK_INIT_FUNCTION_INDEX: Slot<NativeContext, Undefined|Callable>,
154  PROMISE_HOOK_BEFORE_FUNCTION_INDEX: Slot<NativeContext, Undefined|Callable>,
155  PROMISE_HOOK_AFTER_FUNCTION_INDEX: Slot<NativeContext, Undefined|Callable>,
156  PROMISE_HOOK_RESOLVE_FUNCTION_INDEX: Slot<NativeContext, Undefined|Callable>,
157
158  CONTINUATION_PRESERVED_EMBEDDER_DATA_INDEX: Slot<NativeContext, HeapObject>,
159
160  BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX: Slot<NativeContext, Map>,
161  BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX: Slot<NativeContext, Map>,
162
163  MIN_CONTEXT_SLOTS,
164  ...
165}
166
167@export
168macro LoadContextElement(c: Context, i: intptr): Object {
169  return c.elements[i];
170}
171
172@export
173macro LoadContextElement(c: Context, i: Smi): Object {
174  return c.elements[i];
175}
176
177@export
178macro LoadContextElement(c: Context, i: constexpr int32): Object {
179  return c.elements[i];
180}
181
182@export
183macro StoreContextElement(c: Context, i: intptr, o: Object): void {
184  c.elements[i] = o;
185}
186
187@export
188macro StoreContextElement(c: Context, i: Smi, o: Object): void {
189  c.elements[i] = o;
190}
191
192@export
193macro StoreContextElement(c: Context, i: constexpr int32, o: Object): void {
194  c.elements[i] = o;
195}
196
197// A dummy used instead of a context constant for runtime calls that don't need
198// a context.
199type NoContext extends Smi;
200extern macro NoContextConstant(): NoContext;
201const kNoContext: NoContext = NoContextConstant();
202