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