14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include <chrono> 174514f5e3Sopenharmony_ci#include <iostream> 184514f5e3Sopenharmony_ci#include <iterator> 194514f5e3Sopenharmony_ci#include <ostream> 204514f5e3Sopenharmony_ci#include <signal.h> // NOLINTNEXTLINE(modernize-deprecated-headers) 214514f5e3Sopenharmony_ci#include <vector> 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_ci#include "ecmascript/base/string_helper.h" 244514f5e3Sopenharmony_ci#include "ecmascript/ecma_string.h" 254514f5e3Sopenharmony_ci#include "ecmascript/ecma_vm.h" 264514f5e3Sopenharmony_ci#include "ecmascript/js_runtime_options.h" 274514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/js_pandafile.h" 284514f5e3Sopenharmony_ci#include "ecmascript/log.h" 294514f5e3Sopenharmony_ci#include "ecmascript/mem/mem_controller.h" 304514f5e3Sopenharmony_ci#include "ecmascript/napi/include/jsnapi.h" 314514f5e3Sopenharmony_ci 324514f5e3Sopenharmony_cinamespace panda::ecmascript { 334514f5e3Sopenharmony_ciusing PatchErrorCode = panda::JSNApi::PatchErrorCode; 344514f5e3Sopenharmony_ci 354514f5e3Sopenharmony_ciconst std::string TEST_ENTRY_POINT = "test"; 364514f5e3Sopenharmony_ciconst std::string RETEST_ENTRY_POINT = "retest"; 374514f5e3Sopenharmony_ci 384514f5e3Sopenharmony_civoid BlockSignals() 394514f5e3Sopenharmony_ci{ 404514f5e3Sopenharmony_ci#if defined(PANDA_TARGET_UNIX) 414514f5e3Sopenharmony_ci sigset_t set; 424514f5e3Sopenharmony_ci if (sigemptyset(&set) == -1) { 434514f5e3Sopenharmony_ci LOG_ECMA(ERROR) << "sigemptyset failed"; 444514f5e3Sopenharmony_ci return; 454514f5e3Sopenharmony_ci } 464514f5e3Sopenharmony_ci#endif // PANDA_TARGET_UNIX 474514f5e3Sopenharmony_ci} 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_cistd::string GetHelper() 504514f5e3Sopenharmony_ci{ 514514f5e3Sopenharmony_ci std::string str; 524514f5e3Sopenharmony_ci str.append(COMMON_HELP_HEAD_MSG); 534514f5e3Sopenharmony_ci str.append(HELP_OPTION_MSG); 544514f5e3Sopenharmony_ci return str; 554514f5e3Sopenharmony_ci} 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_cibool QuickFixQueryFuncColdPatch(std::string baseFileName, std::string &patchFileName, 584514f5e3Sopenharmony_ci uint8_t ** patchBuffer, size_t &patchBufferSize) 594514f5e3Sopenharmony_ci{ 604514f5e3Sopenharmony_ci return true; 614514f5e3Sopenharmony_ci} 624514f5e3Sopenharmony_ci 634514f5e3Sopenharmony_ciint Main(const int argc, const char **argv) 644514f5e3Sopenharmony_ci{ 654514f5e3Sopenharmony_ci auto startTime = 664514f5e3Sopenharmony_ci std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()) 674514f5e3Sopenharmony_ci .count(); 684514f5e3Sopenharmony_ci 694514f5e3Sopenharmony_ci BlockSignals(); 704514f5e3Sopenharmony_ci 714514f5e3Sopenharmony_ci if (argc < 2) { // 2: at least have two arguments 724514f5e3Sopenharmony_ci std::cout << GetHelper(); 734514f5e3Sopenharmony_ci return -1; 744514f5e3Sopenharmony_ci } 754514f5e3Sopenharmony_ci 764514f5e3Sopenharmony_ci int newArgc = argc; 774514f5e3Sopenharmony_ci std::string files = argv[argc - 1]; 784514f5e3Sopenharmony_ci if (!base::StringHelper::EndsWith(files, ".abc")) { 794514f5e3Sopenharmony_ci std::cout << "The last argument must be abc file" << std::endl; 804514f5e3Sopenharmony_ci std::cout << GetHelper(); 814514f5e3Sopenharmony_ci return 1; 824514f5e3Sopenharmony_ci } 834514f5e3Sopenharmony_ci 844514f5e3Sopenharmony_ci newArgc--; 854514f5e3Sopenharmony_ci JSRuntimeOptions runtimeOptions; 864514f5e3Sopenharmony_ci bool retOpt = runtimeOptions.ParseCommand(newArgc, argv); 874514f5e3Sopenharmony_ci if (!retOpt) { 884514f5e3Sopenharmony_ci std::cout << GetHelper(); 894514f5e3Sopenharmony_ci return 1; 904514f5e3Sopenharmony_ci } 914514f5e3Sopenharmony_ci 924514f5e3Sopenharmony_ci if (runtimeOptions.IsStartupTime()) { 934514f5e3Sopenharmony_ci std::cout << "\n" 944514f5e3Sopenharmony_ci << "Startup start time: " << startTime << std::endl; 954514f5e3Sopenharmony_ci } 964514f5e3Sopenharmony_ci EcmaVM *vm = JSNApi::CreateEcmaVM(runtimeOptions); 974514f5e3Sopenharmony_ci if (vm == nullptr) { 984514f5e3Sopenharmony_ci std::cout << "Cannot Create vm" << std::endl; 994514f5e3Sopenharmony_ci return -1; 1004514f5e3Sopenharmony_ci } 1014514f5e3Sopenharmony_ci 1024514f5e3Sopenharmony_ci { 1034514f5e3Sopenharmony_ci std::cout << "QuickFix Execute start" << std::endl; 1044514f5e3Sopenharmony_ci LocalScope scope(vm); 1054514f5e3Sopenharmony_ci std::string entry = runtimeOptions.GetEntryPoint(); 1064514f5e3Sopenharmony_ci 1074514f5e3Sopenharmony_ci#if defined(PANDA_TARGET_WINDOWS) 1084514f5e3Sopenharmony_ci arg_list_t fileNames = base::StringHelper::SplitString(files, ";"); 1094514f5e3Sopenharmony_ci#else 1104514f5e3Sopenharmony_ci arg_list_t fileNames = base::StringHelper::SplitString(files, ":"); 1114514f5e3Sopenharmony_ci#endif 1124514f5e3Sopenharmony_ci uint32_t len = fileNames.size(); 1134514f5e3Sopenharmony_ci if (len < 4) { // 4: four abc file 1144514f5e3Sopenharmony_ci std::cout << "Must include base.abc, patch.abc, test.abc, retest.abc absolute path" << std::endl; 1154514f5e3Sopenharmony_ci JSNApi::DestroyJSVM(vm); 1164514f5e3Sopenharmony_ci return -1; 1174514f5e3Sopenharmony_ci } 1184514f5e3Sopenharmony_ci std::string baseFileName = fileNames[0]; 1194514f5e3Sopenharmony_ci bool isMergeAbc = runtimeOptions.GetMergeAbc(); 1204514f5e3Sopenharmony_ci JSNApi::SetBundle(vm, !isMergeAbc); 1214514f5e3Sopenharmony_ci 1224514f5e3Sopenharmony_ci arg_list_t entryList = base::StringHelper::SplitString(entry, ":"); 1234514f5e3Sopenharmony_ci uint32_t size = entryList.size(); 1244514f5e3Sopenharmony_ci uint32_t entryNum = 1; // 1: one entry, excluding coldpatch testcases. 1254514f5e3Sopenharmony_ci if (size < entryNum) { // 1: one entry 1264514f5e3Sopenharmony_ci std::cout << "Must include 1 entry at least" << std::endl; 1274514f5e3Sopenharmony_ci JSNApi::DestroyJSVM(vm); 1284514f5e3Sopenharmony_ci return -1; 1294514f5e3Sopenharmony_ci } 1304514f5e3Sopenharmony_ci 1314514f5e3Sopenharmony_ci bool res = false; 1324514f5e3Sopenharmony_ci if (size == entryNum) { 1334514f5e3Sopenharmony_ci res = JSNApi::Execute(vm, baseFileName, entryList[0]); 1344514f5e3Sopenharmony_ci if (!res) { 1354514f5e3Sopenharmony_ci std::cout << "Cannot execute panda file '" << baseFileName << 1364514f5e3Sopenharmony_ci "' with entry '" << entry << "'" << std::endl; 1374514f5e3Sopenharmony_ci JSNApi::DestroyJSVM(vm); 1384514f5e3Sopenharmony_ci return -1; 1394514f5e3Sopenharmony_ci } 1404514f5e3Sopenharmony_ci } 1414514f5e3Sopenharmony_ci JSNApi::EnableUserUncaughtErrorHandler(vm); 1424514f5e3Sopenharmony_ci 1434514f5e3Sopenharmony_ci std::string testLoadFileName = fileNames[1]; 1444514f5e3Sopenharmony_ci std::string testUnloadFileName = fileNames[2]; // 2: third file, test unloadpatch abc file. 1454514f5e3Sopenharmony_ci for (uint32_t i = 3; i < len; i++) { // 3: patch file, test unloadpatch abc file. 1464514f5e3Sopenharmony_ci std::string patchFileName = fileNames[i]; 1474514f5e3Sopenharmony_ci std::cout << "QuickFix start load patch" << std::endl; 1484514f5e3Sopenharmony_ci auto result = JSNApi::LoadPatch(vm, patchFileName, baseFileName); 1494514f5e3Sopenharmony_ci if (result != PatchErrorCode::SUCCESS) { 1504514f5e3Sopenharmony_ci std::cout << "LoadPatch failed"<< std::endl; 1514514f5e3Sopenharmony_ci break; 1524514f5e3Sopenharmony_ci } 1534514f5e3Sopenharmony_ci std::cout << "QuickFix load patch success" << std::endl; 1544514f5e3Sopenharmony_ci 1554514f5e3Sopenharmony_ci if (size > entryNum) { 1564514f5e3Sopenharmony_ci JSNApi::RegisterQuickFixQueryFunc(vm, QuickFixQueryFuncColdPatch); 1574514f5e3Sopenharmony_ci res = JSNApi::Execute(vm, baseFileName, entryList[0]); 1584514f5e3Sopenharmony_ci } 1594514f5e3Sopenharmony_ci 1604514f5e3Sopenharmony_ci res = JSNApi::Execute(vm, testLoadFileName, TEST_ENTRY_POINT); 1614514f5e3Sopenharmony_ci 1624514f5e3Sopenharmony_ci if (size == entryNum) { 1634514f5e3Sopenharmony_ci std::cout << "QuickFix start check exception" << std::endl; 1644514f5e3Sopenharmony_ci Local<ObjectRef> exception = JSNApi::GetAndClearUncaughtException(vm); 1654514f5e3Sopenharmony_ci res = JSNApi::IsQuickFixCausedException(vm, exception, patchFileName); 1664514f5e3Sopenharmony_ci if (res) { 1674514f5e3Sopenharmony_ci std::cout << "QuickFix have exception" << std::endl; 1684514f5e3Sopenharmony_ci } else { 1694514f5e3Sopenharmony_ci std::cout << "QuickFix have no exception" << std::endl; 1704514f5e3Sopenharmony_ci } 1714514f5e3Sopenharmony_ci 1724514f5e3Sopenharmony_ci std::cout << "QuickFix start unload patch" << std::endl; 1734514f5e3Sopenharmony_ci result = JSNApi::UnloadPatch(vm, patchFileName); 1744514f5e3Sopenharmony_ci if (result != PatchErrorCode::SUCCESS) { 1754514f5e3Sopenharmony_ci std::cout << "UnloadPatch failed!" << std::endl; 1764514f5e3Sopenharmony_ci break; 1774514f5e3Sopenharmony_ci } 1784514f5e3Sopenharmony_ci std::cout << "QuickFix unload patch success" << std::endl; 1794514f5e3Sopenharmony_ci 1804514f5e3Sopenharmony_ci res = JSNApi::Execute(vm, testUnloadFileName, RETEST_ENTRY_POINT); 1814514f5e3Sopenharmony_ci if (!res) { 1824514f5e3Sopenharmony_ci std::cout << "Cannot execute panda file '" << testUnloadFileName 1834514f5e3Sopenharmony_ci << "' with entry '" << entry << "'" << std::endl; 1844514f5e3Sopenharmony_ci break; 1854514f5e3Sopenharmony_ci } 1864514f5e3Sopenharmony_ci } 1874514f5e3Sopenharmony_ci } 1884514f5e3Sopenharmony_ci std::cout << "QuickFix Execute end" << std::endl; 1894514f5e3Sopenharmony_ci } 1904514f5e3Sopenharmony_ci 1914514f5e3Sopenharmony_ci JSNApi::DestroyJSVM(vm); 1924514f5e3Sopenharmony_ci return 0; 1934514f5e3Sopenharmony_ci} 1944514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1954514f5e3Sopenharmony_ci 1964514f5e3Sopenharmony_ciint main(int argc, const char **argv) 1974514f5e3Sopenharmony_ci{ 1984514f5e3Sopenharmony_ci return panda::ecmascript::Main(argc, argv); 1994514f5e3Sopenharmony_ci} 200