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