1 /**
2 * Copyright (c) 2023-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 "intrinsics.h"
17 #include "plugins/ets/runtime/interop_js/intrinsics_api_impl.h"
18 #include "plugins/ets/runtime/interop_js/js_value.h"
19 #include "plugins/ets/runtime/interop_js/xgc/xgc.h"
20 #include "plugins/ets/runtime/intrinsics/gc_task_tracker.h"
21 #include "plugins/ets/runtime/types/ets_object.h"
22 #include "plugins/ets/runtime/types/ets_string.h"
23 #include "interop_js/call/call.h"
24
25 namespace ark::ets::interop::js::intrinsics {
26
JSRuntimeFinalizationRegistryCallbackIntrinsic(EtsObject * obj)27 void JSRuntimeFinalizationRegistryCallbackIntrinsic(EtsObject *obj)
28 {
29 JSRuntimeFinalizationRegistryCallback(obj);
30 }
31
JSRuntimeNewJSValueDoubleIntrinsic(double v)32 JSValue *JSRuntimeNewJSValueDoubleIntrinsic(double v)
33 {
34 return JSRuntimeNewJSValueDouble(v);
35 }
36
JSRuntimeNewJSValueBooleanIntrinsic(uint8_t v)37 JSValue *JSRuntimeNewJSValueBooleanIntrinsic(uint8_t v)
38 {
39 return JSRuntimeNewJSValueBoolean(v);
40 }
41
JSRuntimeNewJSValueStringIntrinsic(EtsString * v)42 JSValue *JSRuntimeNewJSValueStringIntrinsic(EtsString *v)
43 {
44 return JSRuntimeNewJSValueString(v);
45 }
46
JSRuntimeNewJSValueObjectIntrinsic(EtsObject * v)47 JSValue *JSRuntimeNewJSValueObjectIntrinsic(EtsObject *v)
48 {
49 return JSRuntimeNewJSValueObject(v);
50 }
51
JSRuntimeIsJSValueIntrinsic(EtsObject * v)52 uint8_t JSRuntimeIsJSValueIntrinsic(EtsObject *v)
53 {
54 return JSRuntimeIsJSValue(v);
55 }
56
JSRuntimeNewJSValueBigIntIntrinsic(EtsBigInt * v)57 JSValue *JSRuntimeNewJSValueBigIntIntrinsic(EtsBigInt *v)
58 {
59 return JSRuntimeNewJSValueBigInt(v);
60 }
61
JSRuntimeGetValueDoubleIntrinsic(JSValue * etsJsValue)62 double JSRuntimeGetValueDoubleIntrinsic(JSValue *etsJsValue)
63 {
64 return JSRuntimeGetValueDouble(etsJsValue);
65 }
66
JSRuntimeGetValueBooleanIntrinsic(JSValue * etsJsValue)67 uint8_t JSRuntimeGetValueBooleanIntrinsic(JSValue *etsJsValue)
68 {
69 return JSRuntimeGetValueBoolean(etsJsValue);
70 }
71
JSRuntimeGetValueStringIntrinsic(JSValue * etsJsValue)72 EtsString *JSRuntimeGetValueStringIntrinsic(JSValue *etsJsValue)
73 {
74 return JSRuntimeGetValueString(etsJsValue);
75 }
76
JSRuntimeGetValueObjectIntrinsic(JSValue * etsJsValue,EtsClass * cls)77 EtsObject *JSRuntimeGetValueObjectIntrinsic(JSValue *etsJsValue, EtsClass *cls)
78 {
79 return JSRuntimeGetValueObject(etsJsValue, cls);
80 }
81
JSRuntimeGetPropertyJSValueIntrinsic(JSValue * etsJsValue,EtsString * etsPropName)82 JSValue *JSRuntimeGetPropertyJSValueIntrinsic(JSValue *etsJsValue, EtsString *etsPropName)
83 {
84 return JSValueNamedGetter<JSConvertJSValue>(etsJsValue, etsPropName);
85 }
86
JSRuntimeGetPropertyJSValueyByKeyIntrinsic(JSValue * objectValue,JSValue * keyValue)87 JSValue *JSRuntimeGetPropertyJSValueyByKeyIntrinsic(JSValue *objectValue, JSValue *keyValue)
88 {
89 return JSRuntimeGetPropertyJSValueyByKey(objectValue, keyValue);
90 }
91
JSRuntimeGetPropertyDoubleIntrinsic(JSValue * etsJsValue,EtsString * etsPropName)92 double JSRuntimeGetPropertyDoubleIntrinsic(JSValue *etsJsValue, EtsString *etsPropName)
93 {
94 return JSValueNamedGetter<JSConvertF64>(etsJsValue, etsPropName);
95 }
96
JSRuntimeGetPropertyStringIntrinsic(JSValue * etsJsValue,EtsString * etsPropName)97 EtsString *JSRuntimeGetPropertyStringIntrinsic(JSValue *etsJsValue, EtsString *etsPropName)
98 {
99 return JSValueNamedGetter<JSConvertString>(etsJsValue, etsPropName);
100 }
101
JSRuntimeGetPropertyBooleanIntrinsic(JSValue * etsJsValue,EtsString * etsPropName)102 uint8_t JSRuntimeGetPropertyBooleanIntrinsic(JSValue *etsJsValue, EtsString *etsPropName)
103 {
104 return static_cast<uint8_t>(JSValueNamedGetter<JSConvertU1>(etsJsValue, etsPropName));
105 }
106
JSRuntimeSetPropertyJSValueIntrinsic(JSValue * etsJsValue,EtsString * etsPropName,JSValue * value)107 void JSRuntimeSetPropertyJSValueIntrinsic(JSValue *etsJsValue, EtsString *etsPropName, JSValue *value)
108 {
109 JSValueNamedSetter<JSConvertJSValue>(etsJsValue, etsPropName, value);
110 }
111
JSRuntimeSetPropertyDoubleIntrinsic(JSValue * etsJsValue,EtsString * etsPropName,double value)112 void JSRuntimeSetPropertyDoubleIntrinsic(JSValue *etsJsValue, EtsString *etsPropName, double value)
113 {
114 JSValueNamedSetter<JSConvertF64>(etsJsValue, etsPropName, value);
115 }
116
JSRuntimeSetPropertyStringIntrinsic(JSValue * etsJsValue,EtsString * etsPropName,EtsString * value)117 void JSRuntimeSetPropertyStringIntrinsic(JSValue *etsJsValue, EtsString *etsPropName, EtsString *value)
118 {
119 JSValueNamedSetter<JSConvertString>(etsJsValue, etsPropName, value);
120 }
121
JSRuntimeSetPropertyBooleanIntrinsic(JSValue * etsJsValue,EtsString * etsPropName,uint8_t value)122 void JSRuntimeSetPropertyBooleanIntrinsic(JSValue *etsJsValue, EtsString *etsPropName, uint8_t value)
123 {
124 JSValueNamedSetter<JSConvertU1>(etsJsValue, etsPropName, static_cast<bool>(value));
125 }
126
JSRuntimeSetElementJSValueIntrinsic(JSValue * etsJsValue,int32_t index,JSValue * value)127 void JSRuntimeSetElementJSValueIntrinsic(JSValue *etsJsValue, int32_t index, JSValue *value)
128 {
129 JSValueIndexedSetter<JSConvertJSValue>(etsJsValue, index, value);
130 }
131
JSRuntimeGetElementJSValueIntrinsic(JSValue * etsJsValue,int32_t index)132 JSValue *JSRuntimeGetElementJSValueIntrinsic(JSValue *etsJsValue, int32_t index)
133 {
134 return JSValueIndexedGetter<JSConvertJSValue>(etsJsValue, index);
135 }
136
JSRuntimeGetElementDoubleIntrinsic(JSValue * etsJsValue,int32_t index)137 double JSRuntimeGetElementDoubleIntrinsic(JSValue *etsJsValue, int32_t index)
138 {
139 return JSValueIndexedGetter<JSConvertF64>(etsJsValue, index);
140 }
141
JSRuntimeGetUndefinedIntrinsic()142 JSValue *JSRuntimeGetUndefinedIntrinsic()
143 {
144 return JSRuntimeGetUndefined();
145 }
146
JSRuntimeGetNullIntrinsic()147 JSValue *JSRuntimeGetNullIntrinsic()
148 {
149 return JSRuntimeGetNull();
150 }
151
JSRuntimeGetGlobalIntrinsic()152 JSValue *JSRuntimeGetGlobalIntrinsic()
153 {
154 return JSRuntimeGetGlobal();
155 }
156
JSRuntimeCreateObjectIntrinsic()157 JSValue *JSRuntimeCreateObjectIntrinsic()
158 {
159 return JSRuntimeCreateObject();
160 }
161
JSRuntimeCreateArrayIntrinsic()162 JSValue *JSRuntimeCreateArrayIntrinsic()
163 {
164 return JSRuntimeCreateArray();
165 }
166
JSRuntimeInstanceOfDynamicIntrinsic(JSValue * object,JSValue * ctor)167 uint8_t JSRuntimeInstanceOfDynamicIntrinsic(JSValue *object, JSValue *ctor)
168 {
169 return JSRuntimeInstanceOfDynamic(object, ctor);
170 }
171
JSRuntimeInstanceOfStaticIntrinsic(JSValue * object,EtsClass * clsObj)172 uint8_t JSRuntimeInstanceOfStaticIntrinsic(JSValue *object, EtsClass *clsObj)
173 {
174 return JSRuntimeInstanceOfStatic(object, clsObj);
175 }
176
JSRuntimeInitJSCallClassIntrinsic()177 uint8_t JSRuntimeInitJSCallClassIntrinsic()
178 {
179 return JSRuntimeInitJSCallClass();
180 }
181
JSRuntimeInitJSNewClassIntrinsic()182 uint8_t JSRuntimeInitJSNewClassIntrinsic()
183 {
184 return JSRuntimeInitJSNewClass();
185 }
186
JSRuntimeLoadModuleIntrinsic(EtsString * module)187 JSValue *JSRuntimeLoadModuleIntrinsic(EtsString *module)
188 {
189 return JSRuntimeLoadModule(module);
190 }
191
JSRuntimeStrictEqualIntrinsic(JSValue * lhs,JSValue * rhs)192 uint8_t JSRuntimeStrictEqualIntrinsic(JSValue *lhs, JSValue *rhs)
193 {
194 return JSRuntimeStrictEqual(lhs, rhs);
195 }
196
JSRuntimeHasPropertyIntrinsic(JSValue * object,EtsString * name)197 uint8_t JSRuntimeHasPropertyIntrinsic(JSValue *object, EtsString *name)
198 {
199 return JSRuntimeHasProperty(object, name);
200 }
201
JSRuntimeGetPropertyIntrinsic(JSValue * object,JSValue * property)202 JSValue *JSRuntimeGetPropertyIntrinsic(JSValue *object, JSValue *property)
203 {
204 return JSRuntimeGetProperty(object, property);
205 }
206
JSRuntimeHasPropertyJSValueIntrinsic(JSValue * object,JSValue * property)207 uint8_t JSRuntimeHasPropertyJSValueIntrinsic(JSValue *object, JSValue *property)
208 {
209 return JSRuntimeHasPropertyJSValue(object, property);
210 }
211
JSRuntimeHasElementIntrinsic(JSValue * object,int index)212 uint8_t JSRuntimeHasElementIntrinsic(JSValue *object, int index)
213 {
214 return JSRuntimeHasElement(object, index);
215 }
216
JSRuntimeHasOwnPropertyIntrinsic(JSValue * object,EtsString * name)217 uint8_t JSRuntimeHasOwnPropertyIntrinsic(JSValue *object, EtsString *name)
218 {
219 return JSRuntimeHasOwnProperty(object, name);
220 }
221
JSRuntimeHasOwnPropertyJSValueIntrinsic(JSValue * object,JSValue * property)222 uint8_t JSRuntimeHasOwnPropertyJSValueIntrinsic(JSValue *object, JSValue *property)
223 {
224 return JSRuntimeHasOwnPropertyJSValue(object, property);
225 }
226
JSRuntimeTypeOfIntrinsic(JSValue * object)227 EtsString *JSRuntimeTypeOfIntrinsic(JSValue *object)
228 {
229 return JSRuntimeTypeOf(object);
230 }
231
JSRuntimeIsPromiseIntrinsic(JSValue * object)232 uint8_t JSRuntimeIsPromiseIntrinsic(JSValue *object)
233 {
234 return JSRuntimeIsPromise(object);
235 }
236
JSRuntimeInstanceOfStaticTypeIntrinsic(JSValue * object,EtsTypeAPIType * paramType)237 uint8_t JSRuntimeInstanceOfStaticTypeIntrinsic(JSValue *object, EtsTypeAPIType *paramType)
238 {
239 return JSRuntimeInstanceOfStaticType(object, paramType);
240 }
241
JSRuntimeInvokeIntrinsic(JSValue * recv,JSValue * func,ObjectHeader * args)242 JSValue *JSRuntimeInvokeIntrinsic(JSValue *recv, JSValue *func, ObjectHeader *args)
243 {
244 return JSRuntimeInvoke(recv, func, reinterpret_cast<EtsArray *>(args));
245 }
JSRuntimeInstantiateIntrinsic(JSValue * callable,ObjectHeader * args)246 JSValue *JSRuntimeInstantiateIntrinsic(JSValue *callable, ObjectHeader *args)
247 {
248 return JSRuntimeInstantiate(callable, reinterpret_cast<EtsArray *>(args));
249 }
250
JSRuntimeXgcStartIntrinsic()251 EtsLong JSRuntimeXgcStartIntrinsic()
252 {
253 auto *coro = EtsCoroutine::GetCurrent();
254 ASSERT(coro != nullptr);
255 auto *gc = coro->GetPandaVM()->GetGC();
256 auto &gcTaskTracker = ets::intrinsics::GCTaskTracker::InitIfNeededAndGet(gc);
257 auto task = MakePandaUnique<GCTask>(GCTaskCause::CROSSREF_CAUSE, time::GetCurrentTimeInNanos());
258 ASSERT(task != nullptr);
259 auto id = task->GetId();
260 gcTaskTracker.AddTaskId(id);
261 if (!XGC::GetInstance()->Trigger(gc, std::move(task))) {
262 gcTaskTracker.RemoveId(id);
263 return static_cast<EtsLong>(-1);
264 }
265 return static_cast<EtsLong>(id);
266 }
267
JSValueToStringIntrinsic(JSValue * object)268 EtsString *JSValueToStringIntrinsic(JSValue *object)
269 {
270 return JSValueToString(object);
271 }
272
JSONStringifyIntrinsic(JSValue * obj)273 EtsString *JSONStringifyIntrinsic(JSValue *obj)
274 {
275 return JSONStringify(obj);
276 }
277
278 // Compiler intrinsics for fast interop
CompilerGetJSNamedPropertyIntrinsic(void * val,void * propName)279 void *CompilerGetJSNamedPropertyIntrinsic(void *val, void *propName)
280 {
281 return CompilerGetJSNamedProperty(val, reinterpret_cast<char *>(propName));
282 }
283
CompilerGetJSPropertyIntrinsic(void * val,void * prop)284 void *CompilerGetJSPropertyIntrinsic(void *val, void *prop)
285 {
286 return CompilerGetJSProperty(val, prop);
287 }
288
CompilerGetJSElementIntrinsic(void * val,int32_t index)289 void *CompilerGetJSElementIntrinsic(void *val, int32_t index)
290 {
291 return CompilerGetJSElement(val, index);
292 }
293
CompilerJSCallCheckIntrinsic(void * fn)294 void *CompilerJSCallCheckIntrinsic(void *fn)
295 {
296 return CompilerJSCallCheck(fn);
297 }
298
CompilerJSCallFunctionIntrinsic(void * obj,void * fn,uint32_t argc,void * args)299 void *CompilerJSCallFunctionIntrinsic(void *obj, void *fn, uint32_t argc, void *args)
300 {
301 return CompilerJSCallFunction<true>(obj, fn, argc, args);
302 }
303
CompilerJSCallVoidFunctionIntrinsic(void * obj,void * fn,uint32_t argc,void * args)304 void CompilerJSCallVoidFunctionIntrinsic(void *obj, void *fn, uint32_t argc, void *args)
305 {
306 CompilerJSCallFunction<false>(obj, fn, argc, args);
307 }
308
CompilerJSNewInstanceIntrinsic(void * fn,uint32_t argc,void * args)309 void *CompilerJSNewInstanceIntrinsic(void *fn, uint32_t argc, void *args)
310 {
311 return CompilerJSNewInstance(fn, argc, args);
312 }
313
CompilerConvertVoidToLocalIntrinsic()314 void *CompilerConvertVoidToLocalIntrinsic()
315 {
316 return CompilerConvertVoidToLocal();
317 }
318
319 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
320 #define CONVERT_LOCAL_VALUE(type, cpptype) \
321 /* CC-OFFNXT(G.PRE.02) part name */ \
322 void *CompilerConvert##type##ToLocalIntrinsic(cpptype etsVal) \
323 { \
324 /* CC-OFFNXT(G.PRE.05) code generation */ \
325 return ConvertToLocal<JSConvert##type>(etsVal); \
326 } \
327 \
328 cpptype CompilerConvertLocalTo##type##Intrinsic(void *val) \
329 { \
330 /* CC-OFFNXT(G.PRE.05) code generation */ \
331 return ConvertFromLocal<JSConvert##type>(val); \
332 }
333
CONVERT_LOCAL_VALUE(U1,uint8_t)334 CONVERT_LOCAL_VALUE(U1, uint8_t)
335 CONVERT_LOCAL_VALUE(U8, uint8_t)
336 CONVERT_LOCAL_VALUE(I8, int8_t)
337 CONVERT_LOCAL_VALUE(U16, uint16_t)
338 CONVERT_LOCAL_VALUE(I16, int16_t)
339 CONVERT_LOCAL_VALUE(U32, uint32_t)
340 CONVERT_LOCAL_VALUE(I32, int32_t)
341 CONVERT_LOCAL_VALUE(U64, uint64_t)
342 CONVERT_LOCAL_VALUE(I64, int64_t)
343 CONVERT_LOCAL_VALUE(F32, float)
344 CONVERT_LOCAL_VALUE(F64, double)
345 CONVERT_LOCAL_VALUE(JSValue, JSValue *)
346
347 #undef CONVERT_LOCAL_VALUE
348
349 void *CompilerConvertRefTypeToLocalIntrinsic(EtsObject *etsVal)
350 {
351 return CompilerConvertRefTypeToLocal(etsVal);
352 }
CompilerConvertLocalToStringIntrinsic(void * val)353 EtsString *CompilerConvertLocalToStringIntrinsic(void *val)
354 {
355 return CompilerConvertLocalToString(val);
356 }
357
CompilerConvertLocalToRefTypeIntrinsic(void * klassPtr,void * val)358 EtsObject *CompilerConvertLocalToRefTypeIntrinsic(void *klassPtr, void *val)
359 {
360 return CompilerConvertLocalToRefType(klassPtr, val);
361 }
362
CompilerCreateLocalScopeIntrinsic()363 void CompilerCreateLocalScopeIntrinsic()
364 {
365 CreateLocalScope();
366 }
367
CompilerDestroyLocalScopeIntrinsic()368 void CompilerDestroyLocalScopeIntrinsic()
369 {
370 CompilerDestroyLocalScope();
371 }
372
CompilerLoadJSConstantPoolIntrinsic()373 void *CompilerLoadJSConstantPoolIntrinsic()
374 {
375 return CompilerLoadJSConstantPool();
376 }
377
CompilerInitJSCallClassForCtxIntrinsic(void * klass)378 void CompilerInitJSCallClassForCtxIntrinsic(void *klass)
379 {
380 return CompilerInitJSCallClassForCtx(klass);
381 }
382
PromiseInteropResolveIntrinsic(EtsObject * value,EtsLong deferred)383 void PromiseInteropResolveIntrinsic(EtsObject *value, EtsLong deferred)
384 {
385 PromiseInteropResolve(value, deferred);
386 }
387
PromiseInteropRejectIntrinsic(EtsObject * value,EtsLong deferred)388 void PromiseInteropRejectIntrinsic(EtsObject *value, EtsLong deferred)
389 {
390 PromiseInteropReject(value, deferred);
391 }
392
InteropTransferHelperTransferArrayBufferToStaticImplIntrinsic(ESValue * object)393 EtsEscompatArrayBuffer *InteropTransferHelperTransferArrayBufferToStaticImplIntrinsic(ESValue *object)
394 {
395 return TransferArrayBufferToStatic(object);
396 }
397
InteropTransferHelperTransferArrayBufferToDynamicImplIntrinsic(EtsEscompatArrayBuffer * object)398 EtsObject *InteropTransferHelperTransferArrayBufferToDynamicImplIntrinsic(EtsEscompatArrayBuffer *object)
399 {
400 return TransferArrayBufferToDynamic(object);
401 }
402
InteropTransferHelperCreateDynamicTypedArrayIntrinsic(EtsEscompatArrayBuffer * object,int32_t typedArrayType,double length,double byteOffset)403 EtsObject *InteropTransferHelperCreateDynamicTypedArrayIntrinsic(EtsEscompatArrayBuffer *object, int32_t typedArrayType,
404 double length, double byteOffset)
405 {
406 return CreateDynamicTypedArray(object, typedArrayType, length, byteOffset);
407 }
408
InteropTransferHelperCreateDynamicDataViewIntrinsic(EtsEscompatArrayBuffer * object,double length,double byteOffset)409 EtsObject *InteropTransferHelperCreateDynamicDataViewIntrinsic(EtsEscompatArrayBuffer *object, double length,
410 double byteOffset)
411 {
412 return CreateDynamicDataView(object, length, byteOffset);
413 }
414
InteropContextSetInteropRuntimeLinkerImplIntrinsic(EtsRuntimeLinker * linker)415 void InteropContextSetInteropRuntimeLinkerImplIntrinsic(EtsRuntimeLinker *linker)
416 {
417 SetInteropRuntimeLinker(linker);
418 }
419
420 } // namespace ark::ets::interop::js::intrinsics
421