1 /**
2 * Copyright (c) 2021-2022 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 "ets_coroutine.h"
17 #include "ets_vm.h"
18 #include "intrinsics.h"
19 #include "mem/vm_handle.h"
20 #include "plugins/ets/runtime/types/ets_object.h"
21 #include "plugins/ets/runtime/types/ets_string.h"
22 #include "plugins/ets/runtime/types/ets_box_primitive-inl.h"
23 #include "plugins/ets/runtime/types/ets_void.h"
24 #include "plugins/ets/runtime/ets_panda_file_items.h"
25 #include "types/ets_array.h"
26 #include "types/ets_box_primitive.h"
27 #include "types/ets_class.h"
28 #include "types/ets_method.h"
29 #include "types/ets_primitives.h"
30 #include "types/ets_type.h"
31 #include "types/ets_type_comptime_traits.h"
32 #include "types/ets_typeapi.h"
33 #include "types/ets_typeapi_field.h"
34
35 namespace panda::ets::intrinsics {
36
ValueAPISetFieldObject(EtsObject * obj,EtsLong i,EtsObject * val)37 EtsVoid *ValueAPISetFieldObject(EtsObject *obj, EtsLong i, EtsObject *val)
38 {
39 auto coroutine = EtsCoroutine::GetCurrent();
40 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
41 VMHandle<EtsObject> objHandle(coroutine, obj->GetCoreType());
42 VMHandle<EtsObject> valHandle(coroutine, val->GetCoreType());
43
44 auto typeClass = objHandle.GetPtr()->GetClass();
45 auto fieldObject = typeClass->GetFieldByIndex(i);
46 objHandle.GetPtr()->SetFieldObject(fieldObject, valHandle.GetPtr());
47 return EtsVoid::GetInstance();
48 }
49
50 template <typename T>
SetFieldValue(EtsObject * obj,EtsLong i,T val)51 void SetFieldValue(EtsObject *obj, EtsLong i, T val)
52 {
53 auto coroutine = EtsCoroutine::GetCurrent();
54 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
55 VMHandle<EtsObject> objHandle(coroutine, obj->GetCoreType());
56
57 auto typeClass = objHandle.GetPtr()->GetClass();
58 auto fieldObject = typeClass->GetFieldByIndex(i);
59 if (fieldObject->GetType()->IsBoxedClass()) {
60 objHandle.GetPtr()->SetFieldObject(fieldObject, EtsBoxPrimitive<T>::Create(coroutine, val));
61 return;
62 }
63 objHandle.GetPtr()->SetFieldPrimitive<T>(fieldObject, val);
64 }
65
ValueAPISetFieldBoolean(EtsObject * obj,EtsLong i,EtsBoolean val)66 EtsVoid *ValueAPISetFieldBoolean(EtsObject *obj, EtsLong i, EtsBoolean val)
67 {
68 SetFieldValue(obj, i, val);
69 return EtsVoid::GetInstance();
70 }
71
ValueAPISetFieldByte(EtsObject * obj,EtsLong i,EtsByte val)72 EtsVoid *ValueAPISetFieldByte(EtsObject *obj, EtsLong i, EtsByte val)
73 {
74 SetFieldValue(obj, i, val);
75 return EtsVoid::GetInstance();
76 }
77
ValueAPISetFieldShort(EtsObject * obj,EtsLong i,EtsShort val)78 EtsVoid *ValueAPISetFieldShort(EtsObject *obj, EtsLong i, EtsShort val)
79 {
80 SetFieldValue(obj, i, val);
81 return EtsVoid::GetInstance();
82 }
83
ValueAPISetFieldChar(EtsObject * obj,EtsLong i,EtsChar val)84 EtsVoid *ValueAPISetFieldChar(EtsObject *obj, EtsLong i, EtsChar val)
85 {
86 SetFieldValue(obj, i, val);
87 return EtsVoid::GetInstance();
88 }
89
ValueAPISetFieldInt(EtsObject * obj,EtsLong i,EtsInt val)90 EtsVoid *ValueAPISetFieldInt(EtsObject *obj, EtsLong i, EtsInt val)
91 {
92 SetFieldValue(obj, i, val);
93 return EtsVoid::GetInstance();
94 }
95
ValueAPISetFieldLong(EtsObject * obj,EtsLong i,EtsLong val)96 EtsVoid *ValueAPISetFieldLong(EtsObject *obj, EtsLong i, EtsLong val)
97 {
98 SetFieldValue(obj, i, val);
99 return EtsVoid::GetInstance();
100 }
101
ValueAPISetFieldFloat(EtsObject * obj,EtsLong i,EtsFloat val)102 EtsVoid *ValueAPISetFieldFloat(EtsObject *obj, EtsLong i, EtsFloat val)
103 {
104 SetFieldValue(obj, i, val);
105 return EtsVoid::GetInstance();
106 }
107
ValueAPISetFieldDouble(EtsObject * obj,EtsLong i,EtsDouble val)108 EtsVoid *ValueAPISetFieldDouble(EtsObject *obj, EtsLong i, EtsDouble val)
109 {
110 SetFieldValue(obj, i, val);
111 return EtsVoid::GetInstance();
112 }
113
ValueAPISetFieldByNameObject(EtsObject * obj,EtsString * name,EtsObject * val)114 EtsVoid *ValueAPISetFieldByNameObject(EtsObject *obj, EtsString *name, EtsObject *val)
115 {
116 auto coroutine = EtsCoroutine::GetCurrent();
117 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
118 VMHandle<EtsObject> objHandle(coroutine, obj->GetCoreType());
119 VMHandle<EtsString> nameHandle(coroutine, name->GetCoreType());
120 VMHandle<EtsObject> valHandle(coroutine, val->GetCoreType());
121
122 auto typeClass = objHandle.GetPtr()->GetClass();
123 auto fieldObject = typeClass->GetFieldIDByName(nameHandle.GetPtr()->GetMutf8().c_str());
124 objHandle.GetPtr()->SetFieldObject(fieldObject, valHandle.GetPtr());
125 return EtsVoid::GetInstance();
126 }
127
128 template <typename T>
SetFieldByNameValue(EtsObject * obj,EtsString * name,T val)129 void SetFieldByNameValue(EtsObject *obj, EtsString *name, T val)
130 {
131 auto coroutine = EtsCoroutine::GetCurrent();
132 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
133 VMHandle<EtsObject> objHandle(coroutine, obj->GetCoreType());
134 VMHandle<EtsString> nameHandle(coroutine, name->GetCoreType());
135
136 auto typeClass = objHandle.GetPtr()->GetClass();
137 auto fieldObject = typeClass->GetFieldIDByName(nameHandle.GetPtr()->GetMutf8().c_str());
138 if (fieldObject->GetType()->IsBoxedClass()) {
139 objHandle.GetPtr()->SetFieldObject(fieldObject, EtsBoxPrimitive<T>::Create(coroutine, val));
140 return;
141 }
142 objHandle.GetPtr()->SetFieldPrimitive<T>(fieldObject, val);
143 }
144
ValueAPISetFieldByNameBoolean(EtsObject * obj,EtsString * name,EtsBoolean val)145 EtsVoid *ValueAPISetFieldByNameBoolean(EtsObject *obj, EtsString *name, EtsBoolean val)
146 {
147 SetFieldByNameValue(obj, name, val);
148 return EtsVoid::GetInstance();
149 }
150
ValueAPISetFieldByNameByte(EtsObject * obj,EtsString * name,EtsByte val)151 EtsVoid *ValueAPISetFieldByNameByte(EtsObject *obj, EtsString *name, EtsByte val)
152 {
153 SetFieldByNameValue(obj, name, val);
154 return EtsVoid::GetInstance();
155 }
156
ValueAPISetFieldByNameShort(EtsObject * obj,EtsString * name,EtsShort val)157 EtsVoid *ValueAPISetFieldByNameShort(EtsObject *obj, EtsString *name, EtsShort val)
158 {
159 SetFieldByNameValue(obj, name, val);
160 return EtsVoid::GetInstance();
161 }
162
ValueAPISetFieldByNameChar(EtsObject * obj,EtsString * name,EtsChar val)163 EtsVoid *ValueAPISetFieldByNameChar(EtsObject *obj, EtsString *name, EtsChar val)
164 {
165 SetFieldByNameValue(obj, name, val);
166 return EtsVoid::GetInstance();
167 }
168
ValueAPISetFieldByNameInt(EtsObject * obj,EtsString * name,EtsInt val)169 EtsVoid *ValueAPISetFieldByNameInt(EtsObject *obj, EtsString *name, EtsInt val)
170 {
171 SetFieldByNameValue(obj, name, val);
172 return EtsVoid::GetInstance();
173 }
174
ValueAPISetFieldByNameLong(EtsObject * obj,EtsString * name,EtsLong val)175 EtsVoid *ValueAPISetFieldByNameLong(EtsObject *obj, EtsString *name, EtsLong val)
176 {
177 SetFieldByNameValue(obj, name, val);
178 return EtsVoid::GetInstance();
179 }
180
ValueAPISetFieldByNameFloat(EtsObject * obj,EtsString * name,EtsFloat val)181 EtsVoid *ValueAPISetFieldByNameFloat(EtsObject *obj, EtsString *name, EtsFloat val)
182 {
183 SetFieldByNameValue(obj, name, val);
184 return EtsVoid::GetInstance();
185 }
186
ValueAPISetFieldByNameDouble(EtsObject * obj,EtsString * name,EtsDouble val)187 EtsVoid *ValueAPISetFieldByNameDouble(EtsObject *obj, EtsString *name, EtsDouble val)
188 {
189 SetFieldByNameValue(obj, name, val);
190 return EtsVoid::GetInstance();
191 }
192
ValueAPIGetFieldObject(EtsObject * obj,EtsLong i)193 EtsObject *ValueAPIGetFieldObject(EtsObject *obj, EtsLong i)
194 {
195 auto coroutine = EtsCoroutine::GetCurrent();
196 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
197 VMHandle<EtsObject> objHandle(coroutine, obj->GetCoreType());
198
199 auto typeClass = objHandle.GetPtr()->GetClass();
200 auto fieldObject = typeClass->GetFieldByIndex(i);
201 return objHandle.GetPtr()->GetFieldObject(fieldObject);
202 }
203
204 template <typename T>
GetFieldValue(EtsObject * obj,EtsLong i)205 T GetFieldValue(EtsObject *obj, EtsLong i)
206 {
207 auto coroutine = EtsCoroutine::GetCurrent();
208 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
209 VMHandle<EtsObject> objHandle(coroutine, obj->GetCoreType());
210
211 auto typeClass = objHandle.GetPtr()->GetClass();
212 auto fieldObject = typeClass->GetFieldByIndex(i);
213 if (fieldObject->GetType()->IsBoxedClass()) {
214 return EtsBoxPrimitive<T>::FromCoreType(objHandle.GetPtr()->GetFieldObject(fieldObject))->GetValue();
215 }
216 return objHandle.GetPtr()->GetFieldPrimitive<T>(fieldObject);
217 }
218
ValueAPIGetFieldBoolean(EtsObject * obj,EtsLong i)219 EtsBoolean ValueAPIGetFieldBoolean(EtsObject *obj, EtsLong i)
220 {
221 return GetFieldValue<EtsBoolean>(obj, i);
222 }
223
ValueAPIGetFieldByte(EtsObject * obj,EtsLong i)224 EtsByte ValueAPIGetFieldByte(EtsObject *obj, EtsLong i)
225 {
226 return GetFieldValue<EtsByte>(obj, i);
227 }
228
ValueAPIGetFieldShort(EtsObject * obj,EtsLong i)229 EtsShort ValueAPIGetFieldShort(EtsObject *obj, EtsLong i)
230 {
231 return GetFieldValue<EtsShort>(obj, i);
232 }
233
ValueAPIGetFieldChar(EtsObject * obj,EtsLong i)234 EtsChar ValueAPIGetFieldChar(EtsObject *obj, EtsLong i)
235 {
236 return GetFieldValue<EtsChar>(obj, i);
237 }
238
ValueAPIGetFieldInt(EtsObject * obj,EtsLong i)239 EtsInt ValueAPIGetFieldInt(EtsObject *obj, EtsLong i)
240 {
241 return GetFieldValue<EtsInt>(obj, i);
242 }
243
ValueAPIGetFieldLong(EtsObject * obj,EtsLong i)244 EtsLong ValueAPIGetFieldLong(EtsObject *obj, EtsLong i)
245 {
246 return GetFieldValue<EtsLong>(obj, i);
247 }
248
ValueAPIGetFieldFloat(EtsObject * obj,EtsLong i)249 EtsFloat ValueAPIGetFieldFloat(EtsObject *obj, EtsLong i)
250 {
251 return GetFieldValue<EtsFloat>(obj, i);
252 }
253
ValueAPIGetFieldDouble(EtsObject * obj,EtsLong i)254 EtsDouble ValueAPIGetFieldDouble(EtsObject *obj, EtsLong i)
255 {
256 return GetFieldValue<EtsDouble>(obj, i);
257 }
258
ValueAPIGetFieldByNameObject(EtsObject * obj,EtsString * name)259 EtsObject *ValueAPIGetFieldByNameObject(EtsObject *obj, EtsString *name)
260 {
261 auto coroutine = EtsCoroutine::GetCurrent();
262 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
263 VMHandle<EtsObject> objHandle(coroutine, obj->GetCoreType());
264
265 auto typeClass = objHandle.GetPtr()->GetClass();
266 auto fieldObject = typeClass->GetFieldIDByName(name->GetMutf8().c_str());
267 return objHandle.GetPtr()->GetFieldObject(fieldObject);
268 }
269
270 template <typename T>
GetFieldByNameValue(EtsObject * obj,EtsString * name)271 T GetFieldByNameValue(EtsObject *obj, EtsString *name)
272 {
273 auto coroutine = EtsCoroutine::GetCurrent();
274 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
275 VMHandle<EtsObject> objHandle(coroutine, obj->GetCoreType());
276
277 auto typeClass = objHandle.GetPtr()->GetClass();
278 auto fieldObject = typeClass->GetFieldIDByName(name->GetMutf8().c_str());
279 if (fieldObject->GetType()->IsBoxedClass()) {
280 return EtsBoxPrimitive<T>::FromCoreType(objHandle.GetPtr()->GetFieldObject(fieldObject))->GetValue();
281 }
282 return objHandle.GetPtr()->GetFieldPrimitive<T>(fieldObject);
283 }
284
ValueAPIGetFieldByNameBoolean(EtsObject * obj,EtsString * name)285 EtsBoolean ValueAPIGetFieldByNameBoolean(EtsObject *obj, EtsString *name)
286 {
287 return GetFieldByNameValue<EtsBoolean>(obj, name);
288 }
289
ValueAPIGetFieldByNameByte(EtsObject * obj,EtsString * name)290 EtsByte ValueAPIGetFieldByNameByte(EtsObject *obj, EtsString *name)
291 {
292 return GetFieldByNameValue<EtsByte>(obj, name);
293 }
294
ValueAPIGetFieldByNameShort(EtsObject * obj,EtsString * name)295 EtsShort ValueAPIGetFieldByNameShort(EtsObject *obj, EtsString *name)
296 {
297 return GetFieldByNameValue<EtsShort>(obj, name);
298 }
299
ValueAPIGetFieldByNameChar(EtsObject * obj,EtsString * name)300 EtsChar ValueAPIGetFieldByNameChar(EtsObject *obj, EtsString *name)
301 {
302 return GetFieldByNameValue<EtsChar>(obj, name);
303 }
304
ValueAPIGetFieldByNameInt(EtsObject * obj,EtsString * name)305 EtsInt ValueAPIGetFieldByNameInt(EtsObject *obj, EtsString *name)
306 {
307 return GetFieldByNameValue<EtsInt>(obj, name);
308 }
309
ValueAPIGetFieldByNameLong(EtsObject * obj,EtsString * name)310 EtsLong ValueAPIGetFieldByNameLong(EtsObject *obj, EtsString *name)
311 {
312 return GetFieldByNameValue<EtsLong>(obj, name);
313 }
314
ValueAPIGetFieldByNameFloat(EtsObject * obj,EtsString * name)315 EtsFloat ValueAPIGetFieldByNameFloat(EtsObject *obj, EtsString *name)
316 {
317 return GetFieldByNameValue<EtsFloat>(obj, name);
318 }
319
ValueAPIGetFieldByNameDouble(EtsObject * obj,EtsString * name)320 EtsDouble ValueAPIGetFieldByNameDouble(EtsObject *obj, EtsString *name)
321 {
322 return GetFieldByNameValue<EtsDouble>(obj, name);
323 }
324
ValueAPIGetArrayLength(EtsObject * obj)325 EtsLong ValueAPIGetArrayLength(EtsObject *obj)
326 {
327 auto coroutine = EtsCoroutine::GetCurrent();
328 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
329 VMHandle<EtsArray> arrHandle(coroutine, obj->GetCoreType());
330 return arrHandle->GetLength();
331 }
332
ValueAPISetElementObject(EtsObject * obj,EtsLong i,EtsObject * val)333 EtsVoid *ValueAPISetElementObject(EtsObject *obj, EtsLong i, EtsObject *val)
334 {
335 auto coroutine = EtsCoroutine::GetCurrent();
336 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
337 VMHandle<EtsObjectArray> arrHandle(coroutine, obj->GetCoreType());
338 VMHandle<EtsObject> valHandle(coroutine, val->GetCoreType());
339
340 arrHandle.GetPtr()->Set(i, valHandle.GetPtr());
341 return EtsVoid::GetInstance();
342 }
343
344 template <typename P, typename T>
SetElement(EtsObject * obj,EtsLong i,T val)345 void SetElement(EtsObject *obj, EtsLong i, T val)
346 {
347 auto coroutine = EtsCoroutine::GetCurrent();
348 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
349 auto typeClass = obj->GetClass();
350 if (!typeClass->GetComponentType()->IsBoxedClass()) {
351 VMHandle<P> arrHandle(coroutine, obj->GetCoreType());
352 arrHandle.GetPtr()->Set(i, val);
353 } else {
354 VMHandle<EtsObjectArray> arrHandle(coroutine, obj->GetCoreType());
355 arrHandle.GetPtr()->Set(i, EtsBoxPrimitive<T>::Create(coroutine, val));
356 }
357 }
358
ValueAPISetElementBoolean(EtsObject * obj,EtsLong i,EtsBoolean val)359 EtsVoid *ValueAPISetElementBoolean(EtsObject *obj, EtsLong i, EtsBoolean val)
360 {
361 SetElement<EtsBooleanArray>(obj, i, val);
362 return EtsVoid::GetInstance();
363 }
364
ValueAPISetElementByte(EtsObject * obj,EtsLong i,EtsByte val)365 EtsVoid *ValueAPISetElementByte(EtsObject *obj, EtsLong i, EtsByte val)
366 {
367 SetElement<EtsByteArray>(obj, i, val);
368 return EtsVoid::GetInstance();
369 }
370
ValueAPISetElementShort(EtsObject * obj,EtsLong i,EtsShort val)371 EtsVoid *ValueAPISetElementShort(EtsObject *obj, EtsLong i, EtsShort val)
372 {
373 SetElement<EtsShortArray>(obj, i, val);
374 return EtsVoid::GetInstance();
375 }
376
ValueAPISetElementChar(EtsObject * obj,EtsLong i,EtsChar val)377 EtsVoid *ValueAPISetElementChar(EtsObject *obj, EtsLong i, EtsChar val)
378 {
379 SetElement<EtsCharArray>(obj, i, val);
380 return EtsVoid::GetInstance();
381 }
382
ValueAPISetElementInt(EtsObject * obj,EtsLong i,EtsInt val)383 EtsVoid *ValueAPISetElementInt(EtsObject *obj, EtsLong i, EtsInt val)
384 {
385 SetElement<EtsIntArray>(obj, i, val);
386 return EtsVoid::GetInstance();
387 }
388
ValueAPISetElementLong(EtsObject * obj,EtsLong i,EtsLong val)389 EtsVoid *ValueAPISetElementLong(EtsObject *obj, EtsLong i, EtsLong val)
390 {
391 SetElement<EtsLongArray>(obj, i, val);
392 return EtsVoid::GetInstance();
393 }
394
ValueAPISetElementFloat(EtsObject * obj,EtsLong i,EtsFloat val)395 EtsVoid *ValueAPISetElementFloat(EtsObject *obj, EtsLong i, EtsFloat val)
396 {
397 SetElement<EtsFloatArray>(obj, i, val);
398 return EtsVoid::GetInstance();
399 }
400
ValueAPISetElementDouble(EtsObject * obj,EtsLong i,EtsDouble val)401 EtsVoid *ValueAPISetElementDouble(EtsObject *obj, EtsLong i, EtsDouble val)
402 {
403 SetElement<EtsDoubleArray>(obj, i, val);
404 return EtsVoid::GetInstance();
405 }
406
ValueAPIGetElementObject(EtsObject * obj,EtsLong i)407 EtsObject *ValueAPIGetElementObject(EtsObject *obj, EtsLong i)
408 {
409 auto coroutine = EtsCoroutine::GetCurrent();
410 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
411 VMHandle<EtsObjectArray> arrHandle(coroutine, obj->GetCoreType());
412
413 return arrHandle.GetPtr()->Get(i);
414 }
415
416 template <typename P>
GetElement(EtsObject * obj,EtsLong i)417 typename P::ValueType GetElement(EtsObject *obj, EtsLong i)
418 {
419 auto coroutine = EtsCoroutine::GetCurrent();
420 [[maybe_unused]] HandleScope<ObjectHeader *> scope(coroutine);
421 auto typeClass = obj->GetClass();
422 if (!typeClass->GetComponentType()->IsBoxedClass()) {
423 VMHandle<P> arrHandle(coroutine, obj->GetCoreType());
424 return arrHandle.GetPtr()->Get(i);
425 }
426 VMHandle<EtsObjectArray> arrHandle(coroutine, obj->GetCoreType());
427 auto value = EtsBoxPrimitive<typename P::ValueType>::FromCoreType(arrHandle.GetPtr()->Get(i));
428 return value->GetValue();
429 }
430
ValueAPIGetElementBoolean(EtsObject * obj,EtsLong i)431 EtsBoolean ValueAPIGetElementBoolean(EtsObject *obj, EtsLong i)
432 {
433 return GetElement<EtsBooleanArray>(obj, i);
434 }
435
ValueAPIGetElementByte(EtsObject * obj,EtsLong i)436 EtsByte ValueAPIGetElementByte(EtsObject *obj, EtsLong i)
437 {
438 return GetElement<EtsByteArray>(obj, i);
439 }
440
ValueAPIGetElementShort(EtsObject * obj,EtsLong i)441 EtsShort ValueAPIGetElementShort(EtsObject *obj, EtsLong i)
442 {
443 return GetElement<EtsShortArray>(obj, i);
444 }
445
ValueAPIGetElementChar(EtsObject * obj,EtsLong i)446 EtsChar ValueAPIGetElementChar(EtsObject *obj, EtsLong i)
447 {
448 return GetElement<EtsCharArray>(obj, i);
449 }
450
ValueAPIGetElementInt(EtsObject * obj,EtsLong i)451 EtsInt ValueAPIGetElementInt(EtsObject *obj, EtsLong i)
452 {
453 return GetElement<EtsIntArray>(obj, i);
454 }
455
ValueAPIGetElementLong(EtsObject * obj,EtsLong i)456 EtsLong ValueAPIGetElementLong(EtsObject *obj, EtsLong i)
457 {
458 return GetElement<EtsLongArray>(obj, i);
459 }
460
ValueAPIGetElementFloat(EtsObject * obj,EtsLong i)461 EtsFloat ValueAPIGetElementFloat(EtsObject *obj, EtsLong i)
462 {
463 return GetElement<EtsFloatArray>(obj, i);
464 }
465
ValueAPIGetElementDouble(EtsObject * obj,EtsLong i)466 EtsDouble ValueAPIGetElementDouble(EtsObject *obj, EtsLong i)
467 {
468 return GetElement<EtsDoubleArray>(obj, i);
469 }
470
471 } // namespace panda::ets::intrinsics
472