1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef ECMASCRIPT_IC_IC_RUNTIME_STUB_INL_H_
17 #define ECMASCRIPT_IC_IC_RUNTIME_STUB_INL_H_
18
19 #include "ecmascript/base/config.h"
20 #include "ic_runtime_stub.h"
21 #include "ic_handler.h"
22 #include "ic_runtime.h"
23 #include "ecmascript/js_tagged_value-inl.h"
24 #include "ecmascript/js_array.h"
25 #include "ecmascript/js_hclass-inl.h"
26 #include "ecmascript/global_dictionary-inl.h"
27 #include "ecmascript/js_function.h"
28 #include "ecmascript/js_proxy.h"
29 #include "ecmascript/global_env.h"
30 #include "ecmascript/object_factory-inl.h"
31 #include "ecmascript/js_handle.h"
32 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
33 #include "ecmascript/ic/proto_change_details.h"
34
35 #include "ecmascript/runtime_call_id.h"
36
37 namespace panda::ecmascript {
LoadGlobalICByName(JSThread * thread,ProfileTypeInfo * profileTypeInfo,JSTaggedValue globalValue,JSTaggedValue key,uint32_t slotId)38 JSTaggedValue ICRuntimeStub::LoadGlobalICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo,
39 JSTaggedValue globalValue, JSTaggedValue key, uint32_t slotId)
40 {
41 INTERPRETER_TRACE(thread, LoadGlobalICByName);
42 JSTaggedValue handler = profileTypeInfo->Get(slotId);
43 if (handler.IsHeapObject()) {
44 auto result = LoadGlobal(handler);
45 if (!result.IsHole()) {
46 return result;
47 }
48 }
49 return LoadMiss(thread, profileTypeInfo, globalValue, key, slotId, ICKind::NamedGlobalLoadIC);
50 }
51
StoreGlobalICByName(JSThread * thread,ProfileTypeInfo * profileTypeInfo,JSTaggedValue globalValue,JSTaggedValue key,JSTaggedValue value,uint32_t slotId)52 JSTaggedValue ICRuntimeStub::StoreGlobalICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo,
53 JSTaggedValue globalValue, JSTaggedValue key,
54 JSTaggedValue value, uint32_t slotId)
55 {
56 INTERPRETER_TRACE(thread, StoreGlobalICByName);
57 JSTaggedValue handler = profileTypeInfo->Get(slotId);
58 if (handler.IsHeapObject()) {
59 auto result = StoreGlobal(thread, value, handler);
60 if (!result.IsHole()) {
61 return result;
62 }
63 }
64 return StoreMiss(thread, profileTypeInfo, globalValue, key, value, slotId, ICKind::NamedGlobalStoreIC);
65 }
66
CheckPolyHClass(JSTaggedValue cachedValue,JSHClass * hclass)67 JSTaggedValue ICRuntimeStub::CheckPolyHClass(JSTaggedValue cachedValue, JSHClass* hclass)
68 {
69 if (!cachedValue.IsWeak()) {
70 ASSERT(cachedValue.IsTaggedArray());
71 TaggedArray *array = TaggedArray::Cast(cachedValue.GetHeapObject());
72 uint32_t length = array->GetLength();
73 for (uint32_t i = 0; i < length; i += 2) { // 2 means one ic, two slot
74 auto result = array->Get(i);
75 if (result != JSTaggedValue::Undefined() && result.GetWeakReferent() == hclass) {
76 return array->Get(i + 1);
77 }
78 }
79 }
80 return JSTaggedValue::Hole();
81 }
82
TryLoadICByName(JSThread * thread,JSTaggedValue receiver,JSTaggedValue firstValue,JSTaggedValue secondValue)83 ARK_INLINE JSTaggedValue ICRuntimeStub::TryLoadICByName(JSThread *thread, JSTaggedValue receiver,
84 JSTaggedValue firstValue, JSTaggedValue secondValue)
85 {
86 INTERPRETER_TRACE(thread, TryLoadICByName);
87 if (LIKELY(receiver.IsHeapObject())) {
88 auto hclass = receiver.GetTaggedObject()->GetClass();
89 if (LIKELY(firstValue.GetWeakReferentUnChecked() == hclass)) {
90 return LoadICWithHandler(thread, receiver, receiver, secondValue);
91 }
92 JSTaggedValue cachedHandler = CheckPolyHClass(firstValue, hclass);
93 if (!cachedHandler.IsHole()) {
94 return LoadICWithHandler(thread, receiver, receiver, cachedHandler);
95 }
96 }
97 return JSTaggedValue::Hole();
98 }
99
LoadICByName(JSThread * thread,ProfileTypeInfo * profileTypeInfo,JSTaggedValue receiver,JSTaggedValue key,uint32_t slotId)100 ARK_NOINLINE JSTaggedValue ICRuntimeStub::LoadICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo,
101 JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId)
102 {
103 INTERPRETER_TRACE(thread, LoadICByName);
104 return LoadMiss(thread, profileTypeInfo, receiver, key, slotId, ICKind::NamedLoadIC);
105 }
106
TryLoadICByValue(JSThread * thread,JSTaggedValue receiver,JSTaggedValue key,JSTaggedValue firstValue,JSTaggedValue secondValue)107 ARK_INLINE JSTaggedValue ICRuntimeStub::TryLoadICByValue(JSThread *thread, JSTaggedValue receiver, JSTaggedValue key,
108 JSTaggedValue firstValue, JSTaggedValue secondValue)
109 {
110 INTERPRETER_TRACE(thread, TryLoadICByValue);
111 if (receiver.IsHeapObject()) {
112 auto hclass = receiver.GetTaggedObject()->GetClass();
113 if (firstValue.GetWeakReferentUnChecked() == hclass) {
114 ASSERT(HandlerBase::IsElement(secondValue.GetInt()));
115 return LoadElement(JSObject::Cast(receiver.GetHeapObject()), key);
116 }
117 // Check key
118 if (firstValue == key) {
119 JSTaggedValue cachedHandler = CheckPolyHClass(secondValue, hclass);
120 if (!cachedHandler.IsHole()) {
121 return LoadICWithHandler(thread, receiver, receiver, cachedHandler);
122 }
123 }
124 }
125 return JSTaggedValue::Hole();
126 }
127
LoadICByValue(JSThread * thread,ProfileTypeInfo * profileTypeInfo,JSTaggedValue receiver,JSTaggedValue key,uint32_t slotId)128 ARK_NOINLINE JSTaggedValue ICRuntimeStub::LoadICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo,
129 JSTaggedValue receiver, JSTaggedValue key, uint32_t slotId)
130 {
131 INTERPRETER_TRACE(thread, LoadICByValue);
132 return LoadMiss(thread, profileTypeInfo, receiver, key, slotId, ICKind::LoadIC);
133 }
134
TryStoreICByValue(JSThread * thread,JSTaggedValue receiver,JSTaggedValue key,JSTaggedValue firstValue,JSTaggedValue secondValue,JSTaggedValue value)135 ARK_INLINE JSTaggedValue ICRuntimeStub::TryStoreICByValue(JSThread *thread, JSTaggedValue receiver,
136 JSTaggedValue key, JSTaggedValue firstValue,
137 JSTaggedValue secondValue, JSTaggedValue value)
138 {
139 INTERPRETER_TRACE(thread, TryStoreICByValue);
140 if (receiver.IsHeapObject()) {
141 auto hclass = receiver.GetTaggedObject()->GetClass();
142 if (firstValue.GetWeakReferentUnChecked() == hclass) {
143 return StoreElement(thread, JSObject::Cast(receiver.GetHeapObject()), key, value, secondValue);
144 }
145 // Check key
146 if (firstValue == key) {
147 JSTaggedValue cachedHandler = CheckPolyHClass(secondValue, hclass);
148 if (!cachedHandler.IsHole()) {
149 return StoreICWithHandler(thread, receiver, receiver, value, cachedHandler);
150 }
151 }
152 }
153
154 return JSTaggedValue::Hole();
155 }
156
StoreICByValue(JSThread * thread,ProfileTypeInfo * profileTypeInfo,JSTaggedValue receiver,JSTaggedValue key,JSTaggedValue value,uint32_t slotId)157 ARK_NOINLINE JSTaggedValue ICRuntimeStub::StoreICByValue(JSThread *thread, ProfileTypeInfo *profileTypeInfo,
158 JSTaggedValue receiver, JSTaggedValue key,
159 JSTaggedValue value, uint32_t slotId)
160 {
161 INTERPRETER_TRACE(thread, StoreICByValue);
162 return StoreMiss(thread, profileTypeInfo, receiver, key, value, slotId, ICKind::StoreIC);
163 }
164
TryStoreICByName(JSThread * thread,JSTaggedValue receiver,JSTaggedValue firstValue,JSTaggedValue secondValue,JSTaggedValue value)165 ARK_INLINE JSTaggedValue ICRuntimeStub::TryStoreICByName(JSThread *thread, JSTaggedValue receiver,
166 JSTaggedValue firstValue, JSTaggedValue secondValue,
167 JSTaggedValue value)
168 {
169 INTERPRETER_TRACE(thread, TryStoreICByName);
170 if (receiver.IsHeapObject()) {
171 auto hclass = receiver.GetTaggedObject()->GetClass();
172 if (firstValue.GetWeakReferentUnChecked() == hclass) {
173 return StoreICWithHandler(thread, receiver, receiver, value, secondValue);
174 }
175 JSTaggedValue cachedHandler = CheckPolyHClass(firstValue, hclass);
176 if (!cachedHandler.IsHole()) {
177 return StoreICWithHandler(thread, receiver, receiver, value, cachedHandler);
178 }
179 }
180 return JSTaggedValue::Hole();
181 }
182
StoreICByName(JSThread * thread,ProfileTypeInfo * profileTypeInfo,JSTaggedValue receiver,JSTaggedValue key,JSTaggedValue value,uint32_t slotId)183 ARK_NOINLINE JSTaggedValue ICRuntimeStub::StoreICByName(JSThread *thread, ProfileTypeInfo *profileTypeInfo,
184 JSTaggedValue receiver, JSTaggedValue key,
185 JSTaggedValue value, uint32_t slotId)
186 {
187 INTERPRETER_TRACE(thread, StoreICByName);
188 return StoreMiss(thread, profileTypeInfo, receiver, key, value, slotId, ICKind::NamedStoreIC);
189 }
190
StoreICWithHandler(JSThread * thread,JSTaggedValue receiver,JSTaggedValue holder,JSTaggedValue value,JSTaggedValue handler)191 ARK_INLINE JSTaggedValue ICRuntimeStub::StoreICWithHandler(JSThread *thread, JSTaggedValue receiver,
192 JSTaggedValue holder,
193 JSTaggedValue value, JSTaggedValue handler)
194 {
195 INTERPRETER_TRACE(thread, StoreICWithHandler);
196 if (handler.IsInt()) {
197 auto handlerInfo = static_cast<uint32_t>(handler.GetInt());
198 if (HandlerBase::IsField(handlerInfo)) {
199 StoreField(thread, JSObject::Cast(receiver.GetHeapObject()), value, handlerInfo);
200 return JSTaggedValue::Undefined();
201 }
202 ASSERT(HandlerBase::IsAccessor(handlerInfo) || HandlerBase::IsInternalAccessor(handlerInfo));
203 auto accessor = LoadFromField(JSObject::Cast(holder.GetHeapObject()), handlerInfo);
204 return FastRuntimeStub::CallSetter(thread, JSTaggedValue(receiver), value, accessor);
205 }
206 if (handler.IsTransitionHandler()) {
207 StoreWithTransition(thread, JSObject::Cast(receiver.GetHeapObject()), value, handler);
208 return JSTaggedValue::Undefined();
209 }
210 if (handler.IsPrototypeHandler()) {
211 return StorePrototype(thread, receiver, value, handler);
212 }
213 if (handler.IsPropertyBox()) {
214 return StoreGlobal(thread, value, handler);
215 }
216 return JSTaggedValue::Undefined();
217 }
218
StorePrototype(JSThread * thread,JSTaggedValue receiver,JSTaggedValue value,JSTaggedValue handler)219 JSTaggedValue ICRuntimeStub::StorePrototype(JSThread *thread, JSTaggedValue receiver,
220 JSTaggedValue value, JSTaggedValue handler)
221 {
222 INTERPRETER_TRACE(thread, StorePrototype);
223 ASSERT(handler.IsPrototypeHandler());
224 PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject());
225 auto cellValue = prototypeHandler->GetProtoCell();
226 ASSERT(cellValue.IsProtoChangeMarker());
227 ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetHeapObject());
228 if (cell->GetHasChanged()) {
229 return JSTaggedValue::Hole();
230 }
231 auto holder = prototypeHandler->GetHolder();
232 JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo();
233 return StoreICWithHandler(thread, receiver, holder, value, handlerInfo);
234 }
235
StoreWithTransition(JSThread * thread,JSObject * receiver,JSTaggedValue value,JSTaggedValue handler)236 void ICRuntimeStub::StoreWithTransition(JSThread *thread, JSObject *receiver, JSTaggedValue value,
237 JSTaggedValue handler)
238 {
239 INTERPRETER_TRACE(thread, StoreWithTransition);
240 TransitionHandler *transitionHandler = TransitionHandler::Cast(handler.GetTaggedObject());
241 JSHClass *newHClass = JSHClass::Cast(transitionHandler->GetTransitionHClass().GetTaggedObject());
242 receiver->SetClass(newHClass);
243 uint32_t handlerInfo = transitionHandler->GetHandlerInfo().GetInt();
244 ASSERT(HandlerBase::IsField(handlerInfo));
245
246 if (!HandlerBase::IsInlinedProps(handlerInfo)) {
247 TaggedArray *array = TaggedArray::Cast(receiver->GetProperties().GetHeapObject());
248 int capacity = array->GetLength();
249 int index = HandlerBase::GetOffset(handlerInfo);
250 if (index >= capacity) {
251 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
252 JSHandle<TaggedArray> properties;
253 JSHandle<JSObject> objHandle(thread, receiver);
254 JSHandle<JSTaggedValue> valueHandle(thread, value);
255 if (capacity == 0) {
256 capacity = JSObject::MIN_PROPERTIES_LENGTH;
257 properties = factory->NewTaggedArray(capacity);
258 } else {
259 auto arrayHandle = JSHandle<TaggedArray>(thread, array);
260 properties = factory->CopyArray(arrayHandle, capacity,
261 JSObject::ComputePropertyCapacity(capacity));
262 }
263 properties->Set(thread, index, valueHandle);
264 objHandle->SetProperties(thread, properties);
265 return;
266 }
267 array->Set(thread, index, value);
268 return;
269 }
270 StoreField(thread, receiver, value, handlerInfo);
271 }
272
StoreField(JSThread * thread,JSObject * receiver,JSTaggedValue value,uint32_t handler)273 ARK_INLINE void ICRuntimeStub::StoreField(JSThread *thread, JSObject *receiver, JSTaggedValue value, uint32_t handler)
274 {
275 INTERPRETER_TRACE(thread, StoreField);
276 int index = HandlerBase::GetOffset(handler);
277 if (HandlerBase::IsInlinedProps(handler)) {
278 SET_VALUE_WITH_BARRIER(thread, receiver, index * JSTaggedValue::TaggedTypeSize(), value);
279 return;
280 }
281 TaggedArray *array = TaggedArray::Cast(receiver->GetProperties().GetHeapObject());
282 ASSERT(index < static_cast<int>(array->GetLength()));
283 array->Set(thread, index, value);
284 }
285
LoadFromField(JSObject * receiver,uint32_t handlerInfo)286 ARK_INLINE JSTaggedValue ICRuntimeStub::LoadFromField(JSObject *receiver, uint32_t handlerInfo)
287 {
288 int index = HandlerBase::GetOffset(handlerInfo);
289 if (HandlerBase::IsInlinedProps(handlerInfo)) {
290 return JSTaggedValue(GET_VALUE(receiver, index * JSTaggedValue::TaggedTypeSize()));
291 }
292 return TaggedArray::Cast(receiver->GetProperties().GetHeapObject())->Get(index);
293 }
294
LoadGlobal(JSTaggedValue handler)295 ARK_INLINE JSTaggedValue ICRuntimeStub::LoadGlobal(JSTaggedValue handler)
296 {
297 ASSERT(handler.IsPropertyBox());
298 PropertyBox *cell = PropertyBox::Cast(handler.GetHeapObject());
299 if (cell->IsInvalid()) {
300 return JSTaggedValue::Hole();
301 }
302 JSTaggedValue ret = cell->GetValue();
303 ASSERT(!ret.IsAccessorData());
304 return ret;
305 }
306
StoreGlobal(JSThread * thread,JSTaggedValue value,JSTaggedValue handler)307 ARK_INLINE JSTaggedValue ICRuntimeStub::StoreGlobal(JSThread *thread, JSTaggedValue value, JSTaggedValue handler)
308 {
309 INTERPRETER_TRACE(thread, StoreGlobal);
310 ASSERT(handler.IsPropertyBox());
311 PropertyBox *cell = PropertyBox::Cast(handler.GetHeapObject());
312 if (cell->IsInvalid()) {
313 return JSTaggedValue::Hole();
314 }
315 ASSERT(!cell->GetValue().IsAccessorData());
316 cell->SetValue(thread, value);
317 return JSTaggedValue::Undefined();
318 }
319
LoadPrototype(JSThread * thread,JSTaggedValue receiver,JSTaggedValue handler)320 JSTaggedValue ICRuntimeStub::LoadPrototype(JSThread *thread, JSTaggedValue receiver, JSTaggedValue handler)
321 {
322 INTERPRETER_TRACE(thread, LoadPrototype);
323 ASSERT(handler.IsPrototypeHandler());
324 PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject());
325 auto cellValue = prototypeHandler->GetProtoCell();
326 ASSERT(cellValue.IsProtoChangeMarker());
327 ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetHeapObject());
328 if (cell->GetHasChanged()) {
329 return JSTaggedValue::Hole();
330 }
331 auto holder = prototypeHandler->GetHolder();
332 JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo();
333 return LoadICWithHandler(thread, receiver, holder, handlerInfo);
334 }
335
LoadICWithHandler(JSThread * thread,JSTaggedValue receiver,JSTaggedValue holder,JSTaggedValue handler)336 ARK_INLINE JSTaggedValue ICRuntimeStub::LoadICWithHandler(JSThread *thread, JSTaggedValue receiver,
337 JSTaggedValue holder, JSTaggedValue handler)
338 {
339 INTERPRETER_TRACE(thread, LoadICWithHandler);
340 if (LIKELY(handler.IsInt())) {
341 auto handlerInfo = static_cast<uint32_t>(handler.GetInt());
342 if (LIKELY(HandlerBase::IsField(handlerInfo))) {
343 return LoadFromField(JSObject::Cast(holder.GetHeapObject()), handlerInfo);
344 }
345 if (HandlerBase::IsNonExist(handlerInfo)) {
346 return JSTaggedValue::Undefined();
347 }
348 ASSERT(HandlerBase::IsAccessor(handlerInfo) || HandlerBase::IsInternalAccessor(handlerInfo));
349 auto accessor = LoadFromField(JSObject::Cast(holder.GetHeapObject()), handlerInfo);
350 return FastRuntimeStub::CallGetter(thread, receiver, holder, accessor);
351 }
352
353 if (handler.IsPrototypeHandler()) {
354 return LoadPrototype(thread, receiver, handler);
355 }
356
357 return LoadGlobal(handler);
358 }
359
LoadElement(JSObject * receiver,JSTaggedValue key)360 ARK_INLINE JSTaggedValue ICRuntimeStub::LoadElement(JSObject *receiver, JSTaggedValue key)
361 {
362 auto index = TryToElementsIndex(key);
363 if (index < 0) {
364 return JSTaggedValue::Hole();
365 }
366 uint32_t elementIndex = index;
367 TaggedArray *elements = TaggedArray::Cast(receiver->GetElements().GetHeapObject());
368 if (elements->GetLength() <= elementIndex) {
369 return JSTaggedValue::Hole();
370 }
371
372 JSTaggedValue value = elements->Get(elementIndex);
373 // TaggedArray elements
374 return value;
375 }
376
StoreElement(JSThread * thread,JSObject * receiver,JSTaggedValue key,JSTaggedValue value,JSTaggedValue handler)377 JSTaggedValue ICRuntimeStub::StoreElement(JSThread *thread, JSObject *receiver, JSTaggedValue key,
378 JSTaggedValue value, JSTaggedValue handler)
379 {
380 INTERPRETER_TRACE(thread, StoreElement);
381 auto index = TryToElementsIndex(key);
382 if (index < 0) {
383 return JSTaggedValue::Hole();
384 }
385 uint32_t elementIndex = index;
386 if (handler.IsInt()) {
387 auto handlerInfo = static_cast<uint32_t>(handler.GetInt());
388 if (HandlerBase::IsJSArray(handlerInfo)) {
389 JSArray *arr = JSArray::Cast(receiver);
390 uint32_t oldLength = arr->GetArrayLength();
391 if (elementIndex >= oldLength) {
392 arr->SetArrayLength(thread, elementIndex + 1);
393 }
394 }
395 TaggedArray *elements = TaggedArray::Cast(receiver->GetElements().GetHeapObject());
396 uint32_t capacity = elements->GetLength();
397 if (elementIndex >= capacity) {
398 if (JSObject::ShouldTransToDict(capacity, elementIndex)) {
399 return JSTaggedValue::Hole();
400 }
401 [[maybe_unused]] EcmaHandleScope handleScope(thread);
402 JSHandle<JSObject> receiverHandle(thread, receiver);
403 JSHandle<JSTaggedValue> valueHandle(thread, value);
404 elements = *JSObject::GrowElementsCapacity(thread, receiverHandle,
405 JSObject::ComputeElementCapacity(elementIndex + 1));
406 receiverHandle->SetElements(thread, JSTaggedValue(elements));
407 elements->Set(thread, elementIndex, valueHandle);
408 return JSTaggedValue::Undefined();
409 }
410 elements->Set(thread, elementIndex, value);
411 } else {
412 ASSERT(handler.IsPrototypeHandler());
413 PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(handler.GetTaggedObject());
414 auto cellValue = prototypeHandler->GetProtoCell();
415 ASSERT(cellValue.IsProtoChangeMarker());
416 ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetHeapObject());
417 if (cell->GetHasChanged()) {
418 return JSTaggedValue::Hole();
419 }
420 JSTaggedValue handlerInfo = prototypeHandler->GetHandlerInfo();
421 return StoreElement(thread, receiver, key, value, handlerInfo);
422 }
423 return JSTaggedValue::Undefined();
424 }
425
TryToElementsIndex(JSTaggedValue key)426 ARK_INLINE int32_t ICRuntimeStub::TryToElementsIndex(JSTaggedValue key)
427 {
428 if (LIKELY(key.IsInt())) {
429 return key.GetInt();
430 }
431
432 if (key.IsString()) {
433 uint32_t index = 0;
434 if (JSTaggedValue::StringToElementIndex(key, &index)) {
435 return static_cast<int32_t>(index);
436 }
437 }
438
439 if (key.IsDouble()) {
440 double number = key.GetDouble();
441 auto integer = static_cast<int32_t>(number);
442 if (number == integer) {
443 return integer;
444 }
445 }
446
447 return -1;
448 }
449
LoadMiss(JSThread * thread,ProfileTypeInfo * profileTypeInfo,JSTaggedValue receiver,JSTaggedValue key,uint32_t slotId,ICKind kind)450 JSTaggedValue ICRuntimeStub::LoadMiss(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver,
451 JSTaggedValue key, uint32_t slotId, ICKind kind)
452 {
453 [[maybe_unused]] EcmaHandleScope handleScope(thread);
454 auto keyHandle = JSHandle<JSTaggedValue>(thread, key);
455 auto receiverHandle = JSHandle<JSTaggedValue>(thread, receiver);
456 auto profileInfoHandle = JSHandle<JSTaggedValue>(thread, profileTypeInfo);
457 LoadICRuntime icRuntime(thread, JSHandle<ProfileTypeInfo>::Cast(profileInfoHandle), slotId, kind);
458 return icRuntime.LoadMiss(receiverHandle, keyHandle);
459 }
460
StoreMiss(JSThread * thread,ProfileTypeInfo * profileTypeInfo,JSTaggedValue receiver,JSTaggedValue key,JSTaggedValue value,uint32_t slotId,ICKind kind)461 JSTaggedValue ICRuntimeStub::StoreMiss(JSThread *thread, ProfileTypeInfo *profileTypeInfo, JSTaggedValue receiver,
462 JSTaggedValue key, JSTaggedValue value, uint32_t slotId, ICKind kind)
463 {
464 [[maybe_unused]] EcmaHandleScope handleScope(thread);
465 auto keyHandle = JSHandle<JSTaggedValue>(thread, key);
466 auto receiverHandle = JSHandle<JSTaggedValue>(thread, receiver);
467 auto valueHandle = JSHandle<JSTaggedValue>(thread, value);
468 auto profileInfoHandle = JSHandle<JSTaggedValue>(thread, profileTypeInfo);
469 StoreICRuntime icRuntime(thread, JSHandle<ProfileTypeInfo>::Cast(profileInfoHandle), slotId, kind);
470 return icRuntime.StoreMiss(receiverHandle, keyHandle, valueHandle);
471 }
472 } // namespace panda::ecmascript
473
474 #endif // ECMASCRIPT_IC_IC_RUNTIME_STUB_INL_H_
475