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 <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
ExecutePandaFile(EcmaVM * vm,JSRuntimeOptions & runtimeOptions,std::string & files)52 bool ExecutePandaFile(EcmaVM *vm, JSRuntimeOptions &runtimeOptions, std::string &files)
53 {
54 bool ret = true;
55 LocalScope scope(vm);
56 std::string entry = runtimeOptions.GetEntryPoint();
57 #if defined(PANDA_TARGET_WINDOWS)
58 arg_list_t fileNames = base::StringHelper::SplitString(files, ";");
59 #else
60 arg_list_t fileNames = base::StringHelper::SplitString(files, ":");
61 #endif
62 EcmaContext *context1 = nullptr;
63 if (runtimeOptions.IsEnableContext()) {
64 context1 = JSNApi::CreateJSContext(vm);
65 JSNApi::SwitchCurrentContext(vm, context1);
66 }
67 if (runtimeOptions.WasAOTOutputFileSet()) {
68 JSNApi::LoadAotFile(vm, "");
69 }
70 ClockScope execute;
71 for (const auto &fileName : fileNames) {
72 auto res = JSNApi::Execute(vm, fileName, entry);
73 if (!res) {
74 std::cerr << "Cannot execute panda file '" << fileName << "' with entry '" << entry << "'" << std::endl;
75 ret = false;
76 break;
77 }
78 }
79 auto totalTime = execute.TotalSpentTime();
80 if (runtimeOptions.IsEnableContext()) {
81 JSNApi::DestroyJSContext(vm, context1);
82 }
83
84 if (runtimeOptions.IsEnablePrintExecuteTime()) {
85 std::cout << "execute pandafile spent time " << totalTime << "ms" << std::endl;
86 }
87 return ret;
88 }
89
Main(const int argc,const char ** argv)90 int Main(const int argc, const char **argv)
91 {
92 auto startTime =
93 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch())
94 .count();
95
96 BlockSignals();
97
98 if (argc < 2) { // 2: at least have two arguments
99 std::cerr << GetHelper();
100 return -1;
101 }
102
103 int newArgc = argc;
104 std::string files = argv[argc - 1];
105 if (!base::StringHelper::EndsWith(files, ".abc")) {
106 std::cerr << "The last argument must be abc file" << std::endl;
107 std::cerr << GetHelper();
108 return 1;
109 }
110
111 newArgc--;
112 JSRuntimeOptions runtimeOptions;
113 bool retOpt = runtimeOptions.ParseCommand(newArgc, argv);
114 if (!retOpt) {
115 std::cerr << GetHelper();
116 return 1;
117 }
118
119 if (runtimeOptions.IsStartupTime()) {
120 std::cout << "\n"
121 << "Startup start time: " << startTime << std::endl;
122 }
123 bool ret = true;
124 EcmaVM *vm = JSNApi::CreateEcmaVM(runtimeOptions);
125 if (vm == nullptr) {
126 std::cerr << "Cannot Create vm" << std::endl;
127 return -1;
128 }
129
130 bool isMergeAbc = runtimeOptions.GetMergeAbc();
131 JSNApi::SetBundle(vm, !isMergeAbc);
132 ret = ExecutePandaFile(vm, runtimeOptions, files);
133
134 JSNApi::DestroyJSVM(vm);
135 return ret ? 0 : -1;
136 }
137 } // namespace panda::ecmascript
138
main(int argc,const char ** argv)139 int main(int argc, const char **argv)
140 {
141 return panda::ecmascript::Main(argc, argv);
142 }
143