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