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 
17 #include <array>
18 #include <cstdint>
19 #include <fcntl.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include "ecmascript/base/json_parser.h"
24 #include "ecmascript/base/json_stringifier.h"
25 #include "ecmascript/base/typed_array_helper-inl.h"
26 #include "ecmascript/builtins/builtins_object.h"
27 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
28 #include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
29 #endif
30 #include "ecmascript/checkpoint/thread_state_transition.h"
31 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
32 #include "ecmascript/js_generator_object.h"
33 #include "ecmascript/js_regexp.h"
34 #include "ecmascript/module/module_path_helper.h"
35 #include "ecmascript/regexp/regexp_parser.h"
36 #include "ecmascript/js_weak_container.h"
37 #ifdef ARK_SUPPORT_INTL
38 #include "ecmascript/js_bigint.h"
39 #include "ecmascript/js_collator.h"
40 #include "ecmascript/js_date_time_format.h"
41 #include "ecmascript/js_number_format.h"
42 #endif
43 
44 #if defined(ECMASCRIPT_SUPPORT_DEBUGGER) && defined(PANDA_TARGET_IOS)
45 namespace OHOS::ArkCompiler::Toolchain {
46 using DebuggerPostTask = std::function<void(std::function<void()> &&)>;
47 extern "C" {
48     bool StartDebug(const std::string& componentName, void* vm, bool isDebugMode, int32_t instanceId,
49         const DebuggerPostTask& debuggerPostTask, int port);
50     void StopDebug(void* vm);
51     void WaitForDebugger(void* vm);
52 }
53 } // namespace OHOS::ArkCompiler::Toolchain
54 const std::string DEBUGGER_NAME = "PandaDebugger";
55 #endif
56 
57 namespace panda {
58 using ecmascript::ECMAObject;
59 using ecmascript::EcmaString;
60 using ecmascript::EcmaStringAccessor;
61 using ecmascript::ErrorType;
62 using ecmascript::FastRuntimeStub;
63 using ecmascript::GlobalEnv;
64 using ecmascript::GlobalEnvConstants;
65 using ecmascript::EcmaRuntimeCallInfo;
66 using ecmascript::JSArray;
67 using ecmascript::JSArrayBuffer;
68 using ecmascript::JSDataView;
69 using ecmascript::ByteArray;
70 using ecmascript::JSDate;
71 using ecmascript::JSFunction;
72 using ecmascript::JSFunctionBase;
73 using ecmascript::JSHClass;
74 using ecmascript::JSMap;
75 using ecmascript::Method;
76 using ecmascript::JSNativePointer;
77 using ecmascript::JSObject;
78 using ecmascript::JSPandaFile;
79 using ecmascript::JSPandaFileManager;
80 using ecmascript::JSPrimitiveRef;
81 using ecmascript::JSPromise;
82 using ecmascript::JSRegExp;
83 using ecmascript::JSSet;
84 using ecmascript::JSSymbol;
85 using ecmascript::JSTaggedNumber;
86 using ecmascript::JSTaggedType;
87 using ecmascript::JSTaggedValue;
88 using ecmascript::JSThread;
89 using ecmascript::LinkedHashMap;
90 using ecmascript::LinkedHashSet;
91 using ecmascript::ObjectFactory;
92 using ecmascript::PromiseCapability;
93 using ecmascript::PropertyDescriptor;
94 using ecmascript::OperationResult;
95 using ecmascript::Region;
96 using ecmascript::TaggedArray;
97 using ecmascript::JSTypedArray;
98 using ecmascript::base::BuiltinsBase;
99 using ecmascript::builtins::BuiltinsObject;
100 using ecmascript::base::Utf8JsonParser;
101 using ecmascript::base::Utf16JsonParser;
102 using ecmascript::base::JsonStringifier;
103 using ecmascript::base::StringHelper;
104 using ecmascript::base::TypedArrayHelper;
105 using ecmascript::job::MicroJobQueue;
106 using ecmascript::job::QueueType;
107 using ecmascript::JSRuntimeOptions;
108 using ecmascript::BigInt;
109 using ecmascript::MemMapAllocator;
110 using ecmascript::Mutex;
111 using ecmascript::LockHolder;
112 using ecmascript::JSMapIterator;
113 using ecmascript::JSSetIterator;
114 using ecmascript::IterationKind;
115 using ecmascript::JSGeneratorState;
116 using ecmascript::JSIterator;
117 using ecmascript::JSGeneratorFunction;
118 using ecmascript::JSGeneratorObject;
119 using ecmascript::GeneratorContext;
120 using ecmascript::JSProxy;
121 #ifdef ARK_SUPPORT_INTL
122 using ecmascript::JSCollator;
123 using ecmascript::JSDateTimeFormat;
124 using ecmascript::JSNumberFormat;
125 #endif
126 using ecmascript::RegExpParser;
127 using ecmascript::DebugInfoExtractor;
128 using ecmascript::PatchErrorCode;
129 using ecmascript::base::NumberHelper;
130 using ecmascript::Log;
131 using ecmascript::EcmaContext;
132 using ecmascript::JSWeakMap;
133 using ecmascript::JSWeakSet;
134 using ecmascript::JSSendableArrayBuffer;
135 template<typename T>
136 using JSHandle = ecmascript::JSHandle<T>;
137 
138 template<typename T>
139 using JSMutableHandle = ecmascript::JSMutableHandle<T>;
140 
141 using PathHelper = ecmascript::base::PathHelper;
142 using ModulePathHelper = ecmascript::ModulePathHelper;
143 using TransformType = ecmascript::base::JsonHelper::TransformType;
144 
145 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
146 #define TYPED_ARRAY_NEW(Type)                                                                             \
147     Local<Type##Ref> Type##Ref::New(                                                                      \
148         const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length)               \
149     {                                                                                                     \
150         CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));                      \
151         ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());                                   \
152         JSHandle<GlobalEnv> env = vm->GetGlobalEnv();                                                     \
153                                                                                                           \
154         JSHandle<JSTaggedValue> func = env->Get##Type##Function();                                        \
155         JSHandle<JSArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(buffer));                            \
156         JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();             \
157         const uint32_t argsLength = 3;                                                                    \
158         EcmaRuntimeCallInfo *info =                                                                       \
159             ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, func, argsLength);   \
160         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));                                        \
161         info->SetCallArg(arrayBuffer.GetTaggedValue(), JSTaggedValue(byteOffset), JSTaggedValue(length)); \
162         JSTaggedValue result = JSFunction::Construct(info);                                               \
163         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));                                        \
164         JSHandle<JSTaggedValue> resultHandle(thread, result);                                             \
165         return JSNApiHelper::ToLocal<Type##Ref>(resultHandle);                                            \
166     }
167 
168 TYPED_ARRAY_ALL(TYPED_ARRAY_NEW)
169 
170 #undef TYPED_ARRAY_NEW
171 
172 #define SENDABLE_TYPED_ARRAY_NEW(Type)                                                                    \
173     Local<Type##Ref> Type##Ref::New(                                                                      \
174         const EcmaVM *vm, Local<SendableArrayBufferRef> buffer, int32_t byteOffset, int32_t length)       \
175     {                                                                                                     \
176         CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));                      \
177         ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());                                   \
178         JSHandle<GlobalEnv> env = vm->GetGlobalEnv();                                                     \
179                                                                                                           \
180         JSHandle<JSTaggedValue> func = env->Get##Type##Function();                                        \
181         JSHandle<JSSendableArrayBuffer> arrayBuffer(JSNApiHelper::ToJSHandle(buffer));                    \
182         JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();             \
183         const uint32_t argsLength = 3;                                                                    \
184         EcmaRuntimeCallInfo *info =                                                                       \
185             ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, func, undefined, func, argsLength);   \
186         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));                                        \
187         info->SetCallArg(arrayBuffer.GetTaggedValue(), JSTaggedValue(byteOffset), JSTaggedValue(length)); \
188         JSTaggedValue result = JSFunction::Construct(info);                                               \
189         RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));                                        \
190         JSHandle<JSTaggedValue> resultHandle(thread, result);                                             \
191         return JSNApiHelper::ToLocal<Type##Ref>(resultHandle);                                            \
192     }
193 
194 SENDABLE_TYPED_ARRAY_ALL(SENDABLE_TYPED_ARRAY_NEW)
195 
196 #undef SENDABLE_TYPED_ARRAY_NEW
197 
198 // ---------------------------------- JSON ------------------------------------------
Parse(const EcmaVM *vm, Local<StringRef> string)199 Local<JSValueRef> JSON::Parse(const EcmaVM *vm, Local<StringRef> string)
200 {
201     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
202     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
203     auto ecmaStr = EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject());
204     JSHandle<JSTaggedValue> result;
205     if (EcmaStringAccessor(ecmaStr).IsUtf8()) {
206         Utf8JsonParser parser(thread, TransformType::NORMAL);
207         JSHandle<EcmaString> str(thread, JSNApiHelper::ToJSTaggedValue(*string));
208         result = parser.Parse(str);
209     } else {
210         Utf16JsonParser parser(thread, TransformType::NORMAL);
211         result = parser.Parse(EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject()));
212     }
213     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
214     return JSNApiHelper::ToLocal<JSValueRef>(result);
215 }
216 
Stringify(const EcmaVM *vm, Local<JSValueRef> json)217 Local<JSValueRef> JSON::Stringify(const EcmaVM *vm, Local<JSValueRef> json)
218 {
219     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
220     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
221     auto constants = thread->GlobalConstants();
222     JsonStringifier stringifier(thread);
223     JSHandle<JSTaggedValue> str = stringifier.Stringify(
224         JSNApiHelper::ToJSHandle(json), constants->GetHandledUndefined(), constants->GetHandledUndefined());
225     RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
226     return JSNApiHelper::ToLocal<JSValueRef>(str);
227 }
228 
GetOriginalSource(const EcmaVM *vm)229 Local<StringRef> RegExpRef::GetOriginalSource(const EcmaVM *vm)
230 {
231     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
232     ecmascript::ThreadManagedScope managedScope(thread);
233     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
234     LOG_IF_SPECIAL(regExp, FATAL);
235     JSTaggedValue source = regExp->GetOriginalSource();
236     if (!source.IsString()) {
237         auto constants = thread->GlobalConstants();
238         return JSNApiHelper::ToLocal<StringRef>(constants->GetHandledEmptyString());
239     }
240     JSHandle<JSTaggedValue> sourceHandle(thread, source);
241     return JSNApiHelper::ToLocal<StringRef>(sourceHandle);
242 }
243 
GetOriginalFlags([[maybe_unused]] const EcmaVM *vm)244 std::string RegExpRef::GetOriginalFlags([[maybe_unused]] const EcmaVM *vm)
245 {
246     DCHECK_SPECIAL_VALUE_WITH_RETURN(this, "");
247     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
248     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
249     JSTaggedValue regExpFlags = regExp->GetOriginalFlags();
250     uint32_t regExpFlagsInt = static_cast<uint32_t>(regExpFlags.GetInt());
251     std::string strFlags = "";
252     if (regExpFlagsInt & RegExpParser::FLAG_GLOBAL) {
253         strFlags += "g";
254     }
255     if (regExpFlagsInt & RegExpParser::FLAG_IGNORECASE) {
256         strFlags += "i";
257     }
258     if (regExpFlagsInt & RegExpParser::FLAG_MULTILINE) {
259         strFlags += "m";
260     }
261     if (regExpFlagsInt & RegExpParser::FLAG_DOTALL) {
262         strFlags += "s";
263     }
264     if (regExpFlagsInt & RegExpParser::FLAG_UTF16) {
265         strFlags += "u";
266     }
267     if (regExpFlagsInt & RegExpParser::FLAG_STICKY) {
268         strFlags += "y";
269     }
270     std::sort(strFlags.begin(), strFlags.end());
271     return strFlags;
272 }
273 
IsGlobal(const EcmaVM *vm)274 Local<JSValueRef> RegExpRef::IsGlobal(const EcmaVM *vm)
275 {
276     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
277     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
278     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
279     LOG_IF_SPECIAL(regExp, FATAL);
280     JSTaggedValue flags = regExp->GetOriginalFlags();
281     bool result = flags.GetInt() & RegExpParser::FLAG_GLOBAL;
282     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
283     return jsValue;
284 }
285 
IsIgnoreCase(const EcmaVM *vm)286 Local<JSValueRef> RegExpRef::IsIgnoreCase(const EcmaVM *vm)
287 {
288     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
289     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
290     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
291     LOG_IF_SPECIAL(regExp, FATAL);
292     JSTaggedValue flags = regExp->GetOriginalFlags();
293     bool result = flags.GetInt() & RegExpParser::FLAG_IGNORECASE;
294     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
295     return jsValue;
296 }
297 
IsMultiline(const EcmaVM *vm)298 Local<JSValueRef> RegExpRef::IsMultiline(const EcmaVM *vm)
299 {
300     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
301     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
302     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
303     LOG_IF_SPECIAL(regExp, FATAL);
304     JSTaggedValue flags = regExp->GetOriginalFlags();
305     bool result = flags.GetInt() & RegExpParser::FLAG_MULTILINE;
306     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
307     return jsValue;
308 }
309 
IsDotAll(const EcmaVM *vm)310 Local<JSValueRef> RegExpRef::IsDotAll(const EcmaVM *vm)
311 {
312     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
313     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
314     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
315     LOG_IF_SPECIAL(regExp, FATAL);
316     JSTaggedValue flags = regExp->GetOriginalFlags();
317     bool result = flags.GetInt() & RegExpParser::FLAG_DOTALL;
318     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
319     return jsValue;
320 }
321 
IsUtf16(const EcmaVM *vm)322 Local<JSValueRef> RegExpRef::IsUtf16(const EcmaVM *vm)
323 {
324     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
325     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
326     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
327     LOG_IF_SPECIAL(regExp, FATAL);
328     JSTaggedValue flags = regExp->GetOriginalFlags();
329     bool result = flags.GetInt() & RegExpParser::FLAG_UTF16;
330     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
331     return jsValue;
332 }
333 
IsStick(const EcmaVM *vm)334 Local<JSValueRef> RegExpRef::IsStick(const EcmaVM *vm)
335 {
336     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
337     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
338     JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
339     LOG_IF_SPECIAL(regExp, FATAL);
340     JSTaggedValue flags = regExp->GetOriginalFlags();
341     bool result = flags.GetInt() & RegExpParser::FLAG_STICKY;
342     Local<JSValueRef> jsValue = BooleanRef::New(vm, result);
343     return jsValue;
344 }
345 
IsGenerator(const EcmaVM *vm)346 bool GeneratorFunctionRef::IsGenerator(const EcmaVM *vm)
347 {
348     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
349     // Omit exception check because ark calls here may not
350     // cause side effect even pending exception exists.
351     return IsGeneratorFunction(vm);
352 }
353 
GetGeneratorState(const EcmaVM *vm)354 Local<JSValueRef> GeneratorObjectRef::GetGeneratorState(const EcmaVM *vm)
355 {
356     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
357     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
358     JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
359     LOG_IF_SPECIAL(jsGenerator, FATAL);
360     if (jsGenerator->GetGeneratorState() == JSGeneratorState::COMPLETED) {
361         return StringRef::NewFromUtf8(vm, "closed");
362     }
363     return StringRef::NewFromUtf8(vm, "suspended");
364 }
365 
GetGeneratorFunction(const EcmaVM *vm)366 Local<JSValueRef> GeneratorObjectRef::GetGeneratorFunction(const EcmaVM *vm)
367 {
368     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
369     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
370     JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
371     LOG_IF_SPECIAL(jsGenerator, FATAL);
372     JSHandle<GeneratorContext> generatorContext(thread, jsGenerator->GetGeneratorContext());
373     JSTaggedValue jsTagValue = generatorContext->GetMethod();
374     return JSNApiHelper::ToLocal<GeneratorFunctionRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
375 }
376 
GetGeneratorReceiver(const EcmaVM *vm)377 Local<JSValueRef> GeneratorObjectRef::GetGeneratorReceiver(const EcmaVM *vm)
378 {
379     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
380     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
381     JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
382     LOG_IF_SPECIAL(jsGenerator, FATAL);
383     JSHandle<GeneratorContext> generatorContext(thread, jsGenerator->GetGeneratorContext());
384     JSTaggedValue jsTagValue = generatorContext->GetAcc();
385     return JSNApiHelper::ToLocal<GeneratorObjectRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
386 }
387 
GetCompareFunction(const EcmaVM *vm)388 Local<JSValueRef> CollatorRef::GetCompareFunction(const EcmaVM *vm)
389 {
390     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
391     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
392 #ifdef ARK_SUPPORT_INTL
393     JSHandle<JSCollator> jsCollator(JSNApiHelper::ToJSHandle(this));
394     LOG_IF_SPECIAL(jsCollator, FATAL);
395     JSTaggedValue jsTagValue = jsCollator->GetBoundCompare();
396     return JSNApiHelper::ToLocal<CollatorRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
397 #else
398     LOG_ECMA(ERROR) << "Not support arkcompiler intl";
399     return JSNApiHelper::ToLocal<CollatorRef>(JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
400 #endif
401 }
402 
GetFormatFunction(const EcmaVM *vm)403 Local<JSValueRef> DataTimeFormatRef::GetFormatFunction(const EcmaVM *vm)
404 {
405     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
406     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
407 #ifdef ARK_SUPPORT_INTL
408     JSHandle<JSDateTimeFormat> jsDateTimeFormat(JSNApiHelper::ToJSHandle(this));
409     LOG_IF_SPECIAL(jsDateTimeFormat, FATAL);
410     JSTaggedValue jsTagValue = jsDateTimeFormat->GetBoundFormat();
411     return JSNApiHelper::ToLocal<DataTimeFormatRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
412 #else
413     LOG_ECMA(ERROR) << "Not support arkcompiler intl";
414     return JSNApiHelper::ToLocal<DataTimeFormatRef>(JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
415 #endif
416 }
417 
GetFormatFunction(const EcmaVM *vm)418 Local<JSValueRef> NumberFormatRef::GetFormatFunction(const EcmaVM *vm)
419 {
420     CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
421     ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
422 #ifdef ARK_SUPPORT_INTL
423     JSHandle<JSNumberFormat> jsNumberFormat(JSNApiHelper::ToJSHandle(this));
424     LOG_IF_SPECIAL(jsNumberFormat, FATAL);
425     JSTaggedValue jsTagValue = jsNumberFormat->GetBoundFormat();
426     return JSNApiHelper::ToLocal<NumberFormatRef>(JSHandle<JSTaggedValue>(thread, jsTagValue));
427 #else
428     LOG_ECMA(ERROR) << "Not support arkcompiler intl";
429     return JSNApiHelper::ToLocal<NumberFormatRef>(JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
430 #endif
431 }
432 
433 // ----------------------------------- FunctionCallback ---------------------------------
RegisterCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)434 JSTaggedValue Callback::RegisterCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRuntimeCallInfo)
435 {
436     // Constructor
437     JSThread *thread = ecmaRuntimeCallInfo->GetThread();
438     ecmascript::ThreadManagedScope managedScope(thread);
439     JSHandle<JSTaggedValue> constructor = BuiltinsBase::GetConstructor(ecmaRuntimeCallInfo);
440     if (!constructor->IsJSFunction()) {
441         return JSTaggedValue::False();
442     }
443     [[maybe_unused]] LocalScope scope(thread->GetEcmaVM());
444     JSHandle<JSFunctionBase> function(constructor);
445     JSTaggedValue extraInfoValue = function->GetFunctionExtraInfo();
446     if (!extraInfoValue.IsJSNativePointer()) {
447         return JSTaggedValue::False();
448     }
449     JSHandle<JSNativePointer> extraInfo(thread, extraInfoValue);
450     // callBack
451     FunctionCallback nativeFunc = reinterpret_cast<FunctionCallback>(extraInfo->GetExternalPointer());
452 
453     JsiRuntimeCallInfo *jsiRuntimeCallInfo = reinterpret_cast<JsiRuntimeCallInfo *>(ecmaRuntimeCallInfo);
454 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
455     bool getStackBeforeCallNapiSuccess = false;
456     if (thread->GetIsProfiling() && function->IsCallNapi()) {
457         getStackBeforeCallNapiSuccess = thread->GetEcmaVM()->GetProfiler()->GetStackBeforeCallNapi(thread);
458     }
459 #endif
460     Local<JSValueRef> result;
461     {
462         ecmascript::ThreadNativeScope nativeScope(thread);
463         result = nativeFunc(jsiRuntimeCallInfo);
464     }
465 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
466     if (thread->GetIsProfiling() && function->IsCallNapi() && getStackBeforeCallNapiSuccess) {
467         thread->GetEcmaVM()->GetProfiler()->GetStackAfterCallNapi(thread);
468     }
469 #endif
470     return JSNApiHelper::ToJSHandle(result).GetTaggedValue();
471 }
472 }  // namespace panda
473