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 json 25import sys 26import signal 27import re 28import fileinput 29import subprocess 30from utils import * 31from config import * 32import mix_compile 33 34 35def parse_args(): 36 parser = argparse.ArgumentParser() 37 parser.add_argument('--ark-tool', 38 default=DEFAULT_ARK_TOOL, 39 required=False, 40 help="ark's binary tool") 41 parser.add_argument('--ark-aot', action='store_true', 42 required=False, 43 help="Run test262 with aot") 44 parser.add_argument('--ark-aot-tool', 45 default=DEFAULT_ARK_AOT_TOOL, 46 required=False, 47 help="ark's aot tool") 48 parser.add_argument("--libs-dir", 49 default=DEFAULT_LIBS_DIR, 50 required=False, 51 help="The path collection of dependent so has been divided by':'") 52 parser.add_argument("--js-file", 53 required=True, 54 help="js file") 55 parser.add_argument("--stub-file", 56 default=DEFAULT_STUB_FILE, 57 required=False, 58 help="stub file") 59 parser.add_argument('--ark-frontend', 60 default=DEFAULT_ARK_FRONTEND, 61 required=False, 62 nargs='?', choices=ARK_FRONTEND_LIST, type=str, 63 help="Choose one of them") 64 parser.add_argument('--ark-frontend-binary', 65 default=DEFAULT_ARK_FRONTEND_BINARY, 66 required=False, 67 help="ark frontend conversion binary tool") 68 parser.add_argument('--icu-data-path', 69 default=DEFAULT_ICU_PATH, 70 required=False, 71 help="ark frontend conversion binary tool") 72 parser.add_argument('--ark-arch', 73 default=DEFAULT_ARK_ARCH, 74 required=False, 75 nargs='?', choices=ARK_ARCH_LIST, type=str, 76 help="Choose one of them") 77 parser.add_argument('--ark-arch-root', 78 default=DEFAULT_ARK_ARCH, 79 required=False, 80 help="the root path for qemu-aarch64 or qemu-arm") 81 parser.add_argument('--opt-level', 82 default=DEFAULT_OPT_LEVEL, 83 required=False, 84 help="the opt level for es2abc") 85 parser.add_argument('--es2abc-thread-count', 86 default=DEFAULT_ES2ABC_THREAD_COUNT, 87 required=False, 88 help="the thread count for es2abc") 89 parser.add_argument('--merge-abc-binary', 90 default=DEFAULT_MERGE_ABC_BINARY, 91 required=False, 92 help="frontend merge abc binary tool") 93 parser.add_argument('--merge-abc-mode', 94 default=DEFAULT_MERGE_ABC_MODE, 95 required=False, 96 help="run test for merge abc mode") 97 parser.add_argument('--product-name', 98 default=DEFAULT_PRODUCT_NAME, 99 required=False, 100 help="ark's product name") 101 parser.add_argument('--run-pgo', action='store_true', 102 required=False, 103 help="Run test262 with aot pgo") 104 parser.add_argument('--enable-litecg', action='store_true', 105 required=False, 106 help="Run test262 with aot litecg enabled") 107 parser.add_argument('--run-jit', action='store_true', 108 required=False, 109 help="Run test262 with JIT") 110 parser.add_argument('--run-baseline-jit', action='store_true', 111 required=False, 112 help="Run test262 with baseline JIT") 113 parser.add_argument('--abc2program', action='store_true', 114 help="Use abc2prog to generate abc, aot or pgo is not supported yet under this option") 115 parser.add_argument('--disable-force-gc', action='store_true', 116 help="Run test262 with close force-gc") 117 parser.add_argument('--enable-arkguard', action='store_true', 118 required=False, 119 help="enable arkguard for 262 tests") 120 arguments = parser.parse_args() 121 return arguments 122 123 124ICU_PATH = DEFAULT_ICU_PATH 125if platform.system() == "Windows": 126 ICU_PATH = ICU_PATH.replace("/", "\\") 127ARK_TOOL = DEFAULT_ARK_TOOL 128LIBS_DIR = DEFAULT_LIBS_DIR 129ARK_AOT_TOOL = DEFAULT_ARK_AOT_TOOL 130ARK_FRONTEND = DEFAULT_ARK_FRONTEND 131ARK_FRONTEND_BINARY = DEFAULT_ARK_FRONTEND_BINARY 132ARK_ARCH = DEFAULT_ARK_ARCH 133PROTO_BIN_SUFFIX = "protoBin" 134 135 136class ArkProgram(): 137 def __init__(self, args): 138 self.args = args 139 self.ark_tool = ARK_TOOL 140 self.ark_aot = False 141 self.run_pgo = False 142 self.enable_litecg = False 143 self.disable_force_gc = False 144 self.run_jit = False 145 self.run_baseline_jit = False 146 self.ark_aot_tool = ARK_AOT_TOOL 147 self.libs_dir = LIBS_DIR 148 self.ark_frontend = ARK_FRONTEND 149 self.ark_frontend_binary = ARK_FRONTEND_BINARY 150 self.icu_data_path = ICU_PATH 151 self.module_list = [] 152 self.dynamicImport_list = [] 153 self.js_file = "" 154 self.stub_file = "" 155 self.module = False 156 self.abc_file = "" 157 self.arch = ARK_ARCH 158 self.arch_root = "" 159 self.opt_level = DEFAULT_OPT_LEVEL 160 self.es2abc_thread_count = DEFAULT_ES2ABC_THREAD_COUNT 161 self.merge_abc_binary = DEFAULT_MERGE_ABC_BINARY 162 self.merge_abc_mode = DEFAULT_MERGE_ABC_MODE 163 self.abc2program = False 164 # when enabling abc2program, may generate a list of abc files 165 self.abc_outputs = [] 166 self.enable_arkguard = False 167 168 def proce_parameters(self): 169 if self.args.ark_tool: 170 self.ark_tool = self.args.ark_tool 171 172 if self.args.ark_aot: 173 self.ark_aot = self.args.ark_aot 174 175 if self.args.run_pgo: 176 self.run_pgo = self.args.run_pgo 177 178 if self.args.enable_litecg: 179 self.enable_litecg = self.args.enable_litecg 180 181 if self.args.disable_force_gc: 182 self.disable_force_gc = self.args.disable_force_gc 183 184 if self.args.run_jit: 185 self.run_jit = self.args.run_jit 186 187 if self.args.run_baseline_jit: 188 self.run_baseline_jit = self.args.run_baseline_jit 189 190 if self.args.ark_aot_tool: 191 self.ark_aot_tool = self.args.ark_aot_tool 192 193 if self.args.ark_frontend_binary: 194 self.ark_frontend_binary = self.args.ark_frontend_binary 195 if self.args.icu_data_path: 196 self.icu_data_path = self.args.icu_data_path 197 if self.args.libs_dir: 198 self.libs_dir = self.args.libs_dir 199 200 if self.args.ark_frontend: 201 self.ark_frontend = self.args.ark_frontend 202 203 if self.args.opt_level: 204 self.opt_level = self.args.opt_level 205 206 if self.args.es2abc_thread_count: 207 self.es2abc_thread_count = self.args.es2abc_thread_count 208 209 if self.args.merge_abc_binary: 210 self.merge_abc_binary = self.args.merge_abc_binary 211 212 if self.args.merge_abc_mode: 213 self.merge_abc_mode = self.args.merge_abc_mode 214 215 if self.args.abc2program: 216 self.abc2program = self.args.abc2program 217 218 self.enable_arkguard = self.args.enable_arkguard 219 220 self.module_list = MODULE_LIST 221 222 self.dynamicImport_list = DYNAMIC_IMPORT_LIST 223 224 self.js_file = self.args.js_file 225 226 self.stub_file = self.args.stub_file 227 228 self.arch = self.args.ark_arch 229 230 self.arch_root = self.args.ark_arch_root 231 232 def check_compile_mode(self, file): 233 with open(file, 'r', encoding='utf-8') as check_file: 234 content_file = check_file.read() 235 module_pattern = '((?:export|import)\s+(?:{[\s\S]+}|\*))|' 236 module_pattern += '(export\s+(?:let|const|var|function|class|default))|' 237 module_pattern += '(import\s+[\'\"].+[\'\"])' 238 module_mode_list = re.findall(module_pattern, content_file) 239 240 for module_mode in list(set(module_mode_list)): 241 if len(module_mode[0]) != 0 or len(module_mode[1]) != 0 or len(module_mode[2]) != 0: 242 return True 243 244 if "flags: [module]" in content_file or "/language/module-code/" in self.js_file: 245 return True 246 247 return False 248 249 def get_all_skip_force_gc_tests(self): 250 SKIP_FORCE_GC_LIST_FILES.append(TS2ABC_SKIP_FORCE_GC_LIST_FILE) 251 252 for file in SKIP_FORCE_GC_LIST_FILES: 253 with open(file) as jsonfile: 254 json_data = json.load(jsonfile) 255 for key in json_data: 256 FORCE_GC_SKIP_TESTS.extend(key["files"]) 257 258 def gen_dependency_proto(self, dependency): 259 cmd_args = [] 260 output_file = os.path.splitext(dependency.replace(DATA_DIR, BASE_OUT_DIR))[0] 261 output_abc = f"{output_file}{ABC_EXT}" 262 frontend_tool = self.ark_frontend_binary 263 merge_abc_binary = self.args.merge_abc_binary 264 merge_abc_mode = self.merge_abc_mode 265 compile_as_module = self.check_compile_mode(dependency) 266 267 if self.ark_frontend == ARK_FRONTEND_LIST[0]: 268 if merge_abc_mode != "0": 269 cmd_args = ['node', '--expose-gc', frontend_tool, dependency, 270 '--output-proto', '--merge-abc'] 271 else: 272 # for testing no-record-name abc 273 cmd_args = ['node', '--expose-gc', frontend_tool, dependency, 274 '-o', output_abc] 275 if compile_as_module: 276 mod_opt_index = 6 277 cmd_args.insert(mod_opt_index, "--modules") 278 elif self.ark_frontend == ARK_FRONTEND_LIST[1]: 279 if merge_abc_mode != "0": 280 proto_bin_file = output_file + "." + PROTO_BIN_SUFFIX 281 cmd_args = [frontend_tool, dependency, '--outputProto', 282 proto_bin_file, '--merge-abc'] 283 else: 284 # for testing no-record-name abc 285 cmd_args = [frontend_tool, dependency, '--output', output_abc] 286 if compile_as_module: 287 mod_opt_index = 4 288 cmd_args.insert(mod_opt_index, "--module") 289 proc = subprocess.Popen(cmd_args) 290 proc.wait() 291 292 def gen_apart_abc(self, dependencies): 293 merge_abc_binary = self.args.merge_abc_binary 294 retcode = 0 295 for dependency in list(set(dependencies)): 296 cmd_args = [] 297 output_file = os.path.splitext(dependency.replace(DATA_DIR, BASE_OUT_DIR))[0] 298 output_abc = os.path.basename(f"{output_file}{ABC_EXT}") 299 file_dir = os.path.split(self.js_file)[0] 300 is_apart_abc_existed = os.path.exists(file_dir + "/" + output_abc) 301 dependency_file_prefix = os.path.basename(dependency)[:-3] 302 dependency_bin_file = '%s/%s.%s' % (file_dir, 303 dependency_file_prefix, PROTO_BIN_SUFFIX) 304 cmd_args = [merge_abc_binary, '--input', dependency_bin_file, 305 '--suffix', PROTO_BIN_SUFFIX, '--outputFilePath', 306 file_dir, '--output', output_abc] 307 if not is_apart_abc_existed: 308 retcode = exec_command(cmd_args) 309 return retcode 310 311 def gen_merged_abc(self, dependencies, file_name_pre, proto_bin_file): 312 merge_abc_binary = self.args.merge_abc_binary 313 file_dir = os.path.split(self.js_file)[0] 314 proto_abc_file = ".".join([os.path.splitext(os.path.basename(self.js_file))[0], "abc"]) 315 generate_merged_abc = True 316 # collect protoBin file into new-made testcase dir 317 if (len(dependencies) != 0): 318 if os.path.exists(file_name_pre): 319 subprocess.run(['rm', '-rf', file_name_pre]) 320 subprocess.run(['mkdir', file_name_pre]) 321 322 for dependency in list(set(dependencies)): 323 dependency_file_prefix = os.path.basename(dependency)[:-3] 324 dependency_bin_file = '%s/%s.%s' % (file_dir, 325 dependency_file_prefix, PROTO_BIN_SUFFIX) 326 # test262 report syntax error cases 327 if not os.path.exists(dependency_bin_file): 328 generate_merged_abc = False 329 else: 330 subprocess.run(['cp', dependency_bin_file, file_name_pre]) 331 332 if not os.path.exists(proto_bin_file): 333 generate_merged_abc = False 334 else: 335 subprocess.run(['cp', proto_bin_file, file_name_pre]) 336 337 if (len(dependencies) != 0) and generate_merged_abc: 338 # module test262 cases 339 cmd_args = [merge_abc_binary, '--input', file_name_pre, 340 '--suffix', PROTO_BIN_SUFFIX, '--outputFilePath', 341 file_dir, '--output', proto_abc_file] 342 self.abc_file = f'{file_name_pre}.abc' 343 return exec_command(cmd_args) 344 elif os.path.exists(proto_bin_file): 345 cmd_args = [merge_abc_binary, '--input', proto_bin_file, 346 '--suffix', PROTO_BIN_SUFFIX, '--outputFilePath', 347 file_dir, '--output', proto_abc_file] 348 self.abc_file = f'{file_name_pre}.abc' 349 return exec_command(cmd_args) 350 return 0 351 352 def gen_abc_for_merge_abc_mode(self, js_file, dependencies): 353 file_name_pre = os.path.splitext(js_file)[0] 354 proto_bin_file = file_name_pre + "." + PROTO_BIN_SUFFIX 355 356 if "dynamic-import" in js_file: 357 return self.gen_apart_abc(dependencies) 358 else: 359 return self.gen_merged_abc(dependencies, file_name_pre, proto_bin_file) 360 361 def gen_abc_for_script_mode(self, cmd_args, retcode): 362 retcode = exec_command(cmd_args) 363 if retcode == 1: 364 return retcode 365 self.abc_cmd = cmd_args 366 return retcode 367 368 def gen_abc_for_dynamic_import(self, js_file, retcode): 369 file_name_pre = os.path.splitext(js_file)[0] 370 out_file = f"{file_name_pre}{ABC_EXT}" 371 proto_bin_file = file_name_pre + "." + PROTO_BIN_SUFFIX 372 merge_abc_binary = self.args.merge_abc_binary 373 374 if ("dynamic-import" in js_file and not os.path.exists(out_file)): 375 file_dir = os.path.split(self.js_file)[0] 376 proto_abc_file = ".".join([os.path.splitext(os.path.basename(self.js_file))[0], "abc"]) 377 cmd_args = [merge_abc_binary, '--input', proto_bin_file, 378 '--suffix', PROTO_BIN_SUFFIX, '--outputFilePath', 379 file_dir, '--output', proto_abc_file] 380 retcode = exec_command(cmd_args) 381 if retcode == 1: 382 return retcode 383 self.abc_cmd = cmd_args 384 return retcode 385 386 def get_abc_from_import_statement(self, js_file): 387 file_name_pre = os.path.splitext(js_file)[0] 388 out_file = f"{file_name_pre}{ABC_EXT}" 389 390 self.abc_file = os.path.abspath(out_file) 391 js_dir = os.path.dirname(js_file) 392 for line in fileinput.input(js_file): 393 import_line = re.findall(r"^(?:ex|im)port.*\.js", line) 394 if len(import_line): 395 import_file = re.findall(r"['\"].*\.js", import_line[0]) 396 if len(import_file): 397 abc_file = import_file[0][1:].replace(".js", ABC_EXT) 398 abc_file = os.path.abspath(f'{js_dir}/{abc_file}') 399 if self.abc_file.find(abc_file) < 0: 400 self.abc_file += f':{abc_file}' 401 402 def gen_command(self, js_file, compile_as_module): 403 cmd_args = [] 404 mod_opt_index = 0 405 frontend_tool = self.ark_frontend_binary 406 file_name_pre = os.path.splitext(js_file)[0] 407 merge_abc_mode = self.merge_abc_mode 408 proto_bin_file = file_name_pre + "." + PROTO_BIN_SUFFIX 409 out_file = f"{file_name_pre}{ABC_EXT}" 410 411 if self.ark_frontend == ARK_FRONTEND_LIST[0]: 412 mod_opt_index = 3 413 if merge_abc_mode != "0": 414 cmd_args = ['node', '--expose-gc', frontend_tool, js_file, 415 '--output-proto', '--merge-abc'] 416 else: 417 # for testing no-record-name abc 418 cmd_args = ['node', '--expose-gc', frontend_tool, js_file, 419 '-o', out_file] 420 if compile_as_module: 421 cmd_args.insert(mod_opt_index, "-m") 422 self.module = True 423 elif self.ark_frontend == ARK_FRONTEND_LIST[1]: 424 mod_opt_index = 1 425 if merge_abc_mode != "0": 426 # '--merge-abc' is added due to 'merge-abc' is not opened as default in es2abc, should be removed later 427 cmd_args = [frontend_tool, '--function-threads=' + 428 str(self.es2abc_thread_count), '--outputProto', 429 proto_bin_file, js_file, '--merge-abc', '--opt-level=' + str(self.opt_level)] 430 else: 431 # for testing no-record-name abc 432 cmd_args = [frontend_tool, '--opt-level=' + str(self.opt_level), 433 '--function-threads=' + 434 str(self.es2abc_thread_count), '--output', 435 out_file, js_file] 436 if compile_as_module: 437 cmd_args.insert(mod_opt_index, "--module") 438 self.module = True 439 440 return cmd_args 441 442 def gen_dependencies_proto(self, js_file): 443 file_dir = os.path.split(js_file)[0] 444 compile_as_module = False 445 dependencies = [] 446 447 if ("dynamic-import" in js_file): 448 search_dir = os.path.dirname(js_file) 449 else: 450 search_dir = os.path.dirname(js_file.replace(BASE_OUT_DIR, DATA_DIR)) 451 452 dependencies = collect_module_dependencies(js_file, search_dir, []) 453 compile_as_module = self.check_compile_mode(js_file) 454 455 if (self.ark_frontend == ARK_FRONTEND_LIST[1]): 456 if list(set(dependencies)): 457 for dependency in list(set(dependencies)): 458 dependency_file = os.path.basename(dependency) 459 dependency_name = os.path.splitext(dependency_file)[0] 460 out_dependency_pre = '%s/%s' % (file_dir, dependency_name) 461 out_dependency_proto = f"{out_dependency_pre}.protoBin" 462 is_dependency_proto_existed = os.path.exists(out_dependency_proto) 463 if not is_dependency_proto_existed: 464 self.gen_dependency_proto(dependency) 465 466 return compile_as_module, dependencies 467 468 def gen_abc_for_mix_compile_mode(self, dependencies, out_file): 469 record_names = set() 470 files_info_list = [] 471 # In some cases of circular reference, the js file will be from BASE_OUT_DIR, remove it 472 dependencies = [os.path.abspath(dependency) for dependency in dependencies] 473 dependencies.insert(0, os.path.abspath(self.js_file)) 474 for dependency in dependencies: 475 record_name = os.path.splitext(os.path.basename(dependency))[0] 476 if record_name in record_names: 477 continue 478 479 record_names.add(record_name) 480 compile_mode = 'esm' if self.check_compile_mode(dependency) else 'script' 481 files_info_list.append(f"{dependency};{record_name};{compile_mode};xxx;yyy\n") 482 483 mix_compiler = mix_compile.MixCompiler(out_file, files_info_list, self.opt_level, 484 self.es2abc_thread_count, self.es2abc_thread_count, 485 self.es2abc_thread_count, self.ark_frontend_binary) 486 487 retcode = mix_compiler.mix_compile() 488 self.abc_outputs = mix_compiler.abc_outputs 489 return retcode 490 491 def gen_abc(self): 492 js_file = self.js_file 493 file_name_pre = os.path.splitext(js_file)[0] 494 file_name = os.path.basename(js_file) 495 file_dir = os.path.split(js_file)[0] 496 out_file = f"{file_name_pre}{ABC_EXT}" 497 out_proto = f"{file_name_pre}.proto" 498 proto_bin_file = file_name_pre + "." + PROTO_BIN_SUFFIX 499 self.abc_file = out_file 500 mod_opt_index = 0 501 compile_as_module = False 502 cmd_args = [] 503 dependency_cmd_args = [] 504 frontend_tool = self.ark_frontend_binary 505 merge_abc_mode = self.merge_abc_mode 506 dependencies = [] 507 merge_abc_binary = self.args.merge_abc_binary 508 retcode = 0 509 510 # generate the dependencies' proto when ark_frontend is [es2panda] 511 if (file_name in self.module_list or file_name in self.dynamicImport_list): 512 compile_as_module, dependencies = self.gen_dependencies_proto(js_file) 513 514 if self.abc2program: 515 return self.gen_abc_for_mix_compile_mode(dependencies, out_file) 516 517 # generate execution command 518 cmd_args = self.gen_command(js_file, compile_as_module) 519 520 # get abc file list from import statement 521 if merge_abc_mode == "0" and self.ark_aot and self.module: 522 self.get_abc_from_import_statement(js_file) 523 524 # generate abc file by script mode 525 if not os.path.exists(out_proto): 526 retcode = self.gen_abc_for_script_mode(cmd_args, retcode) 527 if retcode == 1: 528 return retcode 529 530 # generate abc file by script mode for dynamic-import 531 if self.ark_frontend == ARK_FRONTEND_LIST[1]: 532 retcode = self.gen_abc_for_dynamic_import(js_file, retcode) 533 if retcode == 1: 534 return retcode 535 536 # generate merged abc file 537 if merge_abc_mode != "0": 538 self.gen_abc_for_merge_abc_mode(js_file, dependencies) 539 540 return retcode 541 542 def execute_arkguard(self): 543 js_file = self.js_file 544 js_file_allpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../', js_file) 545 cmd_args = ['node', '--no-warnings', 546 '--loader=ts-node/esm', 547 './src/cli/SecHarmony.ts', 548 js_file_allpath, 549 '--config-path', 550 './test/test262/test262Config.json', 551 '--inplace'] 552 arkguard_path = os.getcwd() + '/arkguard' 553 retcode = exec_command(cmd_args, custom_cwd = arkguard_path) 554 555 def compile_aot(self): 556 os.environ["LD_LIBRARY_PATH"] = self.libs_dir 557 file_name_pre = os.path.splitext(self.js_file)[0] 558 icu_path = f"--icu-data-path={self.icu_data_path}" 559 cmd_args = [] 560 if self.run_pgo: 561 if self.arch == ARK_ARCH_LIST[1]: 562 qemu_tool = "qemu-aarch64" 563 qemu_arg1 = "-L" 564 qemu_arg2 = self.arch_root 565 cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_aot_tool, 566 icu_path, f'--compiler-target-triple=aarch64-unknown-linux-gnu'] 567 elif self.arch == ARK_ARCH_LIST[2]: 568 cmd_args = [self.ark_aot_tool, icu_path, f'--compiler-target-triple=arm-unknown-linux-gnu'] 569 elif self.arch == ARK_ARCH_LIST[0]: 570 cmd_args = [self.ark_aot_tool, icu_path] 571 cmd_args.append("--compiler-opt-loop-peeling=true") 572 cmd_args.append("--compiler-fast-compile=false") 573 cmd_args.append("--compiler-opt-track-field=true") 574 cmd_args.append("--compiler-opt-inlining=true") 575 cmd_args.append("--compiler-max-inline-bytecodes=45") 576 cmd_args.append("--compiler-opt-level=2") 577 if self.stub_file != "": 578 cmd_args.append(f"--stub-file={self.stub_file}") 579 if self.disable_force_gc: 580 cmd_args.append(f"--enable-force-gc=false") 581 cmd_args.append(f'--compiler-pgo-profiler-path={file_name_pre}.ap') 582 cmd_args.append(f'--aot-file={file_name_pre}') 583 cmd_args.append(self.abc_file) 584 else: 585 if self.arch == ARK_ARCH_LIST[1]: 586 cmd_args = [self.ark_aot_tool, icu_path, 587 f'--compiler-target-triple=aarch64-unknown-linux-gnu', 588 f'--aot-file={file_name_pre}', 589 self.abc_file] 590 elif self.arch == ARK_ARCH_LIST[2]: 591 cmd_args = [self.ark_aot_tool, icu_path, 592 f'--compiler-target-triple=arm-unknown-linux-gnu', 593 f'--aot-file={file_name_pre}', 594 self.abc_file] 595 elif self.arch == ARK_ARCH_LIST[0]: 596 cmd_args = [self.ark_aot_tool, icu_path, 597 f'--aot-file={file_name_pre}', 598 self.abc_file] 599 if self.enable_litecg: 600 cmd_args.insert(-1, "--compiler-enable-litecg=true") 601 retcode = exec_command(cmd_args, 180000) 602 if retcode: 603 print_command(self.abc_cmd) 604 print_command(cmd_args) 605 606 def execute_aot(self): 607 unforce_gc = False 608 os.environ["LD_LIBRARY_PATH"] = self.libs_dir 609 file_name_pre = os.path.splitext(self.js_file)[0] 610 cmd_args = [] 611 icu_path = f"--icu-data-path={self.icu_data_path}" 612 if self.arch == ARK_ARCH_LIST[1]: 613 qemu_tool = "qemu-aarch64" 614 qemu_arg1 = "-L" 615 qemu_arg2 = self.arch_root 616 cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, 617 icu_path, 618 f'--aot-file={file_name_pre}', 619 f'{file_name_pre}.abc'] 620 elif self.arch == ARK_ARCH_LIST[2]: 621 qemu_tool = "qemu-arm" 622 qemu_arg1 = "-L" 623 qemu_arg2 = self.arch_root 624 cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, 625 icu_path, 626 f'--aot-file={file_name_pre}', 627 f'{file_name_pre}.abc'] 628 elif self.arch == ARK_ARCH_LIST[0]: 629 if file_name_pre in FORCE_GC_SKIP_TESTS: 630 unforce_gc = True 631 asm_arg1 = "--enable-force-gc=true" 632 if unforce_gc or self.disable_force_gc: 633 asm_arg1 = "--enable-force-gc=false" 634 cmd_args = [self.ark_tool, icu_path, asm_arg1, 635 f'--aot-file={file_name_pre}', 636 f'{file_name_pre}.abc'] 637 record_name = os.path.splitext(os.path.split(self.js_file)[1])[0] 638 cmd_args.insert(-1, f'--entry-point={record_name}') 639 if self.stub_file != "": 640 cmd_args.insert(-1, f'--stub-file={self.stub_file}') 641 retcode = exec_command(cmd_args) 642 if retcode: 643 print_command(cmd_args) 644 return retcode 645 646 def execute_abc2program_outputs(self, cmd_args): 647 retcode = 0 648 for abc in self.abc_outputs: 649 abc = get_formated_path(abc) 650 cmd_args[-1] = abc 651 retcode = exec_command(cmd_args) 652 if retcode: 653 print_command(cmd_args) 654 return retcode 655 return retcode 656 657 def execute(self): 658 icu_path = f"--icu-data-path={self.icu_data_path}" 659 unforce_gc = False 660 if platform.system() == "Windows": 661 # add env path for cmd/powershell execute 662 libs_dir = self.libs_dir.replace(":", ";") 663 libs_dir = libs_dir.replace("/", "\\") 664 os.environ["PATH"] = libs_dir + ";" + os.environ["PATH"] 665 elif platform.system() == "Linux": 666 os.environ["LD_LIBRARY_PATH"] = self.libs_dir 667 else: 668 sys.exit(f" test262 on {platform.system()} not supported") 669 670 file_name_pre = get_formated_path(os.path.splitext(self.js_file)[0]) 671 cmd_args = [] 672 if self.arch == ARK_ARCH_LIST[1]: 673 qemu_tool = "qemu-aarch64" 674 qemu_arg1 = "-L" 675 qemu_arg2 = self.arch_root 676 cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, 677 icu_path, 678 f'{file_name_pre}.abc'] 679 if self.run_jit or self.run_baseline_jit: 680 cmd_args.insert(-1, f'--compiler-target-triple=aarch64-unknown-linux-gnu') 681 cmd_args.insert(-1, f'--open-ark-tools=true') 682 if self.run_baseline_jit: 683 cmd_args.insert(-1, f'--test-assert=true') 684 elif self.arch == ARK_ARCH_LIST[2]: 685 qemu_tool = "qemu-arm" 686 qemu_arg1 = "-L" 687 qemu_arg2 = self.arch_root 688 cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, 689 icu_path, 690 f'{file_name_pre}.abc'] 691 elif self.arch == ARK_ARCH_LIST[0]: 692 if file_name_pre in FORCE_GC_SKIP_TESTS: 693 unforce_gc = True 694 asm_arg1 = "--enable-force-gc=true" 695 if unforce_gc or self.disable_force_gc: 696 asm_arg1 = "--enable-force-gc=false" 697 cmd_args = [self.ark_tool, icu_path, asm_arg1, 698 f'{file_name_pre}.abc'] 699 700 record_name = os.path.splitext(os.path.split(self.js_file)[1])[0] 701 cmd_args.insert(-1, f'--entry-point={record_name}') 702 if self.run_jit: 703 cmd_args.insert(-1, f'--compiler-enable-litecg=true') 704 cmd_args.insert(-1, f'--compiler-enable-jit=true --log-debug=jit') 705 if self.run_baseline_jit: 706 cmd_args.insert(-1, f'--compiler-enable-baselinejit=true') 707 cmd_args.insert(-1, f'--compiler-force-baselinejit-compile-main=true') 708 if self.stub_file != "": 709 cmd_args.insert(-1, f"--stub-file={self.stub_file}") 710 retcode = 0 711 if self.abc2program: 712 retcode = self.execute_abc2program_outputs(cmd_args) 713 else: 714 retcode = exec_command(cmd_args) 715 if retcode: 716 print_command(cmd_args) 717 return retcode 718 719 def run_generator_ap(self): 720 icu_path = f"--icu-data-path={self.icu_data_path}" 721 os.environ["LD_LIBRARY_PATH"] = self.libs_dir 722 file_name_pre = os.path.splitext(self.js_file)[0] 723 record_name = os.path.splitext(os.path.split(self.js_file)[1])[0] 724 if self.arch == ARK_ARCH_LIST[1]: 725 qemu_tool = "qemu-aarch64" 726 qemu_arg1 = "-L" 727 qemu_arg2 = self.arch_root 728 cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, 729 icu_path, 730 "--log-level=error", 731 "--enable-pgo-profiler=true", 732 "--compiler-opt-inlining=true", 733 f'--compiler-pgo-profiler-path={file_name_pre}.ap', 734 "--asm-interpreter=true", 735 f'--entry-point={record_name}'] 736 else: 737 cmd_args = [self.ark_tool, icu_path, 738 "--log-level=error", 739 "--enable-pgo-profiler=true", 740 "--compiler-opt-inlining=true", 741 f'--compiler-pgo-profiler-path={file_name_pre}.ap', 742 "--asm-interpreter=true", 743 f'--entry-point={record_name}'] 744 if self.stub_file != "": 745 cmd_args.append(f"--stub-file={self.stub_file}") 746 if self.disable_force_gc: 747 cmd_args.append(f"--enable-force-gc=false") 748 cmd_args.append(f'{file_name_pre}.abc') 749 return_code = exec_command(cmd_args) 750 if return_code: 751 print_command(cmd_args) 752 return return_code 753 754 def is_legal_frontend(self): 755 if self.ark_frontend not in ARK_FRONTEND_LIST: 756 sys.stderr.write("Wrong ark front-end option") 757 return False 758 return True 759 760 def execute_ark(self): 761 self.proce_parameters() 762 self.get_all_skip_force_gc_tests() 763 if not self.is_legal_frontend(): 764 return 765 if self.enable_arkguard: 766 self.execute_arkguard() 767 if self.gen_abc(): 768 return 769 if self.run_pgo: 770 self.run_generator_ap() 771 if self.ark_aot: 772 self.compile_aot() 773 self.execute_aot() 774 else: 775 self.execute() 776 777 778def main(): 779 args = parse_args() 780 781 ark = ArkProgram(args) 782 ark.execute_ark() 783 784 785if __name__ == "__main__": 786 sys.exit(main()) 787