1 // Copyright 2016 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 #ifndef V8_IC_HANDLER_CONFIGURATION_INL_H_
6 #define V8_IC_HANDLER_CONFIGURATION_INL_H_
7
8 #include "src/builtins/builtins.h"
9 #include "src/execution/isolate.h"
10 #include "src/handles/handles-inl.h"
11 #include "src/ic/handler-configuration.h"
12 #include "src/objects/data-handler-inl.h"
13 #include "src/objects/field-index-inl.h"
14 #include "src/objects/objects-inl.h"
15 #include "src/objects/smi.h"
16
17 // Has to be the last include (doesn't have include guards):
18 #include "src/objects/object-macros.h"
19
20 namespace v8 {
21 namespace internal {
22
MakeCodeHandler(Isolate * isolate,Builtin builtin)23 inline Handle<Object> MakeCodeHandler(Isolate* isolate, Builtin builtin) {
24 return isolate->builtins()->code_handle(builtin);
25 }
26
OBJECT_CONSTRUCTORS_IMPL(LoadHandler,DataHandler)27 OBJECT_CONSTRUCTORS_IMPL(LoadHandler, DataHandler)
28
29 CAST_ACCESSOR(LoadHandler)
30
31 // Decodes kind from Smi-handler.
32 LoadHandler::Kind LoadHandler::GetHandlerKind(Smi smi_handler) {
33 return KindBits::decode(smi_handler.value());
34 }
35
LoadNormal(Isolate * isolate)36 Handle<Smi> LoadHandler::LoadNormal(Isolate* isolate) {
37 int config = KindBits::encode(Kind::kNormal);
38 return handle(Smi::FromInt(config), isolate);
39 }
40
LoadGlobal(Isolate * isolate)41 Handle<Smi> LoadHandler::LoadGlobal(Isolate* isolate) {
42 int config = KindBits::encode(Kind::kGlobal);
43 return handle(Smi::FromInt(config), isolate);
44 }
45
LoadInterceptor(Isolate * isolate)46 Handle<Smi> LoadHandler::LoadInterceptor(Isolate* isolate) {
47 int config = KindBits::encode(Kind::kInterceptor);
48 return handle(Smi::FromInt(config), isolate);
49 }
50
LoadSlow(Isolate * isolate)51 Handle<Smi> LoadHandler::LoadSlow(Isolate* isolate) {
52 int config = KindBits::encode(Kind::kSlow);
53 return handle(Smi::FromInt(config), isolate);
54 }
55
LoadField(Isolate * isolate,FieldIndex field_index)56 Handle<Smi> LoadHandler::LoadField(Isolate* isolate, FieldIndex field_index) {
57 int config = KindBits::encode(Kind::kField) |
58 IsInobjectBits::encode(field_index.is_inobject()) |
59 IsDoubleBits::encode(field_index.is_double()) |
60 FieldIndexBits::encode(field_index.index());
61 return handle(Smi::FromInt(config), isolate);
62 }
63
LoadWasmStructField(Isolate * isolate,WasmValueType type,int offset)64 Handle<Smi> LoadHandler::LoadWasmStructField(Isolate* isolate,
65 WasmValueType type, int offset) {
66 int config = KindBits::encode(Kind::kField) | IsWasmStructBits::encode(true) |
67 WasmFieldTypeBits::encode(type) |
68 WasmFieldOffsetBits::encode(offset);
69 return handle(Smi::FromInt(config), isolate);
70 }
71
LoadConstantFromPrototype(Isolate * isolate)72 Handle<Smi> LoadHandler::LoadConstantFromPrototype(Isolate* isolate) {
73 int config = KindBits::encode(Kind::kConstantFromPrototype);
74 return handle(Smi::FromInt(config), isolate);
75 }
76
LoadAccessor(Isolate * isolate,int descriptor)77 Handle<Smi> LoadHandler::LoadAccessor(Isolate* isolate, int descriptor) {
78 int config =
79 KindBits::encode(Kind::kAccessor) | DescriptorBits::encode(descriptor);
80 return handle(Smi::FromInt(config), isolate);
81 }
82
LoadProxy(Isolate * isolate)83 Handle<Smi> LoadHandler::LoadProxy(Isolate* isolate) {
84 int config = KindBits::encode(Kind::kProxy);
85 return handle(Smi::FromInt(config), isolate);
86 }
87
LoadNativeDataProperty(Isolate * isolate,int descriptor)88 Handle<Smi> LoadHandler::LoadNativeDataProperty(Isolate* isolate,
89 int descriptor) {
90 int config = KindBits::encode(Kind::kNativeDataProperty) |
91 DescriptorBits::encode(descriptor);
92 return handle(Smi::FromInt(config), isolate);
93 }
94
LoadApiGetter(Isolate * isolate,bool holder_is_receiver)95 Handle<Smi> LoadHandler::LoadApiGetter(Isolate* isolate,
96 bool holder_is_receiver) {
97 int config =
98 KindBits::encode(holder_is_receiver ? Kind::kApiGetter
99 : Kind::kApiGetterHolderIsPrototype);
100 return handle(Smi::FromInt(config), isolate);
101 }
102
LoadModuleExport(Isolate * isolate,int index)103 Handle<Smi> LoadHandler::LoadModuleExport(Isolate* isolate, int index) {
104 int config =
105 KindBits::encode(Kind::kModuleExport) | ExportsIndexBits::encode(index);
106 return handle(Smi::FromInt(config), isolate);
107 }
108
LoadNonExistent(Isolate * isolate)109 Handle<Smi> LoadHandler::LoadNonExistent(Isolate* isolate) {
110 int config = KindBits::encode(Kind::kNonExistent);
111 return handle(Smi::FromInt(config), isolate);
112 }
113
LoadElement(Isolate * isolate,ElementsKind elements_kind,bool convert_hole_to_undefined,bool is_js_array,KeyedAccessLoadMode load_mode)114 Handle<Smi> LoadHandler::LoadElement(Isolate* isolate,
115 ElementsKind elements_kind,
116 bool convert_hole_to_undefined,
117 bool is_js_array,
118 KeyedAccessLoadMode load_mode) {
119 int config =
120 KindBits::encode(Kind::kElement) |
121 AllowOutOfBoundsBits::encode(load_mode == LOAD_IGNORE_OUT_OF_BOUNDS) |
122 ElementsKindBits::encode(elements_kind) |
123 ConvertHoleBits::encode(convert_hole_to_undefined) |
124 IsJsArrayBits::encode(is_js_array);
125 return handle(Smi::FromInt(config), isolate);
126 }
127
LoadIndexedString(Isolate * isolate,KeyedAccessLoadMode load_mode)128 Handle<Smi> LoadHandler::LoadIndexedString(Isolate* isolate,
129 KeyedAccessLoadMode load_mode) {
130 int config =
131 KindBits::encode(Kind::kIndexedString) |
132 AllowOutOfBoundsBits::encode(load_mode == LOAD_IGNORE_OUT_OF_BOUNDS);
133 return handle(Smi::FromInt(config), isolate);
134 }
135
LoadWasmArrayElement(Isolate * isolate,WasmValueType type)136 Handle<Smi> LoadHandler::LoadWasmArrayElement(Isolate* isolate,
137 WasmValueType type) {
138 int config = KindBits::encode(Kind::kElement) |
139 IsWasmArrayBits::encode(true) | WasmArrayTypeBits::encode(type);
140 return handle(Smi::FromInt(config), isolate);
141 }
142
OBJECT_CONSTRUCTORS_IMPL(StoreHandler,DataHandler)143 OBJECT_CONSTRUCTORS_IMPL(StoreHandler, DataHandler)
144
145 CAST_ACCESSOR(StoreHandler)
146
147 Handle<Smi> StoreHandler::StoreGlobalProxy(Isolate* isolate) {
148 int config = KindBits::encode(Kind::kGlobalProxy);
149 return handle(Smi::FromInt(config), isolate);
150 }
151
StoreNormal(Isolate * isolate)152 Handle<Smi> StoreHandler::StoreNormal(Isolate* isolate) {
153 int config = KindBits::encode(Kind::kNormal);
154 return handle(Smi::FromInt(config), isolate);
155 }
156
StoreInterceptor(Isolate * isolate)157 Handle<Smi> StoreHandler::StoreInterceptor(Isolate* isolate) {
158 int config = KindBits::encode(Kind::kInterceptor);
159 return handle(Smi::FromInt(config), isolate);
160 }
161
StoreSloppyArgumentsBuiltin(KeyedAccessStoreMode mode)162 Builtin StoreHandler::StoreSloppyArgumentsBuiltin(KeyedAccessStoreMode mode) {
163 switch (mode) {
164 case STANDARD_STORE:
165 return Builtin::kKeyedStoreIC_SloppyArguments_Standard;
166 case STORE_AND_GROW_HANDLE_COW:
167 return Builtin::kKeyedStoreIC_SloppyArguments_GrowNoTransitionHandleCOW;
168 case STORE_IGNORE_OUT_OF_BOUNDS:
169 return Builtin::kKeyedStoreIC_SloppyArguments_NoTransitionIgnoreOOB;
170 case STORE_HANDLE_COW:
171 return Builtin::kKeyedStoreIC_SloppyArguments_NoTransitionHandleCOW;
172 default:
173 UNREACHABLE();
174 }
175 }
176
StoreFastElementBuiltin(KeyedAccessStoreMode mode)177 Builtin StoreHandler::StoreFastElementBuiltin(KeyedAccessStoreMode mode) {
178 switch (mode) {
179 case STANDARD_STORE:
180 return Builtin::kStoreFastElementIC_Standard;
181 case STORE_AND_GROW_HANDLE_COW:
182 return Builtin::kStoreFastElementIC_GrowNoTransitionHandleCOW;
183 case STORE_IGNORE_OUT_OF_BOUNDS:
184 return Builtin::kStoreFastElementIC_NoTransitionIgnoreOOB;
185 case STORE_HANDLE_COW:
186 return Builtin::kStoreFastElementIC_NoTransitionHandleCOW;
187 default:
188 UNREACHABLE();
189 }
190 }
191
ElementsTransitionAndStoreBuiltin(KeyedAccessStoreMode mode)192 Builtin StoreHandler::ElementsTransitionAndStoreBuiltin(
193 KeyedAccessStoreMode mode) {
194 switch (mode) {
195 case STANDARD_STORE:
196 return Builtin::kElementsTransitionAndStore_Standard;
197 case STORE_AND_GROW_HANDLE_COW:
198 return Builtin::kElementsTransitionAndStore_GrowNoTransitionHandleCOW;
199 case STORE_IGNORE_OUT_OF_BOUNDS:
200 return Builtin::kElementsTransitionAndStore_NoTransitionIgnoreOOB;
201 case STORE_HANDLE_COW:
202 return Builtin::kElementsTransitionAndStore_NoTransitionHandleCOW;
203 default:
204 UNREACHABLE();
205 }
206 }
207
StoreSlow(Isolate * isolate,KeyedAccessStoreMode store_mode)208 Handle<Smi> StoreHandler::StoreSlow(Isolate* isolate,
209 KeyedAccessStoreMode store_mode) {
210 int config = KindBits::encode(Kind::kSlow) |
211 KeyedAccessStoreModeBits::encode(store_mode);
212 return handle(Smi::FromInt(config), isolate);
213 }
214
StoreProxy(Isolate * isolate)215 Handle<Smi> StoreHandler::StoreProxy(Isolate* isolate) {
216 return handle(StoreProxy(), isolate);
217 }
218
StoreProxy()219 Smi StoreHandler::StoreProxy() {
220 int config = KindBits::encode(Kind::kProxy);
221 return Smi::FromInt(config);
222 }
223
StoreField(Isolate * isolate,Kind kind,int descriptor,FieldIndex field_index,Representation representation)224 Handle<Smi> StoreHandler::StoreField(Isolate* isolate, Kind kind,
225 int descriptor, FieldIndex field_index,
226 Representation representation) {
227 DCHECK(!representation.IsNone());
228 DCHECK(kind == Kind::kField || kind == Kind::kConstField ||
229 kind == Kind::kSharedStructField);
230
231 int config = KindBits::encode(kind) |
232 IsInobjectBits::encode(field_index.is_inobject()) |
233 RepresentationBits::encode(representation.kind()) |
234 DescriptorBits::encode(descriptor) |
235 FieldIndexBits::encode(field_index.index());
236 return handle(Smi::FromInt(config), isolate);
237 }
238
StoreField(Isolate * isolate,int descriptor,FieldIndex field_index,PropertyConstness constness,Representation representation)239 Handle<Smi> StoreHandler::StoreField(Isolate* isolate, int descriptor,
240 FieldIndex field_index,
241 PropertyConstness constness,
242 Representation representation) {
243 Kind kind = constness == PropertyConstness::kMutable ? Kind::kField
244 : Kind::kConstField;
245 return StoreField(isolate, kind, descriptor, field_index, representation);
246 }
247
StoreSharedStructField(Isolate * isolate,int descriptor,FieldIndex field_index,Representation representation)248 Handle<Smi> StoreHandler::StoreSharedStructField(
249 Isolate* isolate, int descriptor, FieldIndex field_index,
250 Representation representation) {
251 DCHECK(representation.Equals(Representation::Tagged()));
252 return StoreField(isolate, Kind::kSharedStructField, descriptor, field_index,
253 representation);
254 }
255
StoreNativeDataProperty(Isolate * isolate,int descriptor)256 Handle<Smi> StoreHandler::StoreNativeDataProperty(Isolate* isolate,
257 int descriptor) {
258 int config = KindBits::encode(Kind::kNativeDataProperty) |
259 DescriptorBits::encode(descriptor);
260 return handle(Smi::FromInt(config), isolate);
261 }
262
StoreAccessor(Isolate * isolate,int descriptor)263 Handle<Smi> StoreHandler::StoreAccessor(Isolate* isolate, int descriptor) {
264 int config =
265 KindBits::encode(Kind::kAccessor) | DescriptorBits::encode(descriptor);
266 return handle(Smi::FromInt(config), isolate);
267 }
268
StoreApiSetter(Isolate * isolate,bool holder_is_receiver)269 Handle<Smi> StoreHandler::StoreApiSetter(Isolate* isolate,
270 bool holder_is_receiver) {
271 int config =
272 KindBits::encode(holder_is_receiver ? Kind::kApiSetter
273 : Kind::kApiSetterHolderIsPrototype);
274 return handle(Smi::FromInt(config), isolate);
275 }
276
WasmValueType2String(WasmValueType type)277 inline const char* WasmValueType2String(WasmValueType type) {
278 switch (type) {
279 case WasmValueType::kI8:
280 return "i8";
281 case WasmValueType::kI16:
282 return "i16";
283 case WasmValueType::kI32:
284 return "i32";
285 case WasmValueType::kU32:
286 return "u32";
287 case WasmValueType::kI64:
288 return "i64";
289 case WasmValueType::kF32:
290 return "f32";
291 case WasmValueType::kF64:
292 return "f64";
293 case WasmValueType::kS128:
294 return "s128";
295
296 case WasmValueType::kRef:
297 return "Ref";
298 case WasmValueType::kOptRef:
299 return "OptRef";
300
301 case WasmValueType::kNumTypes:
302 return "???";
303 }
304 }
305
306 } // namespace internal
307 } // namespace v8
308
309 #include "src/objects/object-macros-undef.h"
310
311 #endif // V8_IC_HANDLER_CONFIGURATION_INL_H_
312