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