1 /*
2 * Copyright (c) 2021-2023 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 <array>
17 #include <cstdint>
18 #include <fcntl.h>
19
20 #include "ecmascript/base/json_stringifier.h"
21 #include "ecmascript/base/typed_array_helper-inl.h"
22 #include "ecmascript/builtins/builtins_object.h"
23 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
24 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
25 #endif
26 #include "ecmascript/checkpoint/thread_state_transition.h"
27 #include "ecmascript/ecma_global_storage.h"
28 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
29 #include "ecmascript/interpreter/interpreter_assembly.h"
30 #include "ecmascript/jsnapi_sendable.h"
31 #include "ecmascript/jspandafile/js_pandafile_executor.h"
32 #include "ecmascript/linked_hash_table.h"
33 #include "ecmascript/module/napi_module_loader.h"
34 #include "ecmascript/regexp/regexp_parser.h"
35 #include "ecmascript/serializer/base_deserializer.h"
36 #include "ecmascript/serializer/value_serializer.h"
37 #include "ecmascript/ohos/ohos_preload_app_info.h"
38 #include "ecmascript/platform/aot_crash_info.h"
39 #ifdef ARK_SUPPORT_INTL
40 #include "ecmascript/js_bigint.h"
41 #include "ecmascript/js_collator.h"
42 #include "ecmascript/js_date_time_format.h"
43 #include "ecmascript/js_number_format.h"
44 #endif
45
46 namespace panda {
47 using ecmascript::AccessorData;
48 using ecmascript::BigInt;
49 using ecmascript::ByteArray;
50 using ecmascript::ECMAObject;
51 using ecmascript::EcmaRuntimeCallInfo;
52 using ecmascript::EcmaString;
53 using ecmascript::EcmaStringAccessor;
54 using ecmascript::ErrorType;
55 using ecmascript::FastRuntimeStub;
56 using ecmascript::GeneratorContext;
57 using ecmascript::GlobalEnv;
58 using ecmascript::GlobalEnvConstants;
59 using ecmascript::IterationKind;
60 using ecmascript::JSArray;
61 using ecmascript::JSArrayBuffer;
62 using ecmascript::JSDataView;
63 using ecmascript::JSDate;
64 using ecmascript::JSFunction;
65 using ecmascript::JSFunctionBase;
66 using ecmascript::JSGeneratorFunction;
67 using ecmascript::JSGeneratorObject;
68 using ecmascript::JSGeneratorState;
69 using ecmascript::JSHClass;
70 using ecmascript::JSIterator;
71 using ecmascript::JSMap;
72 using ecmascript::JSMapIterator;
73 using ecmascript::JSNapiSendable;
74 using ecmascript::JSNativePointer;
75 using ecmascript::JSObject;
76 using ecmascript::JSPandaFile;
77 using ecmascript::JSPandaFileManager;
78 using ecmascript::JSPrimitiveRef;
79 using ecmascript::JSPromise;
80 using ecmascript::JSProxy;
81 using ecmascript::ObjectFastOperator;
82 using ecmascript::JSRegExp;
83 using ecmascript::JSRuntimeOptions;
84 using ecmascript::JSSet;
85 using ecmascript::JSSetIterator;
86 using ecmascript::JSSymbol;
87 using ecmascript::JSTaggedNumber;
88 using ecmascript::JSTaggedType;
89 using ecmascript::JSTaggedValue;
90 using ecmascript::JSThread;
91 using ecmascript::JSTypedArray;
92 using ecmascript::LinkedHashMap;
93 using ecmascript::LinkedHashSet;
94 using ecmascript::LockHolder;
95 using ecmascript::MemMapAllocator;
96 using ecmascript::Method;
97 using ecmascript::NativeModuleFailureInfo;
98 using ecmascript::Mutex;
99 using ecmascript::ObjectFactory;
100 using ecmascript::OperationResult;
101 using ecmascript::PromiseCapability;
102 using ecmascript::PropertyDescriptor;
103 using ecmascript::Region;
104 using ecmascript::TaggedArray;
105 using ecmascript::base::BuiltinsBase;
106 using ecmascript::base::JsonStringifier;
107 using ecmascript::base::StringHelper;
108 using ecmascript::base::TypedArrayHelper;
109 using ecmascript::base::Utf16JsonParser;
110 using ecmascript::base::Utf8JsonParser;
111 using ecmascript::builtins::BuiltinsObject;
112 using ecmascript::job::MicroJobQueue;
113 using ecmascript::job::QueueType;
114 #ifdef ARK_SUPPORT_INTL
115 using ecmascript::JSCollator;
116 using ecmascript::JSDateTimeFormat;
117 using ecmascript::JSNumberFormat;
118 #endif
119 using ecmascript::DebugInfoExtractor;
120 using ecmascript::EcmaContext;
121 using ecmascript::JSWeakMap;
122 using ecmascript::JSWeakSet;
123 using ecmascript::Log;
124 using ecmascript::PatchErrorCode;
125 using ecmascript::RegExpParser;
126 using ecmascript::base::NumberHelper;
127 template <typename T>
128 using JSHandle = ecmascript::JSHandle<T>;
129 template <typename T>
130 using JSMutableHandle = ecmascript::JSMutableHandle<T>;
131
132 using PathHelper = ecmascript::base::PathHelper;
133 using ModulePathHelper = ecmascript::ModulePathHelper;
134 using JsDebuggerManager = ecmascript::tooling::JsDebuggerManager;
135 using FrameIterator = ecmascript::FrameIterator;
136 using Concurrent = ecmascript::Concurrent;
137 using EnableAotJitListHelper = ecmascript::ohos::EnableAotJitListHelper;
138 using PGOProfilerManager = ecmascript::pgo::PGOProfilerManager;
139 using AotRuntimeInfo = ecmascript::ohos::AotRuntimeInfo;
140
141 namespace {
142 // NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
143 constexpr std::string_view ENTRY_POINTER = "_GLOBAL::func_main_0";
144 }
145
146 int JSNApi::vmCount_ = 0;
147 bool JSNApi::initialize_ = false;
148 static Mutex *mutex = new panda::Mutex();
149 StartIdleMonitorCallback JSNApi::startIdleMonitorCallback_ = nullptr;
150
151 // ----------------------------------- JSValueRef --------------------------------------
Undefined(const EcmaVM * vm)152 Local<PrimitiveRef> JSValueRef::Undefined(const EcmaVM *vm)
153 {
154 return JSNApiHelper::ToLocal<PrimitiveRef>(
155 vm->GetJSThread()->GlobalConstants()->GetHandledUndefined());
156 }
157
Null(const EcmaVM * vm)158 Local<PrimitiveRef> JSValueRef::Null(const EcmaVM *vm)
159 {
160 return JSNApiHelper::ToLocal<PrimitiveRef>(
161 vm->GetJSThread()->GlobalConstants()->GetHandledNull());
162 }
163
Hole(const EcmaVM * vm)164 Local<PrimitiveRef> JSValueRef::Hole(const EcmaVM *vm)
165 {
166 return JSNApiHelper::ToLocal<PrimitiveRef>(
167 vm->GetJSThread()->GlobalConstants()->GetHandledHole());
168 }
169
True(const EcmaVM * vm)170 Local<PrimitiveRef> JSValueRef::True(const EcmaVM *vm)
171 {
172 return JSNApiHelper::ToLocal<PrimitiveRef>(
173 vm->GetJSThread()->GlobalConstants()->GetHandledTrue());
174 }
175
False(const EcmaVM * vm)176 Local<PrimitiveRef> JSValueRef::False(const EcmaVM *vm)
177 {
178 return JSNApiHelper::ToLocal<PrimitiveRef>(
179 vm->GetJSThread()->GlobalConstants()->GetHandledFalse());
180 }
181
ToObject(const EcmaVM * vm)182 Local<ObjectRef> JSValueRef::ToObject(const EcmaVM *vm)
183 {
184 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
185 if (IsUndefined() || IsNull()) {
186 return Undefined(vm);
187 }
188 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
189 JSHandle<JSTaggedValue> obj(JSTaggedValue::ToObject(thread, JSNApiHelper::ToJSHandle(this)));
190 LOG_IF_SPECIAL(obj, ERROR);
191 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
192 return JSNApiHelper::ToLocal<ObjectRef>(obj);
193 }
194
ToEcmaObject(const EcmaVM * vm)195 Local<ObjectRef> JSValueRef::ToEcmaObject(const EcmaVM *vm)
196 {
197 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
198 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
199 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
200 LOG_IF_SPECIAL(obj, ERROR);
201 if (obj->IsECMAObject()) {
202 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
203 return JSNApiHelper::ToLocal<ObjectRef>(obj);
204 }
205
206 return Undefined(vm);
207 }
208
ToString(const EcmaVM * vm)209 Local<StringRef> JSValueRef::ToString(const EcmaVM *vm)
210 {
211 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
212 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
213 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
214 LOG_IF_SPECIAL(obj, ERROR);
215 if (!obj->IsString()) {
216 obj = JSHandle<JSTaggedValue>(JSTaggedValue::ToString(thread, obj));
217 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
218 }
219 return JSNApiHelper::ToLocal<StringRef>(obj);
220 }
221
ToNativePointer(const EcmaVM * vm)222 Local<NativePointerRef> JSValueRef::ToNativePointer(const EcmaVM *vm)
223 {
224 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
225 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
226 // The function just get handle' value, and will not read and write js object. Don't need to switch state.
227 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
228 LOG_IF_SPECIAL(obj, ERROR);
229 return JSNApiHelper::ToLocal<NativePointerRef>(obj);
230 }
231
BooleaValue(const EcmaVM * vm)232 bool JSValueRef::BooleaValue(const EcmaVM *vm)
233 {
234 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
235 return JSNApiHelper::ToJSTaggedValue(this).ToBoolean();
236 }
237
IntegerValue(const EcmaVM * vm)238 int64_t JSValueRef::IntegerValue(const EcmaVM *vm)
239 {
240 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
241 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
242 JSHandle<JSTaggedValue> tagged = JSNApiHelper::ToJSHandle(this);
243 LOG_IF_SPECIAL(tagged, ERROR);
244 if (tagged->IsNumber()) {
245 if (!NumberHelper::IsFinite(tagged.GetTaggedValue()) || NumberHelper::IsNaN(tagged.GetTaggedValue())) {
246 return 0;
247 } else {
248 return NumberHelper::DoubleToInt64(tagged->GetNumber());
249 }
250 }
251 JSTaggedNumber number = JSTaggedValue::ToInteger(thread, tagged);
252 RETURN_VALUE_IF_ABRUPT(thread, 0);
253 return NumberHelper::DoubleToInt64(number.GetNumber());
254 }
255
Uint32Value(const EcmaVM * vm)256 uint32_t JSValueRef::Uint32Value(const EcmaVM *vm)
257 {
258 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
259 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
260 JSHandle<JSTaggedValue> tagged = JSNApiHelper::ToJSHandle(this);
261 uint32_t number = 0;
262 if (!tagged->IsECMAObject()) {
263 number = JSTaggedValue::ToUint32(thread, tagged);
264 } else {
265 // EcmaObject may call [Symbol.toPrimitive].
266 number = JSTaggedValue::ToUint32(thread, tagged);
267 }
268 RETURN_VALUE_IF_ABRUPT(thread, 0);
269 return number;
270 }
271
Int32Value(const EcmaVM * vm)272 int32_t JSValueRef::Int32Value(const EcmaVM *vm)
273 {
274 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
275 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
276 JSHandle<JSTaggedValue> tagged = JSNApiHelper::ToJSHandle(this);
277 int32_t number = 0;
278 if (!tagged->IsECMAObject()) {
279 number = JSTaggedValue::ToInt32(thread, tagged);
280 } else {
281 // EcmaObject may call [Symbol.toPrimitive].
282 number = JSTaggedValue::ToInt32(thread, tagged);
283 }
284 RETURN_VALUE_IF_ABRUPT(thread, 0);
285 return number;
286 }
287
GetValueDouble(bool & isNumber)288 double JSValueRef::GetValueDouble(bool &isNumber)
289 {
290 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
291 if (value.IsInt()) {
292 isNumber = true;
293 return static_cast<double>(value.GetInt());
294 }
295 if (value.IsDouble()) {
296 isNumber = true;
297 return value.GetDouble();
298 }
299 isNumber = false;
300 return 0.0;
301 }
302
GetValueInt32(bool & isNumber)303 int32_t JSValueRef::GetValueInt32(bool &isNumber)
304 {
305 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
306 if (value.IsInt()) {
307 isNumber = true;
308 return value.GetInt();
309 }
310 if (value.IsDouble()) {
311 isNumber = true;
312 return static_cast<int32_t>(ecmascript::base::NumberHelper::DoubleToInt(value.GetDouble(),
313 ecmascript::base::INT32_BITS));
314 }
315 isNumber = false;
316 return 0;
317 }
318
GetValueUint32(bool & isNumber)319 uint32_t JSValueRef::GetValueUint32(bool &isNumber)
320 {
321 return static_cast<uint32_t>(GetValueInt32(isNumber));
322 }
323
GetValueInt64(bool & isNumber)324 int64_t JSValueRef::GetValueInt64(bool &isNumber)
325 {
326 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
327 if (value.IsInt()) {
328 isNumber = true;
329 return static_cast<int64_t>(value.GetInt());
330 }
331 if (value.IsDouble()) {
332 isNumber = true;
333 double getVale = value.GetDouble();
334 if (!std::isfinite(getVale) || std::isnan(getVale)) {
335 return 0;
336 }
337 return NumberHelper::DoubleToInt64(getVale);
338 }
339 isNumber = false;
340 return 0;
341 }
342
GetValueBool(bool & isBool)343 bool JSValueRef::GetValueBool(bool &isBool)
344 {
345 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
346 if (value.IsTrue()) {
347 isBool = true;
348 return true;
349 }
350 if (value.IsFalse()) {
351 isBool = true;
352 return false;
353 }
354 isBool = false;
355 return false;
356 }
357
ToBoolean(const EcmaVM * vm)358 Local<BooleanRef> JSValueRef::ToBoolean(const EcmaVM *vm)
359 {
360 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
361 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
362 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
363 LOG_IF_SPECIAL(obj, ERROR);
364 JSHandle<JSTaggedValue> booleanObj(thread, JSTaggedValue(obj->ToBoolean()));
365 return JSNApiHelper::ToLocal<BooleanRef>(booleanObj);
366 }
367
ToBigInt(const EcmaVM * vm)368 Local<BigIntRef> JSValueRef::ToBigInt(const EcmaVM *vm)
369 {
370 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
371 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
372 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
373 LOG_IF_SPECIAL(obj, ERROR);
374 JSHandle<JSTaggedValue> bigIntObj(thread, JSTaggedValue::ToBigInt(thread, obj));
375 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
376 return JSNApiHelper::ToLocal<BigIntRef>(bigIntObj);
377 }
378
ToNumber(const EcmaVM * vm)379 Local<NumberRef> JSValueRef::ToNumber(const EcmaVM *vm)
380 {
381 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
382 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
383 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
384 LOG_IF_SPECIAL(obj, ERROR);
385 JSHandle<JSTaggedValue> number(thread, JSTaggedValue::ToNumber(thread, obj));
386 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
387 return JSNApiHelper::ToLocal<NumberRef>(number);
388 }
389
IsStrictEquals(const EcmaVM * vm,Local<JSValueRef> value)390 bool JSValueRef::IsStrictEquals(const EcmaVM *vm, Local<JSValueRef> value)
391 {
392 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
393 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
394 JSHandle<JSTaggedValue> xValue = JSNApiHelper::ToJSHandle(this);
395 LOG_IF_SPECIAL(xValue, ERROR);
396 JSHandle<JSTaggedValue> yValue = JSNApiHelper::ToJSHandle(value);
397 return JSTaggedValue::StrictEqual(thread, xValue, yValue);
398 }
399
Typeof(const EcmaVM * vm)400 Local<StringRef> JSValueRef::Typeof(const EcmaVM *vm)
401 {
402 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
403 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
404 JSTaggedValue value = FastRuntimeStub::FastTypeOf(thread, JSNApiHelper::ToJSTaggedValue(this));
405 return JSNApiHelper::ToLocal<StringRef>(JSHandle<JSTaggedValue>(thread, value));
406 }
407
InstanceOf(const EcmaVM * vm,Local<JSValueRef> value)408 bool JSValueRef::InstanceOf(const EcmaVM *vm, Local<JSValueRef> value)
409 {
410 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
411 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
412 JSHandle<JSTaggedValue> origin = JSNApiHelper::ToJSHandle(this);
413 LOG_IF_SPECIAL(origin, ERROR);
414 JSHandle<JSTaggedValue> target = JSNApiHelper::ToJSHandle(value);
415 return JSObject::InstanceOf(thread, origin, target);
416 }
417
418 // Omit exception check for JSValueRef::IsXxx because ark calls here may not
419 // cause side effect even pending exception exists.
IsUndefined()420 bool JSValueRef::IsUndefined()
421 {
422 return JSNApiHelper::ToJSTaggedValue(this).IsUndefined();
423 }
424
IsNull()425 bool JSValueRef::IsNull()
426 {
427 return JSNApiHelper::ToJSTaggedValue(this).IsNull();
428 }
429
IsHole()430 bool JSValueRef::IsHole()
431 {
432 return JSNApiHelper::ToJSTaggedValue(this).IsHole();
433 }
434
IsTrue()435 bool JSValueRef::IsTrue()
436 {
437 return JSNApiHelper::ToJSTaggedValue(this).IsTrue();
438 }
439
IsFalse()440 bool JSValueRef::IsFalse()
441 {
442 return JSNApiHelper::ToJSTaggedValue(this).IsFalse();
443 }
444
IsNumber()445 bool JSValueRef::IsNumber()
446 {
447 return JSNApiHelper::ToJSTaggedValue(this).IsNumber();
448 }
449
IsBigInt(const EcmaVM * vm)450 bool JSValueRef::IsBigInt(const EcmaVM *vm)
451 {
452 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
453 return JSNApiHelper::ToJSTaggedValue(this).IsBigInt();
454 }
455
IsInt()456 bool JSValueRef::IsInt()
457 {
458 return JSNApiHelper::ToJSTaggedValue(this).IsInt();
459 }
460
WithinInt32()461 bool JSValueRef::WithinInt32()
462 {
463 return JSNApiHelper::ToJSTaggedValue(this).WithinInt32();
464 }
465
IsBoolean()466 bool JSValueRef::IsBoolean()
467 {
468 return JSNApiHelper::ToJSTaggedValue(this).IsBoolean();
469 }
470
IsString(const EcmaVM * vm)471 bool JSValueRef::IsString(const EcmaVM *vm)
472 {
473 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
474 return JSNApiHelper::ToJSTaggedValue(this).IsString();
475 }
476
IsSymbol(const EcmaVM * vm)477 bool JSValueRef::IsSymbol(const EcmaVM *vm)
478 {
479 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
480 return JSNApiHelper::ToJSTaggedValue(this).IsSymbol();
481 }
482
IsObject(const EcmaVM * vm)483 bool JSValueRef::IsObject(const EcmaVM *vm)
484 {
485 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
486 return JSNApiHelper::ToJSTaggedValue(this).IsECMAObject();
487 }
488
IsArray(const EcmaVM * vm)489 bool JSValueRef::IsArray(const EcmaVM *vm)
490 {
491 CROSS_THREAD_CHECK(vm);
492 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
493 return JSNApiHelper::ToJSTaggedValue(this).IsArray(thread);
494 }
495
IsJSArray(const EcmaVM * vm)496 bool JSValueRef::IsJSArray(const EcmaVM *vm)
497 {
498 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
499 return JSNApiHelper::ToJSTaggedValue(this).IsJSArray();
500 }
501
IsConstructor(const EcmaVM * vm)502 bool JSValueRef::IsConstructor(const EcmaVM *vm)
503 {
504 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
505 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
506 return value.IsHeapObject() && value.IsConstructor();
507 }
508
IsFunction(const EcmaVM * vm)509 bool JSValueRef::IsFunction(const EcmaVM *vm)
510 {
511 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
512 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
513 return value.IsCallable();
514 }
515
IsJSFunction(const EcmaVM * vm)516 bool JSValueRef::IsJSFunction(const EcmaVM *vm)
517 {
518 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
519 JSTaggedValue value = JSNApiHelper::ToJSTaggedValue(this);
520 return value.IsJSFunction();
521 }
522
IsProxy(const EcmaVM * vm)523 bool JSValueRef::IsProxy(const EcmaVM *vm)
524 {
525 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
526 return JSNApiHelper::ToJSTaggedValue(this).IsJSProxy();
527 }
528
IsPromise(const EcmaVM * vm)529 bool JSValueRef::IsPromise(const EcmaVM *vm)
530 {
531 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
532 return JSNApiHelper::ToJSTaggedValue(this).IsJSPromise();
533 }
534
IsDataView(const EcmaVM * vm)535 bool JSValueRef::IsDataView(const EcmaVM *vm)
536 {
537 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
538 return JSNApiHelper::ToJSTaggedValue(this).IsDataView();
539 }
540
IsTypedArray(const EcmaVM * vm)541 bool JSValueRef::IsTypedArray(const EcmaVM *vm)
542 {
543 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
544 return JSNApiHelper::ToJSTaggedValue(this).IsTypedArray();
545 }
546
IsNativePointer(const EcmaVM * vm)547 bool JSValueRef::IsNativePointer(const EcmaVM *vm)
548 {
549 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
550 return JSNApiHelper::ToJSTaggedValue(this).IsJSNativePointer();
551 }
552
IsDate(const EcmaVM * vm)553 bool JSValueRef::IsDate(const EcmaVM *vm)
554 {
555 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
556 return JSNApiHelper::ToJSTaggedValue(this).IsDate();
557 }
558
IsError(const EcmaVM * vm)559 bool JSValueRef::IsError(const EcmaVM *vm)
560 {
561 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
562 return JSNApiHelper::ToJSTaggedValue(this).IsJSError();
563 }
564
IsMap(const EcmaVM * vm)565 bool JSValueRef::IsMap(const EcmaVM *vm)
566 {
567 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
568 return JSNApiHelper::ToJSTaggedValue(this).IsJSMap();
569 }
570
IsSet(const EcmaVM * vm)571 bool JSValueRef::IsSet(const EcmaVM *vm)
572 {
573 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
574 return JSNApiHelper::ToJSTaggedValue(this).IsJSSet();
575 }
576
IsWeakRef(const EcmaVM * vm)577 bool JSValueRef::IsWeakRef(const EcmaVM *vm)
578 {
579 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
580 return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakRef();
581 }
582
IsWeakMap(const EcmaVM * vm)583 bool JSValueRef::IsWeakMap(const EcmaVM *vm)
584 {
585 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
586 return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakMap();
587 }
588
IsWeakSet(const EcmaVM * vm)589 bool JSValueRef::IsWeakSet(const EcmaVM *vm)
590 {
591 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
592 return JSNApiHelper::ToJSTaggedValue(this).IsJSWeakSet();
593 }
594
IsRegExp(const EcmaVM * vm)595 bool JSValueRef::IsRegExp(const EcmaVM *vm)
596 {
597 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
598 return JSNApiHelper::ToJSTaggedValue(this).IsJSRegExp();
599 }
600
IsArrayIterator(const EcmaVM * vm)601 bool JSValueRef::IsArrayIterator(const EcmaVM *vm)
602 {
603 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
604 return JSNApiHelper::ToJSTaggedValue(this).IsJSArrayIterator();
605 }
606
IsStringIterator(const EcmaVM * vm)607 bool JSValueRef::IsStringIterator(const EcmaVM *vm)
608 {
609 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
610 return JSNApiHelper::ToJSTaggedValue(this).IsStringIterator();
611 }
612
IsSetIterator(const EcmaVM * vm)613 bool JSValueRef::IsSetIterator(const EcmaVM *vm)
614 {
615 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
616 return JSNApiHelper::ToJSTaggedValue(this).IsJSSetIterator();
617 }
618
IsMapIterator(const EcmaVM * vm)619 bool JSValueRef::IsMapIterator(const EcmaVM *vm)
620 {
621 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
622 return JSNApiHelper::ToJSTaggedValue(this).IsJSMapIterator();
623 }
624
IsArrayBuffer(const EcmaVM * vm)625 bool JSValueRef::IsArrayBuffer(const EcmaVM *vm)
626 {
627 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
628 return JSNApiHelper::ToJSTaggedValue(this).IsArrayBuffer();
629 }
630
IsBuffer(const EcmaVM * vm)631 bool JSValueRef::IsBuffer(const EcmaVM *vm)
632 {
633 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
634 return JSNApiHelper::ToJSTaggedValue(this).IsArrayBuffer();
635 }
636
IsUint8Array(const EcmaVM * vm)637 bool JSValueRef::IsUint8Array(const EcmaVM *vm)
638 {
639 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
640 return JSNApiHelper::ToJSTaggedValue(this).IsJSUint8Array();
641 }
642
IsInt8Array(const EcmaVM * vm)643 bool JSValueRef::IsInt8Array(const EcmaVM *vm)
644 {
645 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
646 return JSNApiHelper::ToJSTaggedValue(this).IsJSInt8Array();
647 }
648
IsUint8ClampedArray(const EcmaVM * vm)649 bool JSValueRef::IsUint8ClampedArray(const EcmaVM *vm)
650 {
651 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
652 return JSNApiHelper::ToJSTaggedValue(this).IsJSUint8ClampedArray();
653 }
654
IsInt16Array(const EcmaVM * vm)655 bool JSValueRef::IsInt16Array(const EcmaVM *vm)
656 {
657 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
658 return JSNApiHelper::ToJSTaggedValue(this).IsJSInt16Array();
659 }
660
IsUint16Array(const EcmaVM * vm)661 bool JSValueRef::IsUint16Array(const EcmaVM *vm)
662 {
663 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
664 return JSNApiHelper::ToJSTaggedValue(this).IsJSUint16Array();
665 }
666
IsInt32Array(const EcmaVM * vm)667 bool JSValueRef::IsInt32Array(const EcmaVM *vm)
668 {
669 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
670 return JSNApiHelper::ToJSTaggedValue(this).IsJSInt32Array();
671 }
672
IsUint32Array(const EcmaVM * vm)673 bool JSValueRef::IsUint32Array(const EcmaVM *vm)
674 {
675 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
676 return JSNApiHelper::ToJSTaggedValue(this).IsJSUint32Array();
677 }
678
IsFloat32Array(const EcmaVM * vm)679 bool JSValueRef::IsFloat32Array(const EcmaVM *vm)
680 {
681 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
682 return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat32Array();
683 }
684
IsFloat64Array(const EcmaVM * vm)685 bool JSValueRef::IsFloat64Array(const EcmaVM *vm)
686 {
687 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
688 return JSNApiHelper::ToJSTaggedValue(this).IsJSFloat64Array();
689 }
690
IsBigInt64Array(const EcmaVM * vm)691 bool JSValueRef::IsBigInt64Array(const EcmaVM *vm)
692 {
693 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
694 return JSNApiHelper::ToJSTaggedValue(this).IsJSBigInt64Array();
695 }
696
IsBigUint64Array(const EcmaVM * vm)697 bool JSValueRef::IsBigUint64Array(const EcmaVM *vm)
698 {
699 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
700 return JSNApiHelper::ToJSTaggedValue(this).IsJSBigUint64Array();
701 }
702
IsJSSharedInt8Array(const EcmaVM * vm)703 bool JSValueRef::IsJSSharedInt8Array(const EcmaVM *vm)
704 {
705 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
706 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedInt8Array();
707 }
708
IsJSSharedUint8Array(const EcmaVM * vm)709 bool JSValueRef::IsJSSharedUint8Array([[maybe_unused]]const EcmaVM *vm)
710 {
711 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
712 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint8Array();
713 }
714
IsJSSharedUint8ClampedArray(const EcmaVM * vm)715 bool JSValueRef::IsJSSharedUint8ClampedArray([[maybe_unused]]const EcmaVM *vm)
716 {
717 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
718 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint8ClampedArray();
719 }
720
IsJSSharedInt16Array(const EcmaVM * vm)721 bool JSValueRef::IsJSSharedInt16Array(const EcmaVM *vm)
722 {
723 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
724 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedInt16Array();
725 }
726
IsJSSharedUint16Array(const EcmaVM * vm)727 bool JSValueRef::IsJSSharedUint16Array(const EcmaVM *vm)
728 {
729 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
730 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint16Array();
731 }
732
IsJSSharedInt32Array(const EcmaVM * vm)733 bool JSValueRef::IsJSSharedInt32Array(const EcmaVM *vm)
734 {
735 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
736 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedInt32Array();
737 }
738
IsJSSharedFloat32Array(const EcmaVM * vm)739 bool JSValueRef::IsJSSharedFloat32Array(const EcmaVM *vm)
740 {
741 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
742 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedFloat32Array();
743 }
744
IsJSSharedUint32Array(const EcmaVM * vm)745 bool JSValueRef::IsJSSharedUint32Array(const EcmaVM *vm)
746 {
747 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
748 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedUint32Array();
749 }
750
IsJSPrimitiveRef(const EcmaVM * vm)751 bool JSValueRef::IsJSPrimitiveRef(const EcmaVM *vm)
752 {
753 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
754 return JSNApiHelper::ToJSTaggedValue(this).IsJSPrimitiveRef();
755 }
756
IsJSPrimitiveNumber(const EcmaVM * vm)757 bool JSValueRef::IsJSPrimitiveNumber(const EcmaVM *vm)
758 {
759 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
760 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
761 LOG_IF_SPECIAL(obj, FATAL);
762 return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsNumber();
763 }
764
IsJSPrimitiveInt(const EcmaVM * vm)765 bool JSValueRef::IsJSPrimitiveInt(const EcmaVM *vm)
766 {
767 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
768 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
769 LOG_IF_SPECIAL(obj, FATAL);
770 return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsInt();
771 }
772
IsJSPrimitiveBoolean(const EcmaVM * vm)773 bool JSValueRef::IsJSPrimitiveBoolean(const EcmaVM *vm)
774 {
775 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
776 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
777 LOG_IF_SPECIAL(obj, FATAL);
778 return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsBoolean();
779 }
780
IsJSPrimitiveString(const EcmaVM * vm)781 bool JSValueRef::IsJSPrimitiveString(const EcmaVM *vm)
782 {
783 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
784 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
785 LOG_IF_SPECIAL(obj, FATAL);
786 return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsString();
787 }
788
IsJSPrimitiveSymbol(const EcmaVM * vm)789 bool JSValueRef::IsJSPrimitiveSymbol(const EcmaVM *vm)
790 {
791 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
792 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
793 LOG_IF_SPECIAL(obj, FATAL);
794 return JSPrimitiveRef::Cast(obj->GetTaggedObject())->IsSymbol();
795 }
796
IsGeneratorObject(const EcmaVM * vm)797 bool JSValueRef::IsGeneratorObject(const EcmaVM *vm)
798 {
799 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
800 return JSNApiHelper::ToJSTaggedValue(this).IsGeneratorObject();
801 }
802
IsModuleNamespaceObject(const EcmaVM * vm)803 bool JSValueRef::IsModuleNamespaceObject(const EcmaVM *vm)
804 {
805 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
806 return JSNApiHelper::ToJSTaggedValue(this).IsModuleNamespace();
807 }
808
IsNativeModuleFailureInfoObject(const EcmaVM * vm)809 bool JSValueRef::IsNativeModuleFailureInfoObject(const EcmaVM *vm)
810 {
811 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
812 return JSNApiHelper::ToJSTaggedValue(this).IsNativeModuleFailureInfo();
813 }
814
IsSharedArrayBuffer(const EcmaVM * vm)815 bool JSValueRef::IsSharedArrayBuffer(const EcmaVM *vm)
816 {
817 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
818 return JSNApiHelper::ToJSTaggedValue(this).IsSharedArrayBuffer();
819 }
820
IsSendableArrayBuffer(const EcmaVM * vm)821 bool JSValueRef::IsSendableArrayBuffer(const EcmaVM *vm)
822 {
823 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
824 return JSNApiHelper::ToJSTaggedValue(this).IsSendableArrayBuffer();
825 }
826
IsJSLocale(const EcmaVM * vm)827 bool JSValueRef::IsJSLocale(const EcmaVM *vm)
828 {
829 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
830 return JSNApiHelper::ToJSTaggedValue(this).IsJSLocale();
831 }
832
IsJSDateTimeFormat(const EcmaVM * vm)833 bool JSValueRef::IsJSDateTimeFormat(const EcmaVM *vm)
834 {
835 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
836 return JSNApiHelper::ToJSTaggedValue(this).IsJSDateTimeFormat();
837 }
838
IsJSRelativeTimeFormat(const EcmaVM * vm)839 bool JSValueRef::IsJSRelativeTimeFormat(const EcmaVM *vm)
840 {
841 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
842 return JSNApiHelper::ToJSTaggedValue(this).IsJSRelativeTimeFormat();
843 }
844
IsJSIntl(const EcmaVM * vm)845 bool JSValueRef::IsJSIntl(const EcmaVM *vm)
846 {
847 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
848 return JSNApiHelper::ToJSTaggedValue(this).IsJSIntl();
849 }
850
IsJSNumberFormat(const EcmaVM * vm)851 bool JSValueRef::IsJSNumberFormat(const EcmaVM *vm)
852 {
853 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
854 return JSNApiHelper::ToJSTaggedValue(this).IsJSNumberFormat();
855 }
856
IsJSCollator(const EcmaVM * vm)857 bool JSValueRef::IsJSCollator(const EcmaVM *vm)
858 {
859 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
860 return JSNApiHelper::ToJSTaggedValue(this).IsJSCollator();
861 }
862
IsJSPluralRules(const EcmaVM * vm)863 bool JSValueRef::IsJSPluralRules(const EcmaVM *vm)
864 {
865 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
866 return JSNApiHelper::ToJSTaggedValue(this).IsJSPluralRules();
867 }
868
IsJSListFormat(const EcmaVM * vm)869 bool JSValueRef::IsJSListFormat(const EcmaVM *vm)
870 {
871 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
872 return JSNApiHelper::ToJSTaggedValue(this).IsJSListFormat();
873 }
874
IsAsyncGeneratorObject(const EcmaVM * vm)875 bool JSValueRef::IsAsyncGeneratorObject(const EcmaVM *vm)
876 {
877 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
878 return JSNApiHelper::ToJSTaggedValue(this).IsAsyncGeneratorObject();
879 }
880
IsAsyncFunction(const EcmaVM * vm)881 bool JSValueRef::IsAsyncFunction(const EcmaVM *vm)
882 {
883 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
884 return JSNApiHelper::ToJSTaggedValue(this).IsJSAsyncFunction();
885 }
886
IsConcurrentFunction(const EcmaVM * vm)887 bool JSValueRef::IsConcurrentFunction(const EcmaVM *vm)
888 {
889 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
890 JSHandle<JSTaggedValue> funcVal = JSNApiHelper::ToJSHandle(this);
891 JSHandle<JSFunction> transFunc = JSHandle<JSFunction>::Cast(funcVal);
892 return transFunc->GetFunctionKind() == ecmascript::FunctionKind::CONCURRENT_FUNCTION;
893 }
894
IsArgumentsObject(const EcmaVM * vm)895 bool JSValueRef::IsArgumentsObject(const EcmaVM *vm)
896 {
897 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
898 return JSNApiHelper::ToJSTaggedValue(this).IsArguments();
899 }
900
IsGeneratorFunction(const EcmaVM * vm)901 bool JSValueRef::IsGeneratorFunction(const EcmaVM *vm)
902 {
903 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
904 return JSNApiHelper::ToJSTaggedValue(this).IsGeneratorFunction();
905 }
906
IsAsyncGeneratorFunction(const EcmaVM * vm)907 bool JSValueRef::IsAsyncGeneratorFunction(const EcmaVM *vm)
908 {
909 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
910 return JSNApiHelper::ToJSTaggedValue(this).IsAsyncGeneratorFunction();
911 }
912
IsArrayList(const EcmaVM * vm)913 bool JSValueRef::IsArrayList(const EcmaVM *vm)
914 {
915 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
916 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIArrayList();
917 }
918
IsDeque(const EcmaVM * vm)919 bool JSValueRef::IsDeque(const EcmaVM *vm)
920 {
921 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
922 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIDeque();
923 }
924
IsHashMap(const EcmaVM * vm)925 bool JSValueRef::IsHashMap(const EcmaVM *vm)
926 {
927 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
928 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIHashMap();
929 }
930
IsHashSet(const EcmaVM * vm)931 bool JSValueRef::IsHashSet(const EcmaVM *vm)
932 {
933 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
934 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIHashSet();
935 }
936
IsLightWeightMap(const EcmaVM * vm)937 bool JSValueRef::IsLightWeightMap(const EcmaVM *vm)
938 {
939 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
940 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPILightWeightMap();
941 }
942
IsLightWeightSet(const EcmaVM * vm)943 bool JSValueRef::IsLightWeightSet(const EcmaVM *vm)
944 {
945 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
946 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPILightWeightSet();
947 }
948
IsLinkedList(const EcmaVM * vm)949 bool JSValueRef::IsLinkedList(const EcmaVM *vm)
950 {
951 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
952 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPILinkedList();
953 }
954
IsLinkedListIterator(const EcmaVM * vm)955 bool JSValueRef::IsLinkedListIterator(const EcmaVM *vm)
956 {
957 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
958 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPILinkedListIterator();
959 }
960
IsList(const EcmaVM * vm)961 bool JSValueRef::IsList(const EcmaVM *vm)
962 {
963 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
964 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIList();
965 }
966
IsPlainArray(const EcmaVM * vm)967 bool JSValueRef::IsPlainArray(const EcmaVM *vm)
968 {
969 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
970 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIPlainArray();
971 }
972
IsQueue(const EcmaVM * vm)973 bool JSValueRef::IsQueue(const EcmaVM *vm)
974 {
975 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
976 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIQueue();
977 }
978
IsStack(const EcmaVM * vm)979 bool JSValueRef::IsStack(const EcmaVM *vm)
980 {
981 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
982 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIStack();
983 }
984
IsTreeMap(const EcmaVM * vm)985 bool JSValueRef::IsTreeMap(const EcmaVM *vm)
986 {
987 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
988 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPITreeMap();
989 }
990
IsTreeSet(const EcmaVM * vm)991 bool JSValueRef::IsTreeSet(const EcmaVM *vm)
992 {
993 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
994 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPITreeSet();
995 }
996
IsVector(const EcmaVM * vm)997 bool JSValueRef::IsVector(const EcmaVM *vm)
998 {
999 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1000 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIVector();
1001 }
1002
IsBitVector(const EcmaVM * vm)1003 bool JSValueRef::IsBitVector(const EcmaVM *vm)
1004 {
1005 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1006 return JSNApiHelper::ToJSTaggedValue(this).IsJSAPIBitVector();
1007 }
1008
IsSendableObject(const EcmaVM * vm)1009 bool JSValueRef::IsSendableObject(const EcmaVM *vm)
1010 {
1011 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1012 return IsJSShared(vm) && IsObject(vm);
1013 }
1014
IsJSShared(const EcmaVM * vm)1015 bool JSValueRef::IsJSShared(const EcmaVM *vm)
1016 {
1017 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1018 return JSNApiHelper::ToJSTaggedValue(this).IsJSShared();
1019 }
1020
IsSharedArray(const EcmaVM * vm)1021 bool JSValueRef::IsSharedArray(const EcmaVM *vm)
1022 {
1023 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1024 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedArray();
1025 }
1026
IsSharedTypedArray(const EcmaVM * vm)1027 bool JSValueRef::IsSharedTypedArray(const EcmaVM *vm)
1028 {
1029 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1030 return JSNApiHelper::ToJSTaggedValue(this).IsSharedTypedArray();
1031 }
1032
IsSharedSet(const EcmaVM * vm)1033 bool JSValueRef::IsSharedSet(const EcmaVM *vm)
1034 {
1035 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1036 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedSet();
1037 }
1038
IsSharedMap(const EcmaVM * vm)1039 bool JSValueRef::IsSharedMap(const EcmaVM *vm)
1040 {
1041 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1042 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedMap();
1043 }
1044
IsSharedMapIterator(const EcmaVM * vm)1045 bool JSValueRef::IsSharedMapIterator(const EcmaVM *vm)
1046 {
1047 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1048 return JSNApiHelper::ToJSTaggedValue(this).IsJSSharedMapIterator();
1049 }
1050
IsHeapObject()1051 bool JSValueRef::IsHeapObject()
1052 {
1053 return JSNApiHelper::ToJSTaggedValue(this).IsHeapObject();
1054 }
1055
GetNativePointerValue(const EcmaVM * vm,bool & isNativePointer)1056 void *JSValueRef::GetNativePointerValue(const EcmaVM* vm, bool &isNativePointer)
1057 {
1058 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1059 if (IsJSShared(vm)) {
1060 return GetNativePointerValueImpl(vm, isNativePointer);
1061 } else {
1062 return GetNativePointerValueImpl(vm, isNativePointer);
1063 }
1064 }
1065
1066 // private
GetNativePointerValueImpl(const EcmaVM * vm,bool & isNativePointer)1067 void *JSValueRef::GetNativePointerValueImpl(const EcmaVM* vm, bool &isNativePointer)
1068 {
1069 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1070 if (!IsNativePointer(vm)) {
1071 isNativePointer = false;
1072 return nullptr;
1073 }
1074 isNativePointer = true;
1075 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
1076 JSHandle<JSTaggedValue> nativePointer = JSNApiHelper::ToJSHandle(this);
1077 return JSHandle<JSNativePointer>(nativePointer)->GetExternalPointer();
1078 }
1079
IsDetachedArraybuffer(const EcmaVM * vm,bool & isArrayBuffer)1080 bool JSValueRef::IsDetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer)
1081 {
1082 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1083 // arraybuffer is not shared. Do not need to switch state
1084 if (!IsArrayBuffer(vm)) {
1085 isArrayBuffer = false;
1086 return false;
1087 }
1088 isArrayBuffer = true;
1089 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1090 return arrayBuffer->IsDetach();
1091 }
1092
DetachedArraybuffer(const EcmaVM * vm,bool & isArrayBuffer)1093 void JSValueRef::DetachedArraybuffer(const EcmaVM *vm, bool &isArrayBuffer)
1094 {
1095 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1096 if (IsArrayBuffer(vm)) {
1097 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1098 if (arrayBuffer->IsDetach()) {
1099 return;
1100 }
1101 arrayBuffer->Detach(vm->GetJSThread());
1102 isArrayBuffer = true;
1103 } else if (IsSendableArrayBuffer(vm)) {
1104 JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1105 if (arrayBuffer->IsDetach()) {
1106 return;
1107 }
1108 arrayBuffer->Detach(vm->GetJSThread());
1109 isArrayBuffer = true;
1110 } else {
1111 isArrayBuffer = false;
1112 }
1113 }
1114
GetDataViewInfo(const EcmaVM * vm,bool & isDataView,size_t * byteLength,void ** data,JSValueRef ** arrayBuffer,size_t * byteOffset)1115 void JSValueRef::GetDataViewInfo(const EcmaVM *vm,
1116 bool &isDataView,
1117 size_t *byteLength,
1118 void **data,
1119 JSValueRef **arrayBuffer,
1120 size_t *byteOffset)
1121 {
1122 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1123 if (!IsDataView(vm)) {
1124 isDataView = false;
1125 return;
1126 }
1127 isDataView = true;
1128 JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1129
1130 if (byteLength) {
1131 *byteLength = dataView->GetByteLength();
1132 }
1133 if (data || arrayBuffer) {
1134 JSThread* thread = vm->GetJSThread();
1135 JSHandle<JSArrayBuffer> retArrayBuffer(thread, dataView->GetViewedArrayBuffer());
1136 if (data) {
1137 JSTaggedValue bufferData = retArrayBuffer->GetArrayBufferData();
1138 if (!bufferData.IsJSNativePointer()) {
1139 *data = nullptr;
1140 }
1141 *data = JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
1142 }
1143 if (arrayBuffer) {
1144 *arrayBuffer = reinterpret_cast<JSValueRef*>(retArrayBuffer.GetAddress());
1145 }
1146 }
1147 if (byteOffset) {
1148 *byteOffset = dataView->GetByteOffset();
1149 }
1150 }
1151
1152 // ---------------------------------- DataView -----------------------------------
New(const EcmaVM * vm,Local<ArrayBufferRef> arrayBuffer,uint32_t byteOffset,uint32_t byteLength)1153 Local<DataViewRef> DataViewRef::New(
1154 const EcmaVM *vm, Local<ArrayBufferRef> arrayBuffer, uint32_t byteOffset, uint32_t byteLength)
1155 {
1156 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1157 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1158 ObjectFactory *factory = vm->GetFactory();
1159
1160 JSHandle<JSArrayBuffer> buffer(JSNApiHelper::ToJSHandle(arrayBuffer));
1161 JSHandle<JSDataView> dataView = factory->NewJSDataView(buffer, byteOffset, byteLength);
1162 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1163 return JSNApiHelper::ToLocal<DataViewRef>(JSHandle<JSTaggedValue>(dataView));
1164 }
1165
ByteLength()1166 uint32_t DataViewRef::ByteLength()
1167 {
1168 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1169 JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1170 return dataView->GetByteLength();
1171 }
1172
ByteOffset()1173 uint32_t DataViewRef::ByteOffset()
1174 {
1175 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1176 JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1177 return dataView->GetByteOffset();
1178 }
1179
GetArrayBuffer(const EcmaVM * vm)1180 Local<ArrayBufferRef> DataViewRef::GetArrayBuffer(const EcmaVM *vm)
1181 {
1182 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1183 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1184 JSHandle<JSDataView> dataView(JSNApiHelper::ToJSHandle(this));
1185 LOG_IF_SPECIAL(dataView, FATAL);
1186 JSHandle<JSTaggedValue> arrayBuffer(thread, dataView->GetViewedArrayBuffer());
1187 return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer);
1188 }
1189 // ---------------------------------- DataView -----------------------------------
1190
1191 // ----------------------------------- PritimitiveRef ---------------------------------------
GetValue(const EcmaVM * vm)1192 Local<JSValueRef> PrimitiveRef::GetValue(const EcmaVM *vm)
1193 {
1194 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1195 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1196 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
1197 LOG_IF_SPECIAL(obj, ERROR);
1198 if (obj->IsJSPrimitiveRef()) {
1199 JSTaggedValue primitiveValue = JSPrimitiveRef::Cast(obj->GetTaggedObject())->GetValue();
1200 JSHandle<JSTaggedValue> value(thread, primitiveValue);
1201 return JSNApiHelper::ToLocal<JSValueRef>(value);
1202 }
1203 return Local<JSValueRef>();
1204 }
1205
1206 // ----------------------------------- NumberRef ---------------------------------------
New(const EcmaVM * vm,double input)1207 Local<NumberRef> NumberRef::New(const EcmaVM *vm, double input)
1208 {
1209 // Omit exception check because ark calls here may not
1210 // cause side effect even pending exception exists.
1211 CROSS_THREAD_CHECK(vm);
1212 if (std::isnan(input)) {
1213 input = ecmascript::base::NAN_VALUE;
1214 }
1215 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
1216 return JSNApiHelper::ToLocal<NumberRef>(number);
1217 }
1218
New(const EcmaVM * vm,int32_t input)1219 Local<NumberRef> NumberRef::New(const EcmaVM *vm, int32_t input)
1220 {
1221 // Omit exception check because ark calls here may not
1222 // cause side effect even pending exception exists.
1223 CROSS_THREAD_CHECK(vm);
1224 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
1225 return JSNApiHelper::ToLocal<NumberRef>(number);
1226 }
1227
New(const EcmaVM * vm,uint32_t input)1228 Local<NumberRef> NumberRef::New(const EcmaVM *vm, uint32_t input)
1229 {
1230 // Omit exception check because ark calls here may not
1231 // cause side effect even pending exception exists.
1232 CROSS_THREAD_CHECK(vm);
1233 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
1234 return JSNApiHelper::ToLocal<NumberRef>(number);
1235 }
1236
New(const EcmaVM * vm,int64_t input)1237 Local<NumberRef> NumberRef::New(const EcmaVM *vm, int64_t input)
1238 {
1239 // Omit exception check because ark calls here may not
1240 // cause side effect even pending exception exists.
1241 CROSS_THREAD_CHECK(vm);
1242 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
1243 return JSNApiHelper::ToLocal<NumberRef>(number);
1244 }
1245
Value()1246 double NumberRef::Value()
1247 {
1248 // Omit exception check because ark calls here may not
1249 // cause side effect even pending exception exists.
1250 return JSTaggedNumber(JSNApiHelper::ToJSTaggedValue(this)).GetNumber();
1251 }
1252
1253 // ----------------------------------- MapRef ---------------------------------------
Get(const EcmaVM * vm,Local<JSValueRef> key)1254 Local<JSValueRef> MapRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
1255 {
1256 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1257 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1258 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1259 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread,
1260 map->Get(thread, JSNApiHelper::ToJSTaggedValue(*key))));
1261 }
1262
Get(const EcmaVM * vm,const char * utf8)1263 Local<JSValueRef> MapRef::Get(const EcmaVM *vm, const char *utf8)
1264 {
1265 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1266 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1267 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1268 ObjectFactory *factory = vm->GetFactory();
1269 JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1270 auto result = JSHandle<JSTaggedValue>(thread, map->Get(thread, key.GetTaggedValue()));
1271 return JSNApiHelper::ToLocal<JSValueRef>(result);
1272 }
1273
Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)1274 void MapRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
1275 {
1276 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1277 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1278 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1279 JSMap::Set(thread, map, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
1280 }
1281
Set(const EcmaVM * vm,const char * utf8,Local<JSValueRef> value)1282 void MapRef::Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
1283 {
1284 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1285 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1286 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1287 ObjectFactory *factory = vm->GetFactory();
1288 JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1289 JSMap::Set(thread, map, key, JSNApiHelper::ToJSHandle(value));
1290 }
1291
Has(const EcmaVM * vm,Local<JSValueRef> key)1292 bool MapRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
1293 {
1294 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1295 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1296 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1297 bool result = map->Has(thread, JSNApiHelper::ToJSTaggedValue(*key));
1298 return result;
1299 }
1300
Has(const EcmaVM * vm,const char * utf8)1301 bool MapRef::Has(const EcmaVM *vm, const char *utf8)
1302 {
1303 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1304 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1305 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1306 ObjectFactory *factory = vm->GetFactory();
1307 JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1308 bool result = map->Has(thread, key.GetTaggedValue());
1309 return result;
1310 }
1311
Delete(const EcmaVM * vm,Local<JSValueRef> key)1312 void MapRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
1313 {
1314 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1315 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1316 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1317 JSMap::Delete(thread, map, JSNApiHelper::ToJSHandle(key));
1318 }
1319
Clear(const EcmaVM * vm)1320 void MapRef::Clear(const EcmaVM *vm)
1321 {
1322 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1323 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1324 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1325 JSMap::Clear(thread, map);
1326 }
1327
New(const EcmaVM * vm)1328 Local<MapRef> MapRef::New(const EcmaVM *vm)
1329 {
1330 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1331 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1332 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1333 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1334 JSHandle<JSTaggedValue> constructor = env->GetBuiltinsMapFunction();
1335 JSHandle<JSMap> map =
1336 JSHandle<JSMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
1337 JSHandle<LinkedHashMap> hashMap = LinkedHashMap::Create(thread);
1338 map->SetLinkedMap(thread, hashMap);
1339 JSHandle<JSTaggedValue> mapTag = JSHandle<JSTaggedValue>::Cast(map);
1340 return JSNApiHelper::ToLocal<MapRef>(mapTag);
1341 }
1342
GetSize(const EcmaVM * vm)1343 int32_t MapRef::GetSize(const EcmaVM *vm)
1344 {
1345 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1346 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1347 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1348 return map->GetSize();
1349 }
1350
GetTotalElements(const EcmaVM * vm)1351 int32_t MapRef::GetTotalElements(const EcmaVM *vm)
1352 {
1353 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1354 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1355 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1356 return static_cast<int>((map->GetSize())) +
1357 LinkedHashMap::Cast(map->GetLinkedMap().GetTaggedObject())->NumberOfDeletedElements();
1358 }
1359
GetKey(const EcmaVM * vm,int entry)1360 Local<JSValueRef> MapRef::GetKey(const EcmaVM *vm, int entry)
1361 {
1362 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1363 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1364 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1365 LOG_IF_SPECIAL(map, FATAL);
1366 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, map->GetKey(entry)));
1367 }
1368
GetValue(const EcmaVM * vm,int entry)1369 Local<JSValueRef> MapRef::GetValue(const EcmaVM *vm, int entry)
1370 {
1371 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1372 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1373 JSHandle<JSMap> map(JSNApiHelper::ToJSHandle(this));
1374 LOG_IF_SPECIAL(map, FATAL);
1375 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, map->GetValue(entry)));
1376 }
1377
GetEntries(const EcmaVM * vm)1378 Local<MapIteratorRef> MapRef::GetEntries(const EcmaVM *vm)
1379 {
1380 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1381 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1382 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1383 JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1384 JSHandle<JSTaggedValue> mapIter =
1385 ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::KEY_AND_VALUE);
1386 return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
1387 }
1388
GetKeys(const EcmaVM * vm)1389 Local<MapIteratorRef> MapRef::GetKeys(const EcmaVM *vm)
1390 {
1391 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1392 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1393 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1394 JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1395 JSHandle<JSTaggedValue> mapIter = ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::KEY);
1396 return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
1397 }
1398
GetValues(const EcmaVM * vm)1399 Local<MapIteratorRef> MapRef::GetValues(const EcmaVM *vm)
1400 {
1401 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1402 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1403 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1404 JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1405 JSHandle<JSTaggedValue> mapIter = ecmascript::JSMapIterator::CreateMapIterator(thread, map, IterationKind::VALUE);
1406 return JSNApiHelper::ToLocal<MapIteratorRef>(mapIter);
1407 }
1408
1409 // SendableMapRef
New(const EcmaVM * vm)1410 Local<SendableMapRef> SendableMapRef::New(const EcmaVM *vm)
1411 {
1412 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1413 ecmascript::ThreadManagedScope managedScope(thread);
1414 ObjectFactory *factory = vm->GetFactory();
1415 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1416 JSHandle<JSTaggedValue> constructor = env->GetSBuiltininMapFunction();
1417 ASSERT(constructor->IsJSSharedFunction() && constructor.GetTaggedValue().IsInSharedHeap());
1418 JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor);
1419 ASSERT(obj.GetTaggedValue().IsInSharedHeap());
1420 JSHandle<ecmascript::JSSharedMap> sharedMap = JSHandle<ecmascript::JSSharedMap>::Cast(obj);
1421 JSHandle<LinkedHashMap> linkedMap =
1422 LinkedHashMap::Create(thread, LinkedHashMap::MIN_CAPACITY, ecmascript::MemSpaceKind::SHARED);
1423 sharedMap->SetLinkedMap(thread, linkedMap);
1424 JSHandle<JSTaggedValue> sharedMapTag = JSHandle<JSTaggedValue>::Cast(sharedMap);
1425 return JSNApiHelper::ToLocal<SendableMapRef>(sharedMapTag);
1426 }
1427
Get(const EcmaVM * vm,Local<JSValueRef> key)1428 Local<JSValueRef> SendableMapRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
1429 {
1430 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1431 ecmascript::ThreadManagedScope managedScope(thread);
1432 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1433 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread,
1434 ecmascript::JSSharedMap::Get(thread, map, JSNApiHelper::ToJSTaggedValue(*key))));
1435 }
1436
Get(const EcmaVM * vm,const char * utf8)1437 Local<JSValueRef> SendableMapRef::Get(const EcmaVM *vm, const char *utf8)
1438 {
1439 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1440 ecmascript::ThreadManagedScope managedScope(thread);
1441 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1442 ObjectFactory *factory = vm->GetFactory();
1443 JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1444 auto result = JSHandle<JSTaggedValue>(thread, ecmascript::JSSharedMap::Get(thread, map, key.GetTaggedValue()));
1445 return JSNApiHelper::ToLocal<JSValueRef>(result);
1446 }
1447
Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)1448 void SendableMapRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
1449 {
1450 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1451 ecmascript::ThreadManagedScope managedScope(thread);
1452 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1453 ecmascript::JSSharedMap::Set(thread, map, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
1454 }
1455
Set(const EcmaVM * vm,const char * utf8,Local<JSValueRef> value)1456 void SendableMapRef::Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
1457 {
1458 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1459 ecmascript::ThreadManagedScope managedScope(thread);
1460 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1461 ObjectFactory *factory = vm->GetFactory();
1462 JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1463 ecmascript::JSSharedMap::Set(thread, map, key, JSNApiHelper::ToJSHandle(value));
1464 }
1465
Has(const EcmaVM * vm,Local<JSValueRef> key)1466 bool SendableMapRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
1467 {
1468 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1469 ecmascript::ThreadManagedScope managedScope(thread);
1470 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1471 bool result = ecmascript::JSSharedMap::Has(thread, map, JSNApiHelper::ToJSTaggedValue(*key));
1472 return result;
1473 }
1474
Has(const EcmaVM * vm,const char * utf8)1475 bool SendableMapRef::Has(const EcmaVM *vm, const char *utf8)
1476 {
1477 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1478 ecmascript::ThreadManagedScope managedScope(thread);
1479 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1480 ObjectFactory *factory = vm->GetFactory();
1481 JSHandle<JSTaggedValue> key(factory->NewFromUtf8(utf8));
1482 bool result = ecmascript::JSSharedMap::Has(thread, map, key.GetTaggedValue());
1483 return result;
1484 }
1485
Delete(const EcmaVM * vm,Local<JSValueRef> key)1486 void SendableMapRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
1487 {
1488 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1489 ecmascript::ThreadManagedScope managedScope(thread);
1490 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1491 ecmascript::JSSharedMap::Delete(thread, map, JSNApiHelper::ToJSHandle(key));
1492 }
1493
Clear(const EcmaVM * vm)1494 void SendableMapRef::Clear(const EcmaVM *vm)
1495 {
1496 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1497 ecmascript::ThreadManagedScope managedScope(thread);
1498 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1499 ecmascript::JSSharedMap::Clear(thread, map);
1500 }
1501
GetSize(const EcmaVM * vm)1502 uint32_t SendableMapRef::GetSize(const EcmaVM *vm)
1503 {
1504 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
1505 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1506 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1507 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1508 return ecmascript::JSSharedMap::GetSize(thread, map);
1509 }
1510
GetTotalElements(const EcmaVM * vm)1511 uint32_t SendableMapRef::GetTotalElements(const EcmaVM *vm)
1512 {
1513 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
1514 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1515 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1516 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1517 return static_cast<int>(ecmascript::JSSharedMap::GetSize(thread, map)) +
1518 LinkedHashMap::Cast(map->GetLinkedMap().GetTaggedObject())->NumberOfDeletedElements();
1519 }
1520
GetKey(const EcmaVM * vm,int entry)1521 Local<JSValueRef> SendableMapRef::GetKey(const EcmaVM *vm, int entry)
1522 {
1523 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1524 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1525 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1526 LOG_IF_SPECIAL(map, FATAL);
1527 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread,
1528 ecmascript::JSSharedMap::GetKey(thread, map, entry)));
1529 }
1530
GetValue(const EcmaVM * vm,int entry)1531 Local<JSValueRef> SendableMapRef::GetValue(const EcmaVM *vm, int entry)
1532 {
1533 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1534 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1535 JSHandle<ecmascript::JSSharedMap> map(JSNApiHelper::ToJSHandle(this));
1536 LOG_IF_SPECIAL(map, FATAL);
1537 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread,
1538 ecmascript::JSSharedMap::GetValue(thread, map, entry)));
1539 }
1540
GetEntries(const EcmaVM * vm)1541 Local<SendableMapIteratorRef> SendableMapRef::GetEntries(const EcmaVM *vm)
1542 {
1543 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1544 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1545 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1546 JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1547 JSHandle<JSTaggedValue> sharedMapIter =
1548 ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::KEY_AND_VALUE);
1549 return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
1550 }
1551
GetKeys(const EcmaVM * vm)1552 Local<SendableMapIteratorRef> SendableMapRef::GetKeys(const EcmaVM *vm)
1553 {
1554 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1555 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1556 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1557 JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1558 JSHandle<JSTaggedValue> sharedMapIter =
1559 ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::KEY);
1560 return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
1561 }
1562
GetValues(const EcmaVM * vm)1563 Local<SendableMapIteratorRef> SendableMapRef::GetValues(const EcmaVM *vm)
1564 {
1565 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1566 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, JSValueRef::Undefined(vm));
1567 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1568 JSHandle<ecmascript::JSTaggedValue> map(JSNApiHelper::ToJSHandle(this));
1569 JSHandle<JSTaggedValue> sharedMapIter =
1570 ecmascript::JSSharedMapIterator::CreateMapIterator(thread, map, IterationKind::VALUE);
1571 return JSNApiHelper::ToLocal<SendableMapIteratorRef>(sharedMapIter);
1572 }
1573
1574 // SendableSetRef
New(const EcmaVM * vm)1575 Local<SendableSetRef> SendableSetRef::New(const EcmaVM *vm)
1576 {
1577 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1578 ecmascript::ThreadManagedScope managedScope(thread);
1579 ObjectFactory *factory = vm->GetFactory();
1580 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1581 JSHandle<JSTaggedValue> constructor = env->GetSBuiltininSetFunction();
1582 ASSERT(constructor->IsJSSharedFunction() && constructor.GetTaggedValue().IsInSharedHeap());
1583 JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor);
1584 ASSERT(obj.GetTaggedValue().IsInSharedHeap());
1585 JSHandle<ecmascript::JSSharedSet> set = JSHandle<ecmascript::JSSharedSet>::Cast(obj);
1586 JSHandle<LinkedHashSet> linkedSet =
1587 LinkedHashSet::Create(thread, LinkedHashSet::MIN_CAPACITY, ecmascript::MemSpaceKind::SHARED);
1588 set->SetLinkedSet(thread, linkedSet);
1589 JSHandle<JSTaggedValue> sharedSetTag = JSHandle<JSTaggedValue>::Cast(set);
1590 return JSNApiHelper::ToLocal<SendableSetRef>(sharedSetTag);
1591 }
1592
GetSize(const EcmaVM * vm)1593 uint32_t SendableSetRef::GetSize(const EcmaVM *vm)
1594 {
1595 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
1596 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1597 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1598 JSHandle<ecmascript::JSSharedSet> set(JSNApiHelper::ToJSHandle(this));
1599 return ecmascript::JSSharedSet::GetSize(thread, set);
1600 }
1601
GetTotalElements(const EcmaVM * vm)1602 uint32_t SendableSetRef::GetTotalElements(const EcmaVM *vm)
1603 {
1604 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
1605 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1606 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1607 JSHandle<ecmascript::JSSharedSet> set(JSNApiHelper::ToJSHandle(this));
1608 return static_cast<int>(ecmascript::JSSharedSet::GetSize(thread, set)) +
1609 LinkedHashSet::Cast(set->GetLinkedSet().GetTaggedObject())->NumberOfDeletedElements();
1610 }
1611
GetValue(const EcmaVM * vm,int entry)1612 Local<JSValueRef> SendableSetRef::GetValue(const EcmaVM *vm, int entry)
1613 {
1614 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1615 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1616 JSHandle<ecmascript::JSSharedSet> set(JSNApiHelper::ToJSHandle(this));
1617 LOG_IF_SPECIAL(set, FATAL);
1618 return JSNApiHelper::ToLocal<JSValueRef>(
1619 JSHandle<JSTaggedValue>(thread, ecmascript::JSSharedSet::GetValue(thread, set, entry)));
1620 }
1621
Add(const EcmaVM * vm,Local<JSValueRef> value)1622 void SendableSetRef::Add(const EcmaVM *vm, Local<JSValueRef> value)
1623 {
1624 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
1625 ecmascript::ThreadManagedScope managedScope(thread);
1626 JSHandle<ecmascript::JSSharedSet> set(JSNApiHelper::ToJSHandle(this));
1627 LOG_IF_SPECIAL(set, FATAL);
1628 ecmascript::JSSharedSet::Add(thread, set, JSNApiHelper::ToJSHandle(value));
1629 }
1630
1631 // ----------------------------------- MapIteratorRef ---------------------------------------
GetIndex()1632 int32_t MapIteratorRef::GetIndex()
1633 {
1634 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, -1);
1635 JSHandle<JSMapIterator> jsMapIter(JSNApiHelper::ToJSHandle(this));
1636 return jsMapIter->GetNextIndex();
1637 }
1638
GetKind(const EcmaVM * vm)1639 Local<JSValueRef> MapIteratorRef::GetKind(const EcmaVM *vm)
1640 {
1641 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1642 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1643 JSHandle<JSMapIterator> jsMapIter(JSNApiHelper::ToJSHandle(this));
1644 LOG_IF_SPECIAL(jsMapIter, FATAL);
1645 IterationKind iterKind = jsMapIter->GetIterationKind();
1646 Local<JSValueRef> result;
1647 const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1648 switch (iterKind) {
1649 case IterationKind::KEY:
1650 result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledKeysString());
1651 break;
1652 case IterationKind::VALUE:
1653 result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledValuesString());
1654 break;
1655 case IterationKind::KEY_AND_VALUE:
1656 result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledEntriesString());
1657 break;
1658 default:
1659 break;
1660 }
1661 return result;
1662 }
1663
New(const EcmaVM * vm,Local<MapRef> map)1664 Local<MapIteratorRef> MapIteratorRef::New(const EcmaVM *vm, Local<MapRef> map)
1665 {
1666 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1667 ecmascript::ThreadManagedScope managedScope(thread);
1668 JSHandle<JSMap> jsMap(JSNApiHelper::ToJSHandle(map));
1669 IterationKind iterKind = IterationKind::KEY_AND_VALUE;
1670 JSHandle<JSTaggedValue> mapIteratorKeyAndValue =
1671 JSMapIterator::CreateMapIterator(vm->GetJSThread(), JSHandle<JSTaggedValue>::Cast(jsMap), iterKind);
1672 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1673 return JSNApiHelper::ToLocal<JSValueRef>(mapIteratorKeyAndValue);
1674 }
1675
GetEcmaRuntimeCallInfo(const EcmaVM * vm)1676 ecmascript::EcmaRuntimeCallInfo *MapIteratorRef::GetEcmaRuntimeCallInfo(const EcmaVM *vm)
1677 {
1678 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
1679 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1680 JSHandle<JSMapIterator> jsMapIter(JSNApiHelper::ToJSHandle(this));
1681 JSHandle<LinkedHashMap> linkedHashMap(vm->GetJSThread(), jsMapIter->GetIteratedMap());
1682 uint32_t size = linkedHashMap->GetLength();
1683 return ecmascript::EcmaInterpreter::NewRuntimeCallInfo(vm->GetJSThread(),
1684 JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::Undefined()),
1685 JSHandle<JSTaggedValue>(vm->GetJSThread(), jsMapIter.GetTaggedValue()),
1686 JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::Undefined()), size);
1687 }
1688
Next(const EcmaVM * vm,ecmascript::EcmaRuntimeCallInfo * ecmaRuntimeCallInfo)1689 Local<ArrayRef> MapIteratorRef::Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)
1690 {
1691 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1692 ecmascript::ThreadManagedScope managedScope(thread);
1693 JSHandle<JSTaggedValue> nextTagValResult(vm->GetJSThread(), JSMapIterator::Next(ecmaRuntimeCallInfo));
1694 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1695 JSHandle<JSTaggedValue> iteratorVal(vm->GetJSThread(),
1696 JSIterator::IteratorValue(vm->GetJSThread(), nextTagValResult).GetTaggedValue());
1697 return JSNApiHelper::ToLocal<ArrayRef>(iteratorVal);
1698 }
1699
Next(const EcmaVM * vm)1700 Local<JSValueRef> MapIteratorRef::Next(const EcmaVM *vm)
1701 {
1702 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1703 ecmascript::ThreadManagedScope managedScope(thread);
1704 JSHandle<JSTaggedValue> mapIter(JSNApiHelper::ToJSHandle(this));
1705 auto result = JSMapIterator::NextInternal(thread, mapIter);
1706 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, result));
1707 }
1708
1709 // SendableMapIteratorRef
Next(const EcmaVM * vm)1710 Local<JSValueRef> SendableMapIteratorRef::Next(const EcmaVM *vm)
1711 {
1712 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1713 ecmascript::ThreadManagedScope managedScope(thread);
1714 JSHandle<JSTaggedValue> sharedMapIter(JSNApiHelper::ToJSHandle(this));
1715 auto result = ecmascript::JSSharedMapIterator::NextInternal(thread, sharedMapIter);
1716 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, result));
1717 }
1718
1719 // ----------------------------------- SetIteratorRef ---------------------------------------
GetIndex()1720 int32_t SetIteratorRef::GetIndex()
1721 {
1722 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, -1);
1723 JSHandle<JSSetIterator> jsSetIter(JSNApiHelper::ToJSHandle(this));
1724 return jsSetIter->GetNextIndex();
1725 }
1726
GetKind(const EcmaVM * vm)1727 Local<JSValueRef> SetIteratorRef::GetKind(const EcmaVM *vm)
1728 {
1729 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1730 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1731 JSHandle<JSSetIterator> jsSetIter(JSNApiHelper::ToJSHandle(this));
1732 LOG_IF_SPECIAL(jsSetIter, FATAL);
1733 IterationKind iterKind = jsSetIter->GetIterationKind();
1734 Local<JSValueRef> result;
1735 const GlobalEnvConstants *globalConst = thread->GlobalConstants();
1736 switch (iterKind) {
1737 case IterationKind::KEY:
1738 result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledKeysString());
1739 break;
1740 case IterationKind::VALUE:
1741 result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledValuesString());
1742 break;
1743 case IterationKind::KEY_AND_VALUE:
1744 result = JSNApiHelper::ToLocal<JSValueRef>(globalConst->GetHandledEntriesString());
1745 break;
1746 default:
1747 break;
1748 }
1749 return result;
1750 }
1751
New(const EcmaVM * vm,Local<SetRef> set)1752 Local<SetIteratorRef> SetIteratorRef::New(const EcmaVM *vm, Local<SetRef> set)
1753 {
1754 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1755 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1756 JSHandle<JSSet> jsSet(JSNApiHelper::ToJSHandle(set));
1757 IterationKind iterKind = IterationKind::KEY_AND_VALUE;
1758 JSHandle<JSTaggedValue> setIteratorKeyAndValue =
1759 JSSetIterator::CreateSetIterator(vm->GetJSThread(), JSHandle<JSTaggedValue>::Cast(jsSet), iterKind);
1760 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1761 return JSNApiHelper::ToLocal<JSValueRef>(setIteratorKeyAndValue);
1762 }
1763
GetEcmaRuntimeCallInfo(const EcmaVM * vm)1764 ecmascript::EcmaRuntimeCallInfo *SetIteratorRef::GetEcmaRuntimeCallInfo(const EcmaVM *vm)
1765 {
1766 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
1767 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1768 JSHandle<JSSetIterator> jsSetIter(JSNApiHelper::ToJSHandle(this));
1769 JSHandle<LinkedHashSet> linkedHashSet(vm->GetJSThread(), jsSetIter->GetIteratedSet());
1770 uint32_t size = linkedHashSet->GetLength();
1771 return ecmascript::EcmaInterpreter::NewRuntimeCallInfo(vm->GetJSThread(),
1772 JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::Undefined()),
1773 JSHandle<JSTaggedValue>(vm->GetJSThread(), jsSetIter.GetTaggedValue()),
1774 JSHandle<JSTaggedValue>(vm->GetJSThread(), JSTaggedValue::Undefined()), size);
1775 }
1776
Next(const EcmaVM * vm,ecmascript::EcmaRuntimeCallInfo * ecmaRuntimeCallInfo)1777 Local<ArrayRef> SetIteratorRef::Next(const EcmaVM *vm, ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)
1778 {
1779 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1780 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1781 JSHandle<JSTaggedValue> nextTagValResult(vm->GetJSThread(), JSSetIterator::Next(ecmaRuntimeCallInfo));
1782 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1783 JSHandle<JSTaggedValue> iteratorVal(vm->GetJSThread(),
1784 JSIterator::IteratorValue(vm->GetJSThread(), nextTagValResult).GetTaggedValue());
1785 return JSNApiHelper::ToLocal<ArrayRef>(iteratorVal);
1786 }
1787
1788 // ---------------------------------- Buffer -----------------------------------
New(const EcmaVM * vm,int32_t length)1789 Local<BufferRef> BufferRef::New(const EcmaVM *vm, int32_t length)
1790 {
1791 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1792 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1793 ObjectFactory *factory = vm->GetFactory();
1794 JSHandle<JSArrayBuffer> arrayBuffer = JSHandle<JSArrayBuffer>::Cast(factory->NewJSArrayBuffer(length));
1795 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1796 JSHandle<JSFunction> current =
1797 factory->NewJSFunction(env, reinterpret_cast<void *>(BufferRef::BufferToStringCallback));
1798 Local<StringRef> key = StringRef::NewFromUtf8(vm, "toString");
1799 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
1800 JSHandle<JSTaggedValue> currentTaggedValue(current);
1801 JSHandle<JSTaggedValue> obj(arrayBuffer);
1802 bool result = JSTaggedValue::SetProperty(thread, obj, keyValue, currentTaggedValue);
1803 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1804 if (!result) {
1805 LOG_ECMA(ERROR) << "SetProperty failed ! ! !";
1806 }
1807 return JSNApiHelper::ToLocal<BufferRef>(obj);
1808 }
1809
New(const EcmaVM * vm,void * buffer,int32_t length,const NativePointerCallback & deleter,void * data)1810 Local<BufferRef> BufferRef::New(
1811 const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data)
1812 {
1813 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1814 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1815 ObjectFactory *factory = vm->GetFactory();
1816 JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(buffer, length, deleter, data);
1817
1818 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
1819 JSHandle<JSFunction> current =
1820 factory->NewJSFunction(env, reinterpret_cast<void *>(BufferRef::BufferToStringCallback));
1821 Local<StringRef> key = StringRef::NewFromUtf8(vm, "toString");
1822 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
1823 JSHandle<JSTaggedValue> currentTaggedValue(current);
1824 JSHandle<JSTaggedValue> obj(arrayBuffer);
1825 bool result = JSTaggedValue::SetProperty(thread, obj, keyValue, currentTaggedValue);
1826 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1827 if (!result) {
1828 LOG_ECMA(ERROR) << "SetProperty failed ! ! !";
1829 }
1830 return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
1831 }
1832
ByteLength(const EcmaVM * vm)1833 int32_t BufferRef::ByteLength(const EcmaVM *vm)
1834 {
1835 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
1836 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1837 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1838 return arrayBuffer->GetArrayBufferByteLength();
1839 }
1840
GetBuffer(const EcmaVM * vm)1841 void *BufferRef::GetBuffer(const EcmaVM *vm)
1842 {
1843 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
1844 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1845 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
1846 JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData();
1847 if (!bufferData.IsJSNativePointer()) {
1848 return nullptr;
1849 }
1850 return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
1851 }
1852
BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo * ecmaRuntimeCallInfo)1853 JSTaggedValue BufferRef::BufferToStringCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)
1854 {
1855 JSThread *thread = ecmaRuntimeCallInfo->GetThread();
1856 ecmascript::ThreadManagedScope managedScope(thread);
1857 [[maybe_unused]] LocalScope scope(thread->GetEcmaVM());
1858 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1859 JSHandle<JSTaggedValue> arrayBuff = ecmaRuntimeCallInfo->GetThis();
1860 JSHandle<JSArrayBuffer> arrayBuffer(arrayBuff);
1861
1862 uint32_t length = arrayBuffer->GetArrayBufferByteLength();
1863 JSTaggedValue data = arrayBuffer->GetArrayBufferData();
1864
1865 ecmascript::CVector<uint16_t> valueTable;
1866 valueTable.reserve(length);
1867 for (uint32_t i = 0; i < length; i++) {
1868 void* rawData = reinterpret_cast<void *>(
1869 ToUintPtr(JSNativePointer::Cast(data.GetTaggedObject())->GetExternalPointer()) + i);
1870 uint8_t *block = reinterpret_cast<uint8_t *>(rawData);
1871 uint16_t nextCv = static_cast<uint16_t>(*block);
1872 valueTable.emplace_back(nextCv);
1873 }
1874
1875 auto *char16tData0 = reinterpret_cast<const char16_t *>(valueTable.data());
1876 std::u16string u16str(char16tData0, length);
1877
1878 const char16_t *constChar16tData = u16str.data();
1879 auto *char16tData = const_cast<char16_t *>(constChar16tData);
1880 auto *uint16tData = reinterpret_cast<uint16_t *>(char16tData);
1881 uint32_t u16strSize = u16str.size();
1882 JSTaggedValue rString = factory->NewFromUtf16Literal(uint16tData, u16strSize).GetTaggedValue();
1883 JSHandle<EcmaString> StringHandle = JSTaggedValue::ToString(thread, rString);
1884 RETURN_VALUE_IF_ABRUPT(thread, JSTaggedValue::Undefined());
1885 return StringHandle.GetTaggedValue();
1886 }
1887
1888 // ---------------------------------- Promise --------------------------------------
New(const EcmaVM * vm)1889 Local<PromiseCapabilityRef> PromiseCapabilityRef::New(const EcmaVM *vm)
1890 {
1891 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1892 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1893 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
1894 JSHandle<JSTaggedValue> constructor(globalEnv->GetPromiseFunction());
1895 JSHandle<JSTaggedValue> capability(JSPromise::NewPromiseCapability(thread, constructor));
1896 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
1897 return JSNApiHelper::ToLocal<PromiseCapabilityRef>(capability);
1898 }
1899
GetPromise(const EcmaVM * vm)1900 Local<PromiseRef> PromiseCapabilityRef::GetPromise(const EcmaVM *vm)
1901 {
1902 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
1903 ecmascript::ThreadManagedScope managedScope(thread);
1904 JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
1905 LOG_IF_SPECIAL(capacity, FATAL);
1906 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, capacity->GetPromise()));
1907 }
1908
Resolve(const EcmaVM * vm,uintptr_t value)1909 bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, uintptr_t value)
1910 {
1911 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1912 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1913 const GlobalEnvConstants *constants = thread->GlobalConstants();
1914
1915 JSTaggedValue arg = *reinterpret_cast<JSTaggedValue *>(value);
1916 JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
1917 LOG_IF_SPECIAL(capacity, FATAL);
1918 JSTaggedValue resolve = capacity->GetResolve();
1919 JSTaggedValue undefined = constants->GetUndefined();
1920 EcmaRuntimeCallInfo *info =
1921 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, resolve, undefined, undefined, 1);
1922 RETURN_VALUE_IF_ABRUPT(thread, false);
1923 info->SetCallArg(arg);
1924 JSFunction::Call(info);
1925 RETURN_VALUE_IF_ABRUPT(thread, false);
1926
1927 thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
1928 RETURN_VALUE_IF_ABRUPT(thread, false);
1929 thread->GetCurrentEcmaContext()->ClearKeptObjects();
1930 return true;
1931 }
1932
Resolve(const EcmaVM * vm,Local<JSValueRef> value)1933 bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, Local<JSValueRef> value)
1934 {
1935 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1936 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1937 const GlobalEnvConstants *constants = thread->GlobalConstants();
1938
1939 JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(value);
1940 JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
1941 LOG_IF_SPECIAL(capacity, FATAL);
1942 JSHandle<JSTaggedValue> resolve(thread, capacity->GetResolve());
1943 JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
1944 EcmaRuntimeCallInfo *info =
1945 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, resolve, undefined, undefined, 1);
1946 RETURN_VALUE_IF_ABRUPT(thread, false);
1947 info->SetCallArg(arg.GetTaggedValue());
1948 JSFunction::Call(info);
1949 RETURN_VALUE_IF_ABRUPT(thread, false);
1950
1951 thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
1952 RETURN_VALUE_IF_ABRUPT(thread, false);
1953 thread->GetCurrentEcmaContext()->ClearKeptObjects();
1954 return true;
1955 }
1956
Reject(const EcmaVM * vm,uintptr_t reason)1957 bool PromiseCapabilityRef::Reject(const EcmaVM *vm, uintptr_t reason)
1958 {
1959 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1960 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1961 const GlobalEnvConstants *constants = thread->GlobalConstants();
1962
1963 JSTaggedValue arg = *reinterpret_cast<JSTaggedValue *>(reason);
1964 JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
1965 LOG_IF_SPECIAL(capacity, FATAL);
1966 JSTaggedValue reject = capacity->GetReject();
1967 JSTaggedValue undefined = constants->GetUndefined();
1968
1969 EcmaRuntimeCallInfo *info =
1970 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, reject, undefined, undefined, 1);
1971 RETURN_VALUE_IF_ABRUPT(thread, false);
1972 info->SetCallArg(arg);
1973 JSFunction::Call(info);
1974 RETURN_VALUE_IF_ABRUPT(thread, false);
1975
1976 thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
1977 RETURN_VALUE_IF_ABRUPT(thread, false);
1978 thread->GetCurrentEcmaContext()->ClearKeptObjects();
1979 return true;
1980 }
1981
Reject(const EcmaVM * vm,Local<JSValueRef> reason)1982 bool PromiseCapabilityRef::Reject(const EcmaVM *vm, Local<JSValueRef> reason)
1983 {
1984 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
1985 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
1986 const GlobalEnvConstants *constants = thread->GlobalConstants();
1987
1988 JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(reason);
1989 JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
1990 LOG_IF_SPECIAL(capacity, FATAL);
1991 JSHandle<JSTaggedValue> reject(thread, capacity->GetReject());
1992 JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
1993
1994 EcmaRuntimeCallInfo *info =
1995 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, reject, undefined, undefined, 1);
1996 RETURN_VALUE_IF_ABRUPT(thread, false);
1997 info->SetCallArg(arg.GetTaggedValue());
1998 JSFunction::Call(info);
1999 RETURN_VALUE_IF_ABRUPT(thread, false);
2000
2001 thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
2002 RETURN_VALUE_IF_ABRUPT(thread, false);
2003 thread->GetCurrentEcmaContext()->ClearKeptObjects();
2004 return true;
2005 }
2006
2007 // ----------------------------------- SymbolRef -----------------------------------------
New(const EcmaVM * vm,Local<StringRef> description)2008 Local<SymbolRef> SymbolRef::New(const EcmaVM *vm, Local<StringRef> description)
2009 {
2010 // Omit exception check because ark calls here may not
2011 // cause side effect even pending exception exists.
2012 CROSS_THREAD_CHECK(vm);
2013 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2014 ObjectFactory *factory = vm->GetFactory();
2015 JSHandle<JSSymbol> symbol = factory->NewJSSymbol();
2016 if (!description.IsEmpty()) {
2017 JSTaggedValue desc = JSNApiHelper::ToJSTaggedValue(*description);
2018 symbol->SetDescription(thread, desc);
2019 }
2020 return JSNApiHelper::ToLocal<SymbolRef>(JSHandle<JSTaggedValue>(symbol));
2021 }
2022
GetDescription(const EcmaVM * vm)2023 Local<StringRef> SymbolRef::GetDescription(const EcmaVM *vm)
2024 {
2025 CROSS_THREAD_CHECK(vm);
2026 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2027 JSTaggedValue description = JSSymbol::Cast(
2028 JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetDescription();
2029 if (!description.IsString()) {
2030 auto constants = thread->GlobalConstants();
2031 return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString());
2032 }
2033 JSHandle<JSTaggedValue> descriptionHandle(thread, description);
2034 return JSNApiHelper::ToLocal<StringRef>(descriptionHandle);
2035 }
2036
2037 // ----------------------------------- BooleanRef ---------------------------------------
New(const EcmaVM * vm,bool value)2038 Local<BooleanRef> BooleanRef::New(const EcmaVM *vm, bool value)
2039 {
2040 // Omit exception check because ark calls here may not
2041 // cause side effect even pending exception exists.
2042 CROSS_THREAD_CHECK(vm);
2043 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2044 JSHandle<JSTaggedValue> boolean(thread, JSTaggedValue(value));
2045 return JSNApiHelper::ToLocal<BooleanRef>(boolean);
2046 }
2047
Value()2048 bool BooleanRef::Value()
2049 {
2050 // Omit exception check because ark calls here may not
2051 // cause side effect even pending exception exists.
2052 return JSNApiHelper::ToJSTaggedValue(this).IsTrue();
2053 }
2054
2055 // ----------------------------------- StringRef ----------------------------------------
NewFromUtf8(const EcmaVM * vm,const char * utf8,int length)2056 Local<StringRef> StringRef::NewFromUtf8(const EcmaVM *vm, const char *utf8, int length)
2057 {
2058 // Omit exception check because ark calls here may not
2059 // cause side effect even pending exception exists.
2060 CROSS_THREAD_CHECK(vm);
2061 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2062 ObjectFactory *factory = vm->GetFactory();
2063 if (length < 0) {
2064 JSHandle<JSTaggedValue> current(factory->NewFromUtf8(utf8));
2065 return JSNApiHelper::ToLocal<StringRef>(current);
2066 }
2067 JSHandle<JSTaggedValue> current(factory->NewFromUtf8(reinterpret_cast<const uint8_t *>(utf8), length));
2068 return JSNApiHelper::ToLocal<StringRef>(current);
2069 }
2070
NewFromUtf8WithoutStringTable(const EcmaVM * vm,const char * utf8,int length)2071 Local<StringRef> StringRef::NewFromUtf8WithoutStringTable(const EcmaVM *vm, const char *utf8, int length)
2072 {
2073 // This only supports for napi_create_string_utf8
2074 CROSS_THREAD_CHECK(vm);
2075 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2076 ObjectFactory *factory = vm->GetFactory();
2077 if (length < 0) {
2078 JSHandle<JSTaggedValue> current(factory->NewFromUtf8WithoutStringTable(utf8));
2079 return JSNApiHelper::ToLocal<StringRef>(current);
2080 }
2081 JSHandle<JSTaggedValue> current(factory->NewFromUtf8WithoutStringTable(reinterpret_cast<const uint8_t *>(utf8),
2082 length));
2083 return JSNApiHelper::ToLocal<StringRef>(current);
2084 }
2085
NewFromUtf16WithoutStringTable(const EcmaVM * vm,const char16_t * utf16,int length)2086 Local<StringRef> StringRef::NewFromUtf16WithoutStringTable(const EcmaVM *vm, const char16_t *utf16, int length)
2087 {
2088 // Omit exception check because ark calls here may not
2089 // cause side effect even pending exception exists.
2090 CROSS_THREAD_CHECK(vm);
2091 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2092 ObjectFactory *factory = vm->GetFactory();
2093 if (length < 0) {
2094 JSHandle<JSTaggedValue> current(factory->NewFromUtf16WithoutStringTable(utf16));
2095 return JSNApiHelper::ToLocal<StringRef>(current);
2096 }
2097 JSHandle<JSTaggedValue> current(factory->NewFromUtf16WithoutStringTable(reinterpret_cast<const uint16_t *>(utf16),
2098 length));
2099 return JSNApiHelper::ToLocal<StringRef>(current);
2100 }
2101
NewFromUtf16(const EcmaVM * vm,const char16_t * utf16,int length)2102 Local<StringRef> StringRef::NewFromUtf16(const EcmaVM *vm, const char16_t *utf16, int length)
2103 {
2104 // Omit exception check because ark calls here may not
2105 // cause side effect even pending exception exists.
2106 CROSS_THREAD_CHECK(vm);
2107 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2108 ObjectFactory *factory = vm->GetFactory();
2109 if (length < 0) {
2110 JSHandle<JSTaggedValue> current(factory->NewFromUtf16(utf16));
2111 return JSNApiHelper::ToLocal<StringRef>(current);
2112 }
2113 JSHandle<JSTaggedValue> current(factory->NewFromUtf16(reinterpret_cast<const uint16_t *>(utf16), length));
2114 return JSNApiHelper::ToLocal<StringRef>(current);
2115 }
2116
ToString(const EcmaVM * vm)2117 std::string StringRef::ToString(const EcmaVM *vm)
2118 {
2119 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, "");
2120 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2121 return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).ToStdString();
2122 }
2123
DebuggerToString(const EcmaVM * vm)2124 std::string StringRef::DebuggerToString(const EcmaVM *vm)
2125 {
2126 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, "");
2127 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2128 return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).DebuggerToStdString();
2129 }
2130
Length(const EcmaVM * vm)2131 uint32_t StringRef::Length(const EcmaVM *vm)
2132 {
2133 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2134 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2135 return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this)).GetLength();
2136 }
2137
Utf8Length(const EcmaVM * vm,bool isGetBufferSize)2138 int32_t StringRef::Utf8Length(const EcmaVM *vm, bool isGetBufferSize)
2139 {
2140 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2141 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2142 JSHandle<EcmaString> strHandle(vm->GetJSThread(), EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(this)));
2143 return EcmaStringAccessor(EcmaStringAccessor::Flatten(vm, strHandle)).GetUtf8Length(isGetBufferSize);
2144 }
2145
WriteUtf8(const EcmaVM * vm,char * buffer,int length,bool isWriteBuffer)2146 int StringRef::WriteUtf8(const EcmaVM *vm, char *buffer, int length, bool isWriteBuffer)
2147 {
2148 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2149 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2150 return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this))
2151 .WriteToFlatUtf8(reinterpret_cast<uint8_t *>(buffer), length, isWriteBuffer);
2152 }
2153
WriteUtf16(const EcmaVM * vm,char16_t * buffer,int length)2154 int StringRef::WriteUtf16(const EcmaVM *vm, char16_t *buffer, int length)
2155 {
2156 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2157 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2158 return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this))
2159 .WriteToUtf16(reinterpret_cast<uint16_t *>(buffer), length);
2160 }
2161
WriteLatin1(const EcmaVM * vm,char * buffer,int length)2162 int StringRef::WriteLatin1(const EcmaVM *vm, char *buffer, int length)
2163 {
2164 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2165 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2166 return EcmaStringAccessor(JSNApiHelper::ToJSTaggedValue(this))
2167 .WriteToOneByte(reinterpret_cast<uint8_t *>(buffer), length);
2168 }
2169
GetNapiWrapperString(const EcmaVM * vm)2170 Local<StringRef> StringRef::GetNapiWrapperString(const EcmaVM *vm)
2171 {
2172 // Omit exception check because ark calls here may not
2173 // cause side effect even pending exception exists.
2174 CROSS_THREAD_CHECK(vm);
2175 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2176 JSHandle<JSTaggedValue> napiWapperString = thread->GlobalConstants()->GetHandledNapiWrapperString();
2177 return JSNApiHelper::ToLocal<StringRef>(napiWapperString);
2178 }
2179
2180 // ---------------------------------- PromiseRejectInfo ---------------------------------
PromiseRejectInfo(Local<JSValueRef> promise,Local<JSValueRef> reason,PromiseRejectInfo::PROMISE_REJECTION_EVENT operation,void * data)2181 PromiseRejectInfo::PromiseRejectInfo(Local<JSValueRef> promise, Local<JSValueRef> reason,
2182 PromiseRejectInfo::PROMISE_REJECTION_EVENT operation, void* data)
2183 : promise_(promise), reason_(reason), operation_(operation), data_(data) {}
2184
GetPromise() const2185 Local<JSValueRef> PromiseRejectInfo::GetPromise() const
2186 {
2187 return promise_;
2188 }
2189
GetReason() const2190 Local<JSValueRef> PromiseRejectInfo::GetReason() const
2191 {
2192 return reason_;
2193 }
2194
GetOperation() const2195 PromiseRejectInfo::PROMISE_REJECTION_EVENT PromiseRejectInfo::GetOperation() const
2196 {
2197 return operation_;
2198 }
2199
GetData() const2200 void* PromiseRejectInfo::GetData() const
2201 {
2202 return data_;
2203 }
2204
2205 // ----------------------------------- BigIntRef ---------------------------------------
New(const EcmaVM * vm,uint64_t input)2206 Local<BigIntRef> BigIntRef::New(const EcmaVM *vm, uint64_t input)
2207 {
2208 // Omit exception check because ark calls here may not
2209 // cause side effect even pending exception exists.
2210 CROSS_THREAD_CHECK(vm);
2211 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2212 JSHandle<BigInt> big = BigInt::Uint64ToBigInt(thread, input);
2213 JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
2214 return JSNApiHelper::ToLocal<BigIntRef>(bigint);
2215 }
2216
New(const EcmaVM * vm,int64_t input)2217 Local<BigIntRef> BigIntRef::New(const EcmaVM *vm, int64_t input)
2218 {
2219 // Omit exception check because ark calls here may not
2220 // cause side effect even pending exception exists.
2221 CROSS_THREAD_CHECK(vm);
2222 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2223 JSHandle<BigInt> big = BigInt::Int64ToBigInt(thread, input);
2224 JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
2225 return JSNApiHelper::ToLocal<BigIntRef>(bigint);
2226 }
2227
CreateBigWords(const EcmaVM * vm,bool sign,uint32_t size,const uint64_t * words)2228 Local<JSValueRef> BigIntRef::CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words)
2229 {
2230 // Omit exception check because ark calls here may not
2231 // cause side effect even pending exception exists.
2232 CROSS_THREAD_CHECK(vm);
2233 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2234 JSHandle<BigInt> big = BigInt::CreateBigWords(thread, sign, size, words);
2235 JSHandle<JSTaggedValue> bigint = JSHandle<JSTaggedValue>::Cast(big);
2236 return JSNApiHelper::ToLocal<JSValueRef>(bigint);
2237 }
2238
BigIntToInt64(const EcmaVM * vm,int64_t * value,bool * lossless)2239 void BigIntRef::BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless)
2240 {
2241 // Omit exception check because ark calls here may not
2242 // cause side effect even pending exception exists.
2243 CROSS_THREAD_CHECK(vm);
2244 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2245 JSHandle<JSTaggedValue> bigintVal(JSNApiHelper::ToJSHandle(this));
2246 LOG_IF_SPECIAL(bigintVal, ERROR);
2247 BigInt::BigIntToInt64(thread, bigintVal, value, lossless);
2248 }
2249
BigIntToUint64(const EcmaVM * vm,uint64_t * value,bool * lossless)2250 void BigIntRef::BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless)
2251 {
2252 // Omit exception check because ark calls here may not
2253 // cause side effect even pending exception exists.
2254 CROSS_THREAD_CHECK(vm);
2255 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2256 JSHandle<JSTaggedValue> bigintVal(JSNApiHelper::ToJSHandle(this));
2257 LOG_IF_SPECIAL(bigintVal, ERROR);
2258 BigInt::BigIntToUint64(thread, bigintVal, value, lossless);
2259 }
2260
GetWordsArray(const EcmaVM * vm,bool * signBit,size_t wordCount,uint64_t * words)2261 void BigIntRef::GetWordsArray(const EcmaVM *vm, bool* signBit, size_t wordCount, uint64_t* words)
2262 {
2263 DCHECK_SPECIAL_VALUE(this);
2264 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2265 JSHandle<BigInt> bigintVal(JSNApiHelper::ToJSHandle(this));
2266 uint32_t len = bigintVal->GetLength();
2267 uint32_t count = 0;
2268 uint32_t index = 0;
2269 ASSERT(wordCount > 0);
2270 for (; index < wordCount - 1; ++index) {
2271 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
2272 words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
2273 }
2274 if (len % 2 == 0) { // 2 : len is odd or even
2275 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
2276 words[index] |= static_cast<uint64_t>(bigintVal->GetDigit(count++)) << 32; // 32 : int32_t bits
2277 } else {
2278 words[index] = static_cast<uint64_t>(bigintVal->GetDigit(count++));
2279 }
2280 *signBit = bigintVal->GetSign();
2281 }
2282
GetWordsArraySize(const EcmaVM * vm)2283 uint32_t BigIntRef::GetWordsArraySize(const EcmaVM *vm)
2284 {
2285 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2286 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2287 JSHandle<BigInt> bigintVal(JSNApiHelper::ToJSHandle(this));
2288 uint32_t len = bigintVal->GetLength();
2289 return len % 2 != 0 ? len / 2 + 1 : len / 2; // 2 : len is odd or even
2290 }
2291
2292 // ----------------------------------- HandleScope -------------------------------------
LocalScope(const EcmaVM * vm)2293 LocalScope::LocalScope(const EcmaVM *vm) : thread_(vm->GetJSThread())
2294 {
2295 // Only get handle ptr here. Do not need to swtich state.
2296 auto context = reinterpret_cast<JSThread *>(thread_)->GetCurrentEcmaContext();
2297 prevNext_ = context->GetHandleScopeStorageNext();
2298 prevEnd_ = context->GetHandleScopeStorageEnd();
2299 prevHandleStorageIndex_ = context->GetCurrentHandleStorageIndex();
2300
2301 prevPrimitiveNext_ = context->GetPrimitiveScopeStorageNext();
2302 prevPrimitiveEnd_ = context->GetPrimitiveScopeStorageEnd();
2303 prevPrimitiveStorageIndex_ = context->GetCurrentPrimitiveStorageIndex();
2304 #ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
2305 context->HandleScopeCountAdd();
2306 context->PrimitiveScopeCountAdd();
2307 #endif
2308 }
2309
LocalScope(const EcmaVM * vm,JSTaggedType value)2310 LocalScope::LocalScope(const EcmaVM *vm, JSTaggedType value) : thread_(vm->GetJSThread())
2311 {
2312 ecmascript::ThreadManagedScope managedScope(reinterpret_cast<JSThread *>(thread_));
2313 // Simply reserve a slot on the handlescope. The escaped handle will still be retained in this slot.
2314 ecmascript::EcmaHandleScope::NewHandle(reinterpret_cast<JSThread *>(thread_), value);
2315 auto context = reinterpret_cast<JSThread *>(thread_)->GetCurrentEcmaContext();
2316 prevNext_ = context->GetHandleScopeStorageNext();
2317 prevEnd_ = context->GetHandleScopeStorageEnd();
2318 prevHandleStorageIndex_ = context->GetCurrentHandleStorageIndex();
2319
2320 prevPrimitiveNext_ = context->GetPrimitiveScopeStorageNext();
2321 prevPrimitiveEnd_ = context->GetPrimitiveScopeStorageEnd();
2322 prevPrimitiveStorageIndex_ = context->GetCurrentPrimitiveStorageIndex();
2323 #ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
2324 context->HandleScopeCountAdd();
2325 context->PrimitiveScopeCountAdd();
2326 #endif
2327 }
2328
~LocalScope()2329 LocalScope::~LocalScope()
2330 {
2331 ecmascript::ThreadManagedScope managedScope(reinterpret_cast<JSThread *>(thread_));
2332 auto context = reinterpret_cast<JSThread *>(thread_)->GetCurrentEcmaContext();
2333 #ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
2334 context->HandleScopeCountDec();
2335 context->PrimitiveScopeCountDec();
2336 #endif
2337 context->SetHandleScopeStorageNext(static_cast<JSTaggedType *>(prevNext_));
2338 context->SetPrimitiveScopeStorageNext(static_cast<JSTaggedType *>(prevPrimitiveNext_));
2339
2340 if (context->GetHandleScopeStorageEnd() != prevEnd_) {
2341 context->SetHandleScopeStorageEnd(static_cast<JSTaggedType *>(prevEnd_));
2342 context->ShrinkHandleStorage(prevHandleStorageIndex_);
2343 }
2344
2345 if (context->GetPrimitiveScopeStorageEnd() != prevPrimitiveEnd_) {
2346 context->SetPrimitiveScopeStorageEnd(static_cast<JSTaggedType *>(prevPrimitiveEnd_));
2347 context->ShrinkPrimitiveStorage(prevPrimitiveStorageIndex_);
2348 }
2349 }
2350
2351 // ----------------------------------- EscapeLocalScope ------------------------------
EscapeLocalScope(const EcmaVM * vm)2352 EscapeLocalScope::EscapeLocalScope(const EcmaVM *vm) : LocalScope(vm, JSTaggedValue::Undefined().GetRawData())
2353 {
2354 auto thread = vm->GetJSThread();
2355 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
2356 escapeHandle_ = ToUintPtr(thread->GetCurrentEcmaContext()->GetHandleScopeStorageNext() - 1);
2357 }
2358
2359 // ----------------------------------- IntegerRef ---------------------------------------
New(const EcmaVM * vm,int input)2360 Local<IntegerRef> IntegerRef::New(const EcmaVM *vm, int input)
2361 {
2362 // Omit exception check because ark calls here may not
2363 // cause side effect even pending exception exists.
2364 CROSS_THREAD_CHECK(vm);
2365 ecmascript::ThreadManagedScope managedScope(thread);
2366 JSHandle<JSTaggedValue> integer(thread, JSTaggedValue(input));
2367 return JSNApiHelper::ToLocal<IntegerRef>(integer);
2368 }
2369
NewFromUnsigned(const EcmaVM * vm,unsigned int input)2370 Local<IntegerRef> IntegerRef::NewFromUnsigned(const EcmaVM *vm, unsigned int input)
2371 {
2372 // Omit exception check because ark calls here may not
2373 // cause side effect even pending exception exists.
2374 CROSS_THREAD_CHECK(vm);
2375 ecmascript::ThreadManagedScope managedScope(thread);
2376 JSHandle<JSTaggedValue> integer(thread, JSTaggedValue(input));
2377 return JSNApiHelper::ToLocal<IntegerRef>(integer);
2378 }
2379
Value()2380 int IntegerRef::Value()
2381 {
2382 // Omit exception check because ark calls here may not
2383 // cause side effect even pending exception exists.
2384 return JSNApiHelper::ToJSTaggedValue(this).GetInt();
2385 }
2386
2387 // ----------------------------------- ObjectRef ----------------------------------------
New(const EcmaVM * vm)2388 Local<ObjectRef> ObjectRef::New(const EcmaVM *vm)
2389 {
2390 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2391 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2392 ObjectFactory *factory = vm->GetFactory();
2393 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
2394 JSHandle<JSFunction> constructor(globalEnv->GetObjectFunction());
2395 JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(constructor));
2396 return JSNApiHelper::ToLocal<ObjectRef>(object);
2397 }
2398
NewObject(const EcmaVM * vm)2399 uintptr_t ObjectRef::NewObject(const EcmaVM *vm)
2400 {
2401 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm,
2402 (vm->GetJSThread()->GlobalConstants()->GetHandledUndefined()).GetAddress());
2403 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2404 ObjectFactory *factory = vm->GetFactory();
2405 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
2406 JSHandle<JSFunction> constructor(globalEnv->GetObjectFunction());
2407 JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(constructor));
2408 return object.GetAddress();
2409 }
2410
NewS(const EcmaVM * vm)2411 Local<ObjectRef> ObjectRef::NewS(const EcmaVM *vm)
2412 {
2413 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2414 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2415 ObjectFactory *factory = vm->GetFactory();
2416 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
2417 JSHandle<JSFunction> constructor(globalEnv->GetSObjectFunction());
2418 JSHandle<JSTaggedValue> object(factory->NewJSObjectByConstructor(constructor));
2419 return JSNApiHelper::ToLocal<ObjectRef>(object);
2420 }
2421
NewWithProperties(const EcmaVM * vm,size_t propertyCount,const Local<JSValueRef> * keys,const PropertyAttribute * attributes)2422 Local<ObjectRef> ObjectRef::NewWithProperties(const EcmaVM *vm, size_t propertyCount,
2423 const Local<JSValueRef> *keys,
2424 const PropertyAttribute *attributes)
2425 {
2426 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2427 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2428 EscapeLocalScope scope(vm);
2429 JSHandle<JSTaggedValue> obj;
2430 auto CreateObjImpl = [vm, propertyCount, keys, attributes] (uintptr_t head) -> JSHandle<JSTaggedValue> {
2431 JSThread *thread = vm->GetJSThread();
2432 const PropertyDescriptor *desc = reinterpret_cast<const PropertyDescriptor *>(head);
2433 for (size_t i = 0; i < propertyCount; ++i) {
2434 const PropertyAttribute &attr = attributes[i];
2435 new (reinterpret_cast<void *>(head)) PropertyDescriptor(thread,
2436 JSNApiHelper::ToJSHandle(attr.GetValue(vm)),
2437 attr.IsWritable(), attr.IsEnumerable(),
2438 attr.IsConfigurable());
2439 head += sizeof(PropertyDescriptor);
2440 }
2441 ObjectFactory *factory = vm->GetFactory();
2442 return factory->CreateJSObjectWithProperties(propertyCount, keys, desc);
2443 };
2444 if (propertyCount <= MAX_PROPERTIES_ON_STACK) {
2445 char desc[sizeof(PropertyDescriptor) * MAX_PROPERTIES_ON_STACK];
2446 obj = CreateObjImpl(reinterpret_cast<uintptr_t>(desc));
2447 } else {
2448 void *desc = malloc(sizeof(PropertyDescriptor) * propertyCount);
2449 obj = CreateObjImpl(reinterpret_cast<uintptr_t>(desc));
2450 free(desc);
2451 }
2452 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2453 return scope.Escape(JSNApiHelper::ToLocal<ObjectRef>(obj));
2454 }
2455
NewSWithProperties(const EcmaVM * vm,SendablePropertiesInfo & info)2456 Local<ObjectRef> ObjectRef::NewSWithProperties(const EcmaVM *vm, SendablePropertiesInfo &info)
2457 {
2458 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2459 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2460 EscapeLocalScope scope(vm);
2461 ObjectFactory *factory = vm->GetFactory();
2462 std::vector<PropertyDescriptor> descs;
2463 JSNapiSendable::InitWithPropertiesInfo(thread, info, descs);
2464 auto obj = factory->CreateSObjectWithProperties(descs);
2465 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2466 return scope.Escape(JSNApiHelper::ToLocal<ObjectRef>(obj));
2467 }
2468
NewWithNamedProperties(const EcmaVM * vm,size_t propertyCount,const char ** keys,const Local<JSValueRef> * values)2469 Local<ObjectRef> ObjectRef::NewWithNamedProperties(const EcmaVM *vm, size_t propertyCount,
2470 const char **keys, const Local<JSValueRef> *values)
2471 {
2472 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2473 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2474 EscapeLocalScope scope(vm);
2475 ObjectFactory *factory = vm->GetFactory();
2476 JSHandle<JSTaggedValue> obj = factory->CreateJSObjectWithNamedProperties(propertyCount, keys, values);
2477 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2478 return scope.Escape(JSNApiHelper::ToLocal<ObjectRef>(obj));
2479 }
2480
CreateNativeModuleFailureInfo(const EcmaVM * vm,const std::string & failureInfo)2481 Local<ObjectRef> ObjectRef::CreateNativeModuleFailureInfo(const EcmaVM *vm, const std::string &failureInfo)
2482 {
2483 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2484 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2485 if (EcmaVM::GetErrorInfoEnhance()) {
2486 JSHandle<NativeModuleFailureInfo> nativeModuleErrorFailureInfo =
2487 NativeModuleFailureInfo::CreateNativeModuleFailureInfo(vm, failureInfo);
2488 return JSNApiHelper::ToLocal<ObjectRef>(JSHandle<JSTaggedValue>::Cast(nativeModuleErrorFailureInfo));
2489 }
2490 return JSValueRef::Undefined(vm);
2491 }
2492
CreateAccessorData(const EcmaVM * vm,Local<FunctionRef> getter,Local<FunctionRef> setter)2493 Local<ObjectRef> ObjectRef::CreateAccessorData(const EcmaVM *vm,
2494 Local<FunctionRef> getter, Local<FunctionRef> setter)
2495 {
2496 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2497 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2498 JSHandle<JSTaggedValue> getterValue = JSNApiHelper::ToJSHandle(getter);
2499 JSHandle<JSTaggedValue> setterValue = JSNApiHelper::ToJSHandle(setter);
2500 JSHandle<AccessorData> accessor = thread->GetEcmaVM()->GetFactory()->NewAccessorData();
2501 accessor->SetGetter(thread, getterValue);
2502 accessor->SetSetter(thread, setterValue);
2503 return JSNApiHelper::ToLocal<ObjectRef>(JSHandle<JSTaggedValue>::Cast(accessor));
2504 }
2505
CreateSendableAccessorData(const EcmaVM * vm,Local<FunctionRef> getter,Local<FunctionRef> setter)2506 Local<ObjectRef> ObjectRef::CreateSendableAccessorData(const EcmaVM *vm,
2507 Local<FunctionRef> getter,
2508 Local<FunctionRef> setter)
2509 {
2510 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2511 ecmascript::ThreadManagedScope managedScope(thread);
2512 JSHandle<JSTaggedValue> getterValue = JSNApiHelper::ToJSHandle(getter);
2513 JSHandle<JSTaggedValue> setterValue = JSNApiHelper::ToJSHandle(setter);
2514 JSHandle<AccessorData> accessor = thread->GetEcmaVM()->GetFactory()->NewSAccessorData();
2515 accessor->SetGetter(thread, getterValue);
2516 accessor->SetSetter(thread, setterValue);
2517 return JSNApiHelper::ToLocal<ObjectRef>(JSHandle<JSTaggedValue>::Cast(accessor));
2518 }
2519
ConvertToNativeBindingObject(const EcmaVM * vm,Local<NativePointerRef> value)2520 bool ObjectRef::ConvertToNativeBindingObject(const EcmaVM *vm, Local<NativePointerRef> value)
2521 {
2522 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2523 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2524 [[maybe_unused]] LocalScope scope(vm);
2525 JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(this);
2526 LOG_IF_SPECIAL(object, ERROR);
2527 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
2528 JSHandle<JSTaggedValue> keyValue = env->GetNativeBindingSymbol();
2529 JSHandle<JSTaggedValue> valueValue = JSNApiHelper::ToJSHandle(value);
2530 bool result = JSTaggedValue::SetProperty(vm->GetJSThread(), object, keyValue, valueValue);
2531 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
2532 object->GetTaggedObject()->GetClass()->SetIsNativeBindingObject(true);
2533 return result;
2534 }
2535
Set(const EcmaVM * vm,Local<JSValueRef> key,Local<JSValueRef> value)2536 bool ObjectRef::Set(const EcmaVM *vm, Local<JSValueRef> key, Local<JSValueRef> value)
2537 {
2538 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2539 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2540 [[maybe_unused]] LocalScope scope(vm);
2541 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2542 LOG_IF_SPECIAL(obj, ERROR);
2543 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
2544 JSHandle<JSTaggedValue> valueValue = JSNApiHelper::ToJSHandle(value);
2545 if (!obj->IsHeapObject()) {
2546 return JSTaggedValue::SetProperty(thread, obj, keyValue, valueValue);
2547 }
2548 return ObjectFastOperator::FastSetPropertyByValue(thread, obj.GetTaggedValue(),
2549 keyValue.GetTaggedValue(),
2550 valueValue.GetTaggedValue());
2551 }
2552
Set(const EcmaVM * vm,const char * utf8,Local<JSValueRef> value)2553 bool ObjectRef::Set(const EcmaVM *vm, const char *utf8, Local<JSValueRef> value)
2554 {
2555 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2556 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2557 [[maybe_unused]] LocalScope scope(vm);
2558 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2559 LOG_IF_SPECIAL(obj, ERROR);
2560 ObjectFactory *factory = vm->GetFactory();
2561 JSHandle<JSTaggedValue> keyValue(factory->NewFromUtf8(utf8));
2562 JSTaggedValue valueValue = JSNApiHelper::ToJSTaggedValue(*value);
2563 if (!obj->IsHeapObject()) {
2564 return JSTaggedValue::SetProperty(thread, obj, keyValue, JSHandle<JSTaggedValue>(thread, valueValue));
2565 }
2566 JSTaggedValue res = ObjectFastOperator::TrySetPropertyByNameThroughCacheAtLocal(thread, obj.GetTaggedValue(),
2567 keyValue.GetTaggedValue(),
2568 valueValue);
2569 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
2570 if (!res.IsHole()) {
2571 return !res.IsException();
2572 }
2573 if (!JSNApi::KeyIsNumber(utf8)) {
2574 res = ObjectFastOperator::SetPropertyByName(thread, obj.GetTaggedValue(), keyValue.GetTaggedValue(),
2575 valueValue);
2576 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false);
2577 if (!res.IsHole()) {
2578 return !res.IsException();
2579 }
2580 return JSTaggedValue::SetProperty(thread, JSHandle<JSTaggedValue>(thread, obj.GetTaggedValue()), keyValue,
2581 JSHandle<JSTaggedValue>(thread, valueValue), true);
2582 }
2583 return ObjectFastOperator::FastSetPropertyByValue(thread, obj.GetTaggedValue(),
2584 keyValue.GetTaggedValue(),
2585 valueValue);
2586 }
2587
Set(const EcmaVM * vm,uint32_t key,Local<JSValueRef> value)2588 bool ObjectRef::Set(const EcmaVM *vm, uint32_t key, Local<JSValueRef> value)
2589 {
2590 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2591 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2592 [[maybe_unused]] LocalScope scope(vm);
2593 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2594 LOG_IF_SPECIAL(obj, ERROR);
2595 JSHandle<JSTaggedValue> valueValue = JSNApiHelper::ToJSHandle(value);
2596 if (!obj->IsHeapObject()) {
2597 return JSTaggedValue::SetProperty(thread, obj, key, valueValue);
2598 }
2599 return ObjectFastOperator::FastSetPropertyByIndex(thread, obj.GetTaggedValue(),
2600 key, valueValue.GetTaggedValue());
2601 }
2602
SetAccessorProperty(const EcmaVM * vm,Local<JSValueRef> key,Local<FunctionRef> getter,Local<FunctionRef> setter,PropertyAttribute attribute)2603 bool ObjectRef::SetAccessorProperty(const EcmaVM *vm, Local<JSValueRef> key, Local<FunctionRef> getter,
2604 Local<FunctionRef> setter, PropertyAttribute attribute)
2605 {
2606 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2607 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2608 [[maybe_unused]] LocalScope scope(vm);
2609 JSHandle<JSTaggedValue> getterValue = JSNApiHelper::ToJSHandle(getter);
2610 JSHandle<JSTaggedValue> setterValue = JSNApiHelper::ToJSHandle(setter);
2611 PropertyDescriptor desc(thread, attribute.IsWritable(), attribute.IsEnumerable(), attribute.IsConfigurable());
2612 desc.SetValue(JSNApiHelper::ToJSHandle(attribute.GetValue(vm)));
2613 desc.SetSetter(setterValue);
2614 desc.SetGetter(getterValue);
2615 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2616 LOG_IF_SPECIAL(obj, ERROR);
2617 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
2618 return JSTaggedValue::DefineOwnProperty(thread, obj, keyValue, desc);
2619 }
2620
Get(const EcmaVM * vm,Local<JSValueRef> key)2621 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, Local<JSValueRef> key)
2622 {
2623 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2624 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2625 JSTaggedValue result;
2626 {
2627 LocalScope scope(vm);
2628 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2629 LOG_IF_SPECIAL(obj, ERROR);
2630 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
2631 if (UNLIKELY(!obj->IsHeapObject())) {
2632 OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue);
2633 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2634 result = ret.GetValue().GetTaggedValue();
2635 } else {
2636 result = ObjectFastOperator::FastGetPropertyByValue(thread, obj.GetTaggedValue(),
2637 keyValue.GetTaggedValue());
2638 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2639 }
2640 }
2641 JSHandle<JSTaggedValue> resultValue(thread, result);
2642 return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
2643 }
2644
Get(const EcmaVM * vm,const char * utf8)2645 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, const char *utf8)
2646 {
2647 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2648 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2649 JSTaggedValue result;
2650 {
2651 LocalScope scope(vm);
2652 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2653 LOG_IF_SPECIAL(obj, ERROR);
2654 ObjectFactory *factory = vm->GetFactory();
2655 JSHandle<JSTaggedValue> keyValue(factory->NewFromUtf8(utf8));
2656 if (UNLIKELY(!obj->IsHeapObject())) {
2657 OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue);
2658 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2659 result = ret.GetValue().GetTaggedValue();
2660 } else {
2661 result = ObjectFastOperator::FastGetPropertyByValue(thread, obj.GetTaggedValue(),
2662 keyValue.GetTaggedValue());
2663 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2664 }
2665 }
2666 JSHandle<JSTaggedValue> resultValue(thread, result);
2667 return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
2668 }
2669
Get(const EcmaVM * vm,int32_t key)2670 Local<JSValueRef> ObjectRef::Get(const EcmaVM *vm, int32_t key)
2671 {
2672 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2673 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2674 JSTaggedValue result;
2675 {
2676 LocalScope scope(vm);
2677 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2678 LOG_IF_SPECIAL(obj, ERROR);
2679 if (!obj->IsHeapObject()) {
2680 OperationResult ret = JSTaggedValue::GetProperty(thread, obj, key);
2681 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2682 result = ret.GetValue().GetTaggedValue();
2683 } else {
2684 result = ObjectFastOperator::FastGetPropertyByIndex(thread, obj.GetTaggedValue(), key);
2685 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2686 }
2687 }
2688 JSHandle<JSTaggedValue> resultValue(thread, result);
2689 return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
2690 }
2691
GetOwnProperty(const EcmaVM * vm,Local<JSValueRef> key,PropertyAttribute & property)2692 bool ObjectRef::GetOwnProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute &property)
2693 {
2694 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2695 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2696 JSHandle<JSTaggedValue> obj = JSNApiHelper::ToJSHandle(this);
2697 LOG_IF_SPECIAL(obj, ERROR);
2698 JSHandle<JSTaggedValue> keyValue = JSNApiHelper::ToJSHandle(key);
2699 PropertyDescriptor desc(thread);
2700 bool ret = JSObject::GetOwnProperty(thread, JSHandle<JSObject>(obj), keyValue, desc);
2701 if (!ret) {
2702 return false;
2703 }
2704 property.SetValue(JSNApiHelper::ToLocal<JSValueRef>(desc.GetValue()));
2705 if (desc.HasGetter()) {
2706 property.SetGetter(JSNApiHelper::ToLocal<JSValueRef>(desc.GetGetter()));
2707 }
2708 if (desc.HasSetter()) {
2709 property.SetSetter(JSNApiHelper::ToLocal<JSValueRef>(desc.GetSetter()));
2710 }
2711 if (desc.HasWritable()) {
2712 property.SetWritable(desc.IsWritable());
2713 }
2714 if (desc.HasEnumerable()) {
2715 property.SetEnumerable(desc.IsEnumerable());
2716 }
2717 if (desc.HasConfigurable()) {
2718 property.SetConfigurable(desc.IsConfigurable());
2719 }
2720
2721 return true;
2722 }
2723
GetOwnPropertyNames(const EcmaVM * vm)2724 Local<ArrayRef> ObjectRef::GetOwnPropertyNames(const EcmaVM *vm)
2725 {
2726 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2727 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2728 JSHandle<JSTaggedValue> obj(JSNApiHelper::ToJSHandle(this));
2729 LOG_IF_SPECIAL(obj, ERROR);
2730 JSHandle<TaggedArray> array(JSTaggedValue::GetOwnPropertyKeys(thread, obj));
2731 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2732 JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
2733 return JSNApiHelper::ToLocal<ArrayRef>(jsArray);
2734 }
2735
GetAllPropertyNames(const EcmaVM * vm,uint32_t filter)2736 Local<ArrayRef> ObjectRef::GetAllPropertyNames(const EcmaVM *vm, uint32_t filter)
2737 {
2738 // This interface is only used by napi.
2739 // This interface currently only supports normal objects.
2740 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2741 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2742 JSHandle<JSTaggedValue> obj(JSNApiHelper::ToJSHandle(this));
2743 LOG_IF_SPECIAL(obj, ERROR);
2744 JSHandle<TaggedArray> array(JSTaggedValue::GetAllPropertyKeys(thread, obj, filter));
2745 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2746 JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
2747 return JSNApiHelper::ToLocal<ArrayRef>(jsArray);
2748 }
2749
GetOwnEnumerablePropertyNames(const EcmaVM * vm)2750 Local<ArrayRef> ObjectRef::GetOwnEnumerablePropertyNames(const EcmaVM *vm)
2751 {
2752 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2753 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2754 JSHandle<JSObject> obj(JSNApiHelper::ToJSHandle(this));
2755 LOG_IF_SPECIAL(obj, ERROR);
2756 JSHandle<TaggedArray> array(JSObject::EnumerableOwnNames(thread, obj));
2757 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2758 JSHandle<JSTaggedValue> jsArray(JSArray::CreateArrayFromList(thread, array));
2759 return JSNApiHelper::ToLocal<ArrayRef>(jsArray);
2760 }
2761
GetPrototype(const EcmaVM * vm)2762 Local<JSValueRef> ObjectRef::GetPrototype(const EcmaVM *vm)
2763 {
2764 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2765 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2766 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
2767 LOG_IF_SPECIAL(object, ERROR);
2768 JSHandle<JSTaggedValue> prototype(thread, JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(object)));
2769 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
2770 return JSNApiHelper::ToLocal<JSValueRef>(prototype);
2771 }
2772
SetPrototype(const EcmaVM * vm,Local<ObjectRef> prototype)2773 bool ObjectRef::SetPrototype(const EcmaVM *vm, Local<ObjectRef> prototype)
2774 {
2775 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2776 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2777 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
2778 JSHandle<JSObject> proto(JSNApiHelper::ToJSHandle(prototype));
2779 return JSTaggedValue::SetPrototype(thread, JSHandle<JSTaggedValue>(object), JSHandle<JSTaggedValue>(proto));
2780 }
2781
DefineProperty(const EcmaVM * vm,Local<JSValueRef> key,PropertyAttribute attribute)2782 bool ObjectRef::DefineProperty(const EcmaVM *vm, Local<JSValueRef> key, PropertyAttribute attribute)
2783 {
2784 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2785 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2786 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
2787 LOG_IF_SPECIAL(object, ERROR);
2788 JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
2789 PropertyDescriptor desc(thread, attribute.IsWritable(), attribute.IsEnumerable(), attribute.IsConfigurable());
2790 desc.SetValue(JSNApiHelper::ToJSHandle(attribute.GetValue(vm)));
2791 return JSTaggedValue::DefinePropertyOrThrow(thread, object, keyValue, desc);
2792 }
2793
Has(const EcmaVM * vm,Local<JSValueRef> key)2794 bool ObjectRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
2795 {
2796 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2797 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2798 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
2799 LOG_IF_SPECIAL(object, ERROR);
2800 JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
2801 return JSTaggedValue::HasProperty(thread, object, keyValue);
2802 }
2803
Has(const EcmaVM * vm,uint32_t key)2804 bool ObjectRef::Has(const EcmaVM *vm, uint32_t key)
2805 {
2806 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2807 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2808 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
2809 LOG_IF_SPECIAL(object, ERROR);
2810 return JSTaggedValue::HasProperty(thread, object, key);
2811 }
2812
HasOwnProperty(const EcmaVM * vm,Local<JSValueRef> key)2813 bool ObjectRef::HasOwnProperty(const EcmaVM *vm, Local<JSValueRef> key)
2814 {
2815 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2816 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2817 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
2818 LOG_IF_SPECIAL(object, ERROR);
2819 JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
2820 return JSTaggedValue::HasOwnProperty(thread, object, keyValue);
2821 }
2822
Delete(const EcmaVM * vm,Local<JSValueRef> key)2823 bool ObjectRef::Delete(const EcmaVM *vm, Local<JSValueRef> key)
2824 {
2825 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2826 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2827 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
2828 LOG_IF_SPECIAL(object, ERROR);
2829 JSHandle<JSTaggedValue> keyValue(JSNApiHelper::ToJSHandle(key));
2830 return JSTaggedValue::DeleteProperty(thread, object, keyValue);
2831 }
2832
Delete(const EcmaVM * vm,uint32_t key)2833 bool ObjectRef::Delete(const EcmaVM *vm, uint32_t key)
2834 {
2835 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
2836 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2837 JSHandle<JSTaggedValue> object(JSNApiHelper::ToJSHandle(this));
2838 LOG_IF_SPECIAL(object, ERROR);
2839 JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(key));
2840 return JSTaggedValue::DeleteProperty(thread, object, keyHandle);
2841 }
2842
Freeze(const EcmaVM * vm)2843 Local<JSValueRef> ObjectRef::Freeze(const EcmaVM *vm)
2844 {
2845 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2846 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2847 EscapeLocalScope scope(vm);
2848 JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(this);
2849 LOG_IF_SPECIAL(object, ERROR);
2850 JSHandle<JSObject> obj(object);
2851 bool status = JSObject::SetIntegrityLevel(thread, obj, ecmascript::IntegrityLevel::FROZEN);
2852 if (JSNApi::HasPendingException(vm)) {
2853 JSHandle<JSTaggedValue> exception(thread, JSTaggedValue::Exception());
2854 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(exception));
2855 }
2856 if (!status) {
2857 LOG_ECMA(ERROR) << "Freeze: freeze failed";
2858 Local<StringRef> message = StringRef::NewFromUtf8(vm, "Freeze: freeze failed");
2859 Local<JSValueRef> error = Exception::Error(vm, message);
2860 JSNApi::ThrowException(vm, error);
2861 JSHandle<JSTaggedValue> exception(thread, JSTaggedValue::Exception());
2862 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(exception));
2863 }
2864 JSHandle<JSTaggedValue> resultValue(obj);
2865 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(resultValue));
2866 }
2867
Seal(const EcmaVM * vm)2868 Local<JSValueRef> ObjectRef::Seal(const EcmaVM *vm)
2869 {
2870 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2871 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2872 EscapeLocalScope scope(vm);
2873 JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(this);
2874 LOG_IF_SPECIAL(object, ERROR);
2875 JSHandle<JSObject> obj(object);
2876 bool status = JSObject::SetIntegrityLevel(thread, obj, ecmascript::IntegrityLevel::SEALED);
2877 if (JSNApi::HasPendingException(vm)) {
2878 JSHandle<JSTaggedValue> exception(thread, JSTaggedValue::Exception());
2879 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(exception));
2880 }
2881 if (!status) {
2882 LOG_ECMA(ERROR) << "Seal: seal failed";
2883 Local<StringRef> message = StringRef::NewFromUtf8(vm, "Freeze: freeze failed");
2884 Local<JSValueRef> error = Exception::Error(vm, message);
2885 JSNApi::ThrowException(vm, error);
2886 JSHandle<JSTaggedValue> exception(thread, JSTaggedValue::Exception());
2887 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(exception));
2888 }
2889 JSHandle<JSTaggedValue> resultValue(obj);
2890 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(resultValue));
2891 }
2892
SetNativePointerFieldCount(const EcmaVM * vm,int32_t count)2893 void ObjectRef::SetNativePointerFieldCount(const EcmaVM *vm, int32_t count)
2894 {
2895 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
2896 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2897 // ObjectRef::New may return special value if exception occurs.
2898 // So we need do special value check before use it.
2899 DCHECK_SPECIAL_VALUE(this);
2900 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
2901 object->SetNativePointerFieldCount(thread, count);
2902 }
2903
GetNativePointerFieldCount(const EcmaVM * vm)2904 int32_t ObjectRef::GetNativePointerFieldCount(const EcmaVM *vm)
2905 {
2906 // ObjectRef::New may return special value if exception occurs.
2907 // So we need do special value check before use it.
2908 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
2909 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2910 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
2911 return object->GetNativePointerFieldCount();
2912 }
2913
GetNativePointerField(const EcmaVM * vm,int32_t index)2914 void *ObjectRef::GetNativePointerField(const EcmaVM *vm, int32_t index)
2915 {
2916 // ObjectRef::New may return special value if exception occurs.
2917 // So we need do special value check before use it.
2918 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
2919 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2920 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
2921 return object->GetNativePointerField(index);
2922 }
2923
SetNativePointerField(const EcmaVM * vm,int32_t index,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)2924 void ObjectRef::SetNativePointerField(const EcmaVM *vm, int32_t index, void *nativePointer,
2925 NativePointerCallback callBack, void *data, size_t nativeBindingsize)
2926 {
2927 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
2928 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2929 // ObjectRef::New may return special value if exception occurs.
2930 // So we need do special value check before use it.
2931 DCHECK_SPECIAL_VALUE(this);
2932 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
2933 object->SetNativePointerField(thread, index, nativePointer, callBack, data, nativeBindingsize);
2934 }
2935
SetConcurrentNativePointerField(const EcmaVM * vm,int32_t index,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)2936 void ObjectRef::SetConcurrentNativePointerField(const EcmaVM *vm, int32_t index, void *nativePointer,
2937 NativePointerCallback callBack, void *data, size_t nativeBindingsize)
2938 {
2939 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
2940 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2941 // ObjectRef::New may return special value if exception occurs.
2942 // So we need do special value check before use it.
2943 DCHECK_SPECIAL_VALUE(this);
2944 JSHandle<JSObject> object(JSNApiHelper::ToJSHandle(this));
2945 object->SetNativePointerField(thread, index, nativePointer, callBack, data, nativeBindingsize, Concurrent::YES);
2946 }
2947
2948 // -------------------------------- NativePointerRef ------------------------------------
New(const EcmaVM * vm,void * nativePointer,size_t nativeBindingsize)2949 Local<NativePointerRef> NativePointerRef::New(const EcmaVM *vm, void *nativePointer, size_t nativeBindingsize)
2950 {
2951 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2952 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2953 ObjectFactory *factory = vm->GetFactory();
2954 JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer, nullptr, nullptr,
2955 false, nativeBindingsize);
2956 return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
2957 }
2958
New(const EcmaVM * vm,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)2959 Local<NativePointerRef> NativePointerRef::New(
2960 const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize)
2961 {
2962 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2963 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2964 ObjectFactory *factory = vm->GetFactory();
2965 JSHandle<JSNativePointer> obj = factory->NewJSNativePointer(nativePointer, callBack, data,
2966 false, nativeBindingsize);
2967 return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
2968 }
2969
NewConcurrent(const EcmaVM * vm,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)2970 Local<NativePointerRef> NativePointerRef::NewConcurrent(
2971 const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize)
2972 {
2973 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2974 ecmascript::ThreadManagedScope managedScope(thread);
2975 ObjectFactory *factory = vm->GetFactory();
2976 JSHandle<JSNativePointer> obj =
2977 factory->NewJSNativePointer(nativePointer, callBack, data, false, nativeBindingsize, Concurrent::YES);
2978 return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
2979 }
2980
NewSendable(const EcmaVM * vm,void * nativePointer,NativePointerCallback callBack,void * data,size_t nativeBindingsize)2981 Local<NativePointerRef> NativePointerRef::NewSendable(
2982 const EcmaVM *vm, void *nativePointer, NativePointerCallback callBack, void *data, size_t nativeBindingsize)
2983 {
2984 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
2985 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
2986 ObjectFactory *factory = vm->GetFactory();
2987 JSHandle<JSNativePointer> obj =
2988 factory->NewSJSNativePointer(nativePointer, callBack, data, false, nativeBindingsize);
2989 return JSNApiHelper::ToLocal<NativePointerRef>(JSHandle<JSTaggedValue>(obj));
2990 }
2991
Value()2992 void *NativePointerRef::Value()
2993 {
2994 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
2995 JSHandle<JSTaggedValue> nativePointer = JSNApiHelper::ToJSHandle(this);
2996 return JSHandle<JSNativePointer>(nativePointer)->GetExternalPointer();
2997 }
2998
2999 // ---------------------------------- Buffer -----------------------------------
New(const EcmaVM * vm,int32_t length)3000 Local<ArrayBufferRef> ArrayBufferRef::New(const EcmaVM *vm, int32_t length)
3001 {
3002 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3003 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3004 ObjectFactory *factory = vm->GetFactory();
3005 JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(length);
3006 return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
3007 }
3008
New(const EcmaVM * vm,void * buffer,int32_t length,const NativePointerCallback & deleter,void * data)3009 Local<ArrayBufferRef> ArrayBufferRef::New(
3010 const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data)
3011 {
3012 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3013 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3014 ObjectFactory *factory = vm->GetFactory();
3015 JSHandle<JSArrayBuffer> arrayBuffer = factory->NewJSArrayBuffer(buffer, length, deleter, data);
3016 return JSNApiHelper::ToLocal<ArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
3017 }
3018
ByteLength(const EcmaVM * vm)3019 int32_t ArrayBufferRef::ByteLength(const EcmaVM *vm)
3020 {
3021 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3022 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3023 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3024 LOG_IF_SPECIAL(arrayBuffer, FATAL);
3025 return arrayBuffer->GetArrayBufferByteLength();
3026 }
3027
GetBuffer(const EcmaVM * vm)3028 void *ArrayBufferRef::GetBuffer(const EcmaVM *vm)
3029 {
3030 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
3031 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3032 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3033 JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData();
3034 if (!bufferData.IsJSNativePointer()) {
3035 return nullptr;
3036 }
3037 return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
3038 }
3039
Detach(const EcmaVM * vm)3040 void ArrayBufferRef::Detach(const EcmaVM *vm)
3041 {
3042 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3043 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3044 // arraybuffer is not shared. Do not need to switch state
3045 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3046 arrayBuffer->Detach(thread);
3047 }
3048
IsDetach(const EcmaVM * vm)3049 bool ArrayBufferRef::IsDetach(const EcmaVM *vm)
3050 {
3051 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
3052 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3053 JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3054 return arrayBuffer->IsDetach();
3055 }
3056
New(const EcmaVM * vm,int32_t length)3057 Local<SendableArrayBufferRef> SendableArrayBufferRef::New(const EcmaVM *vm, int32_t length)
3058 {
3059 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3060 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3061 ObjectFactory *factory = vm->GetFactory();
3062 JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer = factory->NewJSSendableArrayBuffer(length);
3063 return JSNApiHelper::ToLocal<SendableArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
3064 }
3065
New(const EcmaVM * vm,void * buffer,int32_t length,const NativePointerCallback & deleter,void * data)3066 Local<SendableArrayBufferRef> SendableArrayBufferRef::New(
3067 const EcmaVM *vm, void *buffer, int32_t length, const NativePointerCallback &deleter, void *data)
3068 {
3069 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3070 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3071 ObjectFactory *factory = vm->GetFactory();
3072 JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer =
3073 factory->NewJSSendableArrayBuffer(buffer, length, deleter, data);
3074 return JSNApiHelper::ToLocal<SendableArrayBufferRef>(JSHandle<JSTaggedValue>(arrayBuffer));
3075 }
3076
ByteLength(const EcmaVM * vm)3077 int32_t SendableArrayBufferRef::ByteLength(const EcmaVM *vm)
3078 {
3079 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3080 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3081 JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3082 LOG_IF_SPECIAL(arrayBuffer, FATAL);
3083 return arrayBuffer->GetArrayBufferByteLength();
3084 }
3085
Detach(const EcmaVM * vm)3086 void SendableArrayBufferRef::Detach(const EcmaVM *vm)
3087 {
3088 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3089 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3090 JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3091 arrayBuffer->Detach(thread);
3092 }
3093
IsDetach(const EcmaVM * vm)3094 bool SendableArrayBufferRef::IsDetach(const EcmaVM *vm)
3095 {
3096 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
3097 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3098 JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3099 return arrayBuffer->IsDetach();
3100 }
3101
GetBuffer(const EcmaVM * vm)3102 void *SendableArrayBufferRef::GetBuffer(const EcmaVM *vm)
3103 {
3104 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, nullptr);
3105 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3106 JSHandle<ecmascript::JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(this));
3107 JSTaggedValue bufferData = arrayBuffer->GetArrayBufferData();
3108 if (!bufferData.IsJSNativePointer()) {
3109 return nullptr;
3110 }
3111 return JSNativePointer::Cast(bufferData.GetTaggedObject())->GetExternalPointer();
3112 }
3113
3114 // ---------------------------------- DateRef -----------------------------------
New(const EcmaVM * vm,double time)3115 Local<DateRef> DateRef::New(const EcmaVM *vm, double time)
3116 {
3117 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3118 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3119 ObjectFactory *factory = vm->GetFactory();
3120 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
3121 JSHandle<JSFunction> dateFunction(globalEnv->GetDateFunction());
3122 JSHandle<JSDate> dateObject(factory->NewJSObjectByConstructor(dateFunction));
3123 dateObject->SetTimeValue(thread, JSTaggedValue(time));
3124 return JSNApiHelper::ToLocal<DateRef>(JSHandle<JSTaggedValue>(dateObject));
3125 }
3126
ToString(const EcmaVM * vm)3127 Local<StringRef> DateRef::ToString(const EcmaVM *vm)
3128 {
3129 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3130 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3131 JSHandle<JSDate> date(JSNApiHelper::ToJSHandle(this));
3132 LOG_IF_SPECIAL(date, ERROR);
3133 JSTaggedValue dateStr = date->ToString(thread);
3134 if (!dateStr.IsString()) {
3135 auto constants = thread->GlobalConstants();
3136 return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString());
3137 }
3138 JSHandle<JSTaggedValue> dateStrHandle(thread, dateStr);
3139 return JSNApiHelper::ToLocal<StringRef>(dateStrHandle);
3140 }
3141
GetTime(const EcmaVM * vm)3142 double DateRef::GetTime(const EcmaVM *vm)
3143 {
3144 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0.0);
3145 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3146 JSHandle<JSDate> date(JSNApiHelper::ToJSHandle(this));
3147 if (!date->IsDate()) {
3148 LOG_ECMA(ERROR) << "Not a Date Object";
3149 }
3150 return date->GetTime().GetDouble();
3151 }
3152
3153 // ---------------------------------- TypedArray -----------------------------------
ByteLength(const EcmaVM * vm)3154 uint32_t TypedArrayRef::ByteLength(const EcmaVM *vm)
3155 {
3156 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3157 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3158 JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3159 LOG_IF_SPECIAL(typedArray, FATAL);
3160 return typedArray->GetByteLength();
3161 }
3162
ByteOffset(const EcmaVM * vm)3163 uint32_t TypedArrayRef::ByteOffset(const EcmaVM *vm)
3164 {
3165 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3166 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3167 JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3168 LOG_IF_SPECIAL(typedArray, FATAL);
3169 return typedArray->GetByteOffset();
3170 }
3171
ArrayLength(const EcmaVM * vm)3172 uint32_t TypedArrayRef::ArrayLength(const EcmaVM *vm)
3173 {
3174 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3175 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3176 JSHandle<JSTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3177 LOG_IF_SPECIAL(typedArray, FATAL);
3178 return typedArray->GetArrayLength();
3179 }
3180
GetArrayBuffer(const EcmaVM * vm)3181 Local<ArrayBufferRef> TypedArrayRef::GetArrayBuffer(const EcmaVM *vm)
3182 {
3183 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3184 ecmascript::ThreadManagedScope managedScope(thread);
3185 JSHandle<JSTypedArray> typeArray(JSNApiHelper::ToJSHandle(this));
3186 LOG_IF_SPECIAL(typeArray, ERROR);
3187 JSHandle<JSTaggedValue> arrayBuffer(thread, JSTypedArray::GetOffHeapBuffer(thread, typeArray));
3188 return JSNApiHelper::ToLocal<ArrayBufferRef>(arrayBuffer);
3189 }
3190
ByteLength(const EcmaVM * vm)3191 uint32_t SendableTypedArrayRef::ByteLength(const EcmaVM *vm)
3192 {
3193 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3194 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3195 JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3196 LOG_IF_SPECIAL(typedArray, FATAL);
3197 return typedArray->GetByteLength();
3198 }
3199
ByteOffset(const EcmaVM * vm)3200 uint32_t SendableTypedArrayRef::ByteOffset(const EcmaVM *vm)
3201 {
3202 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3203 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3204 JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3205 LOG_IF_SPECIAL(typedArray, FATAL);
3206 return typedArray->GetByteOffset();
3207 }
3208
ArrayLength(const EcmaVM * vm)3209 uint32_t SendableTypedArrayRef::ArrayLength(const EcmaVM *vm)
3210 {
3211 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3212 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3213 JSHandle<ecmascript::JSSharedTypedArray> typedArray(JSNApiHelper::ToJSHandle(this));
3214 LOG_IF_SPECIAL(typedArray, FATAL);
3215 return typedArray->GetArrayLength();
3216 }
3217
GetArrayBuffer(const EcmaVM * vm)3218 Local<SendableArrayBufferRef> SendableTypedArrayRef::GetArrayBuffer(const EcmaVM *vm)
3219 {
3220 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3221 ecmascript::ThreadManagedScope managedScope(thread);
3222 JSHandle<ecmascript::JSSharedTypedArray> typeArray(JSNApiHelper::ToJSHandle(this));
3223 LOG_IF_SPECIAL(typeArray, ERROR);
3224 JSHandle<JSTaggedValue> arrayBuffer(thread,
3225 ecmascript::JSSharedTypedArray::GetSharedOffHeapBuffer(thread, typeArray));
3226 return JSNApiHelper::ToLocal<SendableArrayBufferRef>(arrayBuffer);
3227 }
3228
3229 // ----------------------------------- FunctionRef --------------------------------------
New(EcmaVM * vm,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3230 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, FunctionCallback nativeFunc,
3231 NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3232 {
3233 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3234 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3235 ObjectFactory *factory = vm->GetFactory();
3236 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3237 JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(Callback::RegisterCallback)));
3238 current->SetFunctionExtraInfo(thread, reinterpret_cast<void *>(nativeFunc), deleter, data, nativeBindingsize);
3239 current->SetCallNapi(callNapi);
3240 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3241 }
3242
NewConcurrent(EcmaVM * vm,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3243 Local<FunctionRef> FunctionRef::NewConcurrent(EcmaVM *vm, FunctionCallback nativeFunc,
3244 NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3245 {
3246 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3247 ecmascript::ThreadManagedScope managedScope(thread);
3248 ObjectFactory *factory = vm->GetFactory();
3249 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3250 JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(Callback::RegisterCallback)));
3251 current->SetFunctionExtraInfo(thread, reinterpret_cast<void *>(nativeFunc), deleter,
3252 data, nativeBindingsize, Concurrent::YES);
3253 current->SetCallNapi(callNapi);
3254 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3255 }
3256
New(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3257 Local<FunctionRef> FunctionRef::New(EcmaVM *vm, InternalFunctionCallback nativeFunc,
3258 NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3259 {
3260 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3261 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3262 ObjectFactory *factory = vm->GetFactory();
3263 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3264 JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(nativeFunc)));
3265 current->SetFunctionExtraInfo(thread, nullptr, deleter, data, nativeBindingsize);
3266 current->SetCallNapi(callNapi);
3267 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3268 }
3269
NewSendable(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3270 Local<FunctionRef> FunctionRef::NewSendable(EcmaVM *vm,
3271 InternalFunctionCallback nativeFunc,
3272 NativePointerCallback deleter,
3273 void *data,
3274 bool callNapi,
3275 size_t nativeBindingsize)
3276 {
3277 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3278 ecmascript::ThreadManagedScope managedScope(thread);
3279 ObjectFactory *factory = vm->GetFactory();
3280 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3281 JSHandle<JSFunction> current(factory->NewSFunction(env, reinterpret_cast<void *>(nativeFunc)));
3282 current->SetSFunctionExtraInfo(thread, nullptr, deleter, data, nativeBindingsize);
3283 current->SetCallNapi(callNapi);
3284 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3285 }
3286
NewConcurrent(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3287 Local<FunctionRef> FunctionRef::NewConcurrent(EcmaVM *vm, InternalFunctionCallback nativeFunc,
3288 NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3289 {
3290 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3291 ecmascript::ThreadManagedScope managedScope(thread);
3292 ObjectFactory *factory = vm->GetFactory();
3293 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3294 JSHandle<JSFunction> current(factory->NewJSFunction(env, reinterpret_cast<void *>(nativeFunc)));
3295 current->SetFunctionExtraInfo(thread, nullptr, deleter, data, nativeBindingsize, Concurrent::YES);
3296 current->SetCallNapi(callNapi);
3297 return JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3298 }
3299
InitClassFunction(EcmaVM * vm,JSHandle<JSFunction> & func,bool callNapi)3300 static void InitClassFunction(EcmaVM *vm, JSHandle<JSFunction> &func, bool callNapi)
3301 {
3302 CROSS_THREAD_CHECK(vm);
3303 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3304 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3305 auto globalConst = thread->GlobalConstants();
3306 JSHandle<JSTaggedValue> accessor = globalConst->GetHandledFunctionPrototypeAccessor();
3307 func->SetPropertyInlinedProps(thread, JSFunction::CLASS_PROTOTYPE_INLINE_PROPERTY_INDEX,
3308 accessor.GetTaggedValue());
3309 accessor = globalConst->GetHandledFunctionLengthAccessor();
3310 func->SetPropertyInlinedProps(thread, JSFunction::LENGTH_INLINE_PROPERTY_INDEX,
3311 accessor.GetTaggedValue());
3312 JSHandle<JSObject> clsPrototype = JSFunction::NewJSFunctionPrototype(thread, func);
3313 clsPrototype->GetClass()->SetClassPrototype(true);
3314 func->SetClassConstructor(true);
3315 JSHandle<JSTaggedValue> parent = env->GetFunctionPrototype();
3316 JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(func), parent);
3317 func->SetHomeObject(thread, clsPrototype);
3318 func->SetCallNapi(callNapi);
3319 }
3320
NewClassFunction(EcmaVM * vm,FunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3321 Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, FunctionCallback nativeFunc,
3322 NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3323 {
3324 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3325 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3326 EscapeLocalScope scope(vm);
3327 ObjectFactory *factory = vm->GetFactory();
3328 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3329 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutName());
3330 JSHandle<JSFunction> current =
3331 factory->NewJSFunctionByHClass(reinterpret_cast<void *>(Callback::RegisterCallback),
3332 hclass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
3333 InitClassFunction(vm, current, callNapi);
3334 current->SetFunctionExtraInfo(thread, reinterpret_cast<void *>(nativeFunc), deleter, data, nativeBindingsize);
3335 Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3336 return scope.Escape(result);
3337 }
3338
NewConcurrentClassFunction(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3339 Local<FunctionRef> FunctionRef::NewConcurrentClassFunction(EcmaVM *vm, InternalFunctionCallback nativeFunc,
3340 NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3341 {
3342 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3343 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3344 EscapeLocalScope scope(vm);
3345 ObjectFactory *factory = vm->GetFactory();
3346 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3347 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutName());
3348 JSHandle<JSFunction> current =
3349 factory->NewJSFunctionByHClass(reinterpret_cast<void *>(nativeFunc),
3350 hclass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
3351 InitClassFunction(vm, current, callNapi);
3352 current->SetFunctionExtraInfo(thread, nullptr, deleter, data, nativeBindingsize, Concurrent::YES);
3353 Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3354 return scope.Escape(result);
3355 }
3356
NewClassFunction(EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,bool callNapi,size_t nativeBindingsize)3357 Local<FunctionRef> FunctionRef::NewClassFunction(EcmaVM *vm, InternalFunctionCallback nativeFunc,
3358 NativePointerCallback deleter, void *data, bool callNapi, size_t nativeBindingsize)
3359 {
3360 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3361 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3362 EscapeLocalScope scope(vm);
3363 ObjectFactory *factory = vm->GetFactory();
3364 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
3365 JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutName());
3366 JSHandle<JSFunction> current =
3367 factory->NewJSFunctionByHClass(reinterpret_cast<void *>(nativeFunc),
3368 hclass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
3369 InitClassFunction(vm, current, callNapi);
3370 current->SetFunctionExtraInfo(thread, nullptr, deleter, data, nativeBindingsize);
3371 Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(current));
3372 return scope.Escape(result);
3373 }
3374
NewSendableClassFunction(const EcmaVM * vm,InternalFunctionCallback nativeFunc,NativePointerCallback deleter,void * data,Local<StringRef> name,SendablePropertiesInfos & infos,Local<FunctionRef> parent,bool callNapi,size_t nativeBindingSize)3375 Local<FunctionRef> FunctionRef::NewSendableClassFunction(const EcmaVM *vm,
3376 InternalFunctionCallback nativeFunc,
3377 NativePointerCallback deleter,
3378 void *data,
3379 Local<StringRef> name,
3380 SendablePropertiesInfos &infos,
3381 Local<FunctionRef> parent,
3382 bool callNapi,
3383 size_t nativeBindingSize)
3384 {
3385 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3386 ecmascript::ThreadManagedScope managedScope(thread);
3387 EscapeLocalScope scope(vm);
3388 ObjectFactory *factory = vm->GetFactory();
3389
3390 bool hasParent = !parent->IsNull();
3391 JSNapiSendable sendable(thread, infos, name);
3392 JSHandle<JSHClass> prototypeHClass = JSHClass::CreateSPrototypeHClass(thread, sendable.GetNonStaticDescs());
3393 JSHandle<JSObject> prototype = factory->NewSharedOldSpaceJSObject(prototypeHClass);
3394 JSHandle<JSHClass> constructorHClass = JSHClass::CreateSConstructorHClass(thread, sendable.GetStaticDescs());
3395 JSHandle<JSFunction> constructor = factory->NewSFunctionByHClass(
3396 reinterpret_cast<void *>(nativeFunc), constructorHClass, ecmascript::FunctionKind::CLASS_CONSTRUCTOR);
3397
3398 sendable.SetSConstructor(constructor);
3399 JSObject::SetSProperties(thread, prototype, sendable.GetNonStaticDescs());
3400 JSObject::SetSProperties(thread, JSHandle<JSObject>::Cast(constructor), sendable.GetStaticDescs());
3401
3402 if (hasParent) {
3403 auto parentPrototype = parent->GetFunctionPrototype(vm);
3404 prototypeHClass->SetPrototype(thread, JSNApiHelper::ToJSHandle(parentPrototype));
3405 constructorHClass->SetPrototype(thread, JSNApiHelper::ToJSHandle(parent));
3406 }
3407 prototypeHClass->SetExtensible(false);
3408 constructor->SetHomeObject(thread, prototype);
3409 constructor->SetProtoOrHClass(thread, prototype);
3410 constructor->SetLexicalEnv(thread, constructor);
3411 constructor->SetCallNapi(callNapi);
3412 constructor->SetSFunctionExtraInfo(thread, nullptr, deleter, data, nativeBindingSize);
3413
3414 JSHClass *parentIHClass{nullptr};
3415 if (hasParent) {
3416 JSHandle<JSFunction> parentHandle(JSNApiHelper::ToJSHandle(parent));
3417 parentIHClass = reinterpret_cast<JSHClass *>(parentHandle->GetProtoOrHClass().GetTaggedObject());
3418 }
3419 JSHandle<JSHClass> iHClass = JSHClass::CreateSHClass(thread, sendable.GetInstanceDescs(), parentIHClass);
3420 iHClass->SetPrototype(thread, JSHandle<JSTaggedValue>(prototype));
3421 iHClass->SetExtensible(false);
3422 constructor->SetProtoOrHClass(thread, iHClass);
3423 constructorHClass->SetExtensible(false);
3424
3425 Local<FunctionRef> result = JSNApiHelper::ToLocal<FunctionRef>(JSHandle<JSTaggedValue>(constructor));
3426 return scope.Escape(result);
3427 }
3428
Call(const EcmaVM * vm,Local<JSValueRef> thisObj,const Local<JSValueRef> argv[],int32_t length)3429 Local<JSValueRef> FunctionRef::Call(const EcmaVM *vm, Local<JSValueRef> thisObj,
3430 const Local<JSValueRef> argv[], // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3431 int32_t length)
3432 {
3433 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3434 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3435 EscapeLocalScope scope(vm);
3436 FunctionCallScope callScope(EcmaVM::ConstCast(vm));
3437 if (!IsFunction(vm)) {
3438 return JSValueRef::Undefined(vm);
3439 }
3440 vm->GetJsDebuggerManager()->ClearSingleStepper();
3441 JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
3442 LOG_IF_SPECIAL(func, ERROR);
3443 JSHandle<JSTaggedValue> thisValue = JSNApiHelper::ToJSHandle(thisObj);
3444 JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
3445 EcmaRuntimeCallInfo *info =
3446 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, thisValue, undefined, length);
3447 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3448 for (int32_t i = 0; i < length; i++) {
3449 JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(argv[i]);
3450 info->SetCallArg(i, arg.GetTaggedValue());
3451 }
3452 JSTaggedValue result = JSFunction::Call(info);
3453 if (thread->HasPendingException()) {
3454 ecmascript::JsStackInfo::BuildCrashInfo(thread);
3455 }
3456 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3457 JSHandle<JSTaggedValue> resultValue(thread, result);
3458
3459 thread->GetCurrentEcmaContext()->ClearKeptObjects();
3460 vm->GetJsDebuggerManager()->NotifyReturnNative();
3461 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(resultValue));
3462 }
3463
CallForNapi(const EcmaVM * vm,JSValueRef * thisObj,JSValueRef * const argv[],int32_t length)3464 JSValueRef* FunctionRef::CallForNapi(const EcmaVM *vm, JSValueRef *thisObj,
3465 JSValueRef *const argv[], // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3466 int32_t length)
3467 {
3468 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, *JSValueRef::Hole(vm));
3469 ecmascript::ThreadManagedScope managedScope(thread);
3470 JSTaggedValue result;
3471 FunctionCallScope callScope(EcmaVM::ConstCast(vm));
3472 ASSERT(IsFunction(vm)); // IsFunction check has been done in napi.
3473 {
3474 LocalScope scope(vm);
3475 ecmascript::tooling::JsDebuggerManager *dm = vm->GetJsDebuggerManager();
3476 bool isDebugApp = dm->IsDebugApp();
3477 if (isDebugApp) {
3478 dm->ClearSingleStepper();
3479 }
3480 JSTaggedValue func = *reinterpret_cast<JSTaggedValue *>(this);
3481 JSTaggedValue undefined = thread->GlobalConstants()->GetUndefined();
3482 JSTaggedValue thisValue = undefined;
3483 if (thisObj != nullptr) {
3484 thisValue = *reinterpret_cast<JSTaggedValue *>(thisObj);
3485 }
3486 EcmaRuntimeCallInfo *info =
3487 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, thisValue, undefined, length);
3488 RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Hole(vm));
3489 for (int32_t i = 0; i < length; i++) {
3490 if (argv[i]) {
3491 // NewRuntimeCallInfo has set Undefined defaultly in Argv's slot.
3492 info->SetCallArg(i, JSNApiHelper::ToJSTaggedValue(argv[i]));
3493 }
3494 }
3495 if (LIKELY(thread->IsAsmInterpreter())) {
3496 STACK_LIMIT_CHECK(thread, reinterpret_cast<JSValueRef *>(*JSValueRef::Hole(vm)));
3497 auto *hclass = func.GetTaggedObject()->GetClass();
3498 if (hclass->IsClassConstructor()) {
3499 RETURN_STACK_BEFORE_THROW_IF_ASM(thread);
3500 THROW_TYPE_ERROR_AND_RETURN(thread, "class constructor cannot call",
3501 reinterpret_cast<JSValueRef *>(*JSValueRef::Hole(vm)));
3502 }
3503 result = ecmascript::InterpreterAssembly::Execute(info);
3504 } else {
3505 result = JSFunction::Call(info);
3506 }
3507 RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Hole(vm));
3508 if (thread->GetCurrentEcmaContext()->HasKeptObjects()) {
3509 thread->GetCurrentEcmaContext()->ClearKeptObjects();
3510 }
3511 if (isDebugApp && dm->IsMixedDebugEnabled()) {
3512 dm->NotifyReturnNative();
3513 }
3514 }
3515 JSHandle<JSTaggedValue> resultValue(thread, result);
3516 return reinterpret_cast<JSValueRef *>(resultValue.GetAddress());
3517 }
3518
Constructor(const EcmaVM * vm,const Local<JSValueRef> argv[],int32_t length)3519 Local<JSValueRef> FunctionRef::Constructor(const EcmaVM *vm,
3520 const Local<JSValueRef> argv[], // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3521 int32_t length)
3522 {
3523 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3524 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3525 FunctionCallScope callScope(EcmaVM::ConstCast(vm));
3526 if (!IsFunction(vm)) {
3527 return JSValueRef::Undefined(vm);
3528 }
3529 JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
3530 LOG_IF_SPECIAL(func, ERROR);
3531 JSHandle<JSTaggedValue> newTarget = func;
3532 JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
3533 EcmaRuntimeCallInfo *info =
3534 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, newTarget, length);
3535 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3536 for (int32_t i = 0; i < length; i++) {
3537 JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(argv[i]);
3538 info->SetCallArg(i, arg.GetTaggedValue());
3539 }
3540 JSTaggedValue result = JSFunction::Construct(info);
3541
3542 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3543 JSHandle<JSTaggedValue> resultValue(thread, result);
3544 return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
3545 }
3546
ConstructorOptimize(const EcmaVM * vm,JSValueRef * argv[],int32_t length)3547 JSValueRef* FunctionRef::ConstructorOptimize(const EcmaVM *vm,
3548 JSValueRef* argv[], // NOLINTNEXTLINE(modernize-avoid-c-arrays)
3549 int32_t length)
3550 {
3551 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, *JSValueRef::Undefined(vm));
3552 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3553 JSTaggedValue result;
3554 FunctionCallScope callScope(EcmaVM::ConstCast(vm));
3555 ASSERT(IsFunction(vm)); // IsFunction check has been done in napi.
3556 {
3557 LocalScope scope(vm);
3558 JSTaggedValue func = *reinterpret_cast<JSTaggedValue*>(this);
3559 JSTaggedValue newTarget = func;
3560 JSTaggedValue undefined = thread->GlobalConstants()->GetUndefined();
3561 EcmaRuntimeCallInfo *info =
3562 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, newTarget, length);
3563 RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Undefined(vm));
3564 for (int32_t i = 0; i < length; ++i) {
3565 JSTaggedValue arg =
3566 argv[i] == nullptr ? JSTaggedValue::Undefined() : JSNApiHelper::ToJSTaggedValue(argv[i]);
3567 info->SetCallArg(i, arg);
3568 }
3569 result = JSFunction::ConstructInternal(info);
3570 RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Undefined(vm));
3571 }
3572 JSHandle<JSTaggedValue> resultValue(thread, result);
3573 return reinterpret_cast<JSValueRef*>(resultValue.GetAddress());
3574 }
3575
GetFunctionPrototype(const EcmaVM * vm)3576 Local<JSValueRef> FunctionRef::GetFunctionPrototype(const EcmaVM *vm)
3577 {
3578 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3579 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3580 JSHandle<JSTaggedValue> func = JSNApiHelper::ToJSHandle(this);
3581 LOG_IF_SPECIAL(func, FATAL);
3582 JSHandle<JSTaggedValue> prototype(thread, JSHandle<JSFunction>(func)->GetFunctionPrototype());
3583 return JSNApiHelper::ToLocal<JSValueRef>(prototype);
3584 }
3585
Inherit(const EcmaVM * vm,Local<FunctionRef> parent)3586 bool FunctionRef::Inherit(const EcmaVM *vm, Local<FunctionRef> parent)
3587 {
3588 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3589 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3590 [[maybe_unused]] LocalScope scope(vm);
3591 JSHandle<JSTaggedValue> parentValue = JSNApiHelper::ToJSHandle(parent);
3592 JSHandle<JSObject> parentHandle = JSHandle<JSObject>::Cast(parentValue);
3593 JSHandle<JSObject> thisHandle = JSHandle<JSObject>::Cast(JSNApiHelper::ToJSHandle(this));
3594 LOG_IF_SPECIAL(thisHandle, ERROR);
3595 // Set this.__proto__ to parent
3596 bool res = JSObject::SetPrototype(thread, thisHandle, parentValue);
3597 if (!res) {
3598 return false;
3599 }
3600 // Set this.Prototype.__proto__ to parent.Prototype
3601 JSHandle<JSTaggedValue> parentProtoType(thread, JSFunction::PrototypeGetter(thread, parentHandle));
3602 JSHandle<JSTaggedValue> thisProtoType(thread, JSFunction::PrototypeGetter(thread, thisHandle));
3603 return JSObject::SetPrototype(thread, JSHandle<JSObject>::Cast(thisProtoType), parentProtoType);
3604 }
3605
SetName(const EcmaVM * vm,Local<StringRef> name)3606 void FunctionRef::SetName(const EcmaVM *vm, Local<StringRef> name)
3607 {
3608 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3609 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3610 [[maybe_unused]] LocalScope scope(vm);
3611 JSFunction *func = JSFunction::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject());
3612 JSTaggedValue key = JSNApiHelper::ToJSTaggedValue(*name);
3613 JSFunction::SetFunctionNameNoPrefix(thread, func, key);
3614 }
3615
GetName(const EcmaVM * vm)3616 Local<StringRef> FunctionRef::GetName(const EcmaVM *vm)
3617 {
3618 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3619 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3620 EscapeLocalScope scope(vm);
3621 JSHandle<JSFunctionBase> func(thread, JSNApiHelper::ToJSTaggedValue(this));
3622 JSHandle<JSTaggedValue> name = JSFunctionBase::GetFunctionName(thread, func);
3623 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3624 return scope.Escape(JSNApiHelper::ToLocal<StringRef>(name));
3625 }
3626
GetSourceCode(const EcmaVM * vm,int lineNumber)3627 Local<StringRef> FunctionRef::GetSourceCode(const EcmaVM *vm, int lineNumber)
3628 {
3629 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3630 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3631 EscapeLocalScope scope(vm);
3632 JSHandle<JSFunctionBase> func(thread, JSNApiHelper::ToJSTaggedValue(this));
3633 JSHandle<Method> method(thread, func->GetMethod());
3634 const JSPandaFile *jsPandaFile = method->GetJSPandaFile();
3635 DebugInfoExtractor *debugExtractor = JSPandaFileManager::GetInstance()->GetJSPtExtractor(jsPandaFile);
3636 ecmascript::CString entry = JSPandaFile::ENTRY_FUNCTION_NAME;
3637 if (!jsPandaFile->IsBundlePack()) {
3638 JSFunction *function = JSFunction::Cast(func.GetTaggedValue().GetTaggedObject());
3639 ecmascript::CString recordName = function->GetRecordName();
3640 ASSERT(!recordName.empty());
3641 entry = recordName;
3642 }
3643
3644 uint32_t mainMethodIndex = jsPandaFile->GetMainMethodIndex(entry);
3645 JSMutableHandle<JSTaggedValue> sourceCodeHandle(thread, BuiltinsBase::GetTaggedString(thread, ""));
3646 if (mainMethodIndex == 0) {
3647 return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
3648 }
3649
3650 const std::string &allSourceCode = debugExtractor->GetSourceCode(panda_file::File::EntityId(mainMethodIndex));
3651 std::string sourceCode = StringHelper::GetSpecifiedLine(allSourceCode, lineNumber);
3652 uint32_t codeLen = sourceCode.length();
3653 if (codeLen == 0) {
3654 return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
3655 }
3656
3657 if (sourceCode[codeLen - 1] == '\r') {
3658 sourceCode = sourceCode.substr(0, codeLen - 1);
3659 }
3660 sourceCodeHandle.Update(BuiltinsBase::GetTaggedString(thread, sourceCode.c_str()));
3661 return scope.Escape(JSNApiHelper::ToLocal<StringRef>(sourceCodeHandle));
3662 }
3663
IsNative(const EcmaVM * vm)3664 bool FunctionRef::IsNative(const EcmaVM *vm)
3665 {
3666 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3667 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3668 JSHandle<JSFunctionBase> func(thread, JSNApiHelper::ToJSTaggedValue(this));
3669 JSHandle<Method> method(thread, func->GetMethod());
3670 return method->IsNativeWithCallField();
3671 }
3672
SetData(const EcmaVM * vm,void * data,NativePointerCallback deleter,bool callNapi)3673 void FunctionRef::SetData(const EcmaVM *vm, void *data, NativePointerCallback deleter, [[maybe_unused]] bool callNapi)
3674 {
3675 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
3676 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3677 JSHandle<JSTaggedValue> funcValue = JSNApiHelper::ToJSHandle(this);
3678 JSHandle<JSFunction> function(funcValue);
3679 if (function->IsJSShared()) {
3680 function->SetSFunctionExtraInfo(thread, nullptr, deleter, data, 0);
3681 } else {
3682 function->SetFunctionExtraInfo(thread, nullptr, deleter, data, 0);
3683 }
3684 }
3685
GetData(const EcmaVM * vm)3686 void* FunctionRef::GetData(const EcmaVM *vm)
3687 {
3688 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
3689 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3690 JSHandle<JSTaggedValue> funcValue = JSNApiHelper::ToJSHandle(this);
3691 JSHandle<JSFunction> function(funcValue);
3692 JSTaggedValue extraInfoValue = function->GetFunctionExtraInfo();
3693 if (!extraInfoValue.IsNativePointer()) {
3694 return nullptr;
3695 }
3696 auto extraInfo = JSNativePointer::Cast(extraInfoValue.GetTaggedObject());
3697 return extraInfo->GetData();
3698 }
3699
3700 // ----------------------------------- ArrayRef ----------------------------------------
New(const EcmaVM * vm,uint32_t length)3701 Local<ArrayRef> ArrayRef::New(const EcmaVM *vm, uint32_t length)
3702 {
3703 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3704 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3705 JSTaggedNumber arrayLen(length);
3706 JSHandle<JSTaggedValue> array = JSArray::ArrayCreate(thread, arrayLen);
3707 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3708 return JSNApiHelper::ToLocal<ArrayRef>(array);
3709 }
3710
Length(const EcmaVM * vm)3711 uint32_t ArrayRef::Length(const EcmaVM *vm)
3712 {
3713 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3714 return JSArray::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetArrayLength();
3715 }
3716
GetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index)3717 Local<JSValueRef> ArrayRef::GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index)
3718 {
3719 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3720 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3721 JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(obj);
3722 JSHandle<JSTaggedValue> result = JSArray::FastGetPropertyByValue(thread, object, index);
3723 return JSNApiHelper::ToLocal<JSValueRef>(result);
3724 }
3725
SetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index,Local<JSValueRef> value)3726 bool ArrayRef::SetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value)
3727 {
3728 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3729 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3730 JSHandle<JSTaggedValue> objectHandle = JSNApiHelper::ToJSHandle(obj);
3731 JSHandle<JSTaggedValue> valueHandle = JSNApiHelper::ToJSHandle(value);
3732 return JSArray::FastSetPropertyByValue(thread, objectHandle, index, valueHandle);
3733 }
3734
3735 // ----------------------------------- SendableArrayRef ----------------------------------------
New(const EcmaVM * vm,uint32_t length)3736 Local<SendableArrayRef> SendableArrayRef::New(const EcmaVM *vm, uint32_t length)
3737 {
3738 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3739 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3740 JSTaggedNumber arrayLen(length);
3741 JSHandle<JSTaggedValue> array = ecmascript::JSSharedArray::ArrayCreate(thread, arrayLen);
3742 JSHandle<JSTaggedValue> initialValue(thread, JSTaggedValue::Undefined());
3743 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
3744 for (uint32_t i = 0; i < length; i++) {
3745 key.Update(JSTaggedValue(i));
3746 JSObject::CreateDataPropertyOrThrow(
3747 thread, JSHandle<JSObject>(array), key, initialValue, ecmascript::JSShared::SCheckMode::SKIP);
3748 }
3749 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
3750 return JSNApiHelper::ToLocal<SendableArrayRef>(array);
3751 }
3752
Length(const EcmaVM * vm)3753 uint32_t SendableArrayRef::Length(const EcmaVM *vm)
3754 {
3755 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, 0);
3756 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3757 return ecmascript::JSSharedArray::Cast(JSNApiHelper::ToJSTaggedValue(this).GetTaggedObject())->GetArrayLength();
3758 }
3759
GetValueAt(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index)3760 Local<JSValueRef> SendableArrayRef::GetValueAt(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index)
3761 {
3762 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
3763 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3764 JSHandle<JSTaggedValue> object = JSNApiHelper::ToJSHandle(obj);
3765 JSHandle<JSTaggedValue> result = ecmascript::JSSharedArray::FastGetPropertyByValue(thread, object, index);
3766 return JSNApiHelper::ToLocal<JSValueRef>(result);
3767 }
3768
SetProperty(const EcmaVM * vm,Local<JSValueRef> obj,uint32_t index,Local<JSValueRef> value)3769 bool SendableArrayRef::SetProperty(const EcmaVM *vm, Local<JSValueRef> obj, uint32_t index, Local<JSValueRef> value)
3770 {
3771 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
3772 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3773 JSHandle<JSTaggedValue> objectHandle = JSNApiHelper::ToJSHandle(obj);
3774 JSHandle<JSTaggedValue> valueHandle = JSNApiHelper::ToJSHandle(value);
3775 return ecmascript::JSSharedArray::SetProperty(
3776 thread, objectHandle, index, valueHandle, true, ecmascript::SCheckMode::CHECK);
3777 }
3778
3779 // ---------------------------------- Error ---------------------------------------
3780 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
3781 #define EXCEPTION_ERROR_NEW(name, type) \
3782 Local<JSValueRef> Exception::name(const EcmaVM *vm, Local<StringRef> message) \
3783 { \
3784 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm)); \
3785 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread()); \
3786 ObjectFactory *factory = vm->GetFactory(); \
3787 \
3788 JSHandle<EcmaString> messageValue(JSNApiHelper::ToJSHandle(message)); \
3789 JSHandle<JSTaggedValue> result(factory->NewJSError(ErrorType::type, \
3790 messageValue, ecmascript::StackCheck::NO)); \
3791 return JSNApiHelper::ToLocal<JSValueRef>(result); \
3792 }
3793
EXCEPTION_ERROR_ALL(EXCEPTION_ERROR_NEW)3794 EXCEPTION_ERROR_ALL(EXCEPTION_ERROR_NEW)
3795
3796 #undef EXCEPTION_ERROR_NEW
3797 // ---------------------------------- Error ---------------------------------------
3798
3799 // ---------------------------------- FunctionCallScope ---------------------------------------
3800 FunctionCallScope::FunctionCallScope(EcmaVM *vm) : vm_(vm)
3801 {
3802 vm_->IncreaseCallDepth();
3803 }
3804
~FunctionCallScope()3805 FunctionCallScope::~FunctionCallScope()
3806 {
3807 vm_->DecreaseCallDepth();
3808 if (vm_->IsTopLevelCallDepth()) {
3809 JSThread *thread = vm_->GetJSThread();
3810 ecmascript::ThreadManagedScope managedScope(vm_->GetJSThread());
3811 thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
3812 }
3813 }
3814
3815 // ------------------------------------- JSExecutionScope ------------------------------
JSExecutionScope(const EcmaVM * vm)3816 JSExecutionScope::JSExecutionScope([[maybe_unused]] const EcmaVM *vm)
3817 {
3818 }
3819
~JSExecutionScope()3820 JSExecutionScope::~JSExecutionScope()
3821 {
3822 lastCurrentThread_ = nullptr;
3823 isRevert_ = false;
3824 }
3825
3826 // ------------------------------------ JsiNativeScope -----------------------------------------------
3827
JsiNativeScope(const EcmaVM * vm)3828 JsiNativeScope::JsiNativeScope(const EcmaVM *vm)
3829 {
3830 thread_ = vm->GetAssociatedJSThread();
3831 #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
3832 if (vm->IsCollectingScopeLockStats()) {
3833 const_cast<EcmaVM*>(vm)->IncreaseEnterJsiNativeScopeCount();
3834 const_cast<EcmaVM*>(vm)->IncreaseUpdateThreadStateTransCount();
3835 }
3836 #endif
3837 oldThreadState_ = static_cast<uint16_t>(thread_->GetState());
3838 thread_->UpdateState(ecmascript::ThreadState::NATIVE);
3839 }
3840
~JsiNativeScope()3841 JsiNativeScope::~JsiNativeScope()
3842 {
3843 thread_->UpdateState(static_cast<ecmascript::ThreadState>(oldThreadState_));
3844 }
3845
3846 // ------------------------------------ JsiFastNativeScope -----------------------------------------------
3847
JsiFastNativeScope(const EcmaVM * vm)3848 JsiFastNativeScope::JsiFastNativeScope(const EcmaVM *vm)
3849 {
3850 thread_ = vm->GetAssociatedJSThread();
3851 #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
3852 if (vm->IsCollectingScopeLockStats()) {
3853 const_cast<EcmaVM*>(vm)->IncreaseEnterFastNativeScopeCount();
3854 const_cast<EcmaVM*>(vm)->IncreaseUpdateThreadStateTransCount();
3855 }
3856 #endif
3857 ecmascript::ThreadState oldState = thread_->GetState();
3858 if (oldState == ecmascript::ThreadState::RUNNING) {
3859 return;
3860 }
3861 oldThreadState_ = static_cast<uint16_t>(oldState);
3862 hasSwitchState_ = true;
3863 thread_->UpdateState(ecmascript::ThreadState::RUNNING);
3864 }
3865
~JsiFastNativeScope()3866 JsiFastNativeScope::~JsiFastNativeScope()
3867 {
3868 if (hasSwitchState_) {
3869 thread_->UpdateState(static_cast<ecmascript::ThreadState>(oldThreadState_));
3870 }
3871 }
3872
3873 // ------------------------------------ JsiRuntimeCallInfo -----------------------------------------------
GetData()3874 void *JsiRuntimeCallInfo::GetData()
3875 {
3876 ecmascript::ThreadManagedScope managedScope(thread_);
3877 JSHandle<JSTaggedValue> constructor = BuiltinsBase::GetConstructor(reinterpret_cast<EcmaRuntimeCallInfo *>(this));
3878 if (!constructor->IsJSFunction()) {
3879 return nullptr;
3880 }
3881 JSHandle<JSFunction> function(constructor);
3882 JSTaggedValue extraInfoValue = function->GetFunctionExtraInfo();
3883 if (!extraInfoValue.IsJSNativePointer()) {
3884 return nullptr;
3885 }
3886 return JSNativePointer::Cast(extraInfoValue.GetTaggedObject())->GetData();
3887 }
3888
GetVM() const3889 EcmaVM *JsiRuntimeCallInfo::GetVM() const
3890 {
3891 return thread_->GetEcmaVM();
3892 }
3893
3894 // ---------------------------------------JSNApi-------------------------------------------
LoadPatch(EcmaVM * vm,const std::string & patchFileName,const std::string & baseFileName)3895 PatchErrorCode JSNApi::LoadPatch(EcmaVM *vm, const std::string &patchFileName, const std::string &baseFileName)
3896 {
3897 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, PatchErrorCode::INTERNAL_ERROR);
3898 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3899 ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
3900 return quickFixManager->LoadPatch(thread, patchFileName, baseFileName);
3901 }
3902
LoadPatch(EcmaVM * vm,const std::string & patchFileName,uint8_t * patchBuffer,size_t patchSize,const std::string & baseFileName,uint8_t * baseBuffer,size_t baseSize)3903 PatchErrorCode JSNApi::LoadPatch(EcmaVM *vm,
3904 const std::string &patchFileName, uint8_t *patchBuffer, size_t patchSize,
3905 const std::string &baseFileName, uint8_t *baseBuffer, size_t baseSize)
3906 {
3907 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, PatchErrorCode::INTERNAL_ERROR);
3908 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3909 ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
3910 return quickFixManager->LoadPatch(
3911 thread, patchFileName, patchBuffer, patchSize, baseFileName, baseBuffer, baseSize);
3912 }
3913
UnloadPatch(EcmaVM * vm,const std::string & patchFileName)3914 PatchErrorCode JSNApi::UnloadPatch(EcmaVM *vm, const std::string &patchFileName)
3915 {
3916 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, PatchErrorCode::INTERNAL_ERROR);
3917 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
3918 ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
3919 return quickFixManager->UnloadPatch(thread, patchFileName);
3920 }
3921
3922 /*
3923 * check whether the exception is caused by quickfix methods.
3924 */
IsQuickFixCausedException(EcmaVM * vm,Local<ObjectRef> exception,const std::string & patchFileName)3925 bool JSNApi::IsQuickFixCausedException(EcmaVM *vm, Local<ObjectRef> exception, const std::string &patchFileName)
3926 {
3927 if (exception.IsEmpty()) {
3928 return false;
3929 }
3930 CROSS_THREAD_CHECK(vm);
3931 ecmascript::ThreadManagedScope managedScope(thread);
3932 ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
3933 JSHandle<JSTaggedValue> exceptionInfo = JSNApiHelper::ToJSHandle(exception);
3934 return quickFixManager->IsQuickFixCausedException(thread, exceptionInfo, patchFileName);
3935 }
3936
3937 /*
3938 * register quickfix query function.
3939 */
RegisterQuickFixQueryFunc(EcmaVM * vm,std::function<bool (std::string baseFileName,std::string & patchFileName,uint8_t ** patchBuffer,size_t & patchSize)> callBack)3940 void JSNApi::RegisterQuickFixQueryFunc(EcmaVM *vm, std::function<bool(std::string baseFileName,
3941 std::string &patchFileName,
3942 uint8_t **patchBuffer,
3943 size_t &patchSize)> callBack)
3944 {
3945 CROSS_THREAD_CHECK(vm);
3946 ecmascript::QuickFixManager *quickFixManager = vm->GetQuickFixManager();
3947 quickFixManager->RegisterQuickFixQueryFunc(callBack);
3948 }
3949
IsBundle(EcmaVM * vm)3950 bool JSNApi::IsBundle(EcmaVM *vm)
3951 {
3952 return vm->IsBundlePack();
3953 }
3954
SetBundle(EcmaVM * vm,bool value)3955 void JSNApi::SetBundle(EcmaVM *vm, bool value)
3956 {
3957 vm->SetIsBundlePack(value);
3958 }
3959
IsNormalizedOhmUrlPack(EcmaVM * vm)3960 bool JSNApi::IsNormalizedOhmUrlPack(EcmaVM *vm)
3961 {
3962 return vm->IsNormalizedOhmUrlPack();
3963 }
3964
SetModuleInfo(EcmaVM * vm,const std::string & assetPath,const std::string & entryPoint)3965 void JSNApi::SetModuleInfo(EcmaVM *vm, const std::string &assetPath, const std::string &entryPoint)
3966 {
3967 SetAssetPath(vm, assetPath);
3968 size_t pos = entryPoint.find_first_of("/");
3969 if (pos != std::string::npos) {
3970 SetBundleName(vm, entryPoint.substr(0, pos));
3971 ecmascript::CString moduleName = ModulePathHelper::GetModuleName(entryPoint.c_str());
3972 if (!moduleName.empty()) {
3973 SetModuleName(vm, moduleName.c_str());
3974 return;
3975 }
3976 }
3977 std::string errmsg = "SetModuleInfo: entryPoint:" + entryPoint + "is invalid.";
3978 LOG_ECMA(ERROR) << errmsg;
3979 Local<StringRef> message = StringRef::NewFromUtf8(vm, errmsg.c_str());
3980 Local<JSValueRef> error = Exception::Error(vm, message);
3981 JSNApi::ThrowException(vm, error);
3982 }
3983
3984 // note: The function SetAssetPath is a generic interface for previewing and physical machines.
SetAssetPath(EcmaVM * vm,const std::string & assetPath)3985 void JSNApi::SetAssetPath(EcmaVM *vm, const std::string &assetPath)
3986 {
3987 ecmascript::CString path = assetPath.c_str();
3988 // check input assetPath
3989 #if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS)
3990 if (!ModulePathHelper::ValidateAbcPath(path)) {
3991 LOG_FULL(FATAL) << "Invalid input assetPath: " << assetPath.c_str();
3992 }
3993 #endif
3994 vm->SetAssetPath(path);
3995 }
3996
SetLoop(EcmaVM * vm,void * loop)3997 void JSNApi::SetLoop(EcmaVM *vm, void *loop)
3998 {
3999 vm->SetLoop(loop);
4000 }
4001
SetWeakFinalizeTaskCallback(EcmaVM * vm,const WeakFinalizeTaskCallback & callback)4002 void JSNApi::SetWeakFinalizeTaskCallback(EcmaVM *vm, const WeakFinalizeTaskCallback &callback)
4003 {
4004 vm->GetAssociatedJSThread()->SetWeakFinalizeTaskCallback(callback);
4005 }
4006
SetAsyncCleanTaskCallback(EcmaVM * vm,const NativePointerTaskCallback & callback)4007 void JSNApi::SetAsyncCleanTaskCallback(EcmaVM *vm, const NativePointerTaskCallback &callback)
4008 {
4009 vm->GetAssociatedJSThread()->SetAsyncCleanTaskCallback(callback);
4010 }
4011
SetTriggerGCTaskCallback(EcmaVM * vm,const TriggerGCTaskCallback & callback)4012 void JSNApi::SetTriggerGCTaskCallback(EcmaVM *vm, const TriggerGCTaskCallback& callback)
4013 {
4014 vm->GetHeap()->GetIdleGCTrigger()->SetTriggerGCTaskCallback(callback);
4015 }
4016
GetAssetPath(EcmaVM * vm)4017 std::string JSNApi::GetAssetPath(EcmaVM *vm)
4018 {
4019 return vm->GetAssetPath().c_str();
4020 }
4021
SetMockModuleList(EcmaVM * vm,const std::map<std::string,std::string> & list)4022 void JSNApi::SetMockModuleList(EcmaVM *vm, const std::map<std::string, std::string> &list)
4023 {
4024 vm->SetMockModuleList(list);
4025 }
4026
SetHmsModuleList(EcmaVM * vm,const std::vector<panda::HmsMap> & list)4027 void JSNApi::SetHmsModuleList(EcmaVM *vm, const std::vector<panda::HmsMap> &list)
4028 {
4029 vm->SetHmsModuleList(list);
4030 }
4031
SetPkgAliasList(EcmaVM * vm,const std::map<std::string,std::string> & list)4032 void JSNApi::SetPkgAliasList(EcmaVM *vm, const std::map<std::string, std::string> &list)
4033 {
4034 ecmascript::CMap<ecmascript::CString, ecmascript::CString> pkgAliasList;
4035 for (auto it = list.begin(); it != list.end(); ++it) {
4036 pkgAliasList.emplace(it->first.c_str(), it->second.c_str());
4037 }
4038 vm->SetPkgAliasList(pkgAliasList);
4039 }
4040
SetPkgNameList(EcmaVM * vm,const std::map<std::string,std::string> & list)4041 void JSNApi::SetPkgNameList(EcmaVM *vm, const std::map<std::string, std::string> &list)
4042 {
4043 ecmascript::CMap<ecmascript::CString, ecmascript::CString> pkgNameList;
4044 for (auto it = list.begin(); it != list.end(); ++it) {
4045 pkgNameList.emplace(it->first.c_str(), it->second.c_str());
4046 }
4047 vm->SetPkgNameList(pkgNameList);
4048 }
GetPkgName(EcmaVM * vm,const std::string & moduleName)4049 std::string JSNApi::GetPkgName(EcmaVM *vm, const std::string &moduleName)
4050 {
4051 return vm->GetPkgName(moduleName.c_str()).c_str();
4052 }
4053
SetpkgContextInfoList(EcmaVM * vm,const std::map<std::string,std::vector<std::vector<std::string>>> & list)4054 void JSNApi::SetpkgContextInfoList(EcmaVM *vm, const std::map<std::string,
4055 std::vector<std::vector<std::string>>> &list)
4056 {
4057 ecmascript::CMap<ecmascript::CString, ecmascript::CMap<ecmascript::CString,
4058 ecmascript::CVector<ecmascript::CString>>> pkgContextInfoList;
4059 for (auto it = list.begin(); it != list.end(); it++) {
4060 const std::vector<std::vector<std::string>> vec = it->second;
4061 ecmascript::CMap<ecmascript::CString, ecmascript::CVector<ecmascript::CString>> map;
4062 for (size_t i = 0; i < vec.size(); i++) {
4063 ecmascript::CString pkgName = vec[i][0].c_str();
4064 ecmascript::CVector<ecmascript::CString> pkgContextInfo;
4065 for (size_t j = 1; j < vec[i].size(); j++) {
4066 pkgContextInfo.emplace_back(vec[i][j].c_str());
4067 }
4068 map.emplace(pkgName, pkgContextInfo);
4069 }
4070 pkgContextInfoList.emplace(it->first.c_str(), map);
4071 }
4072 vm->SetpkgContextInfoList(pkgContextInfoList);
4073 }
4074
4075 // Only used for env created by napi to set module execution mode
SetExecuteBufferMode(const EcmaVM * vm)4076 void JSNApi::SetExecuteBufferMode(const EcmaVM *vm)
4077 {
4078 ecmascript::ModuleManager *moduleManager =
4079 vm->GetAssociatedJSThread()->GetCurrentEcmaContext()->GetModuleManager();
4080 moduleManager->SetExecuteMode(ecmascript::ModuleExecuteMode::ExecuteBufferMode);
4081 }
4082
InitForConcurrentThread(EcmaVM * vm,ConcurrentCallback cb,void * data)4083 bool JSNApi::InitForConcurrentThread(EcmaVM *vm, ConcurrentCallback cb, void *data)
4084 {
4085 vm->SetConcurrentCallback(cb, data);
4086
4087 return true;
4088 }
4089
InitForConcurrentFunction(EcmaVM * vm,Local<JSValueRef> function,void * taskInfo)4090 bool JSNApi::InitForConcurrentFunction(EcmaVM *vm, Local<JSValueRef> function, void *taskInfo)
4091 {
4092 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4093 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
4094 [[maybe_unused]] LocalScope scope(vm);
4095 JSHandle<JSTaggedValue> funcVal = JSNApiHelper::ToJSHandle(function);
4096 JSHandle<JSFunction> transFunc = JSHandle<JSFunction>::Cast(funcVal);
4097 if (transFunc->GetFunctionKind() != ecmascript::FunctionKind::CONCURRENT_FUNCTION) {
4098 LOG_ECMA(ERROR) << "Function is not concurrent";
4099 return false;
4100 }
4101 transFunc->SetTaskConcurrentFuncFlag(1); // 1 : concurrent function flag
4102 thread->SetTaskInfo(reinterpret_cast<uintptr_t>(taskInfo));
4103 thread->SetIsInConcurrentScope(true);
4104 return true;
4105 }
4106
GetCurrentTaskInfo(const EcmaVM * vm)4107 void* JSNApi::GetCurrentTaskInfo(const EcmaVM *vm)
4108 {
4109 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
4110 return reinterpret_cast<void*>(thread->GetTaskInfo());
4111 }
4112
ClearCurrentTaskInfo(const EcmaVM * vm)4113 void JSNApi::ClearCurrentTaskInfo(const EcmaVM *vm)
4114 {
4115 JSThread *thread = vm->GetJSThread();
4116 thread->SetTaskInfo(reinterpret_cast<uintptr_t>(nullptr));
4117 thread->SetIsInConcurrentScope(false);
4118 }
4119
SetBundleName(EcmaVM * vm,const std::string & bundleName)4120 void JSNApi::SetBundleName(EcmaVM *vm, const std::string &bundleName)
4121 {
4122 ecmascript::CString name = bundleName.c_str();
4123 vm->SetBundleName(name);
4124 }
4125
GetBundleName(EcmaVM * vm)4126 std::string JSNApi::GetBundleName(EcmaVM *vm)
4127 {
4128 return vm->GetBundleName().c_str();
4129 }
4130
SetModuleName(EcmaVM * vm,const std::string & moduleName)4131 void JSNApi::SetModuleName(EcmaVM *vm, const std::string &moduleName)
4132 {
4133 ecmascript::CString name = moduleName.c_str();
4134 ecmascript::pgo::PGOProfilerManager::GetInstance()->SetModuleName(moduleName);
4135 vm->SetModuleName(name);
4136 }
4137
GetModuleName(EcmaVM * vm)4138 std::string JSNApi::GetModuleName(EcmaVM *vm)
4139 {
4140 return vm->GetModuleName().c_str();
4141 }
4142
GetCurrentModuleInfo(EcmaVM * vm,bool needRecordName)4143 std::pair<std::string, std::string> JSNApi::GetCurrentModuleInfo(EcmaVM *vm, bool needRecordName)
4144 {
4145 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
4146 return vm->GetCurrentModuleInfo(needRecordName);
4147 }
4148
NormalizePath(const std::string & string)4149 std::string JSNApi::NormalizePath(const std::string &string)
4150 {
4151 return PathHelper::NormalizePath(string.c_str()).c_str();
4152 }
4153
4154 // Enable cross thread execution.
AllowCrossThreadExecution(EcmaVM * vm)4155 void JSNApi::AllowCrossThreadExecution(EcmaVM *vm)
4156 {
4157 LOG_ECMA(WARN) << "enable cross thread execution";
4158 vm->GetAssociatedJSThread()->EnableCrossThreadExecution();
4159 }
4160
GetEnv(EcmaVM * vm)4161 void* JSNApi::GetEnv(EcmaVM *vm)
4162 {
4163 JSThread *thread = vm->GetJSThread();
4164 return thread->GetEnv();
4165 }
4166
SetEnv(EcmaVM * vm,void * env)4167 void JSNApi::SetEnv(EcmaVM *vm, void *env)
4168 {
4169 JSThread *thread = vm->GetJSThread();
4170 thread->SetEnv(env);
4171 }
4172
SynchronizVMInfo(EcmaVM * vm,const EcmaVM * hostVM)4173 void JSNApi::SynchronizVMInfo(EcmaVM *vm, const EcmaVM *hostVM)
4174 {
4175 vm->SetBundleName(hostVM->GetBundleName());
4176 vm->SetModuleName(hostVM->GetModuleName());
4177 vm->SetAssetPath(hostVM->GetAssetPath());
4178 vm->SetIsBundlePack(hostVM->IsBundlePack());
4179 vm->SetPkgNameList(hostVM->GetPkgNameList());
4180 vm->SetPkgAliasList(hostVM->GetPkgAliasList());
4181 vm->SetpkgContextInfoList(hostVM->GetPkgContextInfoLit());
4182
4183 ecmascript::ModuleManager *vmModuleManager =
4184 vm->GetAssociatedJSThread()->GetCurrentEcmaContext()->GetModuleManager();
4185 ecmascript::ModuleManager *hostVMModuleManager =
4186 hostVM->GetAssociatedJSThread()->GetCurrentEcmaContext()->GetModuleManager();
4187 vmModuleManager->SetExecuteMode(hostVMModuleManager->GetExecuteMode());
4188 vm->SetResolveBufferCallback(hostVM->GetResolveBufferCallback());
4189 }
4190
IsProfiling(EcmaVM * vm)4191 bool JSNApi::IsProfiling(EcmaVM *vm)
4192 {
4193 return vm->GetProfilerState();
4194 }
4195
SetProfilerState(const EcmaVM * vm,bool value)4196 void JSNApi::SetProfilerState(const EcmaVM *vm, bool value)
4197 {
4198 const_cast<EcmaVM*>(vm)->SetProfilerState(value);
4199 }
4200
SetSourceMapTranslateCallback(EcmaVM * vm,SourceMapTranslateCallback callback)4201 void JSNApi::SetSourceMapTranslateCallback(EcmaVM *vm, SourceMapTranslateCallback callback)
4202 {
4203 vm->SetSourceMapTranslateCallback(callback);
4204 }
4205
SetSourceMapCallback(EcmaVM * vm,SourceMapCallback callback)4206 void JSNApi::SetSourceMapCallback(EcmaVM *vm, SourceMapCallback callback)
4207 {
4208 vm->SetSourceMapCallback(callback);
4209 }
4210
GetStackBeforeCallNapiSuccess(EcmaVM * vm,bool & getStackBeforeCallNapiSuccess)4211 void JSNApi::GetStackBeforeCallNapiSuccess([[maybe_unused]] EcmaVM *vm,
4212 [[maybe_unused]] bool &getStackBeforeCallNapiSuccess)
4213 {
4214 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
4215 JSThread *thread = vm->GetJSThread();
4216 if (thread->GetIsProfiling()) {
4217 ecmascript::ThreadManagedScope managedScope(thread);
4218 getStackBeforeCallNapiSuccess = vm->GetProfiler()->GetStackBeforeCallNapi(thread);
4219 }
4220 #endif
4221 }
4222
GetStackAfterCallNapi(EcmaVM * vm)4223 void JSNApi::GetStackAfterCallNapi([[maybe_unused]] EcmaVM *vm)
4224 {
4225 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
4226 JSThread *thread = vm->GetJSThread();
4227 if (thread->GetIsProfiling()) {
4228 ecmascript::ThreadManagedScope managedScope(thread);
4229 vm->GetProfiler()->GetStackAfterCallNapi(thread);
4230 }
4231 #endif
4232 }
4233
CreateJSVM(const RuntimeOption & option)4234 EcmaVM *JSNApi::CreateJSVM(const RuntimeOption &option)
4235 {
4236 JSRuntimeOptions runtimeOptions;
4237 runtimeOptions.SetArkProperties(option.GetArkProperties());
4238 runtimeOptions.SetMemConfigProperty(option.GetMemConfigProperty());
4239 runtimeOptions.SetArkBundleName(option.GetArkBundleName());
4240 runtimeOptions.SetLongPauseTime(option.GetLongPauseTime());
4241 runtimeOptions.SetGcThreadNum(option.GetGcThreadNum());
4242 runtimeOptions.SetIsWorker(option.GetIsWorker());
4243 runtimeOptions.SetIsRestrictedWorker(option.GetIsRestrictedWorker());
4244 // Mem
4245 runtimeOptions.SetHeapSizeLimit(option.GetGcPoolSize());
4246 // Disable the asm-interpreter of ark-engine for ios-platform temporarily.
4247 #if !defined(PANDA_TARGET_IOS)
4248 // asmInterpreter
4249 runtimeOptions.SetEnableAsmInterpreter(option.GetEnableAsmInterpreter());
4250 #else
4251 runtimeOptions.SetEnableAsmInterpreter(false);
4252 #endif
4253 runtimeOptions.SetEnableBuiltinsLazy(option.GetEnableBuiltinsLazy());
4254 runtimeOptions.SetAsmOpcodeDisableRange(option.GetAsmOpcodeDisableRange());
4255 // aot
4256 runtimeOptions.SetEnableAOT(option.GetEnableAOT());
4257 runtimeOptions.SetEnablePGOProfiler(option.GetEnableProfile());
4258 runtimeOptions.SetPGOProfilerPath(option.GetProfileDir());
4259 // Dfx
4260 runtimeOptions.SetLogLevel(Log::LevelToString(Log::ConvertFromRuntime(option.GetLogLevel())));
4261 runtimeOptions.SetEnableArkTools(option.GetEnableArkTools());
4262 return CreateEcmaVM(runtimeOptions);
4263 }
4264
CreateJSContext(EcmaVM * vm)4265 EcmaContext *JSNApi::CreateJSContext(EcmaVM *vm)
4266 {
4267 JSThread *thread = vm->GetJSThread();
4268 ecmascript::ThreadManagedScope managedScope(thread);
4269 return EcmaContext::CreateAndInitialize(thread);
4270 }
4271
SwitchCurrentContext(EcmaVM * vm,EcmaContext * context)4272 void JSNApi::SwitchCurrentContext(EcmaVM *vm, EcmaContext *context)
4273 {
4274 JSThread *thread = vm->GetJSThread();
4275 ecmascript::ThreadManagedScope managedScope(thread);
4276 thread->SwitchCurrentContext(context);
4277 }
4278
DestroyJSContext(EcmaVM * vm,EcmaContext * context)4279 void JSNApi::DestroyJSContext(EcmaVM *vm, EcmaContext *context)
4280 {
4281 JSThread *thread = vm->GetJSThread();
4282 ecmascript::ThreadManagedScope managedScope(thread);
4283 EcmaContext::CheckAndDestroy(thread, context);
4284 }
4285
CreateEcmaVM(const JSRuntimeOptions & options)4286 EcmaVM *JSNApi::CreateEcmaVM(const JSRuntimeOptions &options)
4287 {
4288 return EcmaVM::Create(options);
4289 }
4290
DestroyJSVM(EcmaVM * ecmaVm)4291 void JSNApi::DestroyJSVM(EcmaVM *ecmaVm)
4292 {
4293 if (UNLIKELY(ecmaVm == nullptr)) {
4294 return;
4295 }
4296 ecmaVm->GetJSThread()->ManagedCodeBegin();
4297 EcmaVM::Destroy(ecmaVm);
4298 }
4299
RegisterUncatchableErrorHandler(EcmaVM * ecmaVm,const UncatchableErrorHandler & handler)4300 void JSNApi::RegisterUncatchableErrorHandler(EcmaVM *ecmaVm, const UncatchableErrorHandler &handler)
4301 {
4302 ecmaVm->RegisterUncatchableErrorHandler(handler);
4303 }
4304
TriggerGC(const EcmaVM * vm,TRIGGER_GC_TYPE gcType)4305 void JSNApi::TriggerGC(const EcmaVM *vm, TRIGGER_GC_TYPE gcType)
4306 {
4307 TriggerGC(vm, ecmascript::GCReason::EXTERNAL_TRIGGER, gcType);
4308 }
4309
TriggerGC(const EcmaVM * vm,ecmascript::GCReason reason,TRIGGER_GC_TYPE gcType)4310 void JSNApi::TriggerGC(const EcmaVM *vm, ecmascript::GCReason reason, TRIGGER_GC_TYPE gcType)
4311 {
4312 CROSS_THREAD_CHECK(vm);
4313 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
4314 if (thread != nullptr && vm->IsInitialized()) {
4315 switch (gcType) {
4316 case TRIGGER_GC_TYPE::SEMI_GC:
4317 vm->CollectGarbage(vm->GetHeap()->SelectGCType(), reason);
4318 break;
4319 case TRIGGER_GC_TYPE::OLD_GC:
4320 vm->CollectGarbage(ecmascript::TriggerGCType::OLD_GC, reason);
4321 break;
4322 case TRIGGER_GC_TYPE::FULL_GC:
4323 vm->CollectGarbage(ecmascript::TriggerGCType::FULL_GC, reason);
4324 break;
4325 default:
4326 break;
4327 }
4328 }
4329 }
4330
TriggerIdleGC(const EcmaVM * vm,TRIGGER_IDLE_GC_TYPE gcType)4331 void JSNApi::TriggerIdleGC(const EcmaVM *vm, TRIGGER_IDLE_GC_TYPE gcType)
4332 {
4333 CROSS_THREAD_CHECK(vm);
4334 if (thread != nullptr && vm->IsInitialized()) {
4335 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
4336 vm->GetHeap()->GetIdleGCTrigger()->TryTriggerIdleGC(gcType);
4337 }
4338 }
4339
SetStartIdleMonitorCallback(const StartIdleMonitorCallback & callback)4340 void JSNApi::SetStartIdleMonitorCallback(const StartIdleMonitorCallback& callback)
4341 {
4342 startIdleMonitorCallback_ = callback;
4343 }
4344
GetStartIdleMonitorCallback()4345 StartIdleMonitorCallback JSNApi::GetStartIdleMonitorCallback()
4346 {
4347 return startIdleMonitorCallback_;
4348 }
4349
ThrowException(const EcmaVM * vm,Local<JSValueRef> error)4350 void JSNApi::ThrowException(const EcmaVM *vm, Local<JSValueRef> error)
4351 {
4352 auto thread = vm->GetJSThread();
4353 ecmascript::ThreadManagedScope managedScope(thread);
4354 if (thread->HasPendingException()) {
4355 LOG_ECMA(DEBUG) << "An exception has already occurred before, keep old exception here.";
4356 return;
4357 }
4358 thread->SetException(JSNApiHelper::ToJSTaggedValue(*error));
4359 }
4360
PrintExceptionInfo(const EcmaVM * vm)4361 void JSNApi::PrintExceptionInfo(const EcmaVM *vm)
4362 {
4363 JSThread* thread = vm->GetJSThread();
4364 ecmascript::ThreadManagedScope managedScope(thread);
4365 [[maybe_unused]] ecmascript::EcmaHandleScope handleScope(thread);
4366
4367 if (!HasPendingException(vm)) {
4368 return;
4369 }
4370 Local<ObjectRef> exception = GetAndClearUncaughtException(vm);
4371 JSHandle<JSTaggedValue> exceptionHandle = JSNApiHelper::ToJSHandle(exception);
4372 if (exceptionHandle->IsJSError()) {
4373 vm->PrintJSErrorInfo(exceptionHandle);
4374 ThrowException(vm, exception);
4375 return;
4376 }
4377 JSHandle<EcmaString> result = JSTaggedValue::ToString(thread, exceptionHandle);
4378 ecmascript::CString string = ConvertToString(*result);
4379 LOG_ECMA(ERROR) << string;
4380 ThrowException(vm, exception);
4381 }
4382
4383 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER) && !defined(PANDA_TARGET_IOS)
StartDebuggerCheckParameters(EcmaVM * vm,const DebugOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)4384 bool JSNApi::StartDebuggerCheckParameters(EcmaVM *vm, const DebugOption &option, int32_t instanceId,
4385 const DebuggerPostTask &debuggerPostTask)
4386 {
4387 if (vm == nullptr) {
4388 LOG_ECMA(ERROR) << "[StartDebugger] vm is nullptr";
4389 return false;
4390 }
4391
4392 if (option.port < 0) {
4393 LOG_ECMA(ERROR) << "[StartDebugger] option.port is -1" ;
4394 return false;
4395 }
4396 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4397 const auto &handler = vm->GetJsDebuggerManager()->GetDebugLibraryHandle();
4398 if (handler.IsValid()) {
4399 LOG_ECMA(ERROR) << "[StartDebugger] handler has already loaded";
4400 return false;
4401 }
4402 if (option.libraryPath == nullptr) {
4403 LOG_ECMA(ERROR) << "[StartDebugger] option.libraryPath is nullptr";
4404 return false;
4405 }
4406 auto handle = panda::os::library_loader::Load(std::string(option.libraryPath));
4407 if (!handle) {
4408 LOG_ECMA(ERROR) << "[StartDebugger] Load library fail: " << option.libraryPath << " " << errno;
4409 return false;
4410 }
4411 auto sym = panda::os::library_loader::ResolveSymbol(handle.Value(), "StartDebug");
4412 if (!sym) {
4413 LOG_ECMA(ERROR) << "[StartDebugger] Resolve symbol fail: " << sym.Error().ToString();
4414 return false;
4415 }
4416 using StartDebugger = bool (*)(
4417 const std::string &, EcmaVM *, bool, int32_t, const DebuggerPostTask &, int);
4418
4419 vm->GetJsDebuggerManager()->SetDebugMode(option.isDebugMode);
4420 vm->GetJsDebuggerManager()->SetIsDebugApp(true);
4421 vm->GetJsDebuggerManager()->SetDebugLibraryHandle(std::move(handle.Value()));
4422 bool ret = reinterpret_cast<StartDebugger>(sym.Value())(
4423 "PandaDebugger", vm, option.isDebugMode, instanceId, debuggerPostTask, option.port);
4424 if (!ret) {
4425 // Reset the config
4426 vm->GetJsDebuggerManager()->SetDebugMode(false);
4427 panda::os::library_loader::LibraryHandle libraryHandle(nullptr);
4428 vm->GetJsDebuggerManager()->SetDebugLibraryHandle(std::move(libraryHandle));
4429 }
4430 return ret;
4431 }
4432 #endif
4433
4434 // for previewer, cross platform and testcase debugger
StartDebugger(EcmaVM * vm,const DebugOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)4435 bool JSNApi::StartDebugger([[maybe_unused]] EcmaVM *vm, [[maybe_unused]] const DebugOption &option,
4436 [[maybe_unused]] int32_t instanceId,
4437 [[maybe_unused]] const DebuggerPostTask &debuggerPostTask)
4438 {
4439 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4440 #if !defined(PANDA_TARGET_IOS)
4441 LOG_ECMA(INFO) << "JSNApi::StartDebugger, isDebugMode = " << option.isDebugMode
4442 << ", port = " << option.port << ", instanceId = " << instanceId;
4443 return StartDebuggerCheckParameters(vm, option, instanceId, debuggerPostTask);
4444 #else
4445 if (vm == nullptr) {
4446 return false;
4447 }
4448 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4449 vm->GetJsDebuggerManager()->SetDebugMode(option.isDebugMode);
4450 bool ret = OHOS::ArkCompiler::Toolchain::StartDebug(
4451 DEBUGGER_NAME, vm, option.isDebugMode, instanceId, debuggerPostTask, option.port);
4452 if (!ret) {
4453 // Reset the config
4454 vm->GetJsDebuggerManager()->SetDebugMode(false);
4455 }
4456 return ret;
4457 #endif // PANDA_TARGET_IOS
4458 #else
4459 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4460 return false;
4461 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
4462 }
4463
4464 // rk
4465 // FA or Stage
StartDebuggerForOldProcess(EcmaVM * vm,const DebugOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask)4466 bool JSNApi::StartDebuggerForOldProcess([[maybe_unused]] EcmaVM *vm, [[maybe_unused]] const DebugOption &option,
4467 [[maybe_unused]] int32_t instanceId,
4468 [[maybe_unused]] const DebuggerPostTask &debuggerPostTask)
4469 {
4470 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4471 #if !defined(PANDA_TARGET_IOS)
4472 LOG_ECMA(INFO) << "JSNApi::StartDebuggerForOldProcess, isDebugMode = " << option.isDebugMode
4473 << ", instanceId = " << instanceId;
4474 if (vm == nullptr) {
4475 LOG_ECMA(ERROR) << "[StartDebuggerForOldProcess] vm is nullptr";
4476 return false;
4477 }
4478 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4479 const auto &handle = vm->GetJsDebuggerManager()->GetDebugLibraryHandle();
4480 if (!handle.IsValid()) {
4481 LOG_ECMA(ERROR) << "[StartDebuggerForOldProcess] Get library handle fail: " << option.libraryPath;
4482 return false;
4483 }
4484
4485 using StartDebug = bool (*)(
4486 const std::string &, EcmaVM *, bool, int32_t, const DebuggerPostTask &, int);
4487
4488 auto sym = panda::os::library_loader::ResolveSymbol(handle, "StartDebug");
4489 if (!sym) {
4490 LOG_ECMA(ERROR) << "[StartDebuggerForOldProcess] Resolve symbol fail: " << sym.Error().ToString();
4491 return false;
4492 }
4493
4494 bool ret = reinterpret_cast<StartDebug>(sym.Value())(
4495 "PandaDebugger", vm, option.isDebugMode, instanceId, debuggerPostTask, option.port);
4496 if (!ret) {
4497 // Reset the config
4498 vm->GetJsDebuggerManager()->SetDebugMode(false);
4499 panda::os::library_loader::LibraryHandle libraryHandle(nullptr);
4500 vm->GetJsDebuggerManager()->SetDebugLibraryHandle(std::move(libraryHandle));
4501 }
4502 return ret;
4503 #else
4504 if (vm == nullptr) {
4505 LOG_ECMA(ERROR) << "[StartDebuggerForOldProcess] vm is nullptr";
4506 return false;
4507 }
4508 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4509 vm->GetJsDebuggerManager()->SetDebugMode(option.isDebugMode);
4510 bool ret = OHOS::ArkCompiler::Toolchain::StartDebug(
4511 DEBUGGER_NAME, vm, option.isDebugMode, instanceId, debuggerPostTask, option.port);
4512 if (!ret) {
4513 // Reset the config
4514 vm->GetJsDebuggerManager()->SetDebugMode(false);
4515 }
4516 return ret;
4517 #endif // PANDA_TARGET_IOS
4518 #else
4519 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4520 return false;
4521 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
4522 }
4523
4524 // ohos or emulator
4525 // FA or Stage
StartDebuggerForSocketPair(int tid,int socketfd)4526 bool JSNApi::StartDebuggerForSocketPair([[maybe_unused]] int tid, [[maybe_unused]] int socketfd)
4527 {
4528 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4529 LOG_ECMA(INFO) << "JSNApi::StartDebuggerForSocketPair, tid = " << tid << ", socketfd = " << socketfd;
4530 JsDebuggerManager *jsDebuggerManager = JsDebuggerManager::GetJsDebuggerManager(tid);
4531 if (jsDebuggerManager == nullptr) {
4532 LOG_ECMA(ERROR) << "[StartDebuggerForSocketPair] jsDebuggerManager is nullptr";
4533 return false;
4534 }
4535 const auto &handle = jsDebuggerManager->GetDebugLibraryHandle();
4536 if (!handle.IsValid()) {
4537 LOG_ECMA(ERROR) << "[StartDebuggerForSocketPair] Get library handle fail";
4538 return false;
4539 }
4540
4541 using StartDebugForSocketpair = bool (*)(int, int);
4542
4543 auto sym = panda::os::library_loader::ResolveSymbol(handle, "StartDebugForSocketpair");
4544 if (!sym) {
4545 LOG_ECMA(ERROR) << "[StartDebuggerForSocketPair] Resolve symbol fail: " << sym.Error().ToString();
4546 return false;
4547 }
4548
4549 bool ret = reinterpret_cast<StartDebugForSocketpair>(sym.Value())(tid, socketfd);
4550 if (!ret) {
4551 // Reset the config
4552 jsDebuggerManager->SetDebugMode(false);
4553 panda::os::library_loader::LibraryHandle libraryHandle(nullptr);
4554 jsDebuggerManager->SetDebugLibraryHandle(std::move(libraryHandle));
4555 }
4556 return ret;
4557 #else
4558 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4559 return false;
4560 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
4561 }
4562
4563 // ohos or emulator
4564 // FA or Stage
4565 // release or debug hap : aa start
4566 // aa start -D
4567 // aa start -p
4568 // new worker
NotifyDebugMode(int tid,EcmaVM * vm,const DebugOption & option,int32_t instanceId,const DebuggerPostTask & debuggerPostTask,bool debugApp)4569 bool JSNApi::NotifyDebugMode([[maybe_unused]] int tid,
4570 [[maybe_unused]] EcmaVM *vm,
4571 [[maybe_unused]] const DebugOption &option,
4572 [[maybe_unused]] int32_t instanceId,
4573 [[maybe_unused]] const DebuggerPostTask &debuggerPostTask,
4574 [[maybe_unused]] bool debugApp)
4575 {
4576 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4577 LOG_ECMA(INFO) << "JSNApi::NotifyDebugMode, tid = " << tid << ", debugApp = " << debugApp
4578 << ", isDebugMode = " << option.isDebugMode << ", instanceId = " << instanceId;
4579 if (vm == nullptr) {
4580 LOG_ECMA(ERROR) << "[NotifyDebugMode] vm is nullptr";
4581 return false;
4582 }
4583 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4584
4585 bool ret = false;
4586 if (!debugApp) {
4587 return true;
4588 }
4589
4590 if (option.libraryPath == nullptr) {
4591 LOG_ECMA(ERROR) << "[NotifyDebugMode] option.libraryPath is nullptr";
4592 return false;
4593 }
4594 JsDebuggerManager *jsDebuggerManager = vm->GetJsDebuggerManager();
4595 auto handle = panda::os::library_loader::Load(std::string(option.libraryPath));
4596 if (!handle) {
4597 LOG_ECMA(ERROR) << "[NotifyDebugMode] Load library fail: " << option.libraryPath << " " << errno;
4598 return false;
4599 }
4600 JsDebuggerManager::AddJsDebuggerManager(tid, jsDebuggerManager);
4601 jsDebuggerManager->SetDebugLibraryHandle(std::move(handle.Value()));
4602 jsDebuggerManager->SetDebugMode(option.isDebugMode && debugApp);
4603 jsDebuggerManager->SetIsDebugApp(debugApp);
4604 #ifdef PANDA_TARGET_ARM32
4605 ret = StartDebuggerForOldProcess(vm, option, instanceId, debuggerPostTask);
4606 #else
4607 ret = true;
4608 #endif
4609
4610 // store debugger postTask in inspector.
4611 using StoreDebuggerInfo = void (*)(int, EcmaVM *, const DebuggerPostTask &);
4612 auto symOfStoreDebuggerInfo = panda::os::library_loader::ResolveSymbol(
4613 jsDebuggerManager->GetDebugLibraryHandle(), "StoreDebuggerInfo");
4614 if (!symOfStoreDebuggerInfo) {
4615 LOG_ECMA(ERROR) << "[NotifyDebugMode] Resolve StoreDebuggerInfo symbol fail: " <<
4616 symOfStoreDebuggerInfo.Error().ToString();
4617 return false;
4618 }
4619 reinterpret_cast<StoreDebuggerInfo>(symOfStoreDebuggerInfo.Value())(tid, vm, debuggerPostTask);
4620
4621 #ifndef PANDA_TARGET_ARM32
4622 // Initialize debugger
4623 using InitializeDebuggerForSocketpair = bool(*)(void*);
4624 auto sym = panda::os::library_loader::ResolveSymbol(
4625 jsDebuggerManager->GetDebugLibraryHandle(), "InitializeDebuggerForSocketpair");
4626 if (!sym) {
4627 LOG_ECMA(ERROR) << "[NotifyDebugMode] Resolve InitializeDebuggerForSocketpair symbol fail: "
4628 << sym.Error().ToString();
4629 return false;
4630 }
4631 if (!reinterpret_cast<InitializeDebuggerForSocketpair>(sym.Value())(vm)) {
4632 LOG_ECMA(ERROR) << "[NotifyDebugMode] InitializeDebuggerForSocketpair fail";
4633 return false;
4634 }
4635 #endif
4636
4637 if (option.isDebugMode) {
4638 using WaitForDebugger = void (*)(EcmaVM *);
4639 auto symOfWaitForDebugger = panda::os::library_loader::ResolveSymbol(
4640 jsDebuggerManager->GetDebugLibraryHandle(), "WaitForDebugger");
4641 if (!symOfWaitForDebugger) {
4642 LOG_ECMA(ERROR) << "[NotifyDebugMode] Resolve symbol WaitForDebugger fail: " <<
4643 symOfWaitForDebugger.Error().ToString();
4644 return false;
4645 }
4646 reinterpret_cast<WaitForDebugger>(symOfWaitForDebugger.Value())(vm);
4647 }
4648 auto anFileDataMgr = ecmascript::AnFileDataManager::GetInstance();
4649 if (anFileDataMgr != nullptr && anFileDataMgr->SafeGetStubFileInfo()) {
4650 anFileDataMgr->SafeGetStubFileInfo()->RegisterToDebugger();
4651 }
4652 return ret;
4653
4654 #else
4655 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4656 return false;
4657 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
4658 }
4659
StoreDebugInfo(int tid,EcmaVM * vm,const DebugOption & option,const DebuggerPostTask & debuggerPostTask,bool debugApp)4660 bool JSNApi::StoreDebugInfo([[maybe_unused]] int tid,
4661 [[maybe_unused]] EcmaVM *vm,
4662 [[maybe_unused]] const DebugOption &option,
4663 [[maybe_unused]] const DebuggerPostTask &debuggerPostTask,
4664 [[maybe_unused]] bool debugApp)
4665 {
4666 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4667 LOG_ECMA(INFO) << "JSNApi::StoreDebugInfo, tid = " << tid;
4668 if (vm == nullptr) {
4669 LOG_ECMA(ERROR) << "[StoreDebugInfo] vm is nullptr";
4670 return false;
4671 }
4672
4673 JsDebuggerManager *jsDebuggerManager = vm->GetJsDebuggerManager();
4674 const auto &handler = jsDebuggerManager->GetDebugLibraryHandle();
4675 if (handler.IsValid()) {
4676 LOG_ECMA(INFO) << "[StoreDebugInfo] handler has already loaded";
4677 return false;
4678 }
4679
4680 if (option.libraryPath == nullptr) {
4681 LOG_ECMA(ERROR) << "[StoreDebugInfo] option.libraryPath is nullptr";
4682 return false;
4683 }
4684 auto handle = panda::os::library_loader::Load(std::string(option.libraryPath));
4685 if (!handle) {
4686 LOG_ECMA(ERROR) << "[StoreDebugInfo] Load library fail: " << option.libraryPath << " " << errno;
4687 return false;
4688 }
4689 JsDebuggerManager::AddJsDebuggerManager(tid, jsDebuggerManager);
4690 jsDebuggerManager->SetDebugLibraryHandle(std::move(handle.Value()));
4691 jsDebuggerManager->SetDebugMode(option.isDebugMode && debugApp);
4692 jsDebuggerManager->SetIsDebugApp(debugApp);
4693 // store debugger postTask in inspector.
4694 using StoreDebuggerInfo = void (*)(int, EcmaVM *, const DebuggerPostTask &);
4695 auto symOfStoreDebuggerInfo = panda::os::library_loader::ResolveSymbol(
4696 jsDebuggerManager->GetDebugLibraryHandle(), "StoreDebuggerInfo");
4697 if (!symOfStoreDebuggerInfo) {
4698 LOG_ECMA(ERROR) << "[StoreDebugInfo] Resolve StoreDebuggerInfo symbol fail: " <<
4699 symOfStoreDebuggerInfo.Error().ToString();
4700 return false;
4701 }
4702 reinterpret_cast<StoreDebuggerInfo>(symOfStoreDebuggerInfo.Value())(tid, vm, debuggerPostTask);
4703 bool ret = false;
4704 using InitializeDebuggerForSocketpair = bool(*)(void*);
4705 auto sym = panda::os::library_loader::ResolveSymbol(handler, "InitializeDebuggerForSocketpair");
4706 if (!sym) {
4707 LOG_ECMA(ERROR) << "[InitializeDebuggerForSocketpair] Resolve symbol fail: " << sym.Error().ToString();
4708 return false;
4709 }
4710 ret = reinterpret_cast<InitializeDebuggerForSocketpair>(sym.Value())(vm);
4711 if (!ret) {
4712 // Reset the config
4713 vm->GetJsDebuggerManager()->SetDebugMode(false);
4714 return false;
4715 }
4716 return ret;
4717 #else
4718 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4719 return false;
4720 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
4721 }
4722
StopDebugger(EcmaVM * vm)4723 bool JSNApi::StopDebugger([[maybe_unused]] EcmaVM *vm)
4724 {
4725 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4726 #if !defined(PANDA_TARGET_IOS)
4727 LOG_ECMA(DEBUG) << "JSNApi::StopDebugger";
4728 if (vm == nullptr) {
4729 LOG_ECMA(ERROR) << "[StopDebugger] vm is nullptr";
4730 return false;
4731 }
4732 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4733
4734 const auto &handle = vm->GetJsDebuggerManager()->GetDebugLibraryHandle();
4735
4736 using StopDebug = void (*)(void *);
4737
4738 auto sym = panda::os::library_loader::ResolveSymbol(handle, "StopDebug");
4739 if (!sym) {
4740 LOG_ECMA(ERROR) << sym.Error().ToString();
4741 return false;
4742 }
4743
4744 reinterpret_cast<StopDebug>(sym.Value())(vm);
4745
4746 vm->GetJsDebuggerManager()->SetDebugMode(false);
4747 uint32_t tid = vm->GetTid();
4748 JsDebuggerManager::DeleteJsDebuggerManager(tid);
4749 return true;
4750 #else
4751 if (vm == nullptr) {
4752 LOG_ECMA(ERROR) << "[StopDebugger] vm is nullptr";
4753 return false;
4754 }
4755 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4756
4757 OHOS::ArkCompiler::Toolchain::StopDebug(vm);
4758 vm->GetJsDebuggerManager()->SetDebugMode(false);
4759 return true;
4760 #endif // PANDA_TARGET_IOS
4761 #else
4762 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4763 return false;
4764 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
4765 }
4766
StopDebugger(int tid)4767 bool JSNApi::StopDebugger([[maybe_unused]] int tid)
4768 {
4769 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4770 LOG_ECMA(DEBUG) << "JSNApi::StopDebugger, tid = " << tid;
4771 JsDebuggerManager *jsDebuggerManager = JsDebuggerManager::GetJsDebuggerManager(tid);
4772 if (jsDebuggerManager == nullptr) {
4773 LOG_ECMA(ERROR) << "[StopDebugger] jsDebuggerManager is nullptr";
4774 return false;
4775 }
4776
4777 const auto &handle = jsDebuggerManager->GetDebugLibraryHandle();
4778
4779 using StopOldDebug = void (*)(int, const std::string &);
4780
4781 auto sym = panda::os::library_loader::ResolveSymbol(handle, "StopOldDebug");
4782 if (!sym) {
4783 LOG_ECMA(ERROR) << sym.Error().ToString();
4784 return false;
4785 }
4786
4787 reinterpret_cast<StopOldDebug>(sym.Value())(tid, "PandaDebugger");
4788
4789 return true;
4790 #else
4791 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4792 return false;
4793 #endif // ECMASCRIPT_SUPPORT_DEBUGGER
4794 }
4795
IsMixedDebugEnabled(const EcmaVM * vm)4796 bool JSNApi::IsMixedDebugEnabled(const EcmaVM *vm)
4797 {
4798 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4799 return vm->GetJsDebuggerManager()->IsMixedDebugEnabled();
4800 #else
4801 return false;
4802 #endif
4803 }
4804
IsDebugModeEnabled(const EcmaVM * vm)4805 bool JSNApi::IsDebugModeEnabled([[maybe_unused]] const EcmaVM *vm)
4806 {
4807 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4808 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4809 if (vm != nullptr && vm->GetJsDebuggerManager() != nullptr) {
4810 return vm->GetJsDebuggerManager()->IsDebugMode();
4811 }
4812 return false;
4813 #else
4814 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4815 return false;
4816 #endif
4817 }
4818
NotifyNativeCalling(const EcmaVM * vm,const void * nativeAddress)4819 void JSNApi::NotifyNativeCalling(const EcmaVM *vm, [[maybe_unused]] const void *nativeAddress)
4820 {
4821 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4822 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
4823 vm->GetJsDebuggerManager()->GetNotificationManager()->NativeCallingEvent(nativeAddress);
4824 #else
4825 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4826 #endif
4827 }
4828
NotifyNativeReturn(const EcmaVM * vm,const void * nativeAddress)4829 void JSNApi::NotifyNativeReturn(const EcmaVM *vm, [[maybe_unused]] const void *nativeAddress)
4830 {
4831 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4832 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
4833 vm->GetJsDebuggerManager()->GetNotificationManager()->NativeReturnEvent(nativeAddress);
4834 #else
4835 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4836 #endif
4837 }
4838
NotifyLoadModule(const EcmaVM * vm)4839 void JSNApi::NotifyLoadModule(const EcmaVM *vm)
4840 {
4841 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER)
4842 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
4843 // if load module, it needs to check whether clear singlestepper_
4844 vm->GetJsDebuggerManager()->ClearSingleStepper();
4845 #else
4846 LOG_ECMA(ERROR) << "Not support arkcompiler debugger";
4847 #endif
4848 }
4849
NotifyUIIdle(const EcmaVM * vm,int idleTime)4850 void JSNApi::NotifyUIIdle(const EcmaVM *vm, [[maybe_unused]] int idleTime)
4851 {
4852 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
4853 vm->GetHeap()->GetIdleGCTrigger()->NotifyVsyncIdleStart();
4854 }
4855
NotifyLooperIdleStart(const EcmaVM * vm,int64_t timestamp,int idleTime)4856 void JSNApi::NotifyLooperIdleStart(const EcmaVM *vm, int64_t timestamp, int idleTime)
4857 {
4858 if (vm->IsPostForked()) {
4859 vm->GetHeap()->GetIdleGCTrigger()->NotifyLooperIdleStart(timestamp, idleTime);
4860 }
4861 }
4862
NotifyLooperIdleEnd(const EcmaVM * vm,int64_t timestamp)4863 void JSNApi::NotifyLooperIdleEnd(const EcmaVM *vm, int64_t timestamp)
4864 {
4865 if (vm->IsPostForked()) {
4866 vm->GetHeap()->GetIdleGCTrigger()->NotifyLooperIdleEnd(timestamp);
4867 }
4868 }
4869
IsJSMainThreadOfEcmaVM(const EcmaVM * vm)4870 bool JSNApi::IsJSMainThreadOfEcmaVM(const EcmaVM *vm)
4871 {
4872 return vm->GetJSThread()->IsMainThreadFast();
4873 }
4874
SetDeviceDisconnectCallback(EcmaVM * vm,DeviceDisconnectCallback cb)4875 void JSNApi::SetDeviceDisconnectCallback(EcmaVM *vm, DeviceDisconnectCallback cb)
4876 {
4877 vm->SetDeviceDisconnectCallback(cb);
4878 }
4879
KeyIsNumber(const char * utf8)4880 bool JSNApi::KeyIsNumber(const char* utf8)
4881 {
4882 const char *ptr = utf8;
4883 for (char c = *ptr; c; c = *++ptr) {
4884 if (c >= '0' && c <= '9') {
4885 continue;
4886 } else {
4887 return false;
4888 }
4889 }
4890 return true;
4891 }
4892
IsSerializationTimeoutCheckEnabled(const EcmaVM * vm)4893 bool JSNApi::IsSerializationTimeoutCheckEnabled(const EcmaVM *vm)
4894 {
4895 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4896 // Open Control Timeout Consumption
4897 if (const_cast<EcmaVM *>(vm)->GetJSOptions().EnableSerializationTimeoutCheck()) {
4898 return thread->IsMainThread();
4899 }
4900
4901 // Currently only log trace on main thread
4902 auto jsDebuggerManager = vm->GetJsDebuggerManager();
4903 if (jsDebuggerManager != nullptr) {
4904 if (jsDebuggerManager->IsSerializationTimeoutCheckEnabled()) {
4905 return thread->IsMainThread();
4906 }
4907 }
4908 return false;
4909 }
4910
GenerateTimeoutTraceIfNeeded(const EcmaVM * vm,std::chrono::system_clock::time_point & start,std::chrono::system_clock::time_point & end,bool isSerialization)4911 void JSNApi::GenerateTimeoutTraceIfNeeded(const EcmaVM *vm, std::chrono::system_clock::time_point &start,
4912 std::chrono::system_clock::time_point &end, bool isSerialization)
4913 {
4914 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
4915 ecmascript::ThreadManagedScope scope(thread);
4916 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
4917 auto threshold = std::chrono::duration_cast<std::chrono::milliseconds>
4918 (std::chrono::milliseconds(vm->GetJsDebuggerManager()->GetSerializationCheckThreshold())).count();
4919 LOG_ECMA(DEBUG) << "JSNAPI::" << (isSerialization ? "SerializeValue" : "DeserializeValue") << " tid: "
4920 << thread->GetThreadId() << " threshold: " << threshold << " duration: " << duration;
4921 if (duration >= threshold) {
4922 std::stringstream tagMsg;
4923 auto startTimeMS = std::chrono::time_point_cast<std::chrono::nanoseconds>(start);
4924 tagMsg << (isSerialization ? "SerializationTimeout::tid=" : "DeserializationTimeout::tid=");
4925 tagMsg << thread->GetThreadId();
4926 tagMsg << (isSerialization ? ";task=serialization;startTime=" : ";task=deserialization;startTime=");
4927 tagMsg << startTimeMS.time_since_epoch().count() << ";duration=" << duration;
4928 ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, tagMsg.str());
4929 }
4930 }
4931
LoadAotFileInternal(EcmaVM * vm,const std::string & moduleName,std::string & aotFileName)4932 void JSNApi::LoadAotFileInternal(EcmaVM *vm, const std::string &moduleName, std::string &aotFileName)
4933 {
4934 if (vm->GetJSOptions().WasAOTOutputFileSet()) {
4935 aotFileName = vm->GetJSOptions().GetAOTOutputFile();
4936 }
4937 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM)
4938 else if (vm->GetJSOptions().GetEnableAOT())
4939 #else
4940 else if (ecmascript::AnFileDataManager::GetInstance()->IsEnable())
4941 #endif
4942 {
4943 aotFileName = ecmascript::AnFileDataManager::GetInstance()->GetDir() + moduleName;
4944 } else {
4945 std::string hapPath = "";
4946 ecmascript::SearchHapPathCallBack callback = vm->GetSearchHapPathCallBack();
4947 if (callback) {
4948 callback(moduleName, hapPath);
4949 }
4950 aotFileName = ecmascript::OhosPreloadAppInfo::GetPreloadAOTFileName(hapPath, moduleName);
4951 }
4952 if (aotFileName.empty()) {
4953 LOG_ECMA(INFO) << "can not find aot file";
4954 return;
4955 }
4956 if (ecmascript::pgo::PGOProfilerManager::GetInstance()->IsDisableAot()) {
4957 LOG_ECMA(INFO) << "can't load disable aot file: " << aotFileName;
4958 return;
4959 }
4960 LOG_ECMA(INFO) << "start to load aot file: " << aotFileName;
4961 }
4962
LoadAotFile(EcmaVM * vm,const std::string & moduleName)4963 void JSNApi::LoadAotFile(EcmaVM *vm, const std::string &moduleName)
4964 {
4965 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
4966 ecmascript::ThreadManagedScope scope(thread);
4967
4968 std::string aotFileName;
4969 LoadAotFileInternal(vm, moduleName, aotFileName);
4970 thread->GetCurrentEcmaContext()->LoadAOTFiles(aotFileName);
4971 }
4972
4973 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM)
LoadAotFile(EcmaVM * vm,const std::string & bundleName,const std::string & moduleName,std::function<bool (std::string fileName,uint8_t ** buff,size_t * buffSize)> cb)4974 void JSNApi::LoadAotFile(EcmaVM *vm, [[maybe_unused]] const std::string &bundleName, const std::string &moduleName,
4975 std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)> cb)
4976 {
4977 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
4978 ecmascript::ThreadManagedScope scope(thread);
4979
4980 std::string aotFileName;
4981 LoadAotFileInternal(vm, moduleName, aotFileName);
4982 thread->GetCurrentEcmaContext()->LoadAOTFiles(aotFileName, cb);
4983 }
4984 #endif
4985
ExecuteInContext(EcmaVM * vm,const std::string & fileName,const std::string & entry,bool needUpdate)4986 bool JSNApi::ExecuteInContext(EcmaVM *vm, const std::string &fileName, const std::string &entry, bool needUpdate)
4987 {
4988 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
4989 LOG_ECMA(DEBUG) << "start to execute ark file in context: " << fileName;
4990 ecmascript::ThreadManagedScope scope(thread);
4991 EcmaContext::MountContext(thread);
4992 if (!ecmascript::JSPandaFileExecutor::ExecuteFromAbcFile(thread, fileName.c_str(), entry, needUpdate)) {
4993 if (thread->HasPendingException()) {
4994 ecmascript::JsStackInfo::BuildCrashInfo(thread);
4995 thread->GetCurrentEcmaContext()->HandleUncaughtException();
4996 }
4997 LOG_ECMA(ERROR) << "Cannot execute ark file '" << fileName
4998 << "' with entry '" << entry << "'" << std::endl;
4999 return false;
5000 }
5001 EcmaContext::UnmountContext(thread);
5002 return true;
5003 }
5004
ExecuteForAbsolutePath(const EcmaVM * vm,const std::string & fileName,const std::string & entry,bool needUpdate,bool executeFromJob)5005 bool JSNApi::ExecuteForAbsolutePath(const EcmaVM *vm, const std::string &fileName, const std::string &entry,
5006 bool needUpdate, bool executeFromJob)
5007 {
5008 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5009 LOG_ECMA(DEBUG) << "start to execute absolute path ark file: " << fileName;
5010 ecmascript::ThreadManagedScope scope(thread);
5011 if (!ecmascript::JSPandaFileExecutor::ExecuteFromAbsolutePathAbcFile(
5012 thread, fileName.c_str(), entry, needUpdate, executeFromJob)) {
5013 if (thread->HasPendingException()) {
5014 ecmascript::JsStackInfo::BuildCrashInfo(true);
5015 thread->GetCurrentEcmaContext()->HandleUncaughtException();
5016 }
5017 LOG_ECMA(ERROR) << "Cannot execute absolute path ark file '" << fileName
5018 << "' with entry '" << entry << "'" << std::endl;
5019 return false;
5020 }
5021 return true;
5022 }
5023
Execute(const EcmaVM * vm,const std::string & fileName,const std::string & entry,bool needUpdate,bool executeFromJob)5024 bool JSNApi::Execute(const EcmaVM *vm, const std::string &fileName, const std::string &entry,
5025 bool needUpdate, bool executeFromJob)
5026 {
5027 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5028 LOG_ECMA(DEBUG) << "start to execute ark file: " << fileName;
5029 ecmascript::ThreadManagedScope scope(thread);
5030 if (!ecmascript::JSPandaFileExecutor::ExecuteFromAbcFile(
5031 thread, fileName.c_str(), entry, needUpdate, executeFromJob)) {
5032 if (thread->HasPendingException()) {
5033 ecmascript::JsStackInfo::BuildCrashInfo(thread);
5034 thread->GetCurrentEcmaContext()->HandleUncaughtException();
5035 }
5036 LOG_ECMA(ERROR) << "Cannot execute ark file '" << fileName
5037 << "' with entry '" << entry << "'" << std::endl;
5038 return false;
5039 }
5040 return true;
5041 }
5042
5043 // The security interface needs to be modified accordingly.
Execute(EcmaVM * vm,const uint8_t * data,int32_t size,const std::string & entry,const std::string & filename,bool needUpdate)5044 bool JSNApi::Execute(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &entry,
5045 const std::string &filename, bool needUpdate)
5046 {
5047 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5048 LOG_ECMA(DEBUG) << "start to execute ark buffer: " << filename;
5049 ecmascript::ThreadManagedScope scope(thread);
5050 if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, entry, filename.c_str(), needUpdate)) {
5051 if (thread->HasPendingException()) {
5052 ecmascript::JsStackInfo::BuildCrashInfo(thread);
5053 thread->GetCurrentEcmaContext()->HandleUncaughtException();
5054 }
5055 LOG_ECMA(ERROR) << "Cannot execute ark buffer file '" << filename
5056 << "' with entry '" << entry << "'" << std::endl;
5057 return false;
5058 }
5059 return true;
5060 }
5061
ExecuteWithSingletonPatternFlag(EcmaVM * vm,const std::string & bundleName,const std::string & moduleName,const std::string & ohmurl,bool isSingletonPattern)5062 int JSNApi::ExecuteWithSingletonPatternFlag(EcmaVM *vm, const std::string &bundleName,
5063 const std::string &moduleName, const std::string &ohmurl, bool isSingletonPattern)
5064 {
5065 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, ecmascript::JSPandaFileExecutor::ROUTE_INTERNAL_ERROR);
5066 ecmascript::ThreadManagedScope scope(thread);
5067 int result = ecmascript::JSPandaFileExecutor::ExecuteAbcFileWithSingletonPatternFlag(thread, bundleName.c_str(),
5068 moduleName.c_str(), ohmurl.c_str(), isSingletonPattern);
5069 if (!result) {
5070 if (thread->HasPendingException()) {
5071 ecmascript::JsStackInfo::BuildCrashInfo(thread);
5072 thread->GetCurrentEcmaContext()->HandleUncaughtException();
5073 }
5074 LOG_ECMA(ERROR) << "Execute with singleton-pattern flag failed with bundle name is'" << bundleName
5075 << "' and module name is '" << moduleName << "', entry is'" << ohmurl << "'" << std::endl;
5076 }
5077 return result;
5078 }
5079
IsExecuteModuleInAbcFile(EcmaVM * vm,const std::string & bundleName,const std::string & moduleName,const std::string & ohmurl)5080 bool JSNApi::IsExecuteModuleInAbcFile(EcmaVM *vm, const std::string &bundleName,
5081 const std::string &moduleName, const std::string &ohmurl)
5082 {
5083 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5084 ecmascript::ThreadManagedScope scope(thread);
5085 bool result = ecmascript::JSPandaFileExecutor::IsExecuteModuleInAbcFile(thread, bundleName.c_str(),
5086 moduleName.c_str(), ohmurl.c_str());
5087 return result;
5088 }
5089
5090 // The security interface needs to be modified accordingly.
ExecuteModuleBuffer(EcmaVM * vm,const uint8_t * data,int32_t size,const std::string & filename,bool needUpdate)5091 bool JSNApi::ExecuteModuleBuffer(EcmaVM *vm, const uint8_t *data, int32_t size, const std::string &filename,
5092 bool needUpdate)
5093 {
5094 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5095 LOG_ECMA(DEBUG) << "start to execute module buffer: " << filename;
5096 ecmascript::ThreadManagedScope scope(thread);
5097 if (!ecmascript::JSPandaFileExecutor::ExecuteModuleBuffer(thread, data, size, filename.c_str(), needUpdate)) {
5098 if (thread->HasPendingException()) {
5099 ecmascript::JsStackInfo::BuildCrashInfo(thread);
5100 thread->GetCurrentEcmaContext()->HandleUncaughtException();
5101 }
5102 LOG_ECMA(ERROR) << "Cannot execute module buffer file '" << filename;
5103 return false;
5104 }
5105 return true;
5106 }
5107
ExecuteSecure(EcmaVM * vm,uint8_t * data,int32_t size,const std::string & entry,const std::string & filename,bool needUpdate)5108 bool JSNApi::ExecuteSecure(EcmaVM *vm, uint8_t *data, int32_t size, const std::string &entry,
5109 const std::string &filename, bool needUpdate)
5110 {
5111 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5112 LOG_ECMA(INFO) << "start to execute ark buffer with secure memory: " << filename;
5113 ecmascript::ThreadManagedScope scope(thread);
5114 if (!ecmascript::JSPandaFileExecutor::ExecuteFromBufferSecure(thread, data, size, entry, filename.c_str(),
5115 needUpdate)) {
5116 if (thread->HasPendingException()) {
5117 ecmascript::JsStackInfo::BuildCrashInfo(thread);
5118 thread->GetCurrentEcmaContext()->HandleUncaughtException();
5119 }
5120 LOG_ECMA(ERROR) << "Cannot execute ark buffer file '" << filename
5121 << "' with entry '" << entry << "'" << std::endl;
5122 return false;
5123 }
5124 return true;
5125 }
5126
ExecuteModuleBufferSecure(EcmaVM * vm,uint8_t * data,int32_t size,const std::string & filename,bool needUpdate)5127 bool JSNApi::ExecuteModuleBufferSecure(EcmaVM *vm, uint8_t* data, int32_t size, const std::string &filename,
5128 bool needUpdate)
5129 {
5130 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5131 LOG_ECMA(INFO) << "start to execute module buffer with secure memory: " << filename;
5132 ecmascript::ThreadManagedScope scope(thread);
5133 if (!ecmascript::JSPandaFileExecutor::ExecuteModuleBufferSecure(thread, data, size, filename.c_str(),
5134 needUpdate)) {
5135 if (thread->HasPendingException()) {
5136 ecmascript::JsStackInfo::BuildCrashInfo(thread);
5137 thread->GetCurrentEcmaContext()->HandleUncaughtException();
5138 }
5139 LOG_ECMA(ERROR) << "Cannot execute module buffer file '" << filename;
5140 return false;
5141 }
5142 return true;
5143 }
5144
PreFork(EcmaVM * vm)5145 void JSNApi::PreFork(EcmaVM *vm)
5146 {
5147 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5148 vm->PreFork();
5149 }
5150
UpdateAOTCompileStatus(ecmascript::JSRuntimeOptions & jsOption,const RuntimeOption & option)5151 void JSNApi::UpdateAOTCompileStatus(ecmascript::JSRuntimeOptions &jsOption, const RuntimeOption &option)
5152 {
5153 // When AOT compilation failed, disable PGO and JIT
5154 bool aotHasException = false;
5155 for (const auto &value : option.GetAOTCompileStatusMap()) {
5156 auto moduleCompileStatus = static_cast<RuntimeOption::AOTCompileStatus>(value.second);
5157 if (moduleCompileStatus == RuntimeOption::AOTCompileStatus::COMPILE_FAILED ||
5158 moduleCompileStatus == RuntimeOption::AOTCompileStatus::COMPILE_CRASH) {
5159 aotHasException = true;
5160 break;
5161 }
5162 }
5163 jsOption.SetAOTHasException(aotHasException);
5164 }
5165
PostFork(EcmaVM * vm,const RuntimeOption & option)5166 void JSNApi::PostFork(EcmaVM *vm, const RuntimeOption &option)
5167 {
5168 JSRuntimeOptions &jsOption = vm->GetJSOptions();
5169 jsOption.SetEnablePGOProfiler(option.GetEnableProfile());
5170 jsOption.SetEnableJIT(option.GetEnableJIT());
5171 jsOption.SetEnableBaselineJIT(option.GetEnableBaselineJIT());
5172 jsOption.SetMaxAotMethodSize(JSRuntimeOptions::MAX_APP_COMPILE_METHOD_SIZE);
5173 ecmascript::pgo::PGOProfilerManager::GetInstance()->SetBundleName(option.GetBundleName());
5174 ecmascript::pgo::PGOProfilerManager::GetInstance()->SetMaxAotMethodSize(jsOption.GetMaxAotMethodSize());
5175 JSRuntimeOptions runtimeOptions;
5176 runtimeOptions.SetLogLevel(Log::LevelToString(Log::ConvertFromRuntime(option.GetLogLevel())));
5177 Log::Initialize(runtimeOptions);
5178
5179 // 1. system switch 2. an file dir exits 3. whitelist 4. escape mechanism
5180 bool enableAOT = jsOption.GetEnableAOT() &&
5181 !option.GetAnDir().empty() &&
5182 EnableAotJitListHelper::GetInstance()->IsEnableAot(option.GetBundleName()) &&
5183 !ecmascript::AotCrashInfo::IsAotEscaped();
5184 if (enableAOT) {
5185 ecmascript::AnFileDataManager::GetInstance()->SetDir(option.GetAnDir());
5186 ecmascript::AnFileDataManager::GetInstance()->SetEnable(true);
5187 }
5188 UpdateAOTCompileStatus(jsOption, option);
5189
5190 LOG_ECMA(INFO) << "asmint: " << jsOption.GetEnableAsmInterpreter()
5191 << ", aot: " << enableAOT
5192 << ", jit: " << option.GetEnableJIT()
5193 << ", baseline jit: " << option.GetEnableBaselineJIT()
5194 << ", bundle name: " << option.GetBundleName();
5195
5196 vm->PostFork();
5197 }
5198
AddWorker(EcmaVM * hostVm,EcmaVM * workerVm)5199 void JSNApi::AddWorker(EcmaVM *hostVm, EcmaVM *workerVm)
5200 {
5201 if (hostVm != nullptr && workerVm != nullptr) {
5202 hostVm->WorkersetInfo(workerVm);
5203 workerVm->SetBundleName(hostVm->GetBundleName());
5204 }
5205 }
5206
DeleteWorker(EcmaVM * hostVm,EcmaVM * workerVm)5207 bool JSNApi::DeleteWorker(EcmaVM *hostVm, EcmaVM *workerVm)
5208 {
5209 if (hostVm != nullptr && workerVm != nullptr) {
5210 return hostVm->DeleteWorker(workerVm);
5211 }
5212 return false;
5213 }
5214
GetUncaughtException(const EcmaVM * vm)5215 Local<ObjectRef> JSNApi::GetUncaughtException(const EcmaVM *vm)
5216 {
5217 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5218 return JSNApiHelper::ToLocal<ObjectRef>(vm->GetEcmaUncaughtException());
5219 }
5220
GetAndClearUncaughtException(const EcmaVM * vm)5221 Local<ObjectRef> JSNApi::GetAndClearUncaughtException(const EcmaVM *vm)
5222 {
5223 if (!HasPendingException(vm)) {
5224 return Local<ObjectRef>();
5225 }
5226 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5227 return JSNApiHelper::ToLocal<ObjectRef>(vm->GetAndClearEcmaUncaughtException());
5228 }
5229
HasPendingException(const EcmaVM * vm)5230 bool JSNApi::HasPendingException(const EcmaVM *vm)
5231 {
5232 return vm->GetJSThread()->HasPendingException();
5233 }
5234
IsExecutingPendingJob(const EcmaVM * vm)5235 bool JSNApi::IsExecutingPendingJob(const EcmaVM *vm)
5236 {
5237 return vm->GetAssociatedJSThread()->GetCurrentEcmaContext()->IsExecutingPendingJob();
5238 }
5239
HasPendingJob(const EcmaVM * vm)5240 bool JSNApi::HasPendingJob(const EcmaVM *vm)
5241 {
5242 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5243 return vm->GetAssociatedJSThread()->GetCurrentEcmaContext()->HasPendingJob();
5244 }
5245
EnableUserUncaughtErrorHandler(EcmaVM * vm)5246 void JSNApi::EnableUserUncaughtErrorHandler(EcmaVM *vm)
5247 {
5248 return vm->GetJSThread()->GetCurrentEcmaContext()->EnableUserUncaughtErrorHandler();
5249 }
5250
GetGlobalObject(const EcmaVM * vm)5251 Local<ObjectRef> JSNApi::GetGlobalObject(const EcmaVM *vm)
5252 {
5253 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5254 JSHandle<GlobalEnv> globalEnv = vm->GetGlobalEnv();
5255 JSHandle<JSTaggedValue> global(vm->GetJSThread(), globalEnv->GetGlobalObject());
5256 return JSNApiHelper::ToLocal<ObjectRef>(global);
5257 }
5258
ExecutePendingJob(const EcmaVM * vm)5259 void JSNApi::ExecutePendingJob(const EcmaVM *vm)
5260 {
5261 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5262 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5263 EcmaVM::ConstCast(vm)->GetJSThread()->GetCurrentEcmaContext()->ExecutePromisePendingJob();
5264 }
5265
GetHandleAddr(const EcmaVM * vm,uintptr_t localAddress)5266 uintptr_t JSNApi::GetHandleAddr(const EcmaVM *vm, uintptr_t localAddress)
5267 {
5268 if (localAddress == 0) {
5269 return 0;
5270 }
5271 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5272 CROSS_THREAD_CHECK(vm);
5273 JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress));
5274 return ecmascript::EcmaHandleScope::NewHandle(thread, value);
5275 }
5276
GetGlobalHandleAddr(const EcmaVM * vm,uintptr_t localAddress)5277 uintptr_t JSNApi::GetGlobalHandleAddr(const EcmaVM *vm, uintptr_t localAddress)
5278 {
5279 if (localAddress == 0) {
5280 return 0;
5281 }
5282 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5283 CROSS_THREAD_CHECK(vm);
5284 JSTaggedType value = *(reinterpret_cast<JSTaggedType *>(localAddress));
5285 return thread->NewGlobalHandle(value);
5286 }
5287
GetStartRealTime(const EcmaVM * vm)5288 int JSNApi::GetStartRealTime(const EcmaVM *vm)
5289 {
5290 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5291 return vm->GetProcessStartRealtime();
5292 }
5293
NotifyTaskBegin(const EcmaVM * vm)5294 void JSNApi::NotifyTaskBegin(const EcmaVM *vm)
5295 {
5296 const_cast<ecmascript::Heap *>(vm->GetHeap())->NotifyRecordMemorySize();
5297 }
5298
NotifyTaskFinished(const EcmaVM * vm)5299 void JSNApi::NotifyTaskFinished(const EcmaVM *vm)
5300 {
5301 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5302 const_cast<ecmascript::Heap *>(vm->GetHeap())->CheckAndTriggerTaskFinishedGC();
5303 }
5304
IsMultiThreadCheckEnabled(const EcmaVM * vm)5305 bool JSNApi::IsMultiThreadCheckEnabled(const EcmaVM *vm)
5306 {
5307 return vm->GetThreadCheckStatus();
5308 }
5309
GetCurrentThreadId()5310 uint32_t JSNApi::GetCurrentThreadId()
5311 {
5312 return JSThread::GetCurrentThreadId();
5313 }
5314
SetWeak(const EcmaVM * vm,uintptr_t localAddress)5315 uintptr_t JSNApi::SetWeak(const EcmaVM *vm, uintptr_t localAddress)
5316 {
5317 if (localAddress == 0) {
5318 return 0;
5319 }
5320 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5321 CROSS_THREAD_CHECK(vm);
5322 return thread->SetWeak(localAddress);
5323 }
5324
SetWeakCallback(const EcmaVM * vm,uintptr_t localAddress,void * ref,WeakRefClearCallBack freeGlobalCallBack,WeakRefClearCallBack nativeFinalizeCallback)5325 uintptr_t JSNApi::SetWeakCallback(const EcmaVM *vm, uintptr_t localAddress, void *ref,
5326 WeakRefClearCallBack freeGlobalCallBack, WeakRefClearCallBack nativeFinalizeCallback)
5327 {
5328 if (localAddress == 0) {
5329 return 0;
5330 }
5331 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5332 CROSS_THREAD_CHECK(vm);
5333 return thread->SetWeak(localAddress, ref, freeGlobalCallBack, nativeFinalizeCallback);
5334 }
5335
ClearWeak(const EcmaVM * vm,uintptr_t localAddress)5336 uintptr_t JSNApi::ClearWeak(const EcmaVM *vm, uintptr_t localAddress)
5337 {
5338 if (localAddress == 0) {
5339 return 0;
5340 }
5341 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5342 if (JSTaggedValue(reinterpret_cast<ecmascript::Node *>(localAddress)->GetObject())
5343 .IsUndefined()) {
5344 LOG_ECMA(ERROR) << "The object of weak reference has been recycled!";
5345 return 0;
5346 }
5347 CROSS_THREAD_CHECK(vm);
5348 return thread->ClearWeak(localAddress);
5349 }
5350
IsWeak(const EcmaVM * vm,uintptr_t localAddress)5351 bool JSNApi::IsWeak(const EcmaVM *vm, uintptr_t localAddress)
5352 {
5353 if (localAddress == 0) {
5354 return false;
5355 }
5356 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5357 CROSS_THREAD_CHECK(vm);
5358 return thread->IsWeak(localAddress);
5359 }
5360
DisposeGlobalHandleAddr(const EcmaVM * vm,uintptr_t addr)5361 void JSNApi::DisposeGlobalHandleAddr(const EcmaVM *vm, uintptr_t addr)
5362 {
5363 if (addr == 0 || !reinterpret_cast<ecmascript::Node *>(addr)->IsUsing()) {
5364 return;
5365 }
5366
5367 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5368 CROSS_THREAD_CHECK(vm);
5369 thread->DisposeGlobalHandle(addr);
5370 }
5371
SerializeValue(const EcmaVM * vm,Local<JSValueRef> value,Local<JSValueRef> transfer,Local<JSValueRef> cloneList,bool defaultTransfer,bool defaultCloneShared)5372 void *JSNApi::SerializeValue(const EcmaVM *vm, Local<JSValueRef> value, Local<JSValueRef> transfer,
5373 Local<JSValueRef> cloneList, bool defaultTransfer, bool defaultCloneShared)
5374 {
5375 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, nullptr);
5376 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5377 JSHandle<JSTaggedValue> arkValue = JSNApiHelper::ToJSHandle(value);
5378 JSHandle<JSTaggedValue> arkTransfer = JSNApiHelper::ToJSHandle(transfer);
5379 JSHandle<JSTaggedValue> arkCloneList = JSNApiHelper::ToJSHandle(cloneList);
5380 bool serializationTimeoutCheckEnabled = IsSerializationTimeoutCheckEnabled(vm);
5381 std::chrono::system_clock::time_point startTime;
5382 std::chrono::system_clock::time_point endTime;
5383 if (serializationTimeoutCheckEnabled) {
5384 startTime = std::chrono::system_clock::now();
5385 }
5386 ecmascript::ValueSerializer serializer(thread, defaultTransfer, defaultCloneShared);
5387 std::unique_ptr<ecmascript::SerializeData> data;
5388 if (serializer.WriteValue(thread, arkValue, arkTransfer, arkCloneList)) {
5389 data = serializer.Release();
5390 }
5391 if (serializationTimeoutCheckEnabled) {
5392 endTime = std::chrono::system_clock::now();
5393 GenerateTimeoutTraceIfNeeded(vm, startTime, endTime, true);
5394 }
5395 if (data == nullptr) {
5396 return nullptr;
5397 } else {
5398 return reinterpret_cast<void *>(data.release());
5399 }
5400 }
5401
DeserializeValue(const EcmaVM * vm,void * recoder,void * hint)5402 Local<JSValueRef> JSNApi::DeserializeValue(const EcmaVM *vm, void *recoder, void *hint)
5403 {
5404 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5405 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5406 std::unique_ptr<ecmascript::SerializeData> data(reinterpret_cast<ecmascript::SerializeData *>(recoder));
5407 ecmascript::BaseDeserializer deserializer(thread, data.release(), hint);
5408 bool serializationTimeoutCheckEnabled = IsSerializationTimeoutCheckEnabled(vm);
5409 std::chrono::system_clock::time_point startTime;
5410 std::chrono::system_clock::time_point endTime;
5411 if (serializationTimeoutCheckEnabled) {
5412 startTime = std::chrono::system_clock::now();
5413 }
5414 JSHandle<JSTaggedValue> result = deserializer.ReadValue();
5415 if (serializationTimeoutCheckEnabled) {
5416 endTime = std::chrono::system_clock::now();
5417 GenerateTimeoutTraceIfNeeded(vm, startTime, endTime, false);
5418 }
5419 return JSNApiHelper::ToLocal<ObjectRef>(result);
5420 }
5421
DeleteSerializationData(void * data)5422 void JSNApi::DeleteSerializationData(void *data)
5423 {
5424 ecmascript::SerializeData *value = reinterpret_cast<ecmascript::SerializeData *>(data);
5425 delete value;
5426 value = nullptr;
5427 }
5428
HostPromiseRejectionTracker(const EcmaVM * vm,const JSHandle<JSPromise> promise,const JSHandle<JSTaggedValue> reason,const ecmascript::PromiseRejectionEvent operation,void * data)5429 void HostPromiseRejectionTracker(const EcmaVM *vm,
5430 const JSHandle<JSPromise> promise,
5431 const JSHandle<JSTaggedValue> reason,
5432 const ecmascript::PromiseRejectionEvent operation,
5433 void* data)
5434 {
5435 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5436 ecmascript::PromiseRejectCallback promiseRejectCallback =
5437 thread->GetCurrentEcmaContext()->GetPromiseRejectCallback();
5438 if (promiseRejectCallback != nullptr) {
5439 Local<JSValueRef> promiseVal = JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>::Cast(promise));
5440 PromiseRejectInfo promiseRejectInfo(promiseVal, JSNApiHelper::ToLocal<JSValueRef>(reason),
5441 static_cast<PromiseRejectInfo::PROMISE_REJECTION_EVENT>(operation), data);
5442 promiseRejectCallback(reinterpret_cast<void*>(&promiseRejectInfo));
5443 }
5444 }
5445
SetHostPromiseRejectionTracker(EcmaVM * vm,void * cb,void * data)5446 void JSNApi::SetHostPromiseRejectionTracker(EcmaVM *vm, void *cb, void* data)
5447 {
5448 CROSS_THREAD_CHECK(vm);
5449 thread->GetCurrentEcmaContext()->SetHostPromiseRejectionTracker(HostPromiseRejectionTracker);
5450 thread->GetCurrentEcmaContext()->SetPromiseRejectCallback(
5451 reinterpret_cast<ecmascript::PromiseRejectCallback>(cb));
5452 thread->GetCurrentEcmaContext()->SetData(data);
5453 }
5454
SetHostResolveBufferTracker(EcmaVM * vm,std::function<bool (std::string dirPath,uint8_t ** buff,size_t * buffSize,std::string & errorMsg)> cb)5455 void JSNApi::SetHostResolveBufferTracker(EcmaVM *vm,
5456 std::function<bool(std::string dirPath, uint8_t **buff, size_t *buffSize, std::string &errorMsg)> cb)
5457 {
5458 vm->SetResolveBufferCallback(cb);
5459 }
5460
SetSearchHapPathTracker(EcmaVM * vm,std::function<bool (const std::string moduleName,std::string & hapPath)> cb)5461 void JSNApi::SetSearchHapPathTracker(EcmaVM *vm,
5462 std::function<bool(const std::string moduleName, std::string &hapPath)> cb)
5463 {
5464 vm->SetSearchHapPathCallBack(cb);
5465 }
5466
SetMultiThreadCheck(bool multiThreadCheck)5467 void JSNApi::SetMultiThreadCheck(bool multiThreadCheck)
5468 {
5469 EcmaVM::SetMultiThreadCheck(multiThreadCheck);
5470 }
5471
SetErrorInfoEnhance(bool errorInfoEnhance)5472 void JSNApi::SetErrorInfoEnhance(bool errorInfoEnhance)
5473 {
5474 EcmaVM::SetErrorInfoEnhance(errorInfoEnhance);
5475 }
5476
SetRequestAotCallback(EcmaVM * vm,const std::function<int32_t (const std::string & bundleName,const std::string & moduleName,int32_t triggerMode)> & cb)5477 void JSNApi::SetRequestAotCallback([[maybe_unused]] EcmaVM *vm, const std::function<int32_t
5478 (const std::string &bundleName, const std::string &moduleName, int32_t triggerMode)> &cb)
5479 {
5480 ecmascript::pgo::PGOProfilerManager::GetInstance()->SetRequestAotCallback(cb);
5481 }
5482
SetUnloadNativeModuleCallback(EcmaVM * vm,const std::function<bool (const std::string & moduleKey)> & cb)5483 void JSNApi::SetUnloadNativeModuleCallback(EcmaVM *vm, const std::function<bool(const std::string &moduleKey)> &cb)
5484 {
5485 vm->SetUnloadNativeModuleCallback(cb);
5486 }
5487
SetNativePtrGetter(EcmaVM * vm,void * cb)5488 void JSNApi::SetNativePtrGetter(EcmaVM *vm, void* cb)
5489 {
5490 vm->SetNativePtrGetter(reinterpret_cast<ecmascript::NativePtrGetter>(cb));
5491 }
5492
SetHostEnqueueJob(const EcmaVM * vm,Local<JSValueRef> cb,QueueType queueType)5493 void JSNApi::SetHostEnqueueJob(const EcmaVM *vm, Local<JSValueRef> cb, QueueType queueType)
5494 {
5495 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5496 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5497 JSHandle<JSFunction> fun = JSHandle<JSFunction>::Cast(JSNApiHelper::ToJSHandle(cb));
5498 JSHandle<TaggedArray> array = vm->GetFactory()->EmptyArray();
5499 JSHandle<MicroJobQueue> job = thread->GetCurrentEcmaContext()->GetMicroJobQueue();
5500 MicroJobQueue::EnqueueJob(thread, job, queueType, fun, array);
5501 }
5502
ExecuteModuleFromBuffer(EcmaVM * vm,const void * data,int32_t size,const std::string & file)5503 bool JSNApi::ExecuteModuleFromBuffer(EcmaVM *vm, const void *data, int32_t size, const std::string &file)
5504 {
5505 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
5506 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5507 if (!ecmascript::JSPandaFileExecutor::ExecuteFromBuffer(thread, data, size, ENTRY_POINTER, file.c_str(), false,
5508 true)) {
5509 if (thread->HasPendingException()) {
5510 ecmascript::JsStackInfo::BuildCrashInfo(thread);
5511 }
5512 std::cerr << "Cannot execute panda file from memory" << std::endl;
5513 return false;
5514 }
5515 return true;
5516 }
5517
NapiHasProperty(const EcmaVM * vm,uintptr_t nativeObj,uintptr_t key)5518 Local<JSValueRef> JSNApi::NapiHasProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key)
5519 {
5520 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5521 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5522 EscapeLocalScope scope(vm);
5523 JSHandle<JSTaggedValue> obj(nativeObj);
5524 if (!(obj->IsECMAObject() || obj->IsCallable())) {
5525 // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
5526 // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
5527 JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
5528 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
5529 }
5530 LOG_IF_SPECIAL(obj, ERROR);
5531 JSMutableHandle<JSTaggedValue> keyValue(key);
5532 JSTaggedValue res = ObjectFastOperator::TryFastHasProperty(thread, obj.GetTaggedValue(),
5533 keyValue);
5534 if (!res.IsHole()) {
5535 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5536 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
5537 }
5538 auto ret = JSTaggedValue(JSTaggedValue::HasProperty(thread, obj, keyValue));
5539 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, ret)));
5540 }
5541
NapiHasOwnProperty(const EcmaVM * vm,uintptr_t nativeObj,uintptr_t key)5542 Local<JSValueRef> JSNApi::NapiHasOwnProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key)
5543 {
5544 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5545 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5546 EscapeLocalScope scope(vm);
5547 JSHandle<JSTaggedValue> obj(nativeObj);
5548 if (!(obj->IsECMAObject() || obj->IsCallable())) {
5549 // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
5550 // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
5551 JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
5552 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
5553 }
5554 LOG_IF_SPECIAL(obj, ERROR);
5555 JSMutableHandle<JSTaggedValue> keyValue(key);
5556 JSTaggedValue res = ObjectFastOperator::TryFastHasProperty(thread, obj.GetTaggedValue(),
5557 keyValue);
5558 if (!res.IsHole()) {
5559 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5560 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
5561 }
5562 auto ret = JSTaggedValue(JSTaggedValue::HasProperty(thread, obj, keyValue));
5563 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, ret)));
5564 }
5565
NapiGetProperty(const EcmaVM * vm,uintptr_t nativeObj,uintptr_t key)5566 Local<JSValueRef> JSNApi::NapiGetProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key)
5567 {
5568 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5569 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5570 EscapeLocalScope scope(vm);
5571 JSHandle<JSTaggedValue> obj(nativeObj);
5572 if (!(obj->IsECMAObject() || obj->IsCallable())) {
5573 // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
5574 // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
5575 JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
5576 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
5577 }
5578 LOG_IF_SPECIAL(obj, ERROR);
5579 JSMutableHandle<JSTaggedValue> keyValue(key);
5580 if (!obj->IsHeapObject()) {
5581 OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue);
5582 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5583 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(ret.GetValue()));
5584 }
5585
5586 JSTaggedValue res = ObjectFastOperator::TryFastGetPropertyByValue(thread, obj.GetTaggedValue(),
5587 keyValue);
5588 if (!res.IsHole()) {
5589 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5590 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
5591 }
5592
5593 JSTaggedValue ret = ObjectFastOperator::FastGetPropertyByValue(thread, obj.GetTaggedValue(),
5594 keyValue.GetTaggedValue());
5595 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5596 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, ret)));
5597 }
5598
NapiDeleteProperty(const EcmaVM * vm,uintptr_t nativeObj,uintptr_t key)5599 Local<JSValueRef> JSNApi::NapiDeleteProperty(const EcmaVM *vm, uintptr_t nativeObj, uintptr_t key)
5600 {
5601 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5602 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5603 EscapeLocalScope scope(vm);
5604 JSHandle<JSTaggedValue> obj(nativeObj);
5605 if (!(obj->IsECMAObject() || obj->IsCallable())) {
5606 // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
5607 // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
5608 JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
5609 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
5610 }
5611 LOG_IF_SPECIAL(obj, ERROR);
5612 JSMutableHandle<JSTaggedValue> keyValue(key);
5613 if (keyValue->IsString() && !EcmaStringAccessor(keyValue.GetTaggedValue()).IsInternString()) {
5614 [[maybe_unused]] ecmascript::EcmaHandleScope handleScope(thread);
5615 auto string = thread->GetEcmaVM()->GetFactory()->InternString(keyValue);
5616 EcmaStringAccessor(string).SetInternString();
5617 keyValue.Update(JSTaggedValue(string));
5618 }
5619 auto ret = JSTaggedValue(JSTaggedValue::DeleteProperty(thread, obj, keyValue));
5620 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, ret)));
5621 }
5622
NapiGetNamedProperty(const EcmaVM * vm,uintptr_t nativeObj,const char * utf8Key)5623 Local<JSValueRef> JSNApi::NapiGetNamedProperty(const EcmaVM *vm, uintptr_t nativeObj, const char* utf8Key)
5624 {
5625 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5626 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5627 EscapeLocalScope scope(vm);
5628 JSHandle<JSTaggedValue> obj(nativeObj);
5629 if (!(obj->IsECMAObject() || obj->IsCallable())) {
5630 // When input validation is failed, we return JSTaggedValue::Hole to napi native engine.
5631 // Using JSTaggedValue::Hole as the "hand-shaking-protocol" to tell native engine to change error state.
5632 JSHandle<JSTaggedValue> holeHandle(thread, JSTaggedValue::Hole());
5633 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(holeHandle));
5634 }
5635 LOG_IF_SPECIAL(obj, ERROR);
5636 ObjectFactory *factory = vm->GetFactory();
5637 JSHandle<JSTaggedValue> keyValue(factory->NewFromUtf8(utf8Key));
5638 if (!obj->IsHeapObject()) {
5639 OperationResult ret = JSTaggedValue::GetProperty(thread, obj, keyValue);
5640 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5641 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(ret.GetValue()));
5642 }
5643
5644 // FastPath - Try find key entry in cache directly.
5645 JSTaggedValue res = ObjectFastOperator::TryGetPropertyByNameThroughCacheAtLocal(thread, obj.GetTaggedValue(),
5646 keyValue.GetTaggedValue());
5647 if (!res.IsHole()) {
5648 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5649 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
5650 }
5651 if (!KeyIsNumber(utf8Key)) {
5652 res = ObjectFastOperator::GetPropertyByName(thread, obj.GetTaggedValue(), keyValue.GetTaggedValue());
5653 if (res.IsHole()) {
5654 res = JSTaggedValue::GetProperty(thread, obj, keyValue).GetValue().GetTaggedValue();
5655 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5656 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
5657 }
5658 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5659 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
5660 }
5661 res = ObjectFastOperator::FastGetPropertyByValue(thread, obj.GetTaggedValue(), keyValue.GetTaggedValue());
5662 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5663 return scope.Escape(JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, res)));
5664 }
5665
CreateLocal(const EcmaVM * vm,panda::JSValueRef src)5666 Local<JSValueRef> JSNApi::CreateLocal(const EcmaVM *vm, panda::JSValueRef src)
5667 {
5668 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5669 JSHandle<JSTaggedValue> handle(vm->GetJSThread(), JSNApiHelper::ToJSTaggedValue(&src));
5670 return JSNApiHelper::ToLocal<JSValueRef>(handle);
5671 }
5672
GetExportObject(EcmaVM * vm,const std::string & file,const std::string & key)5673 Local<ObjectRef> JSNApi::GetExportObject(EcmaVM *vm, const std::string &file, const std::string &key)
5674 {
5675 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5676 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5677 ecmascript::CString entry = file.c_str();
5678 ecmascript::CString name = vm->GetAssetPath();
5679 if (!vm->IsBundlePack()) {
5680 ModulePathHelper::ParseAbcPathAndOhmUrl(vm, entry, name, entry);
5681 std::shared_ptr<JSPandaFile> jsPandaFile =
5682 JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, name, entry.c_str(), false);
5683 if (jsPandaFile == nullptr) {
5684 JSHandle<JSTaggedValue> exportObj(thread, JSTaggedValue::Null());
5685 return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
5686 }
5687 if (!jsPandaFile->IsRecordWithBundleName()) {
5688 PathHelper::AdaptOldIsaRecord(entry);
5689 }
5690 }
5691 ecmascript::ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
5692 JSHandle<ecmascript::SourceTextModule> ecmaModule = moduleManager->GetImportedModule(entry);
5693 if (ecmaModule->GetIsNewBcVersion()) {
5694 int index = ecmascript::ModuleManager::GetExportObjectIndex(vm, ecmaModule, key.c_str());
5695 JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
5696 JSHandle<JSTaggedValue> exportObj(thread, result);
5697 return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
5698 }
5699 ObjectFactory *factory = vm->GetFactory();
5700 JSHandle<EcmaString> keyHandle = factory->NewFromASCII(key.c_str());
5701
5702 JSTaggedValue result = ecmaModule->GetModuleValue(thread, keyHandle.GetTaggedValue(), false);
5703 JSHandle<JSTaggedValue> exportObj(thread, result);
5704 return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
5705 }
5706
GetExportObjectFromBuffer(EcmaVM * vm,const std::string & file,const std::string & key)5707 Local<ObjectRef> JSNApi::GetExportObjectFromBuffer(EcmaVM *vm, const std::string &file,
5708 const std::string &key)
5709 {
5710 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5711 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5712 ecmascript::ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
5713 JSHandle<ecmascript::SourceTextModule> ecmaModule = moduleManager->GetImportedModule(file.c_str());
5714 if (ecmaModule->GetIsNewBcVersion()) {
5715 int index = ecmascript::ModuleManager::GetExportObjectIndex(vm, ecmaModule, key.c_str());
5716 JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
5717 JSHandle<JSTaggedValue> exportObj(thread, result);
5718 return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
5719 }
5720
5721 ObjectFactory *factory = vm->GetFactory();
5722 JSHandle<EcmaString> keyHandle = factory->NewFromASCII(key.c_str());
5723 JSTaggedValue result = ecmaModule->GetModuleValue(thread, keyHandle.GetTaggedValue(), false);
5724 JSHandle<JSTaggedValue> exportObj(thread, result);
5725 return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
5726 }
5727
ExecuteNativeModule(EcmaVM * vm,const std::string & key)5728 Local<ObjectRef> JSNApi::ExecuteNativeModule(EcmaVM *vm, const std::string &key)
5729 {
5730 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5731 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5732 ecmascript::ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
5733 JSHandle<JSTaggedValue> exportObj = moduleManager->LoadNativeModule(thread, key.c_str());
5734 return JSNApiHelper::ToLocal<ObjectRef>(exportObj);
5735 }
5736
GetModuleNameSpaceFromFile(EcmaVM * vm,const std::string & file,const std::string & module_path)5737 Local<ObjectRef> JSNApi::GetModuleNameSpaceFromFile(EcmaVM *vm, const std::string &file, const std::string &module_path)
5738 {
5739 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5740 ecmascript::ThreadManagedScope managedScope(thread);
5741 ecmascript::CString recordNameStr;
5742 ecmascript::CString abcFilePath;
5743 if (module_path.size() != 0) {
5744 ecmascript::CString moduleName = ModulePathHelper::GetModuleNameWithPath(module_path.c_str());
5745 abcFilePath = ModulePathHelper::ConcatPandaFilePath(moduleName);
5746 recordNameStr = ModulePathHelper::TranslateNapiFileRequestPath(thread, module_path.c_str(), file.c_str());
5747 } else {
5748 // need get moduleName from stack
5749 std::pair<std::string, std::string> moduleInfo = vm->GetCurrentModuleInfo(false);
5750 if (thread->HasPendingException()) {
5751 thread->GetCurrentEcmaContext()->HandleUncaughtException();
5752 return JSValueRef::Undefined(vm);
5753 }
5754 std::string path = std::string(vm->GetBundleName().c_str()) + PathHelper::SLASH_TAG +
5755 moduleInfo.first;
5756 abcFilePath = moduleInfo.second;
5757 recordNameStr = ModulePathHelper::TranslateNapiFileRequestPath(thread, path.c_str(), file.c_str());
5758 }
5759 LOG_ECMA(DEBUG) << "JSNApi::LoadModuleNameSpaceFromFile: Concated recordName " << recordNameStr;
5760 ecmascript::ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager();
5761 JSHandle<JSTaggedValue> moduleNamespace = moduleManager->
5762 GetModuleNameSpaceFromFile(thread, recordNameStr, abcFilePath);
5763 return JSNApiHelper::ToLocal<ObjectRef>(moduleNamespace);
5764 }
5765
GetModuleNameSpaceWithModuleInfo(EcmaVM * vm,const std::string & file,const std::string & module_path)5766 Local<ObjectRef> JSNApi::GetModuleNameSpaceWithModuleInfo(EcmaVM *vm, const std::string &file,
5767 const std::string &module_path)
5768 {
5769 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5770 ecmascript::ThreadManagedScope managedScope(thread);
5771 ecmascript::CString moduleStr = ModulePathHelper::GetModuleNameWithPath(module_path.c_str());
5772 ecmascript::CString srcPrefix = moduleStr + ModulePathHelper::PHYCICAL_FILE_PATH;
5773 std::string prefix = ConvertToStdString(srcPrefix);
5774 if (file.find(srcPrefix) == 0) {
5775 std::string fileName = file.substr(prefix.size() + 1);
5776 return GetModuleNameSpaceFromFile(vm, fileName, module_path);
5777 }
5778 ecmascript::CString requestPath = file.c_str();
5779 ecmascript::CString modulePath = module_path.c_str();
5780 JSHandle<JSTaggedValue> nameSp = ecmascript::NapiModuleLoader::LoadModuleNameSpaceWithModuleInfo(vm,
5781 requestPath, modulePath);
5782 return JSNApiHelper::ToLocal<ObjectRef>(nameSp);
5783 }
5784
5785 // ---------------------------------- Promise -------------------------------------
Catch(const EcmaVM * vm,Local<FunctionRef> handler)5786 Local<PromiseRef> PromiseRef::Catch(const EcmaVM *vm, Local<FunctionRef> handler)
5787 {
5788 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5789 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5790 const GlobalEnvConstants *constants = thread->GlobalConstants();
5791
5792 JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
5793 LOG_IF_SPECIAL(promise, ERROR);
5794 JSHandle<JSTaggedValue> catchKey(thread, constants->GetPromiseCatchString());
5795 JSHandle<JSTaggedValue> reject = JSNApiHelper::ToJSHandle(handler);
5796 JSHandle<JSTaggedValue> undefined = constants->GetHandledUndefined();
5797 EcmaRuntimeCallInfo *info =
5798 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 1);
5799 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5800 info->SetCallArg(reject.GetTaggedValue());
5801 JSTaggedValue result = JSFunction::Invoke(info, catchKey);
5802
5803 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5804 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
5805 }
5806
Finally(const EcmaVM * vm,Local<FunctionRef> handler)5807 Local<PromiseRef> PromiseRef::Finally(const EcmaVM *vm, Local<FunctionRef> handler)
5808 {
5809 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5810 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5811 const GlobalEnvConstants *constants = thread->GlobalConstants();
5812
5813 JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
5814 LOG_IF_SPECIAL(promise, ERROR);
5815 JSHandle<JSTaggedValue> finallyKey = constants->GetHandledPromiseFinallyString();
5816 JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(handler);
5817 JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
5818 EcmaRuntimeCallInfo *info =
5819 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
5820 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5821 info->SetCallArg(resolver.GetTaggedValue(), undefined.GetTaggedValue());
5822 JSTaggedValue result = JSFunction::Invoke(info, finallyKey);
5823
5824 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5825 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
5826 }
5827
Then(const EcmaVM * vm,Local<FunctionRef> handler)5828 Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> handler)
5829 {
5830 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5831 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5832 const GlobalEnvConstants *constants = thread->GlobalConstants();
5833
5834 JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
5835 LOG_IF_SPECIAL(promise, ERROR);
5836 JSHandle<JSTaggedValue> thenKey(thread, constants->GetPromiseThenString());
5837 JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(handler);
5838 JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
5839 EcmaRuntimeCallInfo *info =
5840 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
5841 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5842 info->SetCallArg(resolver.GetTaggedValue(), undefined.GetTaggedValue());
5843 JSTaggedValue result = JSFunction::Invoke(info, thenKey);
5844
5845 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5846 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
5847 }
5848
Then(const EcmaVM * vm,Local<FunctionRef> onFulfilled,Local<FunctionRef> onRejected)5849 Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> onFulfilled, Local<FunctionRef> onRejected)
5850 {
5851 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5852 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5853 const GlobalEnvConstants *constants = thread->GlobalConstants();
5854
5855 JSHandle<JSTaggedValue> promise = JSNApiHelper::ToJSHandle(this);
5856 LOG_IF_SPECIAL(promise, ERROR);
5857 JSHandle<JSTaggedValue> thenKey(thread, constants->GetPromiseThenString());
5858 JSHandle<JSTaggedValue> resolver = JSNApiHelper::ToJSHandle(onFulfilled);
5859 JSHandle<JSTaggedValue> reject = JSNApiHelper::ToJSHandle(onRejected);
5860 JSHandle<JSTaggedValue> undefined(constants->GetHandledUndefined());
5861 EcmaRuntimeCallInfo *info =
5862 ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
5863 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5864 info->SetCallArg(resolver.GetTaggedValue(), reject.GetTaggedValue());
5865 JSTaggedValue result = JSFunction::Invoke(info, thenKey);
5866
5867 RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
5868 return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
5869 }
5870
GetPromiseState(const EcmaVM * vm)5871 Local<JSValueRef> PromiseRef::GetPromiseState(const EcmaVM *vm)
5872 {
5873 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5874 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5875 JSHandle<JSPromise> promise(JSNApiHelper::ToJSHandle(this));
5876 LOG_IF_SPECIAL(promise, ERROR);
5877
5878 ecmascript::PromiseState state = promise->GetPromiseState();
5879 std::string promiseStateStr;
5880 switch (state) {
5881 case ecmascript::PromiseState::PENDING:
5882 promiseStateStr = "Pending";
5883 break;
5884 case ecmascript::PromiseState::FULFILLED:
5885 promiseStateStr = "Fulfilled";
5886 break;
5887 case ecmascript::PromiseState::REJECTED:
5888 promiseStateStr = "Rejected";
5889 break;
5890 }
5891
5892 ObjectFactory *factory = vm->GetFactory();
5893 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(factory->NewFromStdString(promiseStateStr)));
5894 }
5895
GetPromiseResult(const EcmaVM * vm)5896 Local<JSValueRef> PromiseRef::GetPromiseResult(const EcmaVM *vm)
5897 {
5898 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5899 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5900 JSHandle<JSPromise> promise(JSNApiHelper::ToJSHandle(this));
5901 LOG_IF_SPECIAL(promise, ERROR);
5902
5903 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(vm->GetJSThread(), promise->GetPromiseResult()));
5904 }
5905 // ---------------------------------- ProxyRef -----------------------------------------
GetHandler(const EcmaVM * vm)5906 Local<JSValueRef> ProxyRef::GetHandler(const EcmaVM *vm)
5907 {
5908 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5909 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5910 JSHandle<JSProxy> jsProxy(JSNApiHelper::ToJSHandle(this));
5911 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, jsProxy->GetHandler()));
5912 }
5913
GetTarget(const EcmaVM * vm)5914 Local<JSValueRef> ProxyRef::GetTarget(const EcmaVM *vm)
5915 {
5916 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5917 ecmascript::ThreadManagedScope scope(vm->GetJSThread());
5918 JSHandle<JSProxy> jsProxy(JSNApiHelper::ToJSHandle(this));
5919 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, jsProxy->GetTarget()));
5920 }
5921
IsRevoked()5922 bool ProxyRef::IsRevoked()
5923 {
5924 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
5925 JSHandle<JSProxy> jsProxy(JSNApiHelper::ToJSHandle(this));
5926 return jsProxy->GetIsRevoked();
5927 }
5928
5929 // ---------------------------------- SetRef --------------------------------------
GetSize(const EcmaVM * vm)5930 int32_t SetRef::GetSize(const EcmaVM *vm)
5931 {
5932 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
5933 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5934 JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
5935 return set->GetSize();
5936 }
5937
GetTotalElements(const EcmaVM * vm)5938 int32_t SetRef::GetTotalElements(const EcmaVM *vm)
5939 {
5940 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
5941 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5942 JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
5943 return static_cast<int>(set->GetSize()) +
5944 LinkedHashSet::Cast(set->GetLinkedSet().GetTaggedObject())->NumberOfDeletedElements();
5945 }
5946
GetValue(const EcmaVM * vm,int entry)5947 Local<JSValueRef> SetRef::GetValue(const EcmaVM *vm, int entry)
5948 {
5949 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5950 ecmascript::ThreadManagedScope managedScope(thread);
5951 JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
5952 LOG_IF_SPECIAL(set, FATAL);
5953 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, set->GetValue(entry)));
5954 }
5955
New(const EcmaVM * vm)5956 Local<SetRef> SetRef::New(const EcmaVM *vm)
5957 {
5958 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
5959 ecmascript::ThreadManagedScope managedScope(thread);
5960 ObjectFactory *factory = vm->GetJSThread()->GetEcmaVM()->GetFactory();
5961 JSHandle<GlobalEnv> env = vm->GetJSThread()->GetEcmaVM()->GetGlobalEnv();
5962 JSHandle<JSTaggedValue> constructor = env->GetBuiltinsSetFunction();
5963 JSHandle<JSSet> set =
5964 JSHandle<JSSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
5965 JSHandle<LinkedHashSet> hashSet = LinkedHashSet::Create(vm->GetJSThread());
5966 set->SetLinkedSet(vm->GetJSThread(), hashSet);
5967 JSHandle<JSTaggedValue> setTag = JSHandle<JSTaggedValue>::Cast(set);
5968 return JSNApiHelper::ToLocal<SetRef>(setTag);
5969 }
5970
Add(const EcmaVM * vm,Local<JSValueRef> value)5971 void SetRef::Add(const EcmaVM *vm, Local<JSValueRef> value)
5972 {
5973 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
5974 ecmascript::ThreadManagedScope managedScope(thread);
5975 JSHandle<JSSet> set(JSNApiHelper::ToJSHandle(this));
5976 LOG_IF_SPECIAL(set, ERROR);
5977 JSSet::Add(vm->GetJSThread(), set, JSNApiHelper::ToJSHandle(value));
5978 }
5979
5980 // ---------------------------------- WeakMapRef --------------------------------------
GetSize(const EcmaVM * vm)5981 int32_t WeakMapRef::GetSize(const EcmaVM *vm)
5982 {
5983 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
5984 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5985 JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
5986 return weakMap->GetSize();
5987 }
5988
GetTotalElements(const EcmaVM * vm)5989 int32_t WeakMapRef::GetTotalElements(const EcmaVM *vm)
5990 {
5991 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
5992 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
5993 JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
5994 return weakMap->GetSize() +
5995 LinkedHashMap::Cast(weakMap->GetLinkedMap().GetTaggedObject())->NumberOfDeletedElements();
5996 }
5997
GetKey(const EcmaVM * vm,int entry)5998 Local<JSValueRef> WeakMapRef::GetKey(const EcmaVM *vm, int entry)
5999 {
6000 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6001 ecmascript::ThreadManagedScope managedScope(thread);
6002 JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6003 LOG_IF_SPECIAL(weakMap, FATAL);
6004 JSTaggedValue key = weakMap->GetKey(entry);
6005 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, key.GetWeakRawValue()));
6006 }
6007
GetValue(const EcmaVM * vm,int entry)6008 Local<JSValueRef> WeakMapRef::GetValue(const EcmaVM *vm, int entry)
6009 {
6010 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6011 JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6012 LOG_IF_SPECIAL(weakMap, FATAL);
6013 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, weakMap->GetValue(entry)));
6014 }
6015
New(const EcmaVM * vm)6016 Local<WeakMapRef> WeakMapRef::New(const EcmaVM *vm)
6017 {
6018 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6019 ecmascript::ThreadManagedScope managedScope(thread);
6020 ObjectFactory *factory = vm->GetJSThread()->GetEcmaVM()->GetFactory();
6021 JSHandle<GlobalEnv> env = vm->GetJSThread()->GetEcmaVM()->GetGlobalEnv();
6022 JSHandle<JSTaggedValue> constructor = env->GetBuiltinsWeakMapFunction();
6023 JSHandle<JSWeakMap> weakMap =
6024 JSHandle<JSWeakMap>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
6025 JSHandle<LinkedHashMap> hashMap = LinkedHashMap::Create(vm->GetJSThread());
6026 weakMap->SetLinkedMap(vm->GetJSThread(), hashMap);
6027 JSHandle<JSTaggedValue> weakMapTag = JSHandle<JSTaggedValue>::Cast(weakMap);
6028 return JSNApiHelper::ToLocal<WeakMapRef>(weakMapTag);
6029 }
6030
Set(const EcmaVM * vm,const Local<JSValueRef> & key,const Local<JSValueRef> & value)6031 void WeakMapRef::Set(const EcmaVM *vm, const Local<JSValueRef> &key, const Local<JSValueRef> &value)
6032 {
6033 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
6034 ecmascript::ThreadManagedScope managedScope(thread);
6035 JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6036 LOG_IF_SPECIAL(weakMap, FATAL);
6037 JSWeakMap::Set(vm->GetJSThread(), weakMap, JSNApiHelper::ToJSHandle(key), JSNApiHelper::ToJSHandle(value));
6038 }
6039
Has(const EcmaVM * vm,Local<JSValueRef> key)6040 bool WeakMapRef::Has(const EcmaVM *vm, Local<JSValueRef> key)
6041 {
6042 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, false);
6043 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, false);
6044 ecmascript::ThreadManagedScope managedScope(thread);
6045 JSHandle<JSWeakMap> weakMap(JSNApiHelper::ToJSHandle(this));
6046 return weakMap->Has(thread, JSNApiHelper::ToJSTaggedValue(*key));
6047 }
6048
6049 // ---------------------------------- WeakSetRef --------------------------------------
GetSize(const EcmaVM * vm)6050 int32_t WeakSetRef::GetSize(const EcmaVM *vm)
6051 {
6052 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
6053 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
6054 JSHandle<JSWeakSet> weakSet(JSNApiHelper::ToJSHandle(this));
6055 return weakSet->GetSize();
6056 }
6057
GetTotalElements(const EcmaVM * vm)6058 int32_t WeakSetRef::GetTotalElements(const EcmaVM *vm)
6059 {
6060 DCHECK_SPECIAL_VALUE_WITH_RETURN(this, 0);
6061 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
6062 JSHandle<JSWeakSet> weakSet(JSNApiHelper::ToJSHandle(this));
6063 return weakSet->GetSize() +
6064 LinkedHashSet::Cast(weakSet->GetLinkedSet().GetTaggedObject())->NumberOfDeletedElements();
6065 }
6066
GetValue(const EcmaVM * vm,int entry)6067 Local<JSValueRef> WeakSetRef::GetValue(const EcmaVM *vm, int entry)
6068 {
6069 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6070 ecmascript::ThreadManagedScope managedScope(thread);
6071 JSHandle<JSWeakSet> weakSet(JSNApiHelper::ToJSHandle(this));
6072 LOG_IF_SPECIAL(weakSet, FATAL);
6073 JSTaggedValue value = weakSet->GetValue(entry);
6074 return JSNApiHelper::ToLocal<JSValueRef>(JSHandle<JSTaggedValue>(thread, value.GetWeakRawValue()));
6075 }
6076
New(const EcmaVM * vm)6077 Local<WeakSetRef> WeakSetRef::New(const EcmaVM *vm)
6078 {
6079 CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
6080 ecmascript::ThreadManagedScope managedScope(thread);
6081 ObjectFactory *factory = vm->GetJSThread()->GetEcmaVM()->GetFactory();
6082 JSHandle<GlobalEnv> env = vm->GetJSThread()->GetEcmaVM()->GetGlobalEnv();
6083 JSHandle<JSTaggedValue> constructor = env->GetBuiltinsWeakSetFunction();
6084 JSHandle<JSWeakSet> weakSet =
6085 JSHandle<JSWeakSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
6086 JSHandle<LinkedHashSet> hashWeakSet = LinkedHashSet::Create(vm->GetJSThread());
6087 weakSet->SetLinkedSet(vm->GetJSThread(), hashWeakSet);
6088 JSHandle<JSTaggedValue> setTag = JSHandle<JSTaggedValue>::Cast(weakSet);
6089 return JSNApiHelper::ToLocal<WeakSetRef>(setTag);
6090 }
6091
Add(const EcmaVM * vm,Local<JSValueRef> value)6092 void WeakSetRef::Add(const EcmaVM *vm, Local<JSValueRef> value)
6093 {
6094 CROSS_THREAD_AND_EXCEPTION_CHECK(vm);
6095 ecmascript::ThreadManagedScope managedScope(thread);
6096 JSHandle<JSWeakSet> weakSet(JSNApiHelper::ToJSHandle(this));
6097 LOG_IF_SPECIAL(weakSet, ERROR);
6098 JSWeakSet::Add(vm->GetJSThread(), weakSet, JSNApiHelper::ToJSHandle(value));
6099 }
6100
~TryCatch()6101 TryCatch::~TryCatch() {}
6102
HasCaught() const6103 bool TryCatch::HasCaught() const
6104 {
6105 return ecmaVm_->GetJSThread()->HasPendingException();
6106 }
6107
Rethrow()6108 void TryCatch::Rethrow()
6109 {
6110 rethrow_ = true;
6111 }
6112
GetAndClearException()6113 Local<ObjectRef> TryCatch::GetAndClearException()
6114 {
6115 ecmascript::ThreadManagedScope managedScope(ecmaVm_->GetJSThread());
6116 return JSNApiHelper::ToLocal<ObjectRef>(ecmaVm_->GetAndClearEcmaUncaughtException());
6117 }
6118
GetException()6119 Local<ObjectRef> TryCatch::GetException()
6120 {
6121 ecmascript::ThreadManagedScope managedScope(ecmaVm_->GetJSThread());
6122 return JSNApiHelper::ToLocal<ObjectRef>(ecmaVm_->GetEcmaUncaughtException());
6123 }
6124
ClearException()6125 void TryCatch::ClearException()
6126 {
6127 ecmaVm_->GetJSThread()->ClearException();
6128 }
6129
RegisterStringCacheTable(const EcmaVM * vm,uint32_t size)6130 bool ExternalStringCache::RegisterStringCacheTable(const EcmaVM *vm, uint32_t size)
6131 {
6132 auto instance = ecmascript::Runtime::GetInstance();
6133 ASSERT(instance != nullptr);
6134
6135 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
6136 return instance->CreateStringCacheTable(size);
6137 }
6138
SetCachedString(const EcmaVM * vm,const char * name,uint32_t propertyIndex)6139 bool ExternalStringCache::SetCachedString(const EcmaVM *vm, const char *name, uint32_t propertyIndex)
6140 {
6141 auto instance = ecmascript::Runtime::GetInstance();
6142 ASSERT(instance != nullptr);
6143
6144 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
6145 [[maybe_unused]] LocalScope scope(vm);
6146 ObjectFactory *factory = vm->GetFactory();
6147 JSHandle<EcmaString> str = factory->NewFromUtf8(name);
6148 return instance->SetCachedString(str, propertyIndex);
6149 }
6150
GetCachedString(const EcmaVM * vm,uint32_t propertyIndex)6151 Local<StringRef> ExternalStringCache::GetCachedString(const EcmaVM *vm, uint32_t propertyIndex)
6152 {
6153 auto instance = ecmascript::Runtime::GetInstance();
6154 ASSERT(instance != nullptr);
6155
6156 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
6157 JSHandle<EcmaString> str = instance->GetCachedString(vm->GetJSThread(), propertyIndex);
6158 return JSNApiHelper::ToLocal<StringRef>(JSHandle<JSTaggedValue>(str));
6159 }
6160
HasCachedString(const EcmaVM * vm,uint32_t propertyIndex)6161 bool ExternalStringCache::HasCachedString([[maybe_unused]] const EcmaVM *vm, uint32_t propertyIndex)
6162 {
6163 auto instance = ecmascript::Runtime::GetInstance();
6164 ASSERT(instance != nullptr);
6165 ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
6166 return instance->HasCachedString(propertyIndex);
6167 }
6168 } // namespace panda
6169