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