1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <chrono>
17 #include <iostream>
18 #include <iterator>
19 #include <ostream>
20 #include <csignal>
21 #include <vector>
22
23 #include "ecmascript/base/string_helper.h"
24 #include "ecmascript/ecma_string.h"
25 #include "ecmascript/ecma_vm.h"
26 #include "ecmascript/js_runtime_options.h"
27 #include "ecmascript/log.h"
28 #include "ecmascript/mem/mem_controller.h"
29 #include "ecmascript/mem/clock_scope.h"
30 #include "ecmascript/napi/include/jsnapi.h"
31
32 namespace panda::ecmascript {
BlockSignals()33 void BlockSignals()
34 {
35 #if defined(PANDA_TARGET_UNIX)
36 sigset_t set;
37 if (sigemptyset(&set) == -1) {
38 LOG_ECMA(ERROR) << "sigemptyset failed";
39 return;
40 }
41 #endif // PANDA_TARGET_UNIX
42 }
43
GetHelper()44 std::string GetHelper()
45 {
46 std::string str;
47 str.append(COMMON_HELP_HEAD_MSG);
48 str.append(HELP_OPTION_MSG);
49 return str;
50 }
51
Main(const int argc,const char ** argv)52 int Main(const int argc, const char **argv)
53 {
54 auto startTime =
55 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch())
56 .count();
57
58 BlockSignals();
59
60 if (argc < 2) { // 2: at least have two arguments
61 std::cerr << GetHelper();
62 return -1;
63 }
64
65 int newArgc = argc;
66 std::string files = argv[argc - 1];
67 if (!base::StringHelper::EndsWith(files, ".abc")) {
68 std::cerr << "The last argument must be abc file" << std::endl;
69 std::cerr << GetHelper();
70 return 1;
71 }
72
73 newArgc--;
74 JSRuntimeOptions runtimeOptions;
75 bool retOpt = runtimeOptions.ParseCommand(newArgc, argv);
76 if (!retOpt) {
77 std::cerr << GetHelper();
78 return 1;
79 }
80
81 if (runtimeOptions.IsStartupTime()) {
82 std::cout << "\n"
83 << "Startup start time: " << startTime << std::endl;
84 }
85 bool ret = true;
86 EcmaVM *vm = JSNApi::CreateEcmaVM(runtimeOptions);
87 if (vm == nullptr) {
88 std::cerr << "Cannot Create vm" << std::endl;
89 return -1;
90 }
91
92 bool isMergeAbc = runtimeOptions.GetMergeAbc();
93 JSNApi::SetBundle(vm, !isMergeAbc);
94 {
95 LocalScope scope(vm);
96 std::string entry = runtimeOptions.GetEntryPoint();
97 #if defined(PANDA_TARGET_WINDOWS)
98 arg_list_t fileNames = base::StringHelper::SplitString(files, ";");
99 #else
100 arg_list_t fileNames = base::StringHelper::SplitString(files, ":");
101 #endif
102 EcmaContext *context1 = JSNApi::CreateJSContext(vm);
103 ClockScope execute;
104 for (const auto &fileName : fileNames) {
105 auto res = JSNApi::Execute(vm, fileName, entry);
106 if (!res) {
107 std::cerr << "Cannot execute panda file '" << fileName << "' with entry '" << entry << "'" << std::endl;
108 ret = false;
109 break;
110 }
111 }
112 auto totalTime = execute.TotalSpentTime();
113 JSNApi::DestroyJSContext(vm, context1);
114
115 if (runtimeOptions.IsEnablePrintExecuteTime()) {
116 std::cout << "execute pandafile spent time " << totalTime << "ms" << std::endl;
117 }
118 }
119
120 JSNApi::DestroyJSVM(vm);
121 return ret ? 0 : -1;
122 }
123 } // namespace panda::ecmascript
124
main(int argc,const char ** argv)125 int main(int argc, const char **argv)
126 {
127 return panda::ecmascript::Main(argc, argv);
128 }
129