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