1 /**
2 * Copyright (c) 2021-2025 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 #include <string>
17
18 #include "ani.h"
19 #include "ets_runtime_interface.h"
20 #include "plugins/ets/runtime/ets_stubs-inl.h"
21 #include "plugins/ets/runtime/ets_class_linker_extension.h"
22 #include "types/ets_method.h"
23
24 namespace ark::ets {
GetClass(MethodPtr method,IdType id) const25 compiler::RuntimeInterface::ClassPtr EtsRuntimeInterface::GetClass(MethodPtr method, IdType id) const
26 {
27 if (id == RuntimeInterface::MEM_PROMISE_CLASS_ID) {
28 return PlatformTypes(PandaEtsVM::GetCurrent())->corePromise->GetRuntimeClass();
29 }
30 return PandaRuntimeInterface::GetClass(method, id);
31 }
32
ResolveLookUpField(FieldPtr rawField,ClassPtr klass)33 compiler::RuntimeInterface::FieldPtr EtsRuntimeInterface::ResolveLookUpField(FieldPtr rawField, ClassPtr klass)
34 {
35 ASSERT(rawField != nullptr);
36 ASSERT(klass != nullptr);
37 Class *current = ClassCast(klass);
38 Field *raw = FieldCast(rawField);
39 while (current != nullptr) {
40 Field *field = LookupFieldByName(raw->GetName(), current);
41 if (LIKELY(field != nullptr)) {
42 return field;
43 }
44 current = current->GetBase();
45 }
46 return nullptr;
47 }
48
49 template <panda_file::Type::TypeId FIELD_TYPE>
GetLookUpCall(FieldPtr rawField,ClassPtr klass,bool isSetter)50 compiler::RuntimeInterface::MethodPtr EtsRuntimeInterface::GetLookUpCall(FieldPtr rawField, ClassPtr klass,
51 bool isSetter)
52 {
53 Field *raw = FieldCast(rawField);
54 Method *method = nullptr;
55 Class *current = ClassCast(klass);
56 while (current != nullptr) {
57 if (isSetter) {
58 method = LookupSetterByName<FIELD_TYPE>(raw->GetName(), current);
59 } else {
60 method = LookupGetterByName<FIELD_TYPE>(raw->GetName(), current);
61 }
62 if (LIKELY(method != nullptr)) {
63 return method;
64 }
65 current = current->GetBase();
66 }
67 return method;
68 }
69
ResolveLookUpCall(FieldPtr rawField,ClassPtr klass,bool isSetter)70 compiler::RuntimeInterface::MethodPtr EtsRuntimeInterface::ResolveLookUpCall(FieldPtr rawField, ClassPtr klass,
71 bool isSetter)
72 {
73 ASSERT(rawField != nullptr);
74 ASSERT(klass != nullptr);
75 switch (FieldCast(rawField)->GetTypeId()) {
76 case panda_file::Type::TypeId::U1:
77 return GetLookUpCall<panda_file::Type::TypeId::U1>(rawField, klass, isSetter);
78 case panda_file::Type::TypeId::U8:
79 return GetLookUpCall<panda_file::Type::TypeId::U8>(rawField, klass, isSetter);
80 case panda_file::Type::TypeId::I8:
81 return GetLookUpCall<panda_file::Type::TypeId::I8>(rawField, klass, isSetter);
82 case panda_file::Type::TypeId::I16:
83 return GetLookUpCall<panda_file::Type::TypeId::I16>(rawField, klass, isSetter);
84 case panda_file::Type::TypeId::U16:
85 return GetLookUpCall<panda_file::Type::TypeId::U16>(rawField, klass, isSetter);
86 case panda_file::Type::TypeId::I32:
87 return GetLookUpCall<panda_file::Type::TypeId::I32>(rawField, klass, isSetter);
88 case panda_file::Type::TypeId::U32:
89 return GetLookUpCall<panda_file::Type::TypeId::U32>(rawField, klass, isSetter);
90 case panda_file::Type::TypeId::I64:
91 return GetLookUpCall<panda_file::Type::TypeId::I64>(rawField, klass, isSetter);
92 case panda_file::Type::TypeId::U64:
93 return GetLookUpCall<panda_file::Type::TypeId::U64>(rawField, klass, isSetter);
94 case panda_file::Type::TypeId::F32:
95 return GetLookUpCall<panda_file::Type::TypeId::F32>(rawField, klass, isSetter);
96 case panda_file::Type::TypeId::F64:
97 return GetLookUpCall<panda_file::Type::TypeId::F64>(rawField, klass, isSetter);
98 case panda_file::Type::TypeId::REFERENCE:
99 return GetLookUpCall<panda_file::Type::TypeId::REFERENCE>(rawField, klass, isSetter);
100 default: {
101 UNREACHABLE();
102 break;
103 }
104 }
105 return nullptr;
106 }
107
GetUniqueObject() const108 uint64_t EtsRuntimeInterface::GetUniqueObject() const
109 {
110 return ToUintPtr(PandaEtsVM::GetCurrent()->GetNullValue());
111 }
112
GetInteropCallKind(MethodPtr methodPtr) const113 compiler::RuntimeInterface::InteropCallKind EtsRuntimeInterface::GetInteropCallKind(MethodPtr methodPtr) const
114 {
115 auto className = GetClassNameFromMethod(methodPtr);
116 auto classNameSuffix = className.substr(className.find_last_of('.') + 1);
117 if (classNameSuffix == "$jsnew") {
118 return InteropCallKind::NEW_INSTANCE;
119 }
120 if (classNameSuffix != "$jscall") {
121 return InteropCallKind::UNKNOWN;
122 }
123
124 auto method = MethodCast(methodPtr);
125
126 ASSERT(method->GetArgType(0).IsReference()); // arg0 is always a reference
127 if (method->GetArgType(1).IsReference()) {
128 auto pf = method->GetPandaFile();
129 panda_file::ProtoDataAccessor pda(*pf, panda_file::MethodDataAccessor::GetProtoId(*pf, method->GetFileId()));
130 ClassLinker *classLinker = Runtime::GetCurrent()->GetClassLinker();
131 auto linkerCtx = method->GetClass()->GetLoadContext();
132 uint32_t const argReftypeShift = method->GetReturnType().IsReference() ? 1 : 0;
133 ScopedMutatorLock lock;
134 auto cls = classLinker->GetClass(*pf, pda.GetReferenceType(1 + argReftypeShift), linkerCtx);
135 ASSERT(cls != nullptr);
136 if (!cls->IsStringClass()) {
137 return InteropCallKind::CALL_BY_VALUE;
138 }
139 } else {
140 // arg1 and arg2 are start position and length of qualified name
141 ASSERT(method->GetArgType(1).GetId() == panda_file::Type::TypeId::I32);
142 ASSERT(method->GetArgType(2U).GetId() == panda_file::Type::TypeId::I32);
143 }
144 return InteropCallKind::CALL;
145 }
146
GetFuncPropName(MethodPtr methodPtr,uint32_t strId) const147 char *EtsRuntimeInterface::GetFuncPropName(MethodPtr methodPtr, uint32_t strId) const
148 {
149 auto method = MethodCast(methodPtr);
150 auto pf = method->GetPandaFile();
151 auto str = reinterpret_cast<const char *>(pf->GetStringData(ark::panda_file::File::EntityId(strId)).data);
152 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
153 return const_cast<char *>(std::strrchr(str, '.') + 1);
154 }
155
GetFuncPropNameOffset(MethodPtr methodPtr,uint32_t strId) const156 uint64_t EtsRuntimeInterface::GetFuncPropNameOffset(MethodPtr methodPtr, uint32_t strId) const
157 {
158 auto pf = MethodCast(methodPtr)->GetPandaFile();
159 auto str = GetFuncPropName(methodPtr, strId);
160 return reinterpret_cast<uint64_t>(str) - reinterpret_cast<uint64_t>(pf->GetBase());
161 }
162
IsMethodStringConcat(MethodPtr method) const163 bool EtsRuntimeInterface::IsMethodStringConcat(MethodPtr method) const
164 {
165 return GetMethodFullName(method, false) == "std.core.String::concat" &&
166 MethodCast(method)->GetProto().GetSignature() == "([Lstd/core/String;)Lstd/core/String;";
167 }
168
IsMethodStringBuilderConstructorWithStringArg(MethodPtr method) const169 bool EtsRuntimeInterface::IsMethodStringBuilderConstructorWithStringArg(MethodPtr method) const
170 {
171 return MethodCast(method)->IsConstructor() && GetClassNameFromMethod(method) == "std.core.StringBuilder" &&
172 MethodCast(method)->GetProto().GetSignature() == "(Lstd/core/String;)V";
173 }
174
IsMethodStringBuilderConstructorWithCharArrayArg(MethodPtr method) const175 bool EtsRuntimeInterface::IsMethodStringBuilderConstructorWithCharArrayArg(MethodPtr method) const
176 {
177 return MethodCast(method)->IsConstructor() && GetClassNameFromMethod(method) == "std.core.StringBuilder" &&
178 MethodCast(method)->GetProto().GetSignature() == "([C)V";
179 }
180
IsMethodStringBuilderDefaultConstructor(MethodPtr method) const181 bool EtsRuntimeInterface::IsMethodStringBuilderDefaultConstructor(MethodPtr method) const
182 {
183 return MethodCast(method)->IsConstructor() && GetClassNameFromMethod(method) == "std.core.StringBuilder" &&
184 MethodCast(method)->GetProto().GetSignature() == "()V";
185 }
186
IsMethodStringBuilderToString(MethodPtr method) const187 bool EtsRuntimeInterface::IsMethodStringBuilderToString(MethodPtr method) const
188 {
189 return GetMethodFullName(method, false) == "std.core.StringBuilder::toString" &&
190 MethodCast(method)->GetProto().GetSignature() == "()Lstd/core/String;";
191 }
192
IsMethodStringBuilderAppend(MethodPtr method) const193 bool EtsRuntimeInterface::IsMethodStringBuilderAppend(MethodPtr method) const
194 {
195 return GetMethodFullName(method, false) == "std.core.StringBuilder::append";
196 }
197
IsMethodInModuleScope(MethodPtr method) const198 bool EtsRuntimeInterface::IsMethodInModuleScope(MethodPtr method) const
199 {
200 return static_cast<EtsMethod *>(method)->GetClass()->IsModule();
201 }
202
IsClassStringBuilder(ClassPtr klass) const203 bool EtsRuntimeInterface::IsClassStringBuilder(ClassPtr klass) const
204 {
205 return ClassCast(klass)->GetName() == "std.core.StringBuilder";
206 }
207
IsClassEscompatArray(ClassPtr klass) const208 bool EtsRuntimeInterface::IsClassEscompatArray(ClassPtr klass) const
209 {
210 return ClassCast(klass)->GetName() == "escompat.Array";
211 }
212
GetClassOffsetObjectsArray(MethodPtr method) const213 uint32_t EtsRuntimeInterface::GetClassOffsetObjectsArray(MethodPtr method) const
214 {
215 auto pf = MethodCast(method)->GetPandaFile();
216 return pf->GetClassId(utf::CStringAsMutf8("[Lstd/core/Object;")).GetOffset();
217 }
218
GetClassOffsetObject(MethodPtr method) const219 uint32_t EtsRuntimeInterface::GetClassOffsetObject(MethodPtr method) const
220 {
221 auto pf = MethodCast(method)->GetPandaFile();
222 return pf->GetClassId(utf::CStringAsMutf8("std.core.Object")).GetOffset();
223 }
224
GetStringBuilderClass() const225 EtsRuntimeInterface::ClassPtr EtsRuntimeInterface::GetStringBuilderClass() const
226 {
227 return PlatformTypes(PandaEtsVM::GetCurrent())->coreStringBuilder->GetRuntimeClass();
228 }
229
GetEscompatArrayClass() const230 EtsRuntimeInterface::ClassPtr EtsRuntimeInterface::GetEscompatArrayClass() const
231 {
232 return PlatformTypes(PandaEtsVM::GetCurrent())->escompatArray->GetRuntimeClass();
233 }
234
GetStringBuilderDefaultConstructor() const235 EtsRuntimeInterface::MethodPtr EtsRuntimeInterface::GetStringBuilderDefaultConstructor() const
236 {
237 for (auto ctor : PlatformTypes()->coreStringBuilder->GetConstructors()) {
238 if (IsMethodStringBuilderDefaultConstructor(ctor)) {
239 return ctor;
240 }
241 }
242
243 UNREACHABLE();
244 }
245
GetMethodId(MethodPtr method) const246 uint32_t EtsRuntimeInterface::GetMethodId(MethodPtr method) const
247 {
248 ASSERT(method != nullptr);
249 return static_cast<EtsMethod *>(method)->GetMethodId();
250 }
251
IsFieldBooleanFalse(FieldPtr field) const252 bool EtsRuntimeInterface::IsFieldBooleanFalse([[maybe_unused]] FieldPtr field) const
253 {
254 return IsClassBoxedBoolean((FieldCast(field)->GetClass())) && GetFieldName(field) == "FALSE";
255 }
256
IsFieldBooleanTrue(FieldPtr field) const257 bool EtsRuntimeInterface::IsFieldBooleanTrue([[maybe_unused]] FieldPtr field) const
258 {
259 return IsClassBoxedBoolean((FieldCast(field)->GetClass())) && GetFieldName(field) == "TRUE";
260 }
261
IsFieldBooleanValue(FieldPtr field) const262 bool EtsRuntimeInterface::IsFieldBooleanValue([[maybe_unused]] FieldPtr field) const
263 {
264 return IsClassBoxedBoolean((FieldCast(field)->GetClass())) && GetFieldName(field) == "value";
265 }
266
GetFieldStringBuilderBuffer(ClassPtr klass) const267 EtsRuntimeInterface::FieldPtr EtsRuntimeInterface::GetFieldStringBuilderBuffer(ClassPtr klass) const
268 {
269 ASSERT(IsClassStringBuilder(klass));
270 return ClassCast(klass)->GetInstanceFieldByName(utf::CStringAsMutf8("buf"));
271 }
272
GetFieldStringBuilderIndex(ClassPtr klass) const273 EtsRuntimeInterface::FieldPtr EtsRuntimeInterface::GetFieldStringBuilderIndex(ClassPtr klass) const
274 {
275 ASSERT(IsClassStringBuilder(klass));
276 return ClassCast(klass)->GetInstanceFieldByName(utf::CStringAsMutf8("index"));
277 }
278
GetFieldStringBuilderLength(ClassPtr klass) const279 EtsRuntimeInterface::FieldPtr EtsRuntimeInterface::GetFieldStringBuilderLength(ClassPtr klass) const
280 {
281 ASSERT(IsClassStringBuilder(klass));
282 return ClassCast(klass)->GetInstanceFieldByName(utf::CStringAsMutf8("length"));
283 }
284
GetFieldStringBuilderCompress(ClassPtr klass) const285 EtsRuntimeInterface::FieldPtr EtsRuntimeInterface::GetFieldStringBuilderCompress(ClassPtr klass) const
286 {
287 ASSERT(IsClassStringBuilder(klass));
288 return ClassCast(klass)->GetInstanceFieldByName(utf::CStringAsMutf8("compress"));
289 }
290
GetEscompatArrayActualLength(ClassPtr klass) const291 EtsRuntimeInterface::FieldPtr EtsRuntimeInterface::GetEscompatArrayActualLength(ClassPtr klass) const
292 {
293 ASSERT(IsClassEscompatArray(klass));
294 return ClassCast(klass)->GetInstanceFieldByName(utf::CStringAsMutf8("actualLength"));
295 }
296
GetEscompatArrayBuffer(ClassPtr klass) const297 EtsRuntimeInterface::FieldPtr EtsRuntimeInterface::GetEscompatArrayBuffer(ClassPtr klass) const
298 {
299 ASSERT(IsClassEscompatArray(klass));
300 return ClassCast(klass)->GetInstanceFieldByName(utf::CStringAsMutf8("buffer"));
301 }
302
IsFieldStringBuilderBuffer(FieldPtr field) const303 bool EtsRuntimeInterface::IsFieldStringBuilderBuffer(FieldPtr field) const
304 {
305 return IsClassStringBuilder(FieldCast(field)->GetClass()) && GetFieldName(field) == "buf";
306 }
307
IsFieldStringBuilderIndex(FieldPtr field) const308 bool EtsRuntimeInterface::IsFieldStringBuilderIndex(FieldPtr field) const
309 {
310 return IsClassStringBuilder(FieldCast(field)->GetClass()) && GetFieldName(field) == "index";
311 }
312
IsFieldArrayActualLength(FieldPtr field) const313 bool EtsRuntimeInterface::IsFieldArrayActualLength(FieldPtr field) const
314 {
315 return IsClassEscompatArray(FieldCast(field)->GetClass()) && GetFieldName(field) == "actualLength";
316 }
317
IsFieldArrayBuffer(FieldPtr field) const318 bool EtsRuntimeInterface::IsFieldArrayBuffer(FieldPtr field) const
319 {
320 return IsClassEscompatArray(FieldCast(field)->GetClass()) && GetFieldName(field) == "buffer";
321 }
322
IsFieldArray(ArrayField kind,FieldPtr field) const323 bool EtsRuntimeInterface::IsFieldArray(ArrayField kind, FieldPtr field) const
324 {
325 if (!HasFieldMetadata(field)) {
326 return false;
327 }
328 switch (kind) {
329 case ArrayField::ACTUAL_LENGTH:
330 return IsFieldArrayActualLength(field);
331 case ArrayField::BUFFER:
332 return IsFieldArrayBuffer(field);
333 default:
334 return false;
335 }
336 }
337
IsIntrinsicStringBuilderToString(IntrinsicId id) const338 bool EtsRuntimeInterface::IsIntrinsicStringBuilderToString(IntrinsicId id) const
339 {
340 return id == RuntimeInterface::IntrinsicId::INTRINSIC_STD_CORE_SB_TO_STRING;
341 }
342
IsIntrinsicStringBuilderAppendString(IntrinsicId id) const343 bool EtsRuntimeInterface::IsIntrinsicStringBuilderAppendString(IntrinsicId id) const
344 {
345 switch (id) {
346 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING:
347 return true;
348 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING2:
349 return true;
350 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING3:
351 return true;
352 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING4:
353 return true;
354 default:
355 return false;
356 }
357 }
358
IsIntrinsicStringBuilderAppend(IntrinsicId id) const359 bool EtsRuntimeInterface::IsIntrinsicStringBuilderAppend(IntrinsicId id) const
360 {
361 switch (id) {
362 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_FLOAT:
363 return true;
364 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_DOUBLE:
365 return true;
366 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_LONG:
367 return true;
368 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_INT:
369 return true;
370 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_BYTE:
371 return true;
372 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_SHORT:
373 return true;
374 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_CHAR:
375 return true;
376 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_BOOL:
377 return true;
378 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING:
379 return true;
380 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING2:
381 return true;
382 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING3:
383 return true;
384 case IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING4:
385 return true;
386 default:
387 return false;
388 }
389 }
390
IsIntrinsicStringConcat(IntrinsicId id) const391 bool EtsRuntimeInterface::IsIntrinsicStringConcat(IntrinsicId id) const
392 {
393 switch (id) {
394 case IntrinsicId::INTRINSIC_STD_CORE_STRING_CONCAT2:
395 return true;
396 case IntrinsicId::INTRINSIC_STD_CORE_STRING_CONCAT3:
397 return true;
398 case IntrinsicId::INTRINSIC_STD_CORE_STRING_CONCAT4:
399 return true;
400 default:
401 return false;
402 }
403 }
404
ConvertTypeToStringBuilderAppendIntrinsicId(compiler::DataType::Type type) const405 EtsRuntimeInterface::IntrinsicId EtsRuntimeInterface::ConvertTypeToStringBuilderAppendIntrinsicId(
406 compiler::DataType::Type type) const
407 {
408 switch (type) {
409 case compiler::DataType::BOOL:
410 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_BOOL;
411 case compiler::DataType::INT8:
412 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_CHAR;
413 case compiler::DataType::UINT8:
414 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_BYTE;
415 case compiler::DataType::INT16:
416 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_SHORT;
417 case compiler::DataType::INT32:
418 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_INT;
419 case compiler::DataType::INT64:
420 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_LONG;
421 case compiler::DataType::FLOAT64:
422 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_DOUBLE;
423 case compiler::DataType::FLOAT32:
424 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_FLOAT;
425 case compiler::DataType::REFERENCE:
426 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING;
427 default:
428 UNREACHABLE();
429 }
430 return IntrinsicId::INVALID;
431 }
432
GetStringConcatStringsIntrinsicId(size_t numArgs) const433 EtsRuntimeInterface::IntrinsicId EtsRuntimeInterface::GetStringConcatStringsIntrinsicId(size_t numArgs) const
434 {
435 // NOLINTBEGIN(readability-magic-numbers)
436 switch (numArgs) {
437 case 2U:
438 return IntrinsicId::INTRINSIC_STD_CORE_STRING_CONCAT2;
439 case 3U:
440 return IntrinsicId::INTRINSIC_STD_CORE_STRING_CONCAT3;
441 case 4U:
442 return IntrinsicId::INTRINSIC_STD_CORE_STRING_CONCAT4;
443 default:
444 UNREACHABLE();
445 }
446 // NOLINTEND(readability-magic-numbers)
447 }
448
GetStringIsCompressedIntrinsicId() const449 EtsRuntimeInterface::IntrinsicId EtsRuntimeInterface::GetStringIsCompressedIntrinsicId() const
450 {
451 return IntrinsicId::INTRINSIC_STD_CORE_STRING_IS_COMPRESSED;
452 }
453
GetStringBuilderAppendStringsIntrinsicId(size_t numArgs) const454 EtsRuntimeInterface::IntrinsicId EtsRuntimeInterface::GetStringBuilderAppendStringsIntrinsicId(size_t numArgs) const
455 {
456 // NOLINTBEGIN(readability-magic-numbers)
457 switch (numArgs) {
458 case 1U:
459 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING;
460 case 2U:
461 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING2;
462 case 3U:
463 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING3;
464 case 4U:
465 return IntrinsicId::INTRINSIC_STD_CORE_SB_APPEND_STRING4;
466 default:
467 UNREACHABLE();
468 }
469 // NOLINTEND(readability-magic-numbers)
470 }
471
GetStringBuilderToStringIntrinsicId() const472 EtsRuntimeInterface::IntrinsicId EtsRuntimeInterface::GetStringBuilderToStringIntrinsicId() const
473 {
474 return IntrinsicId::INTRINSIC_STD_CORE_SB_TO_STRING;
475 }
476
IsClassValueTyped(ClassPtr klass) const477 bool EtsRuntimeInterface::IsClassValueTyped(ClassPtr klass) const
478 {
479 return EtsClass::FromRuntimeClass(ClassCast(klass))->IsValueTyped();
480 }
481
GetDoubleToStringCache() const482 void *EtsRuntimeInterface::GetDoubleToStringCache() const
483 {
484 return ark::ets::PandaEtsVM::GetCurrent()->GetDoubleToStringCache();
485 }
486
IsStringCachesUsed() const487 bool EtsRuntimeInterface::IsStringCachesUsed() const
488 {
489 return Runtime::GetCurrent()->GetOptions().IsUseStringCaches();
490 }
491
IsNativeMethodOptimizationEnabled() const492 bool EtsRuntimeInterface::IsNativeMethodOptimizationEnabled() const
493 {
494 return true;
495 }
496
GetDeprecatedNativeApiMask() const497 uint64_t EtsRuntimeInterface::GetDeprecatedNativeApiMask() const
498 {
499 return ACC_DEPRECATED_NATIVE_API;
500 }
501
GetRuntimeClassOffset(Arch arch) const502 uint32_t EtsRuntimeInterface::GetRuntimeClassOffset(Arch arch) const
503 {
504 return ark::cross_values::GetEtsClassRuntimeClassOffset(arch);
505 }
506
IsBoxedClass(ClassPtr klass) const507 bool EtsRuntimeInterface::IsBoxedClass(ClassPtr klass) const
508 {
509 return EtsClass::FromRuntimeClass(ClassCast(klass))->IsBoxed();
510 }
511
IsClassBoxedBoolean(ClassPtr klass) const512 bool EtsRuntimeInterface::IsClassBoxedBoolean(ClassPtr klass) const
513 {
514 return PlatformTypes(PandaEtsVM::GetCurrent())->coreBoolean->GetRuntimeClass() == klass;
515 }
516
GetTlsNativeApiOffset(Arch arch) const517 size_t EtsRuntimeInterface::GetTlsNativeApiOffset(Arch arch) const
518 {
519 return ark::cross_values::GetEtsCoroutineAniEnvOffset(arch);
520 }
521
522 } // namespace ark::ets
523