1#! /usr/bin/python 2 3# Copyright (C) 2014 Apple Inc. All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 16# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 19# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26# This tool processes the bytecode list to create Bytecodes.h and InitBytecodes.asm 27 28import hashlib 29import json 30import optparse 31import os 32import re 33import sys 34 35cCopyrightMsg = """/* 36* Copyright (C) 2014 Apple Inc. All rights reserved. 37* 38* Redistribution and use in source and binary forms, with or without 39* modification, are permitted provided that the following conditions 40* are met: 41* 42* 1. Redistributions of source code must retain the above copyright 43* notice, this list of conditions and the following disclaimer. 44* 2. Redistributions in binary form must reproduce the above copyright 45* notice, this list of conditions and the following disclaimer in the 46* documentation and/or other materials provided with the distribution. 47* 48* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 49* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 50* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 51* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 52* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 53* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 54* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 55* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 56* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 57* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 58 59* Autogenerated from %s, do not modify. 60*/ 61 62""" 63 64asmCopyrightMsg = """# Copyright (C) 2014 Apple Inc. All rights reserved. 65# 66# Redistribution and use in source and binary forms, with or without 67# modification, are permitted provided that the following conditions 68# are met: 69# 70# 1. Redistributions of source code must retain the above copyright 71# notice, this list of conditions and the following disclaimer. 72# 2. Redistributions in binary form must reproduce the above copyright 73# notice, this list of conditions and the following disclaimer in the 74# documentation and/or other materials provided with the distribution. 75# 76# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 77# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 78# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 79# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 80# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 81# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 82# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 83# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 84# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 85# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 86 87# Autogenerated from %s, do not modify. 88 89""" 90def openOrExit(path, mode): 91 try: 92 return open(path, mode) 93 except IOError as e: 94 print "I/O error opening {0}, ({1}): {2}".format(path, e.errno, e.strerror) 95 exit(1) 96 97def hashFile(file): 98 sha1 = hashlib.sha1() 99 file.seek(0) 100 for line in file: 101 sha1.update(line) 102 103 file.seek(0) 104 105 return sha1.hexdigest() 106 107if __name__ == "__main__": 108 parser = optparse.OptionParser(usage = "usage: %prog [--bytecodes_h <FILE>] [--init_bytecodes_asm <FILE>] <bytecode-json-file>") 109 parser.add_option("-b", "--bytecodes_h", dest = "bytecodesHFileName", help = "generate bytecodes macro .h FILE", metavar = "FILE") 110 parser.add_option("-a", "--init_bytecodes_asm", dest = "initASMFileName", help="generate ASM bytecodes init FILE", metavar = "FILE") 111 (options, args) = parser.parse_args() 112 113 if len(args) != 1: 114 parser.error("missing <bytecode-json-file>") 115 116 bytecodeJSONFile = args[0] 117 bytecodeFile = openOrExit(bytecodeJSONFile, "rb") 118 sha1Hash = hashFile(bytecodeFile) 119 120 hFileHashString = "// SHA1Hash: {0}\n".format(sha1Hash) 121 asmFileHashString = "# SHA1Hash: {0}\n".format(sha1Hash) 122 123 bytecodeHFilename = options.bytecodesHFileName 124 initASMFileName = options.initASMFileName 125 126 if not bytecodeHFilename and not initASMFileName: 127 parser.print_help() 128 exit(0) 129 130 needToGenerate = False 131 132 if bytecodeHFilename: 133 try: 134 bytecodeHReadFile = open(bytecodeHFilename, "rb") 135 136 hashLine = bytecodeHReadFile.readline() 137 if hashLine != hFileHashString: 138 needToGenerate = True 139 except: 140 needToGenerate = True 141 else: 142 bytecodeHReadFile.close() 143 144 if initASMFileName: 145 try: 146 initBytecodesReadFile = open(initASMFileName, "rb") 147 148 hashLine = initBytecodesReadFile.readline() 149 if hashLine != asmFileHashString: 150 needToGenerate = True 151 except: 152 needToGenerate = True 153 else: 154 initBytecodesReadFile.close() 155 156 if not needToGenerate: 157 print "Nothing changed.\n" 158 exit(0) 159 160 genString = "Generating " 161 162 if bytecodeHFilename: 163 bytecodeHFile = openOrExit(bytecodeHFilename, "wb") 164 genString = genString + "{0} ".format(bytecodeHFilename) 165 166 if initASMFileName: 167 initBytecodesFile = openOrExit(initASMFileName, "wb") 168 if bytecodeHFilename: 169 genString = genString + "and " 170 genString = genString + "{0} ".format(initASMFileName) 171 172 print "{0}from {1}\n".format(genString, bytecodeJSONFile) 173 174 175 try: 176 bytecodeSections = json.load(bytecodeFile, encoding = "utf-8") 177 except: 178 print "Unexpected error parsing {0}: {1}".format(bytecodeJSONFile, sys.exc_info()) 179 180 if bytecodeHFilename: 181 bytecodeHFile.write(hFileHashString) 182 bytecodeHFile.write(cCopyrightMsg % bytecodeJSONFile) 183 bytecodeHFile.write("#ifndef Bytecodes_h\n") 184 bytecodeHFile.write("#define Bytecodes_h\n\n") 185 186 if initASMFileName: 187 initBytecodesFile.write(asmFileHashString) 188 initBytecodesFile.write(asmCopyrightMsg % bytecodeJSONFile) 189 initASMBytecodeNum = 0 190 191 for section in bytecodeSections: 192 if bytecodeHFilename and section['emitInHFile']: 193 bytecodeHFile.write("#define FOR_EACH_{0}_ID(macro) \\\n".format(section["macroNameComponent"])) 194 firstMacro = True 195 defaultLength = 1 196 if "defaultLength" in section: 197 defaultLength = section["defaultLength"] 198 199 bytecodeNum = 0 200 for bytecode in section["bytecodes"]: 201 if not firstMacro: 202 bytecodeHFile.write(" \\\n") 203 204 length = defaultLength 205 if "length" in bytecode: 206 length = bytecode["length"] 207 208 bytecodeHFile.write(" macro({0}, {1})".format(bytecode["name"], length)) 209 firstMacro = False 210 bytecodeNum = bytecodeNum + 1 211 212 bytecodeHFile.write("\n\n") 213 bytecodeHFile.write("#define NUMBER_OF_{0}_IDS {1}\n\n".format(section["macroNameComponent"], bytecodeNum)) 214 215 if initASMFileName and section['emitInASMFile']: 216 prefix = "" 217 if "asmPrefix" in section: 218 prefix = section["asmPrefix"] 219 for bytecode in section["bytecodes"]: 220 initBytecodesFile.write("setEntryAddress({0}, _{1}{2})\n".format(initASMBytecodeNum, prefix, bytecode["name"])) 221 initASMBytecodeNum = initASMBytecodeNum + 1 222 223 if bytecodeHFilename: 224 bytecodeHFile.write("#endif // Bytecodes_h\n") 225 bytecodeHFile.close() 226 227 if initASMFileName: 228 initBytecodesFile.close() 229 230 bytecodeFile.close() 231 232 exit(0) 233