1# Copyright 2012 the V8 project authors. All rights reserved. 2# Redistribution and use in source and binary forms, with or without 3# modification, are permitted provided that the following conditions are 4# met: 5# 6# * Redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer. 8# * Redistributions in binary form must reproduce the above 9# copyright notice, this list of conditions and the following 10# disclaimer in the documentation and/or other materials provided 11# with the distribution. 12# * Neither the name of Google Inc. nor the names of its 13# contributors may be used to endorse or promote products derived 14# from this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28from os.path import exists 29from os.path import isdir 30from os.path import join 31import os 32import platform 33import re 34import urllib 35 36 37### Exit codes and their meaning. 38# Normal execution. 39EXIT_CODE_PASS = 0 40# Execution with test failures. 41EXIT_CODE_FAILURES = 1 42# Execution with no tests executed. 43EXIT_CODE_NO_TESTS = 2 44# Execution aborted with SIGINT (Ctrl-C). 45EXIT_CODE_INTERRUPTED = 3 46# Execution aborted with SIGTERM. 47EXIT_CODE_TERMINATED = 4 48# Internal error. 49EXIT_CODE_INTERNAL_ERROR = 5 50 51 52def GetSuitePaths(test_root): 53 return [ f for f in os.listdir(test_root) if isdir(join(test_root, f)) ] 54 55 56# Reads a file into an array of strings 57def ReadLinesFrom(name): 58 lines = [] 59 with open(name) as f: 60 for line in f: 61 if line.startswith('#'): continue 62 if '#' in line: 63 line = line[:line.find('#')] 64 line = line.strip() 65 if not line: continue 66 lines.append(line) 67 return lines 68 69 70def GuessOS(): 71 system = platform.system() 72 if system == 'Linux': 73 return 'linux' 74 elif system == 'Darwin': 75 return 'macos' 76 elif system.find('CYGWIN') >= 0: 77 return 'cygwin' 78 elif system == 'Windows' or system == 'Microsoft': 79 # On Windows Vista platform.system() can return 'Microsoft' with some 80 # versions of Python, see http://bugs.python.org/issue1082 81 return 'windows' 82 elif system == 'FreeBSD': 83 return 'freebsd' 84 elif system == 'OpenBSD': 85 return 'openbsd' 86 elif system == 'SunOS': 87 return 'solaris' 88 elif system == 'NetBSD': 89 return 'netbsd' 90 elif system in ['AIX', 'OS400']: 91 # OS400 runs an AIX emulator called PASE 92 return 'aix' 93 else: 94 return None 95 96 97# Check if Vector Enhancement Facility 1 is available on the 98# host S390 machine. This facility is required for supporting Simd on V8. 99def IsS390SimdSupported(): 100 import subprocess 101 cpuinfo = subprocess.check_output("cat /proc/cpuinfo", shell=True) 102 cpuinfo_list = cpuinfo.strip().decode("utf-8").splitlines() 103 facilities = "".join(x for x in cpuinfo_list if x.startswith("facilities")) 104 facilities_list = facilities.split(" ") 105 # Having bit 135 set indicates VEF1 is available. 106 return "135" in facilities_list 107 108 109# Returns power processor version, taking compatibility mode into account. 110# (Power9 running in Power8 compatibility mode returns 8) 111# Only useful if arch is ppc64 112def GuessPowerProcessorVersion(): 113 import ctypes, ctypes.util 114 os = GuessOS() 115 if os == 'linux': 116 AT_PLATFORM = 15 # from linux/auxvec.h 117 _LIBC = ctypes.CDLL(ctypes.util.find_library('c')) 118 _LIBC.getauxval.argtypes = [ctypes.c_ulong] 119 _LIBC.getauxval.restype = ctypes.c_char_p 120 at_platform = _LIBC.getauxval(AT_PLATFORM).decode('utf-8').lower() 121 if at_platform.startswith('power6'): 122 return 6 123 elif at_platform.startswith('power7'): 124 return 7 125 elif at_platform.startswith('power8'): 126 return 8 127 elif at_platform.startswith('power9'): 128 return 9 129 elif at_platform.startswith('power10'): 130 return 10 131 else: 132 raise Exception('Unable to guess power processor version') 133 elif os == 'aix': 134 # covers aix and os400 135 RTLD_MEMBER = 0x00040000 136 _LIBC = ctypes.CDLL(ctypes.util.find_library('c'), 137 ctypes.DEFAULT_MODE | RTLD_MEMBER) 138 class _system_configuration(ctypes.Structure): 139 _fields_ = [ 140 ('architecture', ctypes.c_int), 141 ('implementation', ctypes.c_int), 142 ] 143 cfg = _system_configuration.in_dll(_LIBC, '_system_configuration') 144 # Values found in sys/systemcfg.h 145 if cfg.implementation == 0x4000: 146 return 6 147 elif cfg.implementation == 0x8000: 148 return 7 149 elif cfg.implementation == 0x10000: 150 return 8 151 elif cfg.implementation == 0x20000: 152 return 9 153 elif cfg.implementation == 0x40000: 154 return 10 155 else: 156 raise Exception('Unable to guess power processor version') 157 else: 158 raise Exception('Unable to guess power processor version') 159 160 161def UseSimulator(arch): 162 machine = platform.machine() 163 return (machine and 164 (arch == "mipsel" or arch == "arm" or arch == "arm64") and 165 not arch.startswith(machine)) 166 167 168# This will default to building the 32 bit VM even on machines that are 169# capable of running the 64 bit VM. 170def DefaultArch(): 171 machine = platform.machine() 172 machine = machine.lower() # Windows 7 capitalizes 'AMD64'. 173 if machine.startswith('arm'): 174 return 'arm' 175 elif (not machine) or (not re.match('(x|i[3-6])86$', machine) is None): 176 return 'ia32' 177 elif machine == 'i86pc': 178 return 'ia32' 179 elif machine == 'x86_64': 180 return 'ia32' 181 elif machine == 'amd64': 182 return 'ia32' 183 elif machine == 's390x': 184 return 's390' 185 elif machine == 'ppc64': 186 return 'ppc' 187 else: 188 return None 189 190 191def GuessWordsize(): 192 if '64' in platform.machine(): 193 return '64' 194 else: 195 return '32' 196 197 198def IsWindows(): 199 return GuessOS() == 'windows' 200 201 202class FrozenDict(dict): 203 def __setitem__(self, *args, **kwargs): 204 raise Exception('Tried to mutate a frozen dict') 205 206 def update(self, *args, **kwargs): 207 raise Exception('Tried to mutate a frozen dict') 208 209 210def Freeze(obj): 211 if isinstance(obj, dict): 212 return FrozenDict((k, Freeze(v)) for k, v in list(obj.items())) 213 elif isinstance(obj, set): 214 return frozenset(obj) 215 elif isinstance(obj, list): 216 return tuple(Freeze(item) for item in obj) 217 else: 218 # Make sure object is hashable. 219 hash(obj) 220 return obj 221