• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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