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