1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4""" 5Copyright (c) 2021 Huawei Device Co., Ltd. 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17 18Description: Use ark to execute js files 19""" 20 21import argparse 22import os 23import platform 24import sys 25import signal 26import subprocess 27from utils import * 28from config import * 29 30 31def parse_args(): 32 parser = argparse.ArgumentParser() 33 parser.add_argument('--ark-tool', 34 default=DEFAULT_ARK_TOOL, 35 required=False, 36 help="ark's binary tool") 37 parser.add_argument('--ark-frontend-tool', 38 default=DEFAULT_ARK_FRONTEND_TOOL, 39 required=False, 40 help="ark frontend conversion tool") 41 parser.add_argument("--libs-dir", 42 default=DEFAULT_LIBS_DIR, 43 required=False, 44 help="The path collection of dependent so has been divided by':'") 45 parser.add_argument("--js-file", 46 required=True, 47 help="js file") 48 parser.add_argument('--ark-frontend', 49 default=DEFAULT_ARK_FRONTEND, 50 required=False, 51 nargs='?', choices=ARK_FRONTEND_LIST, type=str, 52 help="Choose one of them") 53 parser.add_argument('--ark-arch', 54 default=DEFAULT_ARK_ARCH, 55 required=False, 56 nargs='?', choices=ARK_ARCH_LIST, type=str, 57 help="Choose one of them") 58 parser.add_argument('--ark-arch-root', 59 default=DEFAULT_ARK_ARCH, 60 required=False, 61 help="the root path for qemu-aarch64 or qemu-arm") 62 arguments = parser.parse_args() 63 return arguments 64 65 66ARK_ARGS = "--gc-type=epsilon" 67ICU_PATH = f"--icu-data-path={CODE_ROOT}/third_party/icu/ohos_icu4j/data" 68ARK_TOOL = DEFAULT_ARK_TOOL 69ARK_FRONTEND_TOOL = DEFAULT_ARK_FRONTEND_TOOL 70LIBS_DIR = DEFAULT_LIBS_DIR 71ARK_FRONTEND = DEFAULT_ARK_FRONTEND 72ARK_ARCH = DEFAULT_ARK_ARCH 73 74 75def output(retcode, msg): 76 if retcode == 0: 77 if msg != '': 78 print(str(msg)) 79 elif retcode == -6: 80 sys.stderr.write("Aborted (core dumped)") 81 elif retcode == -4: 82 sys.stderr.write("Aborted (core dumped)") 83 elif retcode == -11: 84 sys.stderr.write("Segmentation fault (core dumped)") 85 elif msg != '': 86 sys.stderr.write(str(msg)) 87 else: 88 sys.stderr.write("Unknown Error: " + str(retcode)) 89 90 91def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT): 92 proc = subprocess.Popen(cmd_args, 93 stderr=subprocess.PIPE, 94 stdout=subprocess.PIPE, 95 close_fds=True, 96 start_new_session=True) 97 cmd_string = " ".join(cmd_args) 98 code_format = 'utf-8' 99 if platform.system() == "Windows": 100 code_format = 'gbk' 101 102 try: 103 (msg, errs) = proc.communicate(timeout=timeout) 104 ret_code = proc.poll() 105 106 if errs.decode(code_format, 'ignore') != '': 107 output(1, errs.decode(code_format, 'ignore')) 108 return 1 109 110 if ret_code and ret_code != 1: 111 code = ret_code 112 msg = f"Command {cmd_string}: \n" 113 msg += f"error: {str(errs.decode(code_format,'ignore'))}" 114 else: 115 code = 0 116 msg = str(msg.decode(code_format, 'ignore')) 117 118 except subprocess.TimeoutExpired: 119 proc.kill() 120 proc.terminate() 121 os.kill(proc.pid, signal.SIGTERM) 122 code = 1 123 msg = f"Timeout:'{cmd_string}' timed out after' {str(timeout)} seconds" 124 except Exception as err: 125 code = 1 126 msg = f"{cmd_string}: unknown error: {str(err)}" 127 output(code, msg) 128 return code 129 130 131class ArkProgram(): 132 def __init__(self, args): 133 self.args = args 134 self.ark_tool = ARK_TOOL 135 self.ark_frontend_tool = ARK_FRONTEND_TOOL 136 self.libs_dir = LIBS_DIR 137 self.ark_frontend = ARK_FRONTEND 138 self.js_file = "" 139 self.arch = ARK_ARCH 140 self.arch_root = "" 141 142 def proce_parameters(self): 143 if self.args.ark_tool: 144 self.ark_tool = self.args.ark_tool 145 146 if self.args.ark_frontend_tool: 147 self.ark_frontend_tool = self.args.ark_frontend_tool 148 149 if self.args.libs_dir: 150 self.libs_dir = self.args.libs_dir 151 152 if self.args.ark_frontend: 153 self.ark_frontend = self.args.ark_frontend 154 155 self.js_file = self.args.js_file 156 157 self.arch = self.args.ark_arch 158 159 self.arch_root = self.args.ark_arch_root 160 161 def gen_abc(self): 162 js_file = self.js_file 163 file_name_pre = os.path.splitext(js_file)[0] 164 file_name = os.path.basename(js_file) 165 out_file = f"{file_name_pre}.abc" 166 mod_opt_index = 0 167 cmd_args = [] 168 frontend_tool = self.ark_frontend_tool 169 if self.ark_frontend == ARK_FRONTEND_LIST[0]: 170 mod_opt_index = 3 171 cmd_args = ['node', '--expose-gc', frontend_tool, 172 js_file, '-o', out_file] 173 elif self.ark_frontend == ARK_FRONTEND_LIST[1]: 174 mod_opt_index = 1 175 cmd_args = [frontend_tool, '-c', 176 '-e', 'js', '-o', out_file, '-i', js_file] 177 178 if file_name in MODULE_FILES_LIST: 179 cmd_args.insert(mod_opt_index, "-m") 180 181 retcode = exec_command(cmd_args) 182 return retcode 183 184 def execute(self): 185 186 os.environ["LD_LIBRARY_PATH"] = self.libs_dir 187 file_name_pre = os.path.splitext(self.js_file)[0] 188 cmd_args = [] 189 if self.arch == ARK_ARCH_LIST[1]: 190 qemu_tool = "qemu-aarch64" 191 qemu_arg1 = "-L" 192 qemu_arg2 = self.arch_root 193 cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, 194 ARK_ARGS, ICU_PATH, 195 f'{file_name_pre}.abc'] 196 elif self.arch == ARK_ARCH_LIST[2]: 197 qemu_tool = "qemu-arm" 198 qemu_arg1 = "-L" 199 qemu_arg2 = self.arch_root 200 cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, 201 ARK_ARGS, ICU_PATH, 202 f'{file_name_pre}.abc'] 203 elif self.arch == ARK_ARCH_LIST[0]: 204 cmd_args = [self.ark_tool, ARK_ARGS, ICU_PATH, 205 f'{file_name_pre}.abc'] 206 207 retcode = exec_command(cmd_args) 208 return retcode 209 210 def is_legal_frontend(self): 211 if self.ark_frontend not in ARK_FRONTEND_LIST: 212 sys.stderr.write("Wrong ark front-end option") 213 return False 214 return True 215 216 def execute_ark(self): 217 self.proce_parameters() 218 if not self.is_legal_frontend(): 219 return 220 if self.gen_abc(): 221 return 222 self.execute() 223 224 225def main(): 226 args = parse_args() 227 228 ark = ArkProgram(args) 229 ark.execute_ark() 230 231 232if __name__ == "__main__": 233 sys.exit(main()) 234