• 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 *
32
33
34def parse_args():
35    parser = argparse.ArgumentParser()
36    parser.add_argument('--ark-tool',
37                        default=DEFAULT_ARK_TOOL,
38                        required=False,
39                        help="ark's binary tool")
40    parser.add_argument('--ark-aot', action='store_true',
41                        required=False,
42                        help="Run test262 with aot")
43    parser.add_argument('--ark-aot-tool',
44                        default=DEFAULT_ARK_AOT_TOOL,
45                        required=False,
46                        help="ark's aot tool")
47    parser.add_argument("--libs-dir",
48                        default=DEFAULT_LIBS_DIR,
49                        required=False,
50                        help="The path collection of dependent so has been divided by':'")
51    parser.add_argument("--js-file",
52                        required=True,
53                        help="js file")
54    parser.add_argument('--ark-frontend',
55                        default=DEFAULT_ARK_FRONTEND,
56                        required=False,
57                        nargs='?', choices=ARK_FRONTEND_LIST, type=str,
58                        help="Choose one of them")
59    parser.add_argument('--ark-frontend-binary',
60                        default=DEFAULT_ARK_FRONTEND_BINARY,
61                        required=False,
62                        help="ark frontend conversion binary tool")
63    parser.add_argument('--ark-arch',
64                        default=DEFAULT_ARK_ARCH,
65                        required=False,
66                        nargs='?', choices=ARK_ARCH_LIST, type=str,
67                        help="Choose one of them")
68    parser.add_argument('--ark-arch-root',
69                        default=DEFAULT_ARK_ARCH,
70                        required=False,
71                        help="the root path for qemu-aarch64 or qemu-arm")
72    parser.add_argument('--opt-level',
73                        default=DEFAULT_OPT_LEVEL,
74                        required=False,
75                        help="the opt level for es2abc")
76    parser.add_argument('--es2abc-thread-count',
77                        default=DEFAULT_ES2ABC_THREAD_COUNT,
78                        required=False,
79                        help="the thread count for es2abc")
80    parser.add_argument('--merge-abc-binary',
81                        default=DEFAULT_MERGE_ABC_BINARY,
82                        required=False,
83                        help="frontend merge abc binary tool")
84    parser.add_argument('--merge-abc-mode',
85                        default=DEFAULT_MERGE_ABC_MODE,
86                        required=False,
87                        help="run test for merge abc mode")
88    parser.add_argument('--product-name',
89                        default=DEFAULT_PRODUCT_NAME,
90                        required=False,
91                        help="ark's product name")
92    parser.add_argument('--run-pgo', action='store_true',
93                        required=False,
94                        help="Run test262 with aot pgo")
95    arguments = parser.parse_args()
96    return arguments
97
98
99ICU_PATH = f"--icu-data-path={CODE_ROOT}/third_party/icu/ohos_icu4j/data"
100if platform.system() == "Windows":
101    ICU_PATH = ICU_PATH.replace("/", "\\")
102ARK_TOOL = DEFAULT_ARK_TOOL
103LIBS_DIR = DEFAULT_LIBS_DIR
104ARK_AOT_TOOL = DEFAULT_ARK_AOT_TOOL
105ARK_FRONTEND = DEFAULT_ARK_FRONTEND
106ARK_FRONTEND_BINARY = DEFAULT_ARK_FRONTEND_BINARY
107ARK_ARCH = DEFAULT_ARK_ARCH
108PROTO_BIN_SUFFIX = "protoBin"
109
110
111def output(retcode, msg):
112    if retcode == 0:
113        if msg != '':
114            print(str(msg))
115    elif retcode == -6:
116        sys.stderr.write("Aborted (core dumped)")
117    elif retcode == -4:
118        sys.stderr.write("Aborted (core dumped)")
119    elif retcode == -11:
120        sys.stderr.write("Segmentation fault (core dumped)")
121    elif msg != '':
122        sys.stderr.write(str(msg))
123    else:
124        sys.stderr.write("Unknown Error: " + str(retcode))
125
126
127def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT):
128    proc = subprocess.Popen(cmd_args,
129                            stderr=subprocess.PIPE,
130                            stdout=subprocess.PIPE,
131                            close_fds=True,
132                            start_new_session=True)
133    cmd_string = " ".join(cmd_args)
134    code_format = 'utf-8'
135    if platform.system() == "Windows":
136        code_format = 'gbk'
137
138    try:
139        (output_res, errs) = proc.communicate(timeout=timeout)
140        ret_code = proc.poll()
141
142        if errs.decode(code_format, 'ignore') != '':
143            output(1, errs.decode(code_format, 'ignore'))
144            return 1
145
146        if ret_code and ret_code != 1:
147            code = ret_code
148            msg = f"Command {cmd_string}: \n"
149            msg += f"error: {str(errs.decode(code_format, 'ignore'))}"
150        else:
151            code = 0
152            msg = str(output_res.decode(code_format, 'ignore'))
153
154    except subprocess.TimeoutExpired:
155        proc.kill()
156        proc.terminate()
157        os.kill(proc.pid, signal.SIGTERM)
158        code = 1
159        msg = f"Timeout:'{cmd_string}' timed out after' {str(timeout)} seconds"
160    except Exception as err:
161        code = 1
162        msg = f"{cmd_string}: unknown error: {str(err)}"
163    output(code, msg)
164    return code
165
166
167def print_command(cmd_args):
168    sys.stderr.write("\n")
169    sys.stderr.write(" ".join(cmd_args))
170    sys.stderr.write("\n")
171
172
173# for debug use, to keep aot file
174def run_command(cmd_args):
175    return subprocess.run(" ".join(cmd_args))
176
177
178class ArkProgram():
179    def __init__(self, args):
180        self.args = args
181        self.ark_tool = ARK_TOOL
182        self.ark_aot = False
183        self.run_pgo = False
184        self.ark_aot_tool = ARK_AOT_TOOL
185        self.libs_dir = LIBS_DIR
186        self.ark_frontend = ARK_FRONTEND
187        self.ark_frontend_binary = ARK_FRONTEND_BINARY
188        self.module_list = []
189        self.dynamicImport_list = []
190        self.js_file = ""
191        self.module = False
192        self.abc_file = ""
193        self.arch = ARK_ARCH
194        self.arch_root = ""
195        self.opt_level = DEFAULT_OPT_LEVEL
196        self.es2abc_thread_count = DEFAULT_ES2ABC_THREAD_COUNT
197        self.merge_abc_binary = DEFAULT_MERGE_ABC_BINARY
198        self.merge_abc_mode = DEFAULT_MERGE_ABC_MODE
199
200    def proce_parameters(self):
201        if self.args.ark_tool:
202            self.ark_tool = self.args.ark_tool
203
204        if self.args.ark_aot:
205            self.ark_aot = self.args.ark_aot
206
207        if self.args.run_pgo:
208            self.run_pgo = self.args.run_pgo
209
210        if self.args.ark_aot_tool:
211            self.ark_aot_tool = self.args.ark_aot_tool
212
213        if self.args.ark_frontend_binary:
214            self.ark_frontend_binary = self.args.ark_frontend_binary
215
216        if self.args.libs_dir:
217            self.libs_dir = self.args.libs_dir
218
219        if self.args.ark_frontend:
220            self.ark_frontend = self.args.ark_frontend
221
222        if self.args.opt_level:
223            self.opt_level = self.args.opt_level
224
225        if self.args.es2abc_thread_count:
226            self.es2abc_thread_count = self.args.es2abc_thread_count
227
228        if self.args.merge_abc_binary:
229            self.merge_abc_binary = self.args.merge_abc_binary
230
231        if self.args.merge_abc_mode:
232            self.merge_abc_mode = self.args.merge_abc_mode
233
234        self.module_list = MODULE_LIST
235
236        self.dynamicImport_list = DYNAMIC_IMPORT_LIST
237
238        self.js_file = self.args.js_file
239
240        self.arch = self.args.ark_arch
241
242        self.arch_root = self.args.ark_arch_root
243
244    def check_compile_mode(self, file):
245        with open(file, 'r', encoding='utf-8') as check_file:
246            content_file = check_file.read()
247            module_pattern = '((?:export|import)\s+(?:{[\s\S]+}|\*))|'
248            module_pattern += '(export\s+(?:let|const|var|function|class|default))|'
249            module_pattern += '(import\s+[\'\"].+[\'\"])'
250            module_mode_list = re.findall(module_pattern, content_file)
251
252            for module_mode in list(set(module_mode_list)):
253                if len(module_mode[0]) != 0 or len(module_mode[1]) != 0 or \
254                        len(module_mode[2]) != 0:
255                    return True
256
257        if "flags: [module]" in content_file or "/language/module-code/" in self.js_file:
258            return True
259
260        return False
261
262    def get_all_skip_force_gc_tests(self):
263        SKIP_FORCE_GC_LIST_FILES.append(TS2ABC_SKIP_FORCE_GC_LIST_FILE)
264
265        for file in SKIP_FORCE_GC_LIST_FILES:
266            with open(file) as jsonfile:
267                json_data = json.load(jsonfile)
268                for key in json_data:
269                    FORCE_GC_SKIP_TESTS.extend(key["files"])
270
271    def gen_dependency_proto(self, dependency):
272        cmd_args = []
273        output_file = os.path.splitext(dependency.replace(DATA_DIR, BASE_OUT_DIR))[0]
274        output_abc = f"{output_file}.abc"
275        frontend_tool = self.ark_frontend_binary
276        merge_abc_binary = self.args.merge_abc_binary
277        merge_abc_mode = self.merge_abc_mode
278        compile_as_module = self.check_compile_mode(dependency)
279
280        if self.ark_frontend == ARK_FRONTEND_LIST[0]:
281            if merge_abc_mode != "0":
282                cmd_args = ['node', '--expose-gc', frontend_tool, dependency,
283                            '--output-proto', '--merge-abc']
284            else:
285                # for testing no-record-name abc
286                cmd_args = ['node', '--expose-gc', frontend_tool, dependency,
287                            '-o', output_abc]
288            if compile_as_module:
289                mod_opt_index = 6
290                cmd_args.insert(mod_opt_index, "--modules")
291        elif self.ark_frontend == ARK_FRONTEND_LIST[1]:
292            if merge_abc_mode != "0":
293                proto_bin_file = output_file + "." + PROTO_BIN_SUFFIX
294                cmd_args = [frontend_tool, dependency, '--outputProto',
295                            proto_bin_file, '--merge-abc']
296            else:
297                # for testing no-record-name abc
298                cmd_args = [frontend_tool, dependency, '--output', output_abc]
299            if compile_as_module:
300                mod_opt_index = 4
301                cmd_args.insert(mod_opt_index, "--module")
302        proc = subprocess.Popen(cmd_args)
303        proc.wait()
304
305    def gen_apart_abc(self, dependencies):
306        merge_abc_binary = self.args.merge_abc_binary
307        retcode = 0
308        for dependency in list(set(dependencies)):
309            cmd_args = []
310            output_file = os.path.splitext(dependency.replace(DATA_DIR, BASE_OUT_DIR))[0]
311            output_abc = os.path.basename(f"{output_file}.abc")
312            file_dir = os.path.split(self.js_file)[0]
313            is_apart_abc_existed = os.path.exists(file_dir + "/" + output_abc)
314            dependency_file_prefix = os.path.basename(dependency)[:-3]
315            dependency_bin_file = '%s/%s.%s' % (file_dir,
316                                                dependency_file_prefix, PROTO_BIN_SUFFIX)
317            cmd_args = [merge_abc_binary, '--input', dependency_bin_file,
318                        '--suffix', PROTO_BIN_SUFFIX, '--outputFilePath',
319                        file_dir, '--output', output_abc]
320            if not is_apart_abc_existed:
321                retcode = exec_command(cmd_args)
322        return retcode
323
324    def gen_merged_abc(self, dependencies, file_name_pre, proto_bin_file):
325        merge_abc_binary = self.args.merge_abc_binary
326        file_dir = os.path.split(self.js_file)[0]
327        proto_abc_file = ".".join([os.path.splitext(os.path.basename(self.js_file))[0], "abc"])
328        generate_merged_abc = True
329        # collect protoBin file into new-made testcase dir
330        if (len(dependencies) != 0):
331            if os.path.exists(file_name_pre):
332                subprocess.run(['rm', '-rf', file_name_pre])
333            subprocess.run(['mkdir', file_name_pre])
334
335            for dependency in list(set(dependencies)):
336                dependency_file_prefix = os.path.basename(dependency)[:-3]
337                dependency_bin_file = '%s/%s.%s' % (file_dir,
338                                                    dependency_file_prefix, PROTO_BIN_SUFFIX)
339                # test262 report syntax error cases
340                if not os.path.exists(dependency_bin_file):
341                    generate_merged_abc = False
342                else:
343                    subprocess.run(['cp', dependency_bin_file, file_name_pre])
344
345            if not os.path.exists(proto_bin_file):
346                generate_merged_abc = False
347            else:
348                subprocess.run(['cp', proto_bin_file, file_name_pre])
349
350        if (len(dependencies) != 0) and generate_merged_abc:
351            # module test262 cases
352            cmd_args = [merge_abc_binary, '--input', file_name_pre,
353                        '--suffix', PROTO_BIN_SUFFIX, '--outputFilePath',
354                        file_dir, '--output', proto_abc_file]
355            self.abc_file = f'{file_name_pre}.abc'
356            return exec_command(cmd_args)
357        elif os.path.exists(proto_bin_file):
358            cmd_args = [merge_abc_binary, '--input', proto_bin_file,
359                        '--suffix', PROTO_BIN_SUFFIX, '--outputFilePath',
360                        file_dir, '--output', proto_abc_file]
361            self.abc_file = f'{file_name_pre}.abc'
362            return exec_command(cmd_args)
363        return 0
364
365    def gen_abc(self):
366        js_file = self.js_file
367        file_name_pre = os.path.splitext(js_file)[0]
368        file_name = os.path.basename(js_file)
369        file_dir = os.path.split(js_file)[0]
370        out_file = f"{file_name_pre}.abc"
371        out_proto = f"{file_name_pre}.proto"
372        proto_bin_file = file_name_pre + "." + PROTO_BIN_SUFFIX
373        self.abc_file = out_file
374        mod_opt_index = 0
375        compile_as_module = False
376        cmd_args = []
377        dependency_cmd_args = []
378        frontend_tool = self.ark_frontend_binary
379        merge_abc_mode = self.merge_abc_mode
380        dependencies = []
381        merge_abc_binary = self.args.merge_abc_binary
382        retcode = 0
383
384        # pre-generate the dependencies' abc when ark_frontend is [es2panda]
385        if (file_name in self.module_list or file_name in self.dynamicImport_list):
386            if ("dynamic-import" in js_file):
387                search_dir = os.path.dirname(js_file)
388            else:
389                search_dir = os.path.dirname(js_file.replace(BASE_OUT_DIR, DATA_DIR))
390            dependencies = collect_module_dependencies(js_file, search_dir, [])
391            compile_as_module = self.check_compile_mode(js_file)
392            if (self.ark_frontend == ARK_FRONTEND_LIST[1]):
393                if list(set(dependencies)):
394                    for dependency in list(set(dependencies)):
395                        dependency_file = os.path.basename(dependency)
396                        dependency_name = os.path.splitext(dependency_file)[0]
397                        out_dependency_pre = '%s/%s' % (file_dir, dependency_name)
398                        out_dependency_proto = f"{out_dependency_pre}.protoBin"
399                        is_dependency_proto_existed = os.path.exists(out_dependency_proto)
400                        if not is_dependency_proto_existed:
401                            self.gen_dependency_proto(dependency)
402
403        if self.ark_frontend == ARK_FRONTEND_LIST[0]:
404            mod_opt_index = 3
405            if merge_abc_mode != "0":
406                cmd_args = ['node', '--expose-gc', frontend_tool, js_file,
407                            '--output-proto', '--merge-abc']
408            else:
409                # for testing no-record-name abc
410                cmd_args = ['node', '--expose-gc', frontend_tool, js_file,
411                            '-o', out_file]
412            if compile_as_module:
413                cmd_args.insert(mod_opt_index, "-m")
414                self.module = True
415        elif self.ark_frontend == ARK_FRONTEND_LIST[1]:
416            mod_opt_index = 1
417            if merge_abc_mode != "0":
418                # '--merge-abc' is added due to 'merge-abc' is not opened as default in es2abc, should be removed later
419                cmd_args = [frontend_tool, '--function-threads=' +
420                            str(self.es2abc_thread_count), '--outputProto',
421                            proto_bin_file, js_file, '--merge-abc', '--opt-level=' + str(self.opt_level)]
422            else:
423                # for testing no-record-name abc
424                cmd_args = [frontend_tool, '--opt-level=' + str(self.opt_level),
425                            '--function-threads=' +
426                            str(self.es2abc_thread_count), '--output',
427                            out_file, js_file]
428            if compile_as_module:
429                cmd_args.insert(mod_opt_index, "--module")
430                self.module = True
431        # get abc file list from import statement
432        if merge_abc_mode == "0" and self.ark_aot and self.module:
433            self.abc_file = os.path.abspath(out_file)
434            js_dir = os.path.dirname(js_file)
435            for line in fileinput.input(js_file):
436                import_line = re.findall(r"^(?:ex|im)port.*\.js", line)
437                if len(import_line):
438                    import_file = re.findall(r"['\"].*\.js", import_line[0])
439                    if len(import_file):
440                        abc_file = import_file[0][1:].replace(".js", ".abc")
441                        abc_file = os.path.abspath(f'{js_dir}/{abc_file}')
442                        if self.abc_file.find(abc_file) < 0:
443                            self.abc_file += f':{abc_file}'
444
445        if not os.path.exists(out_proto):
446            retcode = exec_command(cmd_args)
447            if retcode == 1:
448                return retcode
449            self.abc_cmd = cmd_args
450
451        if self.ark_frontend == ARK_FRONTEND_LIST[1]:
452            if ("dynamic-import" in js_file and not os.path.exists(out_file)):
453                file_dir = os.path.split(self.js_file)[0]
454                proto_abc_file = ".".join([os.path.splitext(os.path.basename(self.js_file))[0], "abc"])
455                cmd_args = [merge_abc_binary, '--input', proto_bin_file,
456                            '--suffix', PROTO_BIN_SUFFIX, '--outputFilePath',
457                            file_dir, '--output', proto_abc_file]
458                retcode = exec_command(cmd_args)
459                if retcode == 1:
460                    return retcode
461                self.abc_cmd = cmd_args
462
463        if merge_abc_mode != "0":
464            if "dynamic-import" in js_file:
465                return self.gen_apart_abc(dependencies)
466            else:
467                return self.gen_merged_abc(dependencies, file_name_pre, proto_bin_file)
468
469        return retcode
470
471    def compile_aot(self):
472        os.environ["LD_LIBRARY_PATH"] = self.libs_dir
473        file_name_pre = os.path.splitext(self.js_file)[0]
474        cmd_args = []
475        if self.run_pgo:
476            if self.arch == ARK_ARCH_LIST[1]:
477                qemu_tool = "qemu-aarch64"
478                qemu_arg1 = "-L"
479                qemu_arg2 = self.arch_root
480                cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_aot_tool,
481                            ICU_PATH, f'--compiler-target-triple=aarch64-unknown-linux-gnu']
482            elif self.arch == ARK_ARCH_LIST[2]:
483                cmd_args = [self.ark_aot_tool, ICU_PATH, f'--compiler-target-triple=arm-unknown-linux-gnu']
484            elif self.arch == ARK_ARCH_LIST[0]:
485                cmd_args = [self.ark_aot_tool, ICU_PATH]
486
487            cmd_args.append("--compiler-opt-loop-peeling=true")
488            cmd_args.append("--compiler-fast-compile=false")
489            cmd_args.append("--compiler-opt-track-field=true")
490            cmd_args.append("--compiler-opt-inlining=true")
491            cmd_args.append("--compiler-max-inline-bytecodes=45")
492            cmd_args.append("--compiler-opt-level=2")
493            cmd_args.append(
494                f"--builtins-dts={CODE_ROOT}/arkcompiler/ets_runtime/ecmascript/ts_types/lib_ark_builtins.d.abc")
495            cmd_args.append(f'--compiler-pgo-profiler-path={file_name_pre}.ap')
496            cmd_args.append(f'--aot-file={file_name_pre}')
497            cmd_args.append(self.abc_file)
498        else:
499            if self.arch == ARK_ARCH_LIST[1]:
500                cmd_args = [self.ark_aot_tool, ICU_PATH,
501                            f'--compiler-target-triple=aarch64-unknown-linux-gnu',
502                            f'--aot-file={file_name_pre}',
503                            self.abc_file]
504            elif self.arch == ARK_ARCH_LIST[2]:
505                cmd_args = [self.ark_aot_tool, ICU_PATH,
506                            f'--compiler-target-triple=arm-unknown-linux-gnu',
507                            f'--aot-file={file_name_pre}',
508                            self.abc_file]
509            elif self.arch == ARK_ARCH_LIST[0]:
510                cmd_args = [self.ark_aot_tool, ICU_PATH,
511                            f'--aot-file={file_name_pre}',
512                            self.abc_file]
513        retcode = exec_command(cmd_args, 180000)
514        if retcode:
515            print_command(self.abc_cmd)
516            print_command(cmd_args)
517
518    def execute_aot(self):
519        unforce_gc = False
520        os.environ["LD_LIBRARY_PATH"] = self.libs_dir
521        file_name_pre = os.path.splitext(self.js_file)[0]
522        cmd_args = []
523        if self.arch == ARK_ARCH_LIST[1]:
524            qemu_tool = "qemu-aarch64"
525            qemu_arg1 = "-L"
526            qemu_arg2 = self.arch_root
527            cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool,
528                        ICU_PATH,
529                        f'--aot-file={file_name_pre}',
530                        f'{file_name_pre}.abc']
531        elif self.arch == ARK_ARCH_LIST[2]:
532            qemu_tool = "qemu-arm"
533            qemu_arg1 = "-L"
534            qemu_arg2 = self.arch_root
535            cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool,
536                        ICU_PATH,
537                        f'--aot-file={file_name_pre}',
538                        f'{file_name_pre}.abc']
539        elif self.arch == ARK_ARCH_LIST[0]:
540            if file_name_pre in FORCE_GC_SKIP_TESTS:
541                unforce_gc = True
542            asm_arg1 = "--enable-force-gc=true"
543            if unforce_gc:
544                asm_arg1 = "--enable-force-gc=false"
545            cmd_args = [self.ark_tool, ICU_PATH, asm_arg1,
546                        f'--aot-file={file_name_pre}',
547                        f'{file_name_pre}.abc']
548
549        record_name = os.path.splitext(os.path.split(self.js_file)[1])[0]
550        cmd_args.insert(-1, f'--entry-point={record_name}')
551        retcode = exec_command(cmd_args)
552        if retcode:
553            print_command(cmd_args)
554        return retcode
555
556    def execute(self):
557        unforce_gc = False
558        if platform.system() == "Windows":
559            # add env path for cmd/powershell execute
560            libs_dir = self.libs_dir.replace(":", ";")
561            libs_dir = libs_dir.replace("/", "\\")
562            os.environ["PATH"] = libs_dir + ";" + os.environ["PATH"]
563        elif platform.system() == "Linux":
564            os.environ["LD_LIBRARY_PATH"] = self.libs_dir
565        else:
566            sys.exit(f" test262 on {platform.system()} not supported")
567        file_name_pre = os.path.splitext(self.js_file)[0]
568        # In the case of Windows, it is necessary to convert ' \\' to '/', otherwise there will be a crash or the file cannot be found
569        # Maintain consistent interface path with DevEco Studio
570        if platform.system() == "Windows":
571            file_name_pre = file_name_pre.replace("\\", "/")
572        cmd_args = []
573        if self.arch == ARK_ARCH_LIST[1]:
574            qemu_tool = "qemu-aarch64"
575            qemu_arg1 = "-L"
576            qemu_arg2 = self.arch_root
577            cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool,
578                        ICU_PATH,
579                        f'{file_name_pre}.abc']
580        elif self.arch == ARK_ARCH_LIST[2]:
581            qemu_tool = "qemu-arm"
582            qemu_arg1 = "-L"
583            qemu_arg2 = self.arch_root
584            cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool,
585                        ICU_PATH,
586                        f'{file_name_pre}.abc']
587        elif self.arch == ARK_ARCH_LIST[0]:
588            if file_name_pre in FORCE_GC_SKIP_TESTS:
589                unforce_gc = True
590            asm_arg1 = "--enable-force-gc=true"
591            if unforce_gc:
592                asm_arg1 = "--enable-force-gc=false"
593            cmd_args = [self.ark_tool, ICU_PATH, asm_arg1,
594                        f'{file_name_pre}.abc']
595
596        record_name = os.path.splitext(os.path.split(self.js_file)[1])[0]
597        cmd_args.insert(-1, f'--entry-point={record_name}')
598        retcode = exec_command(cmd_args)
599        if retcode:
600            print_command(cmd_args)
601        return retcode
602
603    def run_generator_ap(self):
604        os.environ["LD_LIBRARY_PATH"] = self.libs_dir
605        file_name_pre = os.path.splitext(self.js_file)[0]
606        record_name = os.path.splitext(os.path.split(self.js_file)[1])[0]
607        if self.arch == ARK_ARCH_LIST[1]:
608            qemu_tool = "qemu-aarch64"
609            qemu_arg1 = "-L"
610            qemu_arg2 = self.arch_root
611            cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool,
612                        ICU_PATH,
613                        "--log-level=error",
614                        "--enable-pgo-profiler=true",
615                        "--compiler-opt-inlining=true",
616                        f'--compiler-pgo-profiler-path={file_name_pre}.ap',
617                        "--asm-interpreter=true",
618                        f'--entry-point={record_name}',
619                        f'{file_name_pre}.abc']
620        else:
621            cmd_args = [self.ark_tool, ICU_PATH,
622                        "--log-level=error",
623                        "--enable-pgo-profiler=true",
624                        "--compiler-opt-inlining=true",
625                        f'--compiler-pgo-profiler-path={file_name_pre}.ap',
626                        "--asm-interpreter=true",
627                        f'--entry-point={record_name}',
628                        f'{file_name_pre}.abc']
629        return_code = exec_command(cmd_args)
630        if return_code:
631            print_command(cmd_args)
632        return return_code
633
634    def is_legal_frontend(self):
635        if self.ark_frontend not in ARK_FRONTEND_LIST:
636            sys.stderr.write("Wrong ark front-end option")
637            return False
638        return True
639
640    def execute_ark(self):
641        self.proce_parameters()
642        self.get_all_skip_force_gc_tests()
643        if not self.is_legal_frontend():
644            return
645
646        if self.gen_abc():
647            return
648        if self.run_pgo:
649            self.run_generator_ap()
650        if self.ark_aot:
651            self.compile_aot()
652            self.execute_aot()
653        else:
654            self.execute()
655
656
657def main():
658    args = parse_args()
659
660    ark = ArkProgram(args)
661    ark.execute_ark()
662
663
664if __name__ == "__main__":
665    sys.exit(main())
666