13af6ab5fSopenharmony_ci#!/usr/bin/env python3 23af6ab5fSopenharmony_ci# -*- coding: utf-8 -*- 33af6ab5fSopenharmony_ci# 43af6ab5fSopenharmony_ci# Copyright (c) 2024 Huawei Device Co., Ltd. 53af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 63af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License. 73af6ab5fSopenharmony_ci# You may obtain a copy of the License at 83af6ab5fSopenharmony_ci# 93af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 103af6ab5fSopenharmony_ci# 113af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 123af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 133af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and 153af6ab5fSopenharmony_ci# limitations under the License. 163af6ab5fSopenharmony_ci 173af6ab5fSopenharmony_cifrom abc import ABC, abstractmethod 183af6ab5fSopenharmony_ciimport argparse 193af6ab5fSopenharmony_ciimport glob 203af6ab5fSopenharmony_ciimport json 213af6ab5fSopenharmony_ciimport os 223af6ab5fSopenharmony_ciimport re 233af6ab5fSopenharmony_ciimport shutil 243af6ab5fSopenharmony_ciimport stat 253af6ab5fSopenharmony_ciimport subprocess 263af6ab5fSopenharmony_ciimport sys 273af6ab5fSopenharmony_ciimport threading 283af6ab5fSopenharmony_ci 293af6ab5fSopenharmony_ciSUCCESS_STATUS = 0 303af6ab5fSopenharmony_ciCRASH_STATUS = -1 313af6ab5fSopenharmony_ciTIMEOUT_STATUS = -2 323af6ab5fSopenharmony_ci 333af6ab5fSopenharmony_ciWORKLOAD_URL = 'https://gitee.com/xliu-huanwei/ark-workload.git' 343af6ab5fSopenharmony_ciBENCHMARK_PATH = '../benchmark' 353af6ab5fSopenharmony_ciSKIP_TEST = 'skip_tests.json' 363af6ab5fSopenharmony_ciDISCREPANCY_REPORT = 'discrepancy_report' 373af6ab5fSopenharmony_ciHTML_CONTENT = \ 383af6ab5fSopenharmony_ci""" 393af6ab5fSopenharmony_ci<!DOCTYPE html> 403af6ab5fSopenharmony_ci<html> 413af6ab5fSopenharmony_ci<head> 423af6ab5fSopenharmony_ci <title>Instruction Discrepancy Report</title> 433af6ab5fSopenharmony_ci <style> 443af6ab5fSopenharmony_ci table { 453af6ab5fSopenharmony_ci width: 50%; 463af6ab5fSopenharmony_ci border-collapse: collapse; 473af6ab5fSopenharmony_ci margin: auto; 483af6ab5fSopenharmony_ci } 493af6ab5fSopenharmony_ci th, td { 503af6ab5fSopenharmony_ci padding: 8px; 513af6ab5fSopenharmony_ci text-align: center; 523af6ab5fSopenharmony_ci border: 1px solid black; 533af6ab5fSopenharmony_ci white-space: nowrap; 543af6ab5fSopenharmony_ci } 553af6ab5fSopenharmony_ci th:nth-child(2), td:nth-child(2) { 563af6ab5fSopenharmony_ci text-align: left; 573af6ab5fSopenharmony_ci } 583af6ab5fSopenharmony_ci h1 { 593af6ab5fSopenharmony_ci text-align: center; 603af6ab5fSopenharmony_ci } 613af6ab5fSopenharmony_ci </style> 623af6ab5fSopenharmony_ci</head> 633af6ab5fSopenharmony_ci<body> 643af6ab5fSopenharmony_ci <h1>Instruction Discrepancy Report</h1> 653af6ab5fSopenharmony_ci <table> 663af6ab5fSopenharmony_ci <tr> 673af6ab5fSopenharmony_ci <th>No</th> 683af6ab5fSopenharmony_ci <th>Case Path</th> 693af6ab5fSopenharmony_ci <th>es2abc Instruction Number</th> 703af6ab5fSopenharmony_ci <th>v8 Instruction Number</th> 713af6ab5fSopenharmony_ci <th>es2abc/v8 Ratio</th> 723af6ab5fSopenharmony_ci </tr> 733af6ab5fSopenharmony_ci""" 743af6ab5fSopenharmony_ci 753af6ab5fSopenharmony_ci 763af6ab5fSopenharmony_cidef is_file(parser, arg): 773af6ab5fSopenharmony_ci if not os.path.isfile(arg): 783af6ab5fSopenharmony_ci parser.error(f'[ERROR]: The file "{arg}" does not exist!') 793af6ab5fSopenharmony_ci return os.path.abspath(arg) 803af6ab5fSopenharmony_ci 813af6ab5fSopenharmony_ci 823af6ab5fSopenharmony_cidef is_directory(parser, arg): 833af6ab5fSopenharmony_ci if not os.path.isdir(arg): 843af6ab5fSopenharmony_ci parser.error(f'[ERROR]: The directory "{arg}" does not exist!') 853af6ab5fSopenharmony_ci return os.path.abspath(arg) 863af6ab5fSopenharmony_ci 873af6ab5fSopenharmony_ci 883af6ab5fSopenharmony_cidef check_timeout(val): 893af6ab5fSopenharmony_ci val = int(val) 903af6ab5fSopenharmony_ci if val <= 0: 913af6ab5fSopenharmony_ci raise argparse.ArgumentTypeError(f'[ERROR]: {val} is an invalid timeout value') 923af6ab5fSopenharmony_ci return val 933af6ab5fSopenharmony_ci 943af6ab5fSopenharmony_ci 953af6ab5fSopenharmony_cidef get_args(): 963af6ab5fSopenharmony_ci description = "Generate a report on the difference between the number of v8 and es2abc bytecode instructions." 973af6ab5fSopenharmony_ci parser = argparse.ArgumentParser(description=description) 983af6ab5fSopenharmony_ci parser.add_argument('-v8', '-d8', '--d8_path', dest='d8_path', type=lambda arg : is_file(parser, arg), 993af6ab5fSopenharmony_ci help='Path to the V8 executable d8', required=True) 1003af6ab5fSopenharmony_ci parser.add_argument('-es2abc', '--es2abc_path', dest='es2abc_path', type=lambda arg : is_file(parser, arg), 1013af6ab5fSopenharmony_ci help='Path to the executable program es2abc', required=True) 1023af6ab5fSopenharmony_ci parser.add_argument('--timeout', dest='timeout', type=check_timeout, default=180, 1033af6ab5fSopenharmony_ci help='Time limits for use case execution (In seconds)') 1043af6ab5fSopenharmony_ci parser.add_argument('--add_case', dest='case', type=lambda arg : is_file(parser, arg), 1053af6ab5fSopenharmony_ci help='Add the file path of a single test case to be executed', nargs='+') 1063af6ab5fSopenharmony_ci parser.add_argument('--add_case_dir', dest='case_dir', type=lambda arg : is_directory(parser, arg), 1073af6ab5fSopenharmony_ci help='Add the directory where the test cases are to be executed', nargs='+') 1083af6ab5fSopenharmony_ci return parser.parse_args() 1093af6ab5fSopenharmony_ci 1103af6ab5fSopenharmony_ci 1113af6ab5fSopenharmony_cidef assemble_command(command_list: list = None, executable_program_path: str = None, 1123af6ab5fSopenharmony_ci file_path: str = None, parameters: list = None): 1133af6ab5fSopenharmony_ci if command_list is None: 1143af6ab5fSopenharmony_ci command_list = [executable_program_path, file_path] 1153af6ab5fSopenharmony_ci if parameters: 1163af6ab5fSopenharmony_ci command_list.extend(parameters) 1173af6ab5fSopenharmony_ci else: 1183af6ab5fSopenharmony_ci if executable_program_path: 1193af6ab5fSopenharmony_ci command_list[0] = executable_program_path 1203af6ab5fSopenharmony_ci if file_path: 1213af6ab5fSopenharmony_ci command_list[1] = file_path 1223af6ab5fSopenharmony_ci return command_list 1233af6ab5fSopenharmony_ci 1243af6ab5fSopenharmony_ci 1253af6ab5fSopenharmony_ciclass CaseManager: 1263af6ab5fSopenharmony_ci def __init__(self, args, skip_test_flag=True): 1273af6ab5fSopenharmony_ci self.test_root = os.path.dirname(os.path.abspath(__file__)) 1283af6ab5fSopenharmony_ci self.args = args 1293af6ab5fSopenharmony_ci self.case_list = [] 1303af6ab5fSopenharmony_ci self.skip_tests_info = os.path.join(self.test_root, SKIP_TEST) 1313af6ab5fSopenharmony_ci self.report_path = os.path.join(self.test_root, DISCREPANCY_REPORT) 1323af6ab5fSopenharmony_ci 1333af6ab5fSopenharmony_ci self.get_test_case() 1343af6ab5fSopenharmony_ci 1353af6ab5fSopenharmony_ci if skip_test_flag and os.path.exists(self.skip_tests_info): 1363af6ab5fSopenharmony_ci self.skip_cases() 1373af6ab5fSopenharmony_ci 1383af6ab5fSopenharmony_ci self.case_list.sort() 1393af6ab5fSopenharmony_ci 1403af6ab5fSopenharmony_ci # Creating dictionary: {file_path : [d8 status, es2abc status]} 1413af6ab5fSopenharmony_ci self.crash_dict = {file_path : [SUCCESS_STATUS, SUCCESS_STATUS] for file_path in self.case_list} 1423af6ab5fSopenharmony_ci 1433af6ab5fSopenharmony_ci def get_test_case(self): 1443af6ab5fSopenharmony_ci def add_directory_to_case_list(case_dir, case_list, extension='js', recursive=True): 1453af6ab5fSopenharmony_ci if not os.path.isdir(case_dir): 1463af6ab5fSopenharmony_ci print(f'[ERROR]: add_directory_to_case_list failed! {case_dir} does not exist!') 1473af6ab5fSopenharmony_ci return False 1483af6ab5fSopenharmony_ci glob_expression = os.path.join(case_dir, f'**/*.{extension}') 1493af6ab5fSopenharmony_ci files_list = glob.glob(glob_expression, recursive=recursive) 1503af6ab5fSopenharmony_ci for file in files_list: 1513af6ab5fSopenharmony_ci abs_file_path = os.path.abspath(file) 1523af6ab5fSopenharmony_ci if abs_file_path not in case_list: # make sure no duplicate case 1533af6ab5fSopenharmony_ci case_list.append(abs_file_path) 1543af6ab5fSopenharmony_ci return True 1553af6ab5fSopenharmony_ci 1563af6ab5fSopenharmony_ci if self.args.case is not None: 1573af6ab5fSopenharmony_ci for case in self.args.case: 1583af6ab5fSopenharmony_ci abs_file_path = os.path.abspath(case) 1593af6ab5fSopenharmony_ci if abs_file_path not in self.case_list: 1603af6ab5fSopenharmony_ci self.case_list.append(abs_file_path) 1613af6ab5fSopenharmony_ci 1623af6ab5fSopenharmony_ci if self.args.case_dir is not None: 1633af6ab5fSopenharmony_ci for case in self.args.case_dir: 1643af6ab5fSopenharmony_ci add_directory_to_case_list(case, self.case_list) 1653af6ab5fSopenharmony_ci 1663af6ab5fSopenharmony_ci cur_dir = os.getcwd() 1673af6ab5fSopenharmony_ci os.chdir(self.test_root) 1683af6ab5fSopenharmony_ci 1693af6ab5fSopenharmony_ci # add workload cases 1703af6ab5fSopenharmony_ci case_dir_path = self.pull_cases_from_repo(WORKLOAD_URL, 'test_cases/ark-workload') 1713af6ab5fSopenharmony_ci if case_dir_path: 1723af6ab5fSopenharmony_ci print('[INFO]: pull workload cases Success!') 1733af6ab5fSopenharmony_ci case_dir_path = os.path.join(case_dir_path, 'weekly_workload', 'js') 1743af6ab5fSopenharmony_ci add_directory_to_case_list(case_dir_path, self.case_list) 1753af6ab5fSopenharmony_ci 1763af6ab5fSopenharmony_ci # add benchmark cases 1773af6ab5fSopenharmony_ci sys.path.insert(0, BENCHMARK_PATH) 1783af6ab5fSopenharmony_ci from utils import DEFAULT_TESTCASES_DIR, pull_cases, clear_folder_shutil 1793af6ab5fSopenharmony_ci benchmark_case_path = os.path.join(BENCHMARK_PATH, DEFAULT_TESTCASES_DIR) 1803af6ab5fSopenharmony_ci clear_folder_shutil(benchmark_case_path) 1813af6ab5fSopenharmony_ci pull_benchmark_cases_success = pull_cases() 1823af6ab5fSopenharmony_ci if pull_benchmark_cases_success: 1833af6ab5fSopenharmony_ci print('[INFO]: pull benchmark cases Success!') 1843af6ab5fSopenharmony_ci add_directory_to_case_list(benchmark_case_path, self.case_list) 1853af6ab5fSopenharmony_ci 1863af6ab5fSopenharmony_ci os.chdir(cur_dir) 1873af6ab5fSopenharmony_ci 1883af6ab5fSopenharmony_ci def git_clone(self, git_url, code_dir, pull=False): 1893af6ab5fSopenharmony_ci cur_dir = os.getcwd() 1903af6ab5fSopenharmony_ci cmd = ['git', 'clone', git_url, code_dir] 1913af6ab5fSopenharmony_ci if pull: 1923af6ab5fSopenharmony_ci os.chdir(code_dir) 1933af6ab5fSopenharmony_ci cmd = ['git', 'pull'] 1943af6ab5fSopenharmony_ci process = subprocess.Popen(cmd) 1953af6ab5fSopenharmony_ci process.wait() 1963af6ab5fSopenharmony_ci os.chdir(cur_dir) 1973af6ab5fSopenharmony_ci result = True 1983af6ab5fSopenharmony_ci if process.returncode: 1993af6ab5fSopenharmony_ci print(f"\n[ERROR]: git clone or pull '{git_url}' Failed!") 2003af6ab5fSopenharmony_ci result = False 2013af6ab5fSopenharmony_ci return result 2023af6ab5fSopenharmony_ci 2033af6ab5fSopenharmony_ci def pull_cases_from_repo(self, case_url, case_dir): 2043af6ab5fSopenharmony_ci dir_path = os.path.join(self.test_root, case_dir) 2053af6ab5fSopenharmony_ci pull = False 2063af6ab5fSopenharmony_ci if os.path.exists(dir_path): 2073af6ab5fSopenharmony_ci pull = True 2083af6ab5fSopenharmony_ci clone_result = self.git_clone(case_url, dir_path, pull) 2093af6ab5fSopenharmony_ci if not clone_result: 2103af6ab5fSopenharmony_ci return None 2113af6ab5fSopenharmony_ci return dir_path 2123af6ab5fSopenharmony_ci 2133af6ab5fSopenharmony_ci def skip_cases(self): 2143af6ab5fSopenharmony_ci with open(self.skip_tests_info, 'r') as f: 2153af6ab5fSopenharmony_ci data = json.load(f) 2163af6ab5fSopenharmony_ci 2173af6ab5fSopenharmony_ci skip_case_list = [] 2183af6ab5fSopenharmony_ci for reason_files_dict in data: 2193af6ab5fSopenharmony_ci skip_case_list.extend([os.path.abspath(os.path.join(self.test_root, case)) 2203af6ab5fSopenharmony_ci for case in reason_files_dict['files']]) 2213af6ab5fSopenharmony_ci 2223af6ab5fSopenharmony_ci self.case_list = [case for case in self.case_list if case not in skip_case_list] 2233af6ab5fSopenharmony_ci 2243af6ab5fSopenharmony_ci def calculate_ratio_for_discrepancy_report(self, d8_instruction_number, es2abc_instruction_number): 2253af6ab5fSopenharmony_ci if d8_instruction_number <= 0 or es2abc_instruction_number <= 0: 2263af6ab5fSopenharmony_ci return 'Invalid Ratio' 2273af6ab5fSopenharmony_ci ratio = (float(es2abc_instruction_number) / d8_instruction_number) * 100 2283af6ab5fSopenharmony_ci return f'{ratio:.2f}%' 2293af6ab5fSopenharmony_ci 2303af6ab5fSopenharmony_ci def generate_discrepancy_report(self, d8_output, es2abc_output): 2313af6ab5fSopenharmony_ci global HTML_CONTENT 2323af6ab5fSopenharmony_ci case_number = 1 2333af6ab5fSopenharmony_ci for d8_item, es2abc_item in zip(d8_output, es2abc_output): 2343af6ab5fSopenharmony_ci d8_instruction_number = d8_item[1] 2353af6ab5fSopenharmony_ci es2abc_instruction_number = es2abc_item[1] 2363af6ab5fSopenharmony_ci 2373af6ab5fSopenharmony_ci if self.crash_dict[d8_item[0]][0] == CRASH_STATUS: 2383af6ab5fSopenharmony_ci d8_instruction_number = \ 2393af6ab5fSopenharmony_ci "<span style='color:Red; font-weight:bold;'>{}</span>".format(d8_item[1]) 2403af6ab5fSopenharmony_ci elif self.crash_dict[d8_item[0]][0] == TIMEOUT_STATUS: 2413af6ab5fSopenharmony_ci d8_instruction_number = \ 2423af6ab5fSopenharmony_ci "<span style='color:DarkRed; font-weight:bold;'>{}</span>".format(d8_item[1]) 2433af6ab5fSopenharmony_ci 2443af6ab5fSopenharmony_ci if self.crash_dict[es2abc_item[0]][1] == CRASH_STATUS: 2453af6ab5fSopenharmony_ci es2abc_instruction_number = \ 2463af6ab5fSopenharmony_ci "<span style='color:Red; font-weight:bold;'>{}</span>".format(es2abc_item[1]) 2473af6ab5fSopenharmony_ci elif self.crash_dict[es2abc_item[0]][1] == TIMEOUT_STATUS: 2483af6ab5fSopenharmony_ci es2abc_instruction_number = \ 2493af6ab5fSopenharmony_ci "<span style='color:DarkRed; font-weight:bold;'>{}</span>".format(es2abc_item[1]) 2503af6ab5fSopenharmony_ci case_path = os.path.relpath(d8_item[0], self.test_root) 2513af6ab5fSopenharmony_ci html_content_of_case_info = f"""<tr> 2523af6ab5fSopenharmony_ci <td>{case_number}</td> 2533af6ab5fSopenharmony_ci <td>{case_path}</td> 2543af6ab5fSopenharmony_ci <td>{es2abc_instruction_number}</td> 2553af6ab5fSopenharmony_ci <td>{d8_instruction_number}</td> 2563af6ab5fSopenharmony_ci <td>{self.calculate_ratio_for_discrepancy_report(int(d8_item[1]), 2573af6ab5fSopenharmony_ci int(es2abc_item[1]))}</td> 2583af6ab5fSopenharmony_ci </tr>""" 2593af6ab5fSopenharmony_ci HTML_CONTENT = "{}{}".format(HTML_CONTENT, html_content_of_case_info) 2603af6ab5fSopenharmony_ci case_number += 1 2613af6ab5fSopenharmony_ci 2623af6ab5fSopenharmony_ci html_content_of_end_tag = "</table></body></html>" 2633af6ab5fSopenharmony_ci HTML_CONTENT = "{}{}".format(HTML_CONTENT, html_content_of_end_tag) 2643af6ab5fSopenharmony_ci 2653af6ab5fSopenharmony_ci flags = os.O_RDWR | os.O_CREAT 2663af6ab5fSopenharmony_ci mode = stat.S_IWUSR | stat.S_IRUSR 2673af6ab5fSopenharmony_ci with os.fdopen(os.open(self.report_path + '.html', flags, mode), 'w') as f: 2683af6ab5fSopenharmony_ci f.truncate() 2693af6ab5fSopenharmony_ci f.write(HTML_CONTENT) 2703af6ab5fSopenharmony_ci 2713af6ab5fSopenharmony_ci 2723af6ab5fSopenharmony_ciclass Runner(ABC): 2733af6ab5fSopenharmony_ci def __init__(self, command_list:list, case_manager:CaseManager): 2743af6ab5fSopenharmony_ci self.output = [] 2753af6ab5fSopenharmony_ci self.command_list = command_list 2763af6ab5fSopenharmony_ci self.case_manager = case_manager 2773af6ab5fSopenharmony_ci 2783af6ab5fSopenharmony_ci @abstractmethod 2793af6ab5fSopenharmony_ci def run(self): 2803af6ab5fSopenharmony_ci pass 2813af6ab5fSopenharmony_ci 2823af6ab5fSopenharmony_ci 2833af6ab5fSopenharmony_ciclass D8Runner(Runner): 2843af6ab5fSopenharmony_ci def __init__(self, command_list, case_manager): 2853af6ab5fSopenharmony_ci super().__init__(command_list, case_manager) 2863af6ab5fSopenharmony_ci 2873af6ab5fSopenharmony_ci def run(self): 2883af6ab5fSopenharmony_ci for file_path in self.case_manager.case_list: 2893af6ab5fSopenharmony_ci d8_case_path = file_path.replace('.js', '.mjs') 2903af6ab5fSopenharmony_ci shutil.copyfile(file_path, d8_case_path) 2913af6ab5fSopenharmony_ci instruction_number = RecognizeInstructionMethod.recognize_d8_bytecode_instruction( 2923af6ab5fSopenharmony_ci self.command_list, d8_case_path, self.case_manager) 2933af6ab5fSopenharmony_ci if os.path.exists(d8_case_path): 2943af6ab5fSopenharmony_ci os.remove(d8_case_path) 2953af6ab5fSopenharmony_ci self.output.append((file_path, instruction_number)) 2963af6ab5fSopenharmony_ci 2973af6ab5fSopenharmony_ci 2983af6ab5fSopenharmony_ciclass ES2ABCRunner(Runner): 2993af6ab5fSopenharmony_ci def __init__(self, command_list, case_manager): 3003af6ab5fSopenharmony_ci super().__init__(command_list, case_manager) 3013af6ab5fSopenharmony_ci 3023af6ab5fSopenharmony_ci def run(self): 3033af6ab5fSopenharmony_ci for file_path in self.case_manager.case_list: 3043af6ab5fSopenharmony_ci instruction_number = RecognizeInstructionMethod.recognize_es2abc_bytecode_instruction( 3053af6ab5fSopenharmony_ci self.command_list, file_path, self.case_manager) 3063af6ab5fSopenharmony_ci self.output.append((file_path, instruction_number)) 3073af6ab5fSopenharmony_ci 3083af6ab5fSopenharmony_ci 3093af6ab5fSopenharmony_ciclass RecognizeInstructionMethod: 3103af6ab5fSopenharmony_ci @staticmethod 3113af6ab5fSopenharmony_ci def recognize_d8_bytecode_instruction(command_list, file_path, case_manager): 3123af6ab5fSopenharmony_ci original_file_path = file_path.replace('.mjs', '.js') 3133af6ab5fSopenharmony_ci command_list = assemble_command(command_list, file_path=file_path) 3143af6ab5fSopenharmony_ci process = subprocess.Popen(command_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 3153af6ab5fSopenharmony_ci try: 3163af6ab5fSopenharmony_ci output, _ = process.communicate(timeout=case_manager.args.timeout) 3173af6ab5fSopenharmony_ci except subprocess.TimeoutExpired: 3183af6ab5fSopenharmony_ci print(f"[WARNING]: v8 - Killed! Timeout: {file_path}") 3193af6ab5fSopenharmony_ci process.kill() 3203af6ab5fSopenharmony_ci case_manager.crash_dict[original_file_path][0] = TIMEOUT_STATUS 3213af6ab5fSopenharmony_ci return -1 # Script execution timeout sets the instruction number to -1 3223af6ab5fSopenharmony_ci process.wait() 3233af6ab5fSopenharmony_ci 3243af6ab5fSopenharmony_ci if process.returncode != 0: 3253af6ab5fSopenharmony_ci case_manager.crash_dict[original_file_path][0] = CRASH_STATUS 3263af6ab5fSopenharmony_ci print(f'[WARNING]: v8 - Crashed! {file_path}') 3273af6ab5fSopenharmony_ci 3283af6ab5fSopenharmony_ci decoded_output = output.decode('utf-8', errors='ignore') 3293af6ab5fSopenharmony_ci 3303af6ab5fSopenharmony_ci instruction_pattern = r'0x[0-9a-fA-F]+ @\s+\d+\s+:\s+([0-9a-fA-F\s]+)\s+(.*)$' 3313af6ab5fSopenharmony_ci result = re.finditer(instruction_pattern, decoded_output, re.MULTILINE) 3323af6ab5fSopenharmony_ci instruction_number = sum(1 for _ in result) 3333af6ab5fSopenharmony_ci return instruction_number 3343af6ab5fSopenharmony_ci 3353af6ab5fSopenharmony_ci @staticmethod 3363af6ab5fSopenharmony_ci def recognize_es2abc_bytecode_instruction(command_list, file_path, case_manager): 3373af6ab5fSopenharmony_ci command_list = assemble_command(command_list, file_path=file_path) 3383af6ab5fSopenharmony_ci process = subprocess.Popen(command_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 3393af6ab5fSopenharmony_ci try: 3403af6ab5fSopenharmony_ci output, _ = process.communicate(timeout=case_manager.args.timeout) 3413af6ab5fSopenharmony_ci except subprocess.TimeoutExpired: 3423af6ab5fSopenharmony_ci print(f"[WARNING]: es2abc - Killed! Timeout: {file_path}") 3433af6ab5fSopenharmony_ci process.kill() 3443af6ab5fSopenharmony_ci case_manager.crash_dict[file_path][1] = TIMEOUT_STATUS 3453af6ab5fSopenharmony_ci return -1 # Script execution timeout sets the instructions number to -1 3463af6ab5fSopenharmony_ci process.wait() 3473af6ab5fSopenharmony_ci 3483af6ab5fSopenharmony_ci if process.returncode != 0: 3493af6ab5fSopenharmony_ci case_manager.crash_dict[file_path][1] = CRASH_STATUS 3503af6ab5fSopenharmony_ci print(f'[WARNING]: es2abc - Crashed! {file_path}') 3513af6ab5fSopenharmony_ci 3523af6ab5fSopenharmony_ci decoded_output = output.decode('utf-8', errors='ignore') 3533af6ab5fSopenharmony_ci lines = decoded_output.split('\n') 3543af6ab5fSopenharmony_ci instruction_number = 0 3553af6ab5fSopenharmony_ci for line in lines: 3563af6ab5fSopenharmony_ci if 'instructions_number:' in line: 3573af6ab5fSopenharmony_ci instruction_number = line.split('instructions_number:')[-1].strip() 3583af6ab5fSopenharmony_ci break 3593af6ab5fSopenharmony_ci return instruction_number 3603af6ab5fSopenharmony_ci 3613af6ab5fSopenharmony_ci 3623af6ab5fSopenharmony_cidef main(): 3633af6ab5fSopenharmony_ci args = get_args() 3643af6ab5fSopenharmony_ci 3653af6ab5fSopenharmony_ci d8_command = assemble_command(executable_program_path=args.d8_path, parameters=['--print-bytecode']) 3663af6ab5fSopenharmony_ci es2abc_command = assemble_command(executable_program_path=args.es2abc_path, 3673af6ab5fSopenharmony_ci parameters=['--module', '--dump-size-stat', '--output=/dev/null']) 3683af6ab5fSopenharmony_ci 3693af6ab5fSopenharmony_ci case_manager = CaseManager(args) 3703af6ab5fSopenharmony_ci d8_runner = D8Runner(d8_command, case_manager) 3713af6ab5fSopenharmony_ci es2abc_runner = ES2ABCRunner(es2abc_command, case_manager) 3723af6ab5fSopenharmony_ci 3733af6ab5fSopenharmony_ci if len(case_manager.case_list): 3743af6ab5fSopenharmony_ci thread_d8 = threading.Thread(target=d8_runner.run) 3753af6ab5fSopenharmony_ci thread_es2abc = threading.Thread(target=es2abc_runner.run) 3763af6ab5fSopenharmony_ci thread_d8.start() 3773af6ab5fSopenharmony_ci thread_es2abc.start() 3783af6ab5fSopenharmony_ci thread_d8.join() 3793af6ab5fSopenharmony_ci thread_es2abc.join() 3803af6ab5fSopenharmony_ci 3813af6ab5fSopenharmony_ci case_manager.generate_discrepancy_report(d8_runner.output, es2abc_runner.output) 3823af6ab5fSopenharmony_ci 3833af6ab5fSopenharmony_ci 3843af6ab5fSopenharmony_ciif __name__ == "__main__": 3853af6ab5fSopenharmony_ci main()