• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 "ecmascript/builtins/builtins_ark_tools.h"
17 
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include "ecmascript/dfx/vmstat/opt_code_profiler.h"
22 #include "ecmascript/mem/verification.h"
23 #include "ecmascript/module/js_module_source_text.h"
24 #include "ecmascript/property_detector-inl.h"
25 #include "ecmascript/js_arraybuffer.h"
26 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
27 #include "ecmascript/linked_hash_table.h"
28 #include "builtins_typedarray.h"
29 #include "ecmascript/jit/jit.h"
30 
31 #if defined(PANDA_TARGET_ARM64)
32     /* Note: If not open ArkTools option(set by `persist.ark.mem_config_property openArkTools`),  */
33     /*       ArkTools return Empty Implementation                                                 */
34     // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
35     #define RETURN_IF_DISALLOW_ARKTOOLS(thread)                                 \
36         do {                                                                    \
37             if (!((thread)->GetEcmaVM()->GetJSOptions().IsOpenArkTools())) {    \
38                 return JSTaggedValue::Undefined();                              \
39             }                                                                   \
40         } while (0)
41 #else
42     #define RETURN_IF_DISALLOW_ARKTOOLS(thread) static_cast<void>(0) // NOLINT(cppcoreguidelines-macro-usage)
43 #endif
44 
45 namespace panda::ecmascript::builtins {
46 using StringHelper = base::StringHelper;
47 
48 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
49 constexpr char FILEDIR[] = "/data/storage/el2/base/files/";
50 #endif
51 
ObjectDump(EcmaRuntimeCallInfo * info)52 JSTaggedValue BuiltinsArkTools::ObjectDump(EcmaRuntimeCallInfo *info)
53 {
54     ASSERT(info);
55     JSThread *thread = info->GetThread();
56     RETURN_IF_DISALLOW_ARKTOOLS(thread);
57     [[maybe_unused]] EcmaHandleScope handleScope(thread);
58 
59     JSHandle<EcmaString> str = JSTaggedValue::ToString(thread, GetCallArg(info, 0));
60     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
61     // The default log level of ace_engine and js_runtime is error
62     LOG_ECMA(ERROR) << ": " << EcmaStringAccessor(str).ToStdString();
63 
64     uint32_t numArgs = info->GetArgsNumber();
65     for (uint32_t i = 1; i < numArgs; i++) {
66         JSHandle<JSTaggedValue> obj = GetCallArg(info, i);
67         std::ostringstream oss;
68         obj->Dump(oss);
69 
70         // The default log level of ace_engine and js_runtime is error
71         LOG_ECMA(ERROR) << ": " << oss.str();
72     }
73 
74     return JSTaggedValue::Undefined();
75 }
76 
CompareHClass(EcmaRuntimeCallInfo * info)77 JSTaggedValue BuiltinsArkTools::CompareHClass(EcmaRuntimeCallInfo *info)
78 {
79     ASSERT(info);
80     JSThread *thread = info->GetThread();
81     RETURN_IF_DISALLOW_ARKTOOLS(thread);
82     [[maybe_unused]] EcmaHandleScope handleScope(thread);
83 
84     JSHandle<JSTaggedValue> obj1 = GetCallArg(info, 0);
85     JSHandle<JSTaggedValue> obj2 = GetCallArg(info, 1);
86     JSHClass *obj1Hclass = obj1->GetTaggedObject()->GetClass();
87     JSHClass *obj2Hclass = obj2->GetTaggedObject()->GetClass();
88     std::ostringstream oss;
89     obj1Hclass->Dump(oss);
90     obj2Hclass->Dump(oss);
91     bool res = (obj1Hclass == obj2Hclass);
92     if (!res) {
93         LOG_ECMA(ERROR) << "These two object don't share the same hclass:" << oss.str();
94     }
95     return JSTaggedValue(res);
96 }
97 
DumpHClass(EcmaRuntimeCallInfo * info)98 JSTaggedValue BuiltinsArkTools::DumpHClass(EcmaRuntimeCallInfo *info)
99 {
100     ASSERT(info);
101     JSThread *thread = info->GetThread();
102     RETURN_IF_DISALLOW_ARKTOOLS(thread);
103     [[maybe_unused]] EcmaHandleScope handleScope(thread);
104 
105     JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
106     JSHClass *objHclass = obj->GetTaggedObject()->GetClass();
107     std::ostringstream oss;
108     objHclass->Dump(oss);
109 
110     LOG_ECMA(ERROR) << "hclass:" << oss.str();
111     return JSTaggedValue::Undefined();
112 }
113 
IsTSHClass(EcmaRuntimeCallInfo * info)114 JSTaggedValue BuiltinsArkTools::IsTSHClass(EcmaRuntimeCallInfo *info)
115 {
116     ASSERT(info);
117     JSThread *thread = info->GetThread();
118     RETURN_IF_DISALLOW_ARKTOOLS(thread);
119     [[maybe_unused]] EcmaHandleScope handleScope(thread);
120 
121     ASSERT(info->GetArgsNumber() == 1);
122     JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
123     JSHClass *hclass = object->GetTaggedObject()->GetClass();
124     bool isTSHClass = hclass->IsTS();
125     return GetTaggedBoolean(isTSHClass);
126 }
127 
GetHClass(EcmaRuntimeCallInfo * info)128 JSTaggedValue BuiltinsArkTools::GetHClass(EcmaRuntimeCallInfo *info)
129 {
130     ASSERT(info);
131     JSThread *thread = info->GetThread();
132     RETURN_IF_DISALLOW_ARKTOOLS(thread);
133     [[maybe_unused]] EcmaHandleScope handleScope(thread);
134 
135     ASSERT(info->GetArgsNumber() == 1);
136     JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
137     JSHClass *hclass = object->GetTaggedObject()->GetClass();
138     return JSTaggedValue(hclass);
139 }
140 
IsSlicedString(EcmaRuntimeCallInfo * info)141 JSTaggedValue BuiltinsArkTools::IsSlicedString(EcmaRuntimeCallInfo *info)
142 {
143     ASSERT(info);
144     JSThread *thread = info->GetThread();
145     RETURN_IF_DISALLOW_ARKTOOLS(thread);
146     [[maybe_unused]] EcmaHandleScope handleScope(thread);
147 
148     ASSERT(info->GetArgsNumber() == 1);
149     JSHandle<JSTaggedValue> str = GetCallArg(info, 0);
150     return GetTaggedBoolean(str->IsSlicedString());
151 }
152 
IsNotHoleProperty(EcmaRuntimeCallInfo * info)153 JSTaggedValue BuiltinsArkTools::IsNotHoleProperty(EcmaRuntimeCallInfo *info)
154 {
155     [[maybe_unused]] DisallowGarbageCollection noGc;
156     ASSERT(info);
157     JSThread *thread = info->GetThread();
158     RETURN_IF_DISALLOW_ARKTOOLS(thread);
159     [[maybe_unused]] EcmaHandleScope handleScope(thread);
160 
161     ASSERT(info->GetArgsNumber() == 2);  // 2 : object and key
162     JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
163     JSTaggedValue key = GetCallArg(info, 1).GetTaggedValue();
164     JSHClass *hclass = object->GetTaggedObject()->GetClass();
165     int entry = JSHClass::FindPropertyEntry(thread, hclass, key);
166     if (entry == -1) {
167         return GetTaggedBoolean(false);
168     }
169     PropertyAttributes attr = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject())->GetAttr(entry);
170     return GetTaggedBoolean(attr.IsNotHole());
171 }
172 
HiddenStackSourceFile(EcmaRuntimeCallInfo * info)173 JSTaggedValue BuiltinsArkTools::HiddenStackSourceFile(EcmaRuntimeCallInfo *info)
174 {
175     [[maybe_unused]] DisallowGarbageCollection noGc;
176     ASSERT(info);
177     JSThread *thread = info->GetThread();
178     RETURN_IF_DISALLOW_ARKTOOLS(thread);
179     thread->SetEnableStackSourceFile(false);
180     return JSTaggedValue::True();
181 }
182 
ExcutePendingJob(EcmaRuntimeCallInfo * info)183 JSTaggedValue BuiltinsArkTools::ExcutePendingJob(EcmaRuntimeCallInfo *info)
184 {
185     ASSERT(info);
186     JSThread *thread = info->GetThread();
187     RETURN_IF_DISALLOW_ARKTOOLS(thread);
188     [[maybe_unused]] EcmaHandleScope handleScope(thread);
189 
190     thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
191     return JSTaggedValue::True();
192 }
193 
GetLexicalEnv(EcmaRuntimeCallInfo * info)194 JSTaggedValue BuiltinsArkTools::GetLexicalEnv(EcmaRuntimeCallInfo *info)
195 {
196     ASSERT(info);
197     JSThread *thread = info->GetThread();
198     RETURN_IF_DISALLOW_ARKTOOLS(thread);
199     [[maybe_unused]] EcmaHandleScope handleScope(thread);
200 
201     ASSERT(info->GetArgsNumber() == 1);
202     JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
203     if (object->IsHeapObject() && object->IsJSFunction()) {
204         JSHandle<JSFunction> function = JSHandle<JSFunction>::Cast(object);
205         return function->GetLexicalEnv();
206     }
207     return JSTaggedValue::Null();
208 }
209 
ForceFullGC(EcmaRuntimeCallInfo * info)210 JSTaggedValue BuiltinsArkTools::ForceFullGC(EcmaRuntimeCallInfo *info)
211 {
212     ASSERT(info);
213     auto heap = const_cast<Heap *>(info->GetThread()->GetEcmaVM()->GetHeap());
214     heap->CollectGarbage(TriggerGCType::FULL_GC, GCReason::TRIGGER_BY_JS);
215     SharedHeap::GetInstance()->CollectGarbage<TriggerGCType::SHARED_FULL_GC, GCReason::TRIGGER_BY_JS>(
216         info->GetThread());
217     heap->GetHeapPrepare();
218     return JSTaggedValue::True();
219 }
220 
HintGC(EcmaRuntimeCallInfo * info)221 JSTaggedValue BuiltinsArkTools::HintGC(EcmaRuntimeCallInfo *info)
222 {
223     ASSERT(info);
224     return JSTaggedValue(const_cast<Heap *>(info->GetThread()->GetEcmaVM()->GetHeap())->
225         CheckAndTriggerHintGC());
226 }
227 
RemoveAOTFlag(EcmaRuntimeCallInfo * info)228 JSTaggedValue BuiltinsArkTools::RemoveAOTFlag(EcmaRuntimeCallInfo *info)
229 {
230     ASSERT(info);
231     JSThread *thread = info->GetThread();
232     RETURN_IF_DISALLOW_ARKTOOLS(thread);
233     [[maybe_unused]] EcmaHandleScope handleScope(thread);
234 
235     ASSERT(info->GetArgsNumber() == 1);
236     JSHandle<JSTaggedValue> object = GetCallArg(info, 0);
237     if (object->IsHeapObject() && object->IsJSFunction()) {
238         JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(object);
239         JSHandle<Method> method = JSHandle<Method>(thread, func->GetMethod());
240         method->SetAotCodeBit(false);
241     }
242 
243     return JSTaggedValue::Undefined();
244 }
245 
CheckCircularImport(EcmaRuntimeCallInfo * info)246 JSTaggedValue BuiltinsArkTools::CheckCircularImport(EcmaRuntimeCallInfo *info)
247 {
248     ASSERT(info);
249     JSThread *thread = info->GetThread();
250     RETURN_IF_DISALLOW_ARKTOOLS(thread);
251     [[maybe_unused]] EcmaHandleScope handleScope(thread);
252     JSHandle<EcmaString> str = JSTaggedValue::ToString(thread, GetCallArg(info, 0));
253     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
254     bool printOtherCircular = false;
255     if (info->GetArgsNumber() == 2) { // 2: input number
256         printOtherCircular = GetCallArg(info, 1).GetTaggedValue().ToBoolean();
257     }
258     CList<CString> referenceList;
259     // str: bundleName/moduleName/xxx/xxx
260     CString string = ConvertToString(str.GetTaggedValue());
261     LOG_ECMA(INFO) << "checkCircularImport begin with: "<< string;
262     SourceTextModule::CheckCircularImportTool(thread, string, referenceList, printOtherCircular);
263     return JSTaggedValue::Undefined();
264 }
265 
HashCode(EcmaRuntimeCallInfo * info)266 JSTaggedValue BuiltinsArkTools::HashCode(EcmaRuntimeCallInfo *info)
267 {
268     ASSERT(info);
269     JSThread *thread = info->GetThread();
270     RETURN_IF_DISALLOW_ARKTOOLS(thread);
271     [[maybe_unused]] EcmaHandleScope handleScope(thread);
272     JSHandle<JSTaggedValue> key = GetCallArg(info, 0);
273     return JSTaggedValue(LinkedHash::Hash(thread, key.GetTaggedValue()));
274 }
275 
276 #if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
StartCpuProfiler(EcmaRuntimeCallInfo * info)277 JSTaggedValue BuiltinsArkTools::StartCpuProfiler(EcmaRuntimeCallInfo *info)
278 {
279     ASSERT(info);
280     JSThread *thread = info->GetThread();
281     RETURN_IF_DISALLOW_ARKTOOLS(thread);
282     [[maybe_unused]] EcmaHandleScope handleScope(thread);
283 
284     auto vm = thread->GetEcmaVM();
285 
286     // get file name
287     JSHandle<JSTaggedValue> fileNameValue = GetCallArg(info, 0);
288     std::string fileName = "";
289     if (fileNameValue->IsString()) {
290         JSHandle<EcmaString> str = JSTaggedValue::ToString(thread, fileNameValue);
291         RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
292         fileName = EcmaStringAccessor(str).ToStdString() + ".cpuprofile";
293     } else {
294         fileName = GetProfileName();
295     }
296 
297     if (!CreateFile(fileName)) {
298         LOG_ECMA(ERROR) << "CreateFile failed " << fileName;
299     }
300 
301     // get sampling interval
302     JSHandle<JSTaggedValue> samplingIntervalValue = GetCallArg(info, 1);
303     uint32_t interval = 500; // 500:Default Sampling interval 500 microseconds
304     if (samplingIntervalValue->IsNumber()) {
305         interval = JSTaggedValue::ToUint32(thread, samplingIntervalValue);
306     }
307 
308     DFXJSNApi::StartCpuProfilerForFile(vm, fileName, interval);
309     return JSTaggedValue::Undefined();
310 }
311 
StopCpuProfiler(EcmaRuntimeCallInfo * info)312 JSTaggedValue BuiltinsArkTools::StopCpuProfiler(EcmaRuntimeCallInfo *info)
313 {
314     JSThread *thread = info->GetThread();
315     RETURN_IF_DISALLOW_ARKTOOLS(thread);
316     [[maybe_unused]] EcmaHandleScope handleScope(thread);
317     auto vm = thread->GetEcmaVM();
318     DFXJSNApi::StopCpuProfilerForFile(vm);
319 
320     return JSTaggedValue::Undefined();
321 }
322 
GetProfileName()323 std::string BuiltinsArkTools::GetProfileName()
324 {
325     char time1[16] = {0}; // 16:Time format length
326     char time2[16] = {0}; // 16:Time format length
327     time_t timep = std::time(nullptr);
328     struct tm nowTime1;
329     localtime_r(&timep, &nowTime1);
330     size_t result = 0;
331     result = strftime(time1, sizeof(time1), "%Y%m%d", &nowTime1);
332     if (result == 0) {
333         LOG_ECMA(ERROR) << "get time failed";
334         return "";
335     }
336     result = strftime(time2, sizeof(time2), "%H%M%S", &nowTime1);
337     if (result == 0) {
338         LOG_ECMA(ERROR) << "get time failed";
339         return "";
340     }
341     std::string profileName = "cpuprofile-";
342     profileName += time1;
343     profileName += "TO";
344     profileName += time2;
345     profileName += ".cpuprofile";
346     return profileName;
347 }
348 
CreateFile(std::string & fileName)349 bool BuiltinsArkTools::CreateFile(std::string &fileName)
350 {
351     std::string path = FILEDIR + fileName;
352     if (access(path.c_str(), F_OK) == 0) {
353         if (access(path.c_str(), W_OK) == 0) {
354             fileName = path;
355             return true;
356         }
357         LOG_ECMA(ERROR) << "file create failed, W_OK false";
358         return false;
359     }
360     const mode_t defaultMode = S_IRUSR | S_IWUSR | S_IRGRP; // -rw-r--
361     int fd = creat(path.c_str(), defaultMode);
362     if (fd == -1) {
363         fd = creat(fileName.c_str(), defaultMode);
364         if (fd == -1) {
365             LOG_ECMA(ERROR) << "file create failed, errno = "<< errno;
366             return false;
367         }
368         close(fd);
369         return true;
370     } else {
371         fileName = path;
372         close(fd);
373         return true;
374     }
375 }
376 #endif
377 
378 // It is used to check whether an object is a proto, and this function can be
379 // used to check whether the state machine of IC is faulty.
IsPrototype(EcmaRuntimeCallInfo * info)380 JSTaggedValue BuiltinsArkTools::IsPrototype(EcmaRuntimeCallInfo *info)
381 {
382     ASSERT(info);
383     JSThread *thread = info->GetThread();
384     RETURN_IF_DISALLOW_ARKTOOLS(thread);
385     [[maybe_unused]] EcmaHandleScope handleScope(thread);
386 
387     JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
388     JSHClass *objHclass = obj->GetTaggedObject()->GetClass();
389     return JSTaggedValue(objHclass->IsPrototype());
390 }
391 
392 // It is used to check whether a function is aot compiled.
IsAOTCompiled(EcmaRuntimeCallInfo * info)393 JSTaggedValue BuiltinsArkTools::IsAOTCompiled(EcmaRuntimeCallInfo *info)
394 {
395     ASSERT(info);
396     JSThread *thread = info->GetThread();
397     RETURN_IF_DISALLOW_ARKTOOLS(thread);
398     [[maybe_unused]] EcmaHandleScope handleScope(thread);
399 
400     JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
401     JSHandle<JSFunction> func(thread, obj.GetTaggedValue());
402     return JSTaggedValue(func->IsCompiledCode());
403 }
404 
405 // It is used to check whether two functions have same profileTypeInfo
IsSameProfileTypeInfo(EcmaRuntimeCallInfo * info)406 JSTaggedValue BuiltinsArkTools::IsSameProfileTypeInfo(EcmaRuntimeCallInfo *info)
407 {
408     ASSERT(info);
409     JSThread *thread = info->GetThread();
410     RETURN_IF_DISALLOW_ARKTOOLS(thread);
411     [[maybe_unused]] EcmaHandleScope handleScope(thread);
412     JSHandle<JSFunction> func0 = JSHandle<JSFunction>::Cast(GetCallArg(info, 0));
413     JSHandle<JSFunction> func1 = JSHandle<JSFunction>::Cast(GetCallArg(info, 1));
414     return JSTaggedValue(func0->GetProfileTypeInfo() == func1->GetProfileTypeInfo());
415 }
416 
417 // It is used to check whether a function has valid profileTypeInfo
IsProfileTypeInfoValid(EcmaRuntimeCallInfo * info)418 JSTaggedValue BuiltinsArkTools::IsProfileTypeInfoValid(EcmaRuntimeCallInfo *info)
419 {
420     ASSERT(info);
421     JSThread *thread = info->GetThread();
422     RETURN_IF_DISALLOW_ARKTOOLS(thread);
423     [[maybe_unused]] EcmaHandleScope handleScope(thread);
424     JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(GetCallArg(info, 0));
425     return JSTaggedValue(func->GetProfileTypeInfo().IsTaggedArray());
426 }
427 
IsOnHeap(EcmaRuntimeCallInfo * info)428 JSTaggedValue BuiltinsArkTools::IsOnHeap(EcmaRuntimeCallInfo *info)
429 {
430     ASSERT(info);
431     JSThread *thread = info->GetThread();
432     RETURN_IF_DISALLOW_ARKTOOLS(thread);
433     [[maybe_unused]] EcmaHandleScope handleScope(thread);
434 
435     JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
436     return JSTaggedValue(obj.GetTaggedValue().GetTaggedObject()->GetClass()->IsOnHeapFromBitField());
437 }
438 
439 // It is used to check whether a function is aot compiled and deopted at runtime.
IsAOTDeoptimized(EcmaRuntimeCallInfo * info)440 JSTaggedValue BuiltinsArkTools::IsAOTDeoptimized(EcmaRuntimeCallInfo *info)
441 {
442     ASSERT(info);
443     JSThread *thread = info->GetThread();
444     RETURN_IF_DISALLOW_ARKTOOLS(thread);
445     [[maybe_unused]] EcmaHandleScope handleScope(thread);
446 
447     JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
448     JSHandle<JSFunction> func(thread, obj.GetTaggedValue());
449     bool isAotCompiled = func->IsCompiledCode();
450     if (isAotCompiled) {
451         Method *method = func->GetCallTarget();
452         uint32_t deoptedCount = method->GetDeoptThreshold();
453         uint32_t deoptThreshold = thread->GetEcmaVM()->GetJSOptions().GetDeoptThreshold();
454         return JSTaggedValue(deoptedCount != deoptThreshold);
455     }
456 
457     return JSTaggedValue(false);
458 }
459 
CheckDeoptStatus(EcmaRuntimeCallInfo * info)460 JSTaggedValue BuiltinsArkTools::CheckDeoptStatus(EcmaRuntimeCallInfo *info)
461 {
462     ASSERT(info);
463     JSThread *thread = info->GetThread();
464     RETURN_IF_DISALLOW_ARKTOOLS(thread);
465     [[maybe_unused]] EcmaHandleScope handleScope(thread);
466 
467     JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
468     JSHandle<JSFunction> func(thread, obj.GetTaggedValue());
469     Method *method = func->GetCallTarget();
470     bool isAotCompiled = func->IsCompiledCode();
471     uint16_t threshold = method->GetDeoptThreshold();
472     if (threshold > 0) {
473         return JSTaggedValue(isAotCompiled);
474     }
475     // check status before deopt
476     JSHandle<JSTaggedValue> hasDeopt = GetCallArg(info, 1);
477     if (hasDeopt->IsFalse()) {
478         return JSTaggedValue(!isAotCompiled);
479     }
480     if (!hasDeopt->IsTrue()) {
481         return JSTaggedValue(false);
482     }
483     // check status after deopt
484     if (isAotCompiled ||
485         func->IsCompiledFastCall() ||
486         method->GetDeoptType() != kungfu::DeoptType::NONE ||
487         method->GetCodeEntryOrLiteral() == 0) {
488         return JSTaggedValue(false);
489     }
490     return JSTaggedValue(true);
491 }
492 
PrintTypedOpProfiler(EcmaRuntimeCallInfo * info)493 JSTaggedValue BuiltinsArkTools::PrintTypedOpProfiler(EcmaRuntimeCallInfo *info)
494 {
495     ASSERT(info);
496     JSThread *thread = info->GetThread();
497     RETURN_IF_DISALLOW_ARKTOOLS(thread);
498     [[maybe_unused]] EcmaHandleScope handleScope(thread);
499 
500     JSHandle<JSTaggedValue> opStrVal = GetCallArg(info, 0);
501     std::string opStr = EcmaStringAccessor(opStrVal.GetTaggedValue()).ToStdString();
502     TypedOpProfiler *profiler = thread->GetCurrentEcmaContext()->GetTypdOpProfiler();
503     if (profiler != nullptr) {
504         profiler->Print(opStr);
505     }
506     return JSTaggedValue::Undefined();
507 }
508 
ClearTypedOpProfiler(EcmaRuntimeCallInfo * info)509 JSTaggedValue BuiltinsArkTools::ClearTypedOpProfiler(EcmaRuntimeCallInfo *info)
510 {
511     ASSERT(info);
512     JSThread *thread = info->GetThread();
513     RETURN_IF_DISALLOW_ARKTOOLS(thread);
514     [[maybe_unused]] EcmaHandleScope handleScope(thread);
515 
516     TypedOpProfiler *profiler = thread->GetCurrentEcmaContext()->GetTypdOpProfiler();
517     if (profiler != nullptr) {
518         profiler->Clear();
519     }
520     return JSTaggedValue::Undefined();
521 }
522 
GetElementsKind(EcmaRuntimeCallInfo * info)523 JSTaggedValue BuiltinsArkTools::GetElementsKind(EcmaRuntimeCallInfo *info)
524 {
525     ASSERT(info);
526     JSThread *thread = info->GetThread();
527     RETURN_IF_DISALLOW_ARKTOOLS(thread);
528     [[maybe_unused]] EcmaHandleScope handleScope(thread);
529 
530     JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
531     JSHClass *hclass = obj->GetTaggedObject()->GetClass();
532     ElementsKind kind = hclass->GetElementsKind();
533     return JSTaggedValue(static_cast<uint32_t>(kind));
534 }
535 
IsRegExpReplaceDetectorValid(EcmaRuntimeCallInfo * info)536 JSTaggedValue BuiltinsArkTools::IsRegExpReplaceDetectorValid(EcmaRuntimeCallInfo *info)
537 {
538     ASSERT(info);
539     JSThread *thread = info->GetThread();
540     RETURN_IF_DISALLOW_ARKTOOLS(thread);
541     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
542     return JSTaggedValue(PropertyDetector::IsRegExpReplaceDetectorValid(env));
543 }
544 
IsRegExpFlagsDetectorValid(EcmaRuntimeCallInfo * info)545 JSTaggedValue BuiltinsArkTools::IsRegExpFlagsDetectorValid(EcmaRuntimeCallInfo *info)
546 {
547     ASSERT(info);
548     JSThread *thread = info->GetThread();
549     RETURN_IF_DISALLOW_ARKTOOLS(thread);
550     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
551     return JSTaggedValue(PropertyDetector::IsRegExpFlagsDetectorValid(env));
552 }
553 
IsNumberStringNotRegexpLikeDetectorValid(EcmaRuntimeCallInfo * info)554 JSTaggedValue BuiltinsArkTools::IsNumberStringNotRegexpLikeDetectorValid(EcmaRuntimeCallInfo *info)
555 {
556     ASSERT(info);
557     JSThread *thread = info->GetThread();
558     RETURN_IF_DISALLOW_ARKTOOLS(thread);
559     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
560     return JSTaggedValue(PropertyDetector::IsNumberStringNotRegexpLikeDetectorValid(env));
561 }
562 
IsSymbolIteratorDetectorValid(EcmaRuntimeCallInfo * info)563 JSTaggedValue BuiltinsArkTools::IsSymbolIteratorDetectorValid(EcmaRuntimeCallInfo *info)
564 {
565     ASSERT(info);
566     JSThread *thread = info->GetThread();
567     RETURN_IF_DISALLOW_ARKTOOLS(thread);
568     [[maybe_unused]] EcmaHandleScope handleScope(thread);
569 
570     JSHandle<JSTaggedValue> kind = GetCallArg(info, 0);
571     if (!kind->IsString()) {
572         return JSTaggedValue::Undefined();
573     }
574     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
575     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
576     JSHandle<EcmaString> mapString = factory->NewFromUtf8ReadOnly("Map");
577     if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(mapString))) {
578         return JSTaggedValue(PropertyDetector::IsMapIteratorDetectorValid(env));
579     }
580     JSHandle<EcmaString> setString = factory->NewFromUtf8ReadOnly("Set");
581     if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(setString))) {
582         return JSTaggedValue(PropertyDetector::IsSetIteratorDetectorValid(env));
583     }
584     JSHandle<EcmaString> stringString = factory->NewFromUtf8ReadOnly("String");
585     if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(stringString))) {
586         return JSTaggedValue(PropertyDetector::IsStringIteratorDetectorValid(env));
587     }
588     JSHandle<EcmaString> arrayString = factory->NewFromUtf8ReadOnly("Array");
589     if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(arrayString))) {
590         return JSTaggedValue(PropertyDetector::IsArrayIteratorDetectorValid(env));
591     }
592     JSHandle<EcmaString> typedarrayString = factory->NewFromUtf8ReadOnly("TypedArray");
593     if (JSTaggedValue::Equal(thread, kind, JSHandle<JSTaggedValue>(typedarrayString))) {
594         return JSTaggedValue(PropertyDetector::IsTypedArrayIteratorDetectorValid(env));
595     }
596     return JSTaggedValue::Undefined();
597 }
598 
TimeInUs(EcmaRuntimeCallInfo * info)599 JSTaggedValue BuiltinsArkTools::TimeInUs([[maybe_unused]] EcmaRuntimeCallInfo *info)
600 {
601     [[maybe_unused]] JSThread *thread = info->GetThread();
602     RETURN_IF_DISALLOW_ARKTOOLS(thread);
603     ClockScope scope;
604     return JSTaggedValue(scope.GetCurTime());
605 }
606 
607 #if ECMASCRIPT_ENABLE_SCOPE_LOCK_STAT
StartScopeLockStats(EcmaRuntimeCallInfo * info)608 JSTaggedValue BuiltinsArkTools::StartScopeLockStats(EcmaRuntimeCallInfo *info)
609 {
610     JSThread *thread = info->GetThread();
611     RETURN_IF_DISALLOW_ARKTOOLS(thread);
612     auto vm = thread->GetEcmaVM();
613     vm->StartCollectingScopeLockStats();
614     LOG_FULL(INFO) << "Start Collecting ArkCompiler Scope-Lock Stats";
615     return JSTaggedValue::Undefined();
616 }
617 
StopScopeLockStats(EcmaRuntimeCallInfo * info)618 JSTaggedValue BuiltinsArkTools::StopScopeLockStats(EcmaRuntimeCallInfo *info)
619 {
620     JSThread *thread = info->GetThread();
621     RETURN_IF_DISALLOW_ARKTOOLS(thread);
622     auto vm = thread->GetEcmaVM();
623     LOG_FULL(INFO) << "Stop Collecting ArkCompiler Scope-Lock Stats: "
624                    << " ThreadStateTransition count: " << vm->GetUpdateThreadStateTransCount()
625                    << " , Entered Scope But NO State Transition count: " << (vm->GetEnterJsiNativeScopeCount() +
626                                                                      vm->GetEnterFastNativeScopeCount() +
627                                                                      vm->GetEnterThreadManagedScopeCount() -
628                                                                      vm->GetUpdateThreadStateTransCount())
629                    << " , String-Table Lock count: " << vm->GetStringTableLockCount();
630     vm->ResetScopeLockStats();
631     vm->StopCollectingScopeLockStats();
632     return JSTaggedValue::Undefined();
633 }
634 #endif
635 
UnimplementedBuiltin(char const * name,EcmaRuntimeCallInfo * info)636 static JSTaggedValue UnimplementedBuiltin(char const *name, [[maybe_unused]] EcmaRuntimeCallInfo *info)
637 {
638     ASSERT(info);
639     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
640     LOG_ECMA(DEBUG) << "Enter unimplemented ArkTools." << name;
641     return JSTaggedValue::Undefined();
642 }
643 
BuiltinFail(JSThread * thread,char const * msg)644 static JSTaggedValue BuiltinFail(JSThread *thread, char const *msg)
645 {
646     [[maybe_unused]] EcmaHandleScope handleScope(thread);
647     THROW_NEW_ERROR_WITH_MSG_AND_RETURN_VALUE(thread, ErrorType::ERROR, msg, JSTaggedValue::Exception());
648 }
649 
NotSupportedBuiltin(char const * name,EcmaRuntimeCallInfo * info)650 static JSTaggedValue NotSupportedBuiltin(char const *name, [[maybe_unused]] EcmaRuntimeCallInfo *info)
651 {
652     ASSERT(info);
653     JSThread *thread = info->GetThread();
654     RETURN_IF_DISALLOW_ARKTOOLS(thread);
655     std::string msg = std::string(name) + " is not supported";
656     return BuiltinFail(thread, msg.c_str());
657 }
658 
659 // empty function for regress-xxx test cases
PrepareFunctionForOptimization(EcmaRuntimeCallInfo * info)660 JSTaggedValue BuiltinsArkTools::PrepareFunctionForOptimization([[maybe_unused]] EcmaRuntimeCallInfo *info)
661 {
662     return UnimplementedBuiltin(__func__, info);
663 }
664 
665 // empty function for regress-xxx test cases
OptimizeFunctionOnNextCall(EcmaRuntimeCallInfo * info)666 JSTaggedValue BuiltinsArkTools::OptimizeFunctionOnNextCall([[maybe_unused]] EcmaRuntimeCallInfo *info)
667 {
668     return UnimplementedBuiltin(__func__, info);
669 }
670 
671 // empty function for regress-xxx test cases
OptimizeMaglevOnNextCall(EcmaRuntimeCallInfo * info)672 JSTaggedValue BuiltinsArkTools::OptimizeMaglevOnNextCall([[maybe_unused]] EcmaRuntimeCallInfo *info)
673 {
674     return UnimplementedBuiltin(__func__, info);
675 }
676 
677 // empty function for regress-xxx test cases
DeoptimizeFunction(EcmaRuntimeCallInfo * info)678 JSTaggedValue BuiltinsArkTools::DeoptimizeFunction([[maybe_unused]] EcmaRuntimeCallInfo *info)
679 {
680     return UnimplementedBuiltin(__func__, info);
681 }
682 
683 // empty function for regress-xxx test cases
OptimizeOsr(EcmaRuntimeCallInfo * info)684 JSTaggedValue BuiltinsArkTools::OptimizeOsr([[maybe_unused]] EcmaRuntimeCallInfo *info)
685 {
686     return UnimplementedBuiltin(__func__, info);
687 }
688 
689 // empty function for regress-xxx test cases
NeverOptimizeFunction(EcmaRuntimeCallInfo * info)690 JSTaggedValue BuiltinsArkTools::NeverOptimizeFunction([[maybe_unused]] EcmaRuntimeCallInfo *info)
691 {
692     return UnimplementedBuiltin(__func__, info);
693 }
694 
HeapObjectVerify(EcmaRuntimeCallInfo * info)695 JSTaggedValue BuiltinsArkTools::HeapObjectVerify([[maybe_unused]] EcmaRuntimeCallInfo *info)
696 {
697     JSThread *thread = info->GetThread();
698     RETURN_IF_DISALLOW_ARKTOOLS(thread);
699     CHECK(info && info->GetArgsNumber() == 1);
700     JSHandle<JSTaggedValue> arg = GetCallArg(info, 0);
701 
702     if (arg->IsHeapObject()) {
703         JSHandle<TaggedObject> obj(arg);
704         CHECK(obj->GetClass()->GetClass()->IsHClass());
705 
706         size_t failCount = 0;
707         VerifyObjectVisitor heapVerifier(thread->GetEcmaVM()->GetHeap(), &failCount);
708         heapVerifier(*obj);
709         CHECK(failCount == 0);
710     }
711     return JSTaggedValue::True();
712 }
713 
714 // empty function for regress-xxx test cases
DisableOptimizationFinalization(EcmaRuntimeCallInfo * info)715 JSTaggedValue BuiltinsArkTools::DisableOptimizationFinalization([[maybe_unused]] EcmaRuntimeCallInfo *info)
716 {
717     return UnimplementedBuiltin(__func__, info);
718 }
719 
720 // empty function for regress-xxx test cases
DeoptimizeNow(EcmaRuntimeCallInfo * info)721 JSTaggedValue BuiltinsArkTools::DeoptimizeNow([[maybe_unused]] EcmaRuntimeCallInfo *info)
722 {
723     return UnimplementedBuiltin(__func__, info);
724 }
725 
726 // empty function for regress-xxx test cases
WaitForBackgroundOptimization(EcmaRuntimeCallInfo * info)727 JSTaggedValue BuiltinsArkTools::WaitForBackgroundOptimization([[maybe_unused]] EcmaRuntimeCallInfo *info)
728 {
729     return UnimplementedBuiltin(__func__, info);
730 }
731 
Gc(EcmaRuntimeCallInfo * info)732 JSTaggedValue BuiltinsArkTools::Gc([[maybe_unused]] EcmaRuntimeCallInfo *info)
733 {
734     JSThread *thread = info->GetThread();
735     RETURN_IF_DISALLOW_ARKTOOLS(thread);
736     TriggerGCType gctype = TriggerGCType::FULL_GC;
737 
738     if (info->GetArgsNumber() != 0) {
739         JSHandle<JSTaggedValue> arg = GetCallArg(info, 0);
740         if (arg->IsECMAObject()) {
741             return BuiltinFail(thread, "ArkTools.gc object parameter is not supported");
742         }
743         gctype = TriggerGCType::YOUNG_GC;
744     }
745     thread->GetEcmaVM()->CollectGarbage(gctype, GCReason::EXTERNAL_TRIGGER);
746     return JSTaggedValue::Undefined();
747 }
748 
749 // empty function for pgoAssertType
PGOAssertType(EcmaRuntimeCallInfo * info)750 JSTaggedValue BuiltinsArkTools::PGOAssertType([[maybe_unused]] EcmaRuntimeCallInfo *info)
751 {
752     LOG_ECMA(DEBUG) << "Enter PGOAssertType";
753     [[maybe_unused]] JSThread *thread = info->GetThread();
754     RETURN_IF_DISALLOW_ARKTOOLS(thread);
755     return JSTaggedValue::Undefined();
756 }
757 
ToLength(EcmaRuntimeCallInfo * info)758 JSTaggedValue BuiltinsArkTools::ToLength([[maybe_unused]] EcmaRuntimeCallInfo *info)
759 {
760     ASSERT(info);
761     JSThread *thread = info->GetThread();
762     RETURN_IF_DISALLOW_ARKTOOLS(thread);
763     [[maybe_unused]] EcmaHandleScope handleScope(thread);
764     JSHandle<JSTaggedValue> key = GetCallArg(info, 0);
765     return JSTaggedValue::ToLength(thread, key);
766 }
767 
768 template <typename Pred>
TestElementsKind(EcmaRuntimeCallInfo * info,Pred const & pred)769 static JSTaggedValue TestElementsKind([[maybe_unused]] EcmaRuntimeCallInfo *info, Pred const &pred)
770 {
771     JSThread *thread = info->GetThread();
772     RETURN_IF_DISALLOW_ARKTOOLS(thread);
773     CHECK(info && info->GetArgsNumber() == 1);
774     JSHandle<JSTaggedValue> arg = base::BuiltinsBase::GetCallArg(info, 0);
775     CHECK(thread->GetEcmaVM()->IsEnableElementsKind());
776     CHECK(arg->IsJSObject());
777     ElementsKind kind = JSHandle<JSObject>::Cast(arg)->GetClass()->GetElementsKind();
778     return JSTaggedValue(pred(kind));
779 }
780 
HasDictionaryElements(EcmaRuntimeCallInfo * info)781 JSTaggedValue BuiltinsArkTools::HasDictionaryElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
782 {
783     JSThread *thread = info->GetThread();
784     RETURN_IF_DISALLOW_ARKTOOLS(thread);
785     CHECK(info && info->GetArgsNumber() == 1);
786     JSHandle<JSTaggedValue> arg = base::BuiltinsBase::GetCallArg(info, 0);
787     CHECK(thread->GetEcmaVM()->IsEnableElementsKind());
788     CHECK(arg->IsJSObject());
789     JSHandle<JSObject> obj(arg);
790     bool isDict = obj->GetClass()->IsDictionaryElement();
791     CHECK(isDict == ElementAccessor::IsDictionaryMode(obj));
792     CHECK(isDict == (obj->GetClass()->GetElementsKind() == ElementsKind::DICTIONARY));
793     return JSTaggedValue(isDict);
794 }
795 
HasHoleyElements(EcmaRuntimeCallInfo * info)796 JSTaggedValue BuiltinsArkTools::HasHoleyElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
797 {
798     return TestElementsKind(info, [](ElementsKind kind) {
799         return (helpers::ToUnderlying(kind) & helpers::ToUnderlying(ElementsKind::HOLE)) != 0;
800     });
801 }
802 
HasSmiElements(EcmaRuntimeCallInfo * info)803 JSTaggedValue BuiltinsArkTools::HasSmiElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
804 {
805     return TestElementsKind(info, [](ElementsKind kind) {
806         return kind == ElementsKind::INT || kind == ElementsKind::HOLE_INT;
807     });
808 }
809 
HasDoubleElements(EcmaRuntimeCallInfo * info)810 JSTaggedValue BuiltinsArkTools::HasDoubleElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
811 {
812     return TestElementsKind(info, [](ElementsKind kind) {
813         return kind == ElementsKind::NUMBER || kind == ElementsKind::HOLE_NUMBER;
814     });
815 }
816 
HasObjectElements(EcmaRuntimeCallInfo * info)817 JSTaggedValue BuiltinsArkTools::HasObjectElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
818 {
819     return TestElementsKind(info, [](ElementsKind kind) {
820         ElementsKind noHole = static_cast<ElementsKind>(helpers::ToUnderlying(kind)
821             & ~helpers::ToUnderlying(ElementsKind::HOLE));
822         return noHole == ElementsKind::STRING || noHole == ElementsKind::OBJECT || noHole == ElementsKind::TAGGED;
823     });
824 }
825 
ArrayBufferDetach(EcmaRuntimeCallInfo * info)826 JSTaggedValue BuiltinsArkTools::ArrayBufferDetach([[maybe_unused]] EcmaRuntimeCallInfo *info)
827 {
828     JSThread *thread = info->GetThread();
829     RETURN_IF_DISALLOW_ARKTOOLS(thread);
830     CHECK(info && info->GetArgsNumber() == 1);
831     [[maybe_unused]] EcmaHandleScope handleScope(thread);
832     JSHandle<JSTaggedValue> obj1 = GetCallArg(info, 0);
833     JSHandle<JSArrayBuffer> arrBuf = JSHandle<JSArrayBuffer>::Cast(obj1);
834     arrBuf->Detach(thread);
835     return JSTaggedValue::Undefined();
836 }
837 
HaveSameMap(EcmaRuntimeCallInfo * info)838 JSTaggedValue BuiltinsArkTools::HaveSameMap([[maybe_unused]] EcmaRuntimeCallInfo *info)
839 {
840     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
841     CHECK(info && info->GetArgsNumber() == 2);  // 2 args
842     JSHandle<JSTaggedValue> obj1 = GetCallArg(info, 0);
843     JSHandle<JSTaggedValue> obj2 = GetCallArg(info, 1);
844     CHECK(obj1->IsHeapObject() && obj2->IsHeapObject());
845     return JSTaggedValue(obj1->GetTaggedObject()->GetClass() == obj2->GetTaggedObject()->GetClass());
846 }
847 
IsSameHeapObject(EcmaRuntimeCallInfo * info)848 JSTaggedValue BuiltinsArkTools::IsSameHeapObject([[maybe_unused]] EcmaRuntimeCallInfo *info)
849 {
850     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
851     CHECK(info && info->GetArgsNumber() == 2);  // 2 args
852     JSHandle<JSTaggedValue> obj1 = GetCallArg(info, 0);
853     JSHandle<JSTaggedValue> obj2 = GetCallArg(info, 1);
854     if (obj1->IsDouble() && obj2->IsDouble()) {
855         return JSTaggedValue(false); // mocked result
856     }
857     CHECK(obj1->IsHeapObject() && obj2->IsHeapObject());
858     return JSTaggedValue(obj1->GetTaggedObject() == obj2->GetTaggedObject());
859 }
860 
861 // mock builtin
IsSmi(EcmaRuntimeCallInfo * info)862 JSTaggedValue BuiltinsArkTools::IsSmi([[maybe_unused]] EcmaRuntimeCallInfo *info)
863 {
864     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
865     CHECK(info && info->GetArgsNumber() == 1);
866     return JSTaggedValue(info->GetCallArg(0)->IsInt());
867 }
868 
CreatePrivateSymbol(EcmaRuntimeCallInfo * info)869 JSTaggedValue BuiltinsArkTools::CreatePrivateSymbol([[maybe_unused]] EcmaRuntimeCallInfo *info)
870 {
871     JSThread *thread = info->GetThread();
872     RETURN_IF_DISALLOW_ARKTOOLS(thread);
873     CHECK(info && info->GetArgsNumber() == 1);
874     [[maybe_unused]] EcmaHandleScope handleScope(thread);
875     JSHandle<JSTaggedValue> symbolName = GetCallArg(info, 0);
876     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
877     JSHandle<JSSymbol> privateNameSymbol = factory->NewPrivateNameSymbol(symbolName);
878     JSHandle<JSTaggedValue> symbolValue = JSHandle<JSTaggedValue>::Cast(privateNameSymbol);
879     return symbolValue.GetTaggedValue();
880 }
881 
IsArray(EcmaRuntimeCallInfo * info)882 JSTaggedValue BuiltinsArkTools::IsArray([[maybe_unused]] EcmaRuntimeCallInfo *info)
883 {
884     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
885     CHECK(info && info->GetArgsNumber() == 1);
886     return JSTaggedValue(info->GetCallArg(0)->IsJSArray());
887 }
888 
CreateDataProperty(EcmaRuntimeCallInfo * info)889 JSTaggedValue BuiltinsArkTools::CreateDataProperty([[maybe_unused]] EcmaRuntimeCallInfo *info)
890 {
891     JSThread *thread = info->GetThread();
892     RETURN_IF_DISALLOW_ARKTOOLS(thread);
893     CHECK(info && info->GetArgsNumber() == 3);  // 3 args
894     [[maybe_unused]] EcmaHandleScope handleScope(thread);
895     CHECK(GetCallArg(info, 0)->IsJSObject());
896     JSHandle<JSObject> obj(GetCallArg(info, 0));          // 0: object
897     JSHandle<JSTaggedValue> key = GetCallArg(info, 1);    // 1: property key
898     JSHandle<JSTaggedValue> value = GetCallArg(info, 2);  // 2: property value
899     JSObject::CreateDataPropertyOrThrow(thread, obj, key, value);
900     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
901     return value.GetTaggedValue();
902 }
903 
FunctionGetInferredName(EcmaRuntimeCallInfo * info)904 JSTaggedValue BuiltinsArkTools::FunctionGetInferredName([[maybe_unused]] EcmaRuntimeCallInfo *info)
905 {
906     JSThread *thread = info->GetThread();
907     RETURN_IF_DISALLOW_ARKTOOLS(thread);
908     CHECK(info && info->GetArgsNumber() == 1);
909     [[maybe_unused]] EcmaHandleScope handleScope(thread);
910     JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
911     if (obj->IsJSFunction()) {
912         JSHandle<JSFunction> funcObj = JSHandle<JSFunction>::Cast(obj);
913         std::string name = Method::ConstCast(funcObj->GetMethod().GetTaggedObject())->ParseFunctionName();
914         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
915         return factory->NewFromStdString(name).GetTaggedValue();
916     }
917     return thread->GlobalConstants()->GetHandledEmptyString().GetTaggedValue();
918 }
919 
StringLessThan(EcmaRuntimeCallInfo * info)920 JSTaggedValue BuiltinsArkTools::StringLessThan([[maybe_unused]] EcmaRuntimeCallInfo *info)
921 {
922     JSThread *thread = info->GetThread();
923     RETURN_IF_DISALLOW_ARKTOOLS(thread);
924     CHECK(info && info->GetArgsNumber() == 2);  // 2 args
925     [[maybe_unused]] EcmaHandleScope handleScope(thread);
926     JSHandle<JSTaggedValue> x = GetCallArg(info, 0);
927     JSHandle<JSTaggedValue> y = GetCallArg(info, 1);
928     ComparisonResult result = JSTaggedValue::Compare(thread, x, y);
929     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
930     return JSTaggedValue(ComparisonResult::LESS == result);
931 }
932 
StringMaxLength(EcmaRuntimeCallInfo * info)933 JSTaggedValue BuiltinsArkTools::StringMaxLength([[maybe_unused]] EcmaRuntimeCallInfo *info)
934 {
935     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
936     CHECK(info && info->GetArgsNumber() == 0);
937     return JSTaggedValue(static_cast<uint32_t>(EcmaString::MAX_STRING_LENGTH) - 1);
938 }
939 
ArrayBufferMaxByteLength(EcmaRuntimeCallInfo * info)940 JSTaggedValue BuiltinsArkTools::ArrayBufferMaxByteLength([[maybe_unused]] EcmaRuntimeCallInfo *info)
941 {
942     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
943     CHECK(info && info->GetArgsNumber() == 0);
944     return JSTaggedValue(INT_MAX);
945 }
946 
TypedArrayMaxLength(EcmaRuntimeCallInfo * info)947 JSTaggedValue BuiltinsArkTools::TypedArrayMaxLength([[maybe_unused]] EcmaRuntimeCallInfo *info)
948 {
949     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
950     CHECK(info && info->GetArgsNumber() == 0);
951     return JSTaggedValue(BuiltinsTypedArray::MAX_ARRAY_INDEX);
952 }
953 
MaxSmi(EcmaRuntimeCallInfo * info)954 JSTaggedValue BuiltinsArkTools::MaxSmi([[maybe_unused]] EcmaRuntimeCallInfo *info)
955 {
956     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
957     CHECK(info && info->GetArgsNumber() == 0);
958     return JSTaggedValue(INT32_MAX);
959 }
960 
Is64Bit(EcmaRuntimeCallInfo * info)961 JSTaggedValue BuiltinsArkTools::Is64Bit([[maybe_unused]] EcmaRuntimeCallInfo *info)
962 {
963     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
964     CHECK(info && info->GetArgsNumber() == 0);
965     return JSTaggedValue(sizeof(void*) == 8);  // 8 is 64bit pointer size
966 }
967 
968 // empty function for regress-xxx test cases
FinalizeOptimization(EcmaRuntimeCallInfo * info)969 JSTaggedValue BuiltinsArkTools::FinalizeOptimization([[maybe_unused]] EcmaRuntimeCallInfo *info)
970 {
971     return UnimplementedBuiltin(__func__, info);
972 }
973 
EnsureFeedbackVectorForFunction(EcmaRuntimeCallInfo * info)974 JSTaggedValue BuiltinsArkTools::EnsureFeedbackVectorForFunction([[maybe_unused]] EcmaRuntimeCallInfo *info)
975 {
976     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
977     CHECK(info && info->GetArgsNumber() == 1);
978     CHECK(info->GetCallArg(0)->IsJSFunction());
979     JSHandle<JSFunction> func(info->GetCallArg(0));
980     auto prof = func->GetProfileTypeInfo();
981     CHECK(prof.IsUndefined() || prof.GetHeapObject()->GetClass()->IsTaggedArray());
982     return JSTaggedValue(!prof.IsUndefined());
983 }
984 
985 // empty function for regress-xxx test cases
CompileBaseline(EcmaRuntimeCallInfo * info)986 JSTaggedValue BuiltinsArkTools::CompileBaseline([[maybe_unused]] EcmaRuntimeCallInfo *info)
987 {
988     return UnimplementedBuiltin(__func__, info);
989 }
990 
DebugGetLoadedScriptIds(EcmaRuntimeCallInfo * info)991 JSTaggedValue BuiltinsArkTools::DebugGetLoadedScriptIds([[maybe_unused]] EcmaRuntimeCallInfo *info)
992 {
993     return UnimplementedBuiltin(__func__, info);
994 }
995 
ToFastProperties(EcmaRuntimeCallInfo * info)996 JSTaggedValue BuiltinsArkTools::ToFastProperties([[maybe_unused]] EcmaRuntimeCallInfo *info)
997 {
998     JSThread *thread = info->GetThread();
999     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1000     CHECK(info && info->GetArgsNumber() == 1);
1001     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1002     JSHandle<JSTaggedValue> arg = info->GetCallArg(0);
1003 
1004     if (arg->IsJSObject() && !arg->IsJSGlobalObject()) {
1005         JSHandle<JSObject> obj(arg);
1006         // NOTE: extracted from JSHClass::OptimizeAsFastElements
1007         if (obj->GetJSHClass()->IsDictionaryMode()) {
1008             JSObject::OptimizeAsFastProperties(thread, obj);
1009         } else {
1010             JSHClass::OptimizeAsFastProperties(thread, obj);
1011         }
1012     }
1013     return arg.GetTaggedValue();
1014 }
1015 
AbortJS(EcmaRuntimeCallInfo * info)1016 JSTaggedValue BuiltinsArkTools::AbortJS([[maybe_unused]] EcmaRuntimeCallInfo *info)
1017 {
1018     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1019     CHECK(info && info->GetArgsNumber() == 1);
1020     CHECK(info->GetCallArg(0)->IsString());
1021     JSHandle<EcmaString> msg(info->GetCallArg(0));
1022     std::cerr << "AbortJS: " << EcmaStringAccessor(msg).ToCString(StringConvertedUsage::PRINT) << std::endl;
1023     panda::PrintStack(std::cerr);
1024     std::abort();
1025 }
1026 
InternalizeString(EcmaRuntimeCallInfo * info)1027 JSTaggedValue BuiltinsArkTools::InternalizeString([[maybe_unused]] EcmaRuntimeCallInfo *info)
1028 {
1029     JSThread *thread = info->GetThread();
1030     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1031     CHECK(info && info->GetArgsNumber() == 1);
1032     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1033     CHECK(info->GetCallArg(0)->IsString());
1034     return JSTaggedValue(thread->GetEcmaVM()->GetFactory()->InternString(info->GetCallArg(0)));
1035 }
1036 
1037 // empty function for regress-xxx test cases
HandleDebuggerStatement(EcmaRuntimeCallInfo * info)1038 JSTaggedValue BuiltinsArkTools::HandleDebuggerStatement([[maybe_unused]] EcmaRuntimeCallInfo *info)
1039 {
1040     return UnimplementedBuiltin(__func__, info);
1041 }
1042 
1043 // empty function for regress-xxx test cases
SetAllocationTimeout(EcmaRuntimeCallInfo * info)1044 JSTaggedValue BuiltinsArkTools::SetAllocationTimeout([[maybe_unused]] EcmaRuntimeCallInfo *info)
1045 {
1046     return UnimplementedBuiltin(__func__, info);
1047 }
1048 
HasFastProperties(EcmaRuntimeCallInfo * info)1049 JSTaggedValue BuiltinsArkTools::HasFastProperties([[maybe_unused]] EcmaRuntimeCallInfo *info)
1050 {
1051     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1052     CHECK(info && info->GetArgsNumber() == 1);
1053     CHECK(info->GetCallArg(0)->IsJSObject());
1054     JSHandle<JSObject> obj(info->GetCallArg(0));
1055     return JSTaggedValue(!obj->GetClass()->IsDictionaryMode());
1056 }
1057 
HasOwnConstDataProperty(EcmaRuntimeCallInfo * info)1058 JSTaggedValue BuiltinsArkTools::HasOwnConstDataProperty([[maybe_unused]] EcmaRuntimeCallInfo *info)
1059 {
1060     JSThread *thread = info->GetThread();
1061     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1062     CHECK(info && info->GetArgsNumber() == 2);  // 2 args
1063     JSHandle<JSTaggedValue> rec = info->GetCallArg(0);
1064     JSHandle<JSTaggedValue> prop = info->GetCallArg(1);
1065 
1066     if (!(prop->IsNumber() || prop->IsString() || prop->IsSymbol())) {
1067         return JSTaggedValue::Undefined();
1068     }
1069     if (!rec->IsJSObject()) {
1070         return JSTaggedValue::Undefined();
1071     }
1072 
1073     JSHandle<JSObject> obj(rec);
1074     ObjectOperator op(thread, rec, rec, prop, OperatorType::OWN);
1075     if (!op.IsFound()) {
1076         return JSTaggedValue::False();
1077     }
1078     if (!op.IsAccessorDescriptor()) {
1079         return JSTaggedValue(op.GetAttr().IsConstProps());
1080     }
1081     return JSTaggedValue::Undefined();
1082 }
1083 
GetHoleNaNUpper(EcmaRuntimeCallInfo * info)1084 JSTaggedValue BuiltinsArkTools::GetHoleNaNUpper([[maybe_unused]] EcmaRuntimeCallInfo *info)
1085 {
1086     return NotSupportedBuiltin(__func__, info);
1087 }
1088 
GetHoleNaNLower(EcmaRuntimeCallInfo * info)1089 JSTaggedValue BuiltinsArkTools::GetHoleNaNLower([[maybe_unused]] EcmaRuntimeCallInfo *info)
1090 {
1091     return NotSupportedBuiltin(__func__, info);
1092 }
1093 
1094 // empty function for regress-xxx test cases
SystemBreak(EcmaRuntimeCallInfo * info)1095 JSTaggedValue BuiltinsArkTools::SystemBreak([[maybe_unused]] EcmaRuntimeCallInfo *info)
1096 {
1097     return UnimplementedBuiltin(__func__, info);
1098 }
1099 
1100 // empty function for regress-xxx test cases
ScheduleBreak(EcmaRuntimeCallInfo * info)1101 JSTaggedValue BuiltinsArkTools::ScheduleBreak([[maybe_unused]] EcmaRuntimeCallInfo *info)
1102 {
1103     return UnimplementedBuiltin(__func__, info);
1104 }
1105 
EnqueueMicrotask(EcmaRuntimeCallInfo * info)1106 JSTaggedValue BuiltinsArkTools::EnqueueMicrotask([[maybe_unused]] EcmaRuntimeCallInfo *info)
1107 {
1108     JSThread *thread = info->GetThread();
1109     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1110     CHECK(info && info->GetArgsNumber() == 1);
1111     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1112     CHECK(info->GetCallArg(0)->IsJSFunction());
1113     JSHandle<JSFunction> func(info->GetCallArg(0));
1114 
1115     JSHandle<job::MicroJobQueue> queue = thread->GetCurrentEcmaContext()->GetMicroJobQueue();
1116     JSHandle<TaggedArray> argv(thread->GlobalConstants()->GetHandledEmptyArray());
1117 
1118     job::MicroJobQueue::EnqueueJob(thread, queue, job::QueueType::QUEUE_PROMISE, func, argv);
1119     return JSTaggedValue::Undefined();
1120 }
1121 
DebugPrint(EcmaRuntimeCallInfo * info)1122 JSTaggedValue BuiltinsArkTools::DebugPrint([[maybe_unused]] EcmaRuntimeCallInfo *info)
1123 {
1124     return UnimplementedBuiltin(__func__, info);
1125 }
1126 
1127 // empty function for regress-xxx test cases
GetOptimizationStatus(EcmaRuntimeCallInfo * info)1128 JSTaggedValue BuiltinsArkTools::GetOptimizationStatus([[maybe_unused]] EcmaRuntimeCallInfo *info)
1129 {
1130     return UnimplementedBuiltin(__func__, info);
1131 }
1132 
GetUndetectable(EcmaRuntimeCallInfo * info)1133 JSTaggedValue BuiltinsArkTools::GetUndetectable([[maybe_unused]] EcmaRuntimeCallInfo *info)
1134 {
1135     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1136     ASSERT(info && info->GetArgsNumber() == 0);
1137     return JSTaggedValue::Undefined(); // undetectable is just undefined
1138 }
1139 
SetKeyedProperty(EcmaRuntimeCallInfo * info)1140 JSTaggedValue BuiltinsArkTools::SetKeyedProperty([[maybe_unused]] EcmaRuntimeCallInfo *info)
1141 {
1142     JSThread *thread = info->GetThread();
1143     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1144     CHECK(info && info->GetArgsNumber() == 3);  // 3 args
1145     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1146     JSHandle<JSTaggedValue> obj = info->GetCallArg(0);  // 0: object
1147     JSHandle<JSTaggedValue> key = info->GetCallArg(1);  // 1: property key
1148     JSHandle<JSTaggedValue> val = info->GetCallArg(2);  // 2: property value
1149 
1150     JSTaggedValue::SetProperty(thread, obj, key, val, true);
1151     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1152     return JSTaggedValue::Undefined();
1153 }
1154 
DisassembleFunction(EcmaRuntimeCallInfo * info)1155 JSTaggedValue BuiltinsArkTools::DisassembleFunction([[maybe_unused]] EcmaRuntimeCallInfo *info)
1156 {
1157     return UnimplementedBuiltin(__func__, info);
1158 }
1159 
TryMigrateInstance(EcmaRuntimeCallInfo * info)1160 JSTaggedValue BuiltinsArkTools::TryMigrateInstance([[maybe_unused]] EcmaRuntimeCallInfo *info)
1161 {
1162     return NotSupportedBuiltin(__func__, info);
1163 }
1164 
InLargeObjectSpace(EcmaRuntimeCallInfo * info)1165 JSTaggedValue BuiltinsArkTools::InLargeObjectSpace([[maybe_unused]] EcmaRuntimeCallInfo *info)
1166 {
1167     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1168     CHECK(info && info->GetArgsNumber() == 1);
1169     JSHandle<JSTaggedValue> arg = info->GetCallArg(0);
1170     CHECK(arg->IsHeapObject());
1171     Region *region = Region::ObjectAddressToRange(arg->GetTaggedObject());
1172     return JSTaggedValue(region->InHugeObjectSpace());
1173 }
1174 
PerformMicrotaskCheckpoint(EcmaRuntimeCallInfo * info)1175 JSTaggedValue BuiltinsArkTools::PerformMicrotaskCheckpoint([[maybe_unused]] EcmaRuntimeCallInfo *info)
1176 {
1177     JSThread *thread = info->GetThread();
1178     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1179     ASSERT(info && info->GetArgsNumber() == 0);
1180     thread->GetCurrentEcmaContext()->ExecutePromisePendingJob();
1181     return JSTaggedValue::Undefined();
1182 }
1183 
IsJSReceiver(EcmaRuntimeCallInfo * info)1184 JSTaggedValue BuiltinsArkTools::IsJSReceiver([[maybe_unused]] EcmaRuntimeCallInfo *info)
1185 {
1186     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1187     ASSERT(info && info->GetArgsNumber() == 1);
1188     return JSTaggedValue(info->GetCallArg(0)->IsECMAObject());
1189 }
1190 
IsDictPropertyConstTrackingEnabled(EcmaRuntimeCallInfo * info)1191 JSTaggedValue BuiltinsArkTools::IsDictPropertyConstTrackingEnabled([[maybe_unused]] EcmaRuntimeCallInfo *info)
1192 {
1193     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1194     ASSERT(info && info->GetArgsNumber() == 0);
1195     return JSTaggedValue(false);
1196 }
1197 
1198 // mock builtin
AllocateHeapNumber(EcmaRuntimeCallInfo * info)1199 JSTaggedValue BuiltinsArkTools::AllocateHeapNumber([[maybe_unused]] EcmaRuntimeCallInfo *info)
1200 {
1201     RETURN_IF_DISALLOW_ARKTOOLS(info->GetThread());
1202     ASSERT(info && info->GetArgsNumber() == 0);
1203     return JSTaggedValue(0.0);
1204 }
1205 
ConstructConsString(EcmaRuntimeCallInfo * info)1206 JSTaggedValue BuiltinsArkTools::ConstructConsString([[maybe_unused]] EcmaRuntimeCallInfo *info)
1207 {
1208     JSThread *thread = info->GetThread();
1209     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1210     CHECK(info && info->GetArgsNumber() == 2);  // 2 args
1211     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1212     CHECK(info->GetCallArg(0)->IsString());
1213     CHECK(info->GetCallArg(1)->IsString());
1214     JSHandle<EcmaString> str1(info->GetCallArg(0));
1215     JSHandle<EcmaString> str2(info->GetCallArg(1));
1216 
1217     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1218     return factory->ConcatFromString(str1, str2).GetTaggedValue();
1219 }
1220 
1221 // empty function for regress-xxx test cases
CompleteInobjectSlackTracking(EcmaRuntimeCallInfo * info)1222 JSTaggedValue BuiltinsArkTools::CompleteInobjectSlackTracking([[maybe_unused]] EcmaRuntimeCallInfo *info)
1223 {
1224     return UnimplementedBuiltin(__func__, info);
1225 }
1226 
NormalizeElements(EcmaRuntimeCallInfo * info)1227 JSTaggedValue BuiltinsArkTools::NormalizeElements([[maybe_unused]] EcmaRuntimeCallInfo *info)
1228 {
1229     JSThread *thread = info->GetThread();
1230     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1231     CHECK(info && info->GetArgsNumber() == 1);
1232     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1233     CHECK(info->GetCallArg(0)->IsJSObject());
1234     JSHandle<JSObject> obj(info->GetCallArg(0));
1235     JSObject::ElementsToDictionary(thread, obj);
1236     return obj.GetTaggedValue();
1237 }
1238 
Call(EcmaRuntimeCallInfo * info)1239 JSTaggedValue BuiltinsArkTools::Call([[maybe_unused]] EcmaRuntimeCallInfo *info)
1240 {
1241     JSThread *thread = info->GetThread();
1242     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1243     static constexpr uint32_t MIN_ARGS = 2;
1244     CHECK(info && info->GetArgsNumber() >= MIN_ARGS);
1245     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1246     uint32_t argc = info->GetArgsNumber() - MIN_ARGS;
1247     JSHandle<JSTaggedValue> callee = info->GetCallArg(0);
1248     JSHandle<JSTaggedValue> receiver = info->GetCallArg(1);
1249 
1250     JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
1251     EcmaRuntimeCallInfo *calleeInfo = EcmaInterpreter::NewRuntimeCallInfo(thread, callee, receiver, undefined, argc);
1252     RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
1253     for (uint32_t i = 0; i < argc; ++i) {
1254         calleeInfo->SetCallArg(i, info->GetCallArg(i + MIN_ARGS).GetTaggedValue());
1255     }
1256     return JSFunction::Call(calleeInfo);
1257 }
1258 
1259 // empty function for regress-xxx test cases
DebugPushPromise(EcmaRuntimeCallInfo * info)1260 JSTaggedValue BuiltinsArkTools::DebugPushPromise([[maybe_unused]] EcmaRuntimeCallInfo *info)
1261 {
1262     return UnimplementedBuiltin(__func__, info);
1263 }
1264 
1265 // empty function for regress-xxx test cases
SetForceSlowPath(EcmaRuntimeCallInfo * info)1266 JSTaggedValue BuiltinsArkTools::SetForceSlowPath([[maybe_unused]] EcmaRuntimeCallInfo *info)
1267 {
1268     return UnimplementedBuiltin(__func__, info);
1269 }
1270 
1271 // empty function for regress-xxx test cases
NotifyContextDisposed(EcmaRuntimeCallInfo * info)1272 JSTaggedValue BuiltinsArkTools::NotifyContextDisposed([[maybe_unused]] EcmaRuntimeCallInfo *info)
1273 {
1274     return UnimplementedBuiltin(__func__, info);
1275 }
1276 
1277 // empty function for regress-xxx test cases
OptimizeObjectForAddingMultipleProperties(EcmaRuntimeCallInfo * info)1278 JSTaggedValue BuiltinsArkTools::OptimizeObjectForAddingMultipleProperties([[maybe_unused]] EcmaRuntimeCallInfo *info)
1279 {
1280     return UnimplementedBuiltin(__func__, info);
1281 }
1282 
1283 // empty function for regress-xxx test cases
IsBeingInterpreted(EcmaRuntimeCallInfo * info)1284 JSTaggedValue BuiltinsArkTools::IsBeingInterpreted([[maybe_unused]] EcmaRuntimeCallInfo *info)
1285 {
1286     return UnimplementedBuiltin(__func__, info);
1287 }
1288 
1289 // empty function for regress-xxx test cases
ClearFunctionFeedback(EcmaRuntimeCallInfo * info)1290 JSTaggedValue BuiltinsArkTools::ClearFunctionFeedback([[maybe_unused]] EcmaRuntimeCallInfo *info)
1291 {
1292     return UnimplementedBuiltin(__func__, info);
1293 }
1294 
JitCompileSync(EcmaRuntimeCallInfo * info)1295 JSTaggedValue BuiltinsArkTools::JitCompileSync(EcmaRuntimeCallInfo *info)
1296 {
1297     JSThread *thread = info->GetThread();
1298     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1299     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1300 
1301     JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
1302     if (!thisValue->IsJSFunction()) {
1303         return JSTaggedValue::False();
1304     }
1305     JSHandle<JSFunction> jsFunction(thisValue);
1306     Jit::Compile(thread->GetEcmaVM(), jsFunction, CompilerTier::FAST,
1307                  MachineCode::INVALID_OSR_OFFSET, JitCompileMode::SYNC);
1308     return JSTaggedValue::True();
1309 }
1310 
JitCompileAsync(EcmaRuntimeCallInfo * info)1311 JSTaggedValue BuiltinsArkTools::JitCompileAsync(EcmaRuntimeCallInfo *info)
1312 {
1313     JSThread *thread = info->GetThread();
1314     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1315     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1316 
1317     JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
1318     if (!thisValue->IsJSFunction()) {
1319         return JSTaggedValue::False();
1320     }
1321     JSHandle<JSFunction> jsFunction(thisValue);
1322     Jit::Compile(thread->GetEcmaVM(), jsFunction, CompilerTier::FAST,
1323                  MachineCode::INVALID_OSR_OFFSET, JitCompileMode::ASYNC);
1324     return JSTaggedValue::True();
1325 }
1326 
WaitJitCompileFinish(EcmaRuntimeCallInfo * info)1327 JSTaggedValue BuiltinsArkTools::WaitJitCompileFinish(EcmaRuntimeCallInfo *info)
1328 {
1329     JSThread *thread = info->GetThread();
1330     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1331     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1332 
1333     JSHandle<JSTaggedValue> thisValue = GetCallArg(info, 0);
1334     if (!thisValue->IsJSFunction()) {
1335         return JSTaggedValue::False();
1336     }
1337     JSHandle<JSFunction> jsFunction(thisValue);
1338 
1339     auto jit = Jit::GetInstance();
1340     if (!jit->IsEnableFastJit()) {
1341         return JSTaggedValue::False();
1342     }
1343     if (jsFunction->GetMachineCode() == JSTaggedValue::Undefined()) {
1344         return JSTaggedValue::False();
1345     }
1346     while (jsFunction->GetMachineCode() == JSTaggedValue::Hole()) {
1347         // just spin check
1348         thread->CheckSafepoint();
1349     }
1350     return JSTaggedValue::True();
1351 }
1352 
WaitAllJitCompileFinish(EcmaRuntimeCallInfo * info)1353 JSTaggedValue BuiltinsArkTools::WaitAllJitCompileFinish(EcmaRuntimeCallInfo *info)
1354 {
1355     JSThread *thread = info->GetThread();
1356     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1357 
1358     auto jit = Jit::GetInstance();
1359     if (!jit->IsEnableFastJit()) {
1360         return JSTaggedValue::False();
1361     }
1362     while (Jit::GetInstance()->GetRunningTaskCnt(thread->GetEcmaVM())) {
1363         thread->CheckSafepoint();
1364     }
1365     thread->SetPGOProfilerEnable(false);
1366     thread->CheckOrSwitchPGOStubs();
1367     thread->GetEcmaVM()->GetJSOptions().SetEnablePGOProfiler(false);
1368     return JSTaggedValue::True();
1369 }
1370 
StartRuntimeStat(EcmaRuntimeCallInfo * msg)1371 JSTaggedValue BuiltinsArkTools::StartRuntimeStat(EcmaRuntimeCallInfo *msg)
1372 {
1373     JSThread *thread = msg->GetThread();
1374     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1375     BUILTINS_API_TRACE(thread, Global, StartRuntimeStat);
1376     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1377     // start vm runtime stat statistic
1378     thread->GetCurrentEcmaContext()->SetRuntimeStatEnable(true);
1379     return JSTaggedValue::Undefined();
1380 }
1381 
StopRuntimeStat(EcmaRuntimeCallInfo * msg)1382 JSTaggedValue BuiltinsArkTools::StopRuntimeStat(EcmaRuntimeCallInfo *msg)
1383 {
1384     JSThread *thread = msg->GetThread();
1385     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1386     BUILTINS_API_TRACE(thread, Global, StopRuntimeStat);
1387     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1388     // start vm runtime stat statistic
1389     thread->GetCurrentEcmaContext()->SetRuntimeStatEnable(false);
1390     return JSTaggedValue::Undefined();
1391 }
1392 
IterateFrame(EcmaRuntimeCallInfo * info)1393 JSTaggedValue BuiltinsArkTools::IterateFrame(EcmaRuntimeCallInfo *info)
1394 {
1395     ASSERT(info);
1396     JSThread *thread = info->GetThread();
1397     RETURN_IF_DISALLOW_ARKTOOLS(thread);
1398     [[maybe_unused]] EcmaHandleScope handleScope(thread);
1399 
1400     JSTaggedType *currentFrame = const_cast<JSTaggedType *>(thread->GetCurrentFrame());
1401     RootVisitor visitor = []([[maybe_unused]] Root type, [[maybe_unused]] ObjectSlot slot) {};
1402     RootBaseAndDerivedVisitor derivedVisitor = []([[maybe_unused]] Root Type, [[maybe_unused]] ObjectSlot base,
1403                                                   [[maybe_unused]] ObjectSlot derived,
1404                                                   [[maybe_unused]] uintptr_t baseOldObject) {};
1405 
1406     for (FrameIterator it(currentFrame, thread); !it.Done(); it.Advance<GCVisitedFlag::VISITED>()) {
1407         bool ret = it.IteratorStackMap(visitor, derivedVisitor);
1408         FrameType type = it.GetFrameType();
1409         int delta = it.ComputeDelta();
1410         kungfu::CalleeRegAndOffsetVec calleeRegInfo;
1411         it.GetCalleeRegAndOffsetVec(calleeRegInfo);
1412         LOG_BUILTINS(INFO) << "IterateFrameType: " << (int)type;
1413         LOG_BUILTINS(INFO) << "IterateFrameDelta: " << delta;
1414         LOG_BUILTINS(INFO) << "IterateFrameCalleeRegInfo: " << calleeRegInfo.size();
1415         if (!ret) {
1416             break;
1417         }
1418     }
1419 
1420     for (FrameIterator it(currentFrame, thread); !it.Done(); it.Advance<GCVisitedFlag::DEOPT>()) {
1421         FrameType type = it.GetFrameType();
1422         int delta = it.ComputeDelta();
1423         kungfu::CalleeRegAndOffsetVec calleeRegInfo;
1424         it.GetCalleeRegAndOffsetVec(calleeRegInfo);
1425         LOG_BUILTINS(INFO) << "DeoptIterateFrameType: " << (int)type;
1426         LOG_BUILTINS(INFO) << "DeoptIterateFrameDelta: " << delta;
1427         LOG_BUILTINS(INFO) << "DeoptIterateFrameCalleeRegInfo: " << calleeRegInfo.size();
1428     }
1429 
1430     return JSTaggedValue::Undefined();
1431 }
1432 } // namespace panda::ecmascript::builtins
1433