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