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