1 /*
2 * Copyright (c) 2021 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 <chrono>
17 #include <iostream>
18 #include <iterator>
19 #include <limits>
20 #include <ostream>
21 #include <signal.h> // NOLINTNEXTLINE(modernize-deprecated-headers)
22 #include <vector>
23
24 #include "ecmascript/base/string_helper.h"
25 #include "ecmascript/ecma_string.h"
26 #include "ecmascript/ecma_vm.h"
27 #include "ecmascript/js_runtime_options.h"
28 #include "ecmascript/log.h"
29 #include "ecmascript/mem/mem_controller.h"
30 #include "ecmascript/mem/clock_scope.h"
31 #include "ecmascript/napi/include/jsnapi.h"
32
33 namespace panda::ecmascript {
BlockSignals()34 void BlockSignals()
35 {
36 #if defined(PANDA_TARGET_UNIX)
37 sigset_t set;
38 if (sigemptyset(&set) == -1) {
39 LOG_ECMA(ERROR) << "sigemptyset failed";
40 return;
41 }
42 #endif // PANDA_TARGET_UNIX
43 }
44
GetHelper()45 std::string GetHelper()
46 {
47 std::string str;
48 str.append(COMMON_HELP_HEAD_MSG);
49 str.append(HELP_OPTION_MSG);
50 str.append(HELP_TAIL_MSG);
51 return str;
52 }
53
Main(const int argc,const char ** argv)54 int Main(const int argc, const char **argv)
55 {
56 auto startTime =
57 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch())
58 .count();
59
60 BlockSignals();
61
62 if (argc < 2) { // 2: at least have two arguments
63 std::cerr << GetHelper();
64 return -1;
65 }
66
67 int newArgc = argc;
68 std::string files = argv[argc - 1];
69 if (!base::StringHelper::EndsWith(files, ".abc")) {
70 std::cerr << "The last argument must be abc file" << std::endl;
71 std::cerr << GetHelper();
72 return 1;
73 }
74
75 newArgc--;
76 JSRuntimeOptions runtimeOptions;
77 bool retOpt = runtimeOptions.ParseCommand(newArgc, argv);
78 if (!retOpt) {
79 std::cerr << GetHelper();
80 return 1;
81 }
82
83 if (runtimeOptions.IsStartupTime()) {
84 std::cout << "\n"
85 << "Startup start time: " << startTime << std::endl;
86 }
87 bool ret = true;
88 EcmaVM *vm = JSNApi::CreateEcmaVM(runtimeOptions);
89 if (vm == nullptr) {
90 std::cerr << "Cannot Create vm" << std::endl;
91 return -1;
92 }
93
94 bool isMergeAbc = runtimeOptions.GetMergeAbc();
95 JSNApi::SetBundle(vm, !isMergeAbc);
96 {
97 LocalScope scope(vm);
98 std::string entry = runtimeOptions.GetEntryPoint();
99 #if defined(PANDA_TARGET_WINDOWS)
100 arg_list_t fileNames = base::StringHelper::SplitString(files, ";");
101 #else
102 arg_list_t fileNames = base::StringHelper::SplitString(files, ":");
103 #endif
104 ClockScope execute;
105 for (const auto &fileName : fileNames) {
106 auto res = JSNApi::Execute(vm, fileName, entry);
107 if (!res) {
108 std::cerr << "Cannot execute panda file '" << fileName << "' with entry '" << entry << "'" << std::endl;
109 ret = false;
110 break;
111 }
112 }
113 auto totalTime = execute.TotalSpentTime();
114 if (runtimeOptions.IsEnablePrintExecuteTime()) {
115 std::cout << "execute pandafile spent time " << totalTime << "ms" << std::endl;
116 }
117 }
118
119 JSNApi::DestroyJSVM(vm);
120 return ret ? 0 : -1;
121 }
122 } // namespace panda::ecmascript
123
main(int argc,const char ** argv)124 int main(int argc, const char **argv)
125 {
126 return panda::ecmascript::Main(argc, argv);
127 }
128