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