Implement a faster Interpreter::getOpcodeID().
[WebKit-https.git] / Source / JavaScriptCore / generate-bytecode-files
1 #! /usr/bin/python
2
3 # Copyright (C) 2014-2017 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
28 import hashlib
29 import json
30 import optparse
31 import os
32 import re
33 import sys
34
35 cCopyrightMsg = """/*
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
64 asmCopyrightMsg = """# 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 """
90 def 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
97 def 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
107 if __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         exit(0)
158
159     if bytecodeHFilename:
160         bytecodeHFile = openOrExit(bytecodeHFilename, "wb")
161
162     if initASMFileName:
163         initBytecodesFile = openOrExit(initASMFileName, "wb")
164
165     try:
166         bytecodeSections = json.load(bytecodeFile, encoding = "utf-8")
167     except:
168         print "Unexpected error parsing {0}: {1}".format(bytecodeJSONFile, sys.exc_info())
169
170     if bytecodeHFilename:
171         bytecodeHFile.write(hFileHashString)
172         bytecodeHFile.write(cCopyrightMsg % bytecodeJSONFile)
173         bytecodeHFile.write("#pragma once\n\n")
174
175     if initASMFileName:
176         initBytecodesFile.write(asmFileHashString)
177         initBytecodesFile.write(asmCopyrightMsg % bytecodeJSONFile)
178         initASMBytecodeNum = 0
179
180     for section in bytecodeSections:
181         if bytecodeHFilename and section['emitInHFile']:
182             bytecodeHFile.write("#define FOR_EACH_{0}_ID(macro) \\\n".format(section["macroNameComponent"]))
183             firstMacro = True
184             defaultLength = 1
185             if "defaultLength" in section:
186                 defaultLength = section["defaultLength"]
187
188             bytecodeNum = 0
189             for bytecode in section["bytecodes"]:
190                 if not firstMacro:
191                     bytecodeHFile.write(" \\\n")
192
193                 length = defaultLength
194                 if "length" in bytecode:
195                     length = bytecode["length"]
196
197                 bytecodeHFile.write("    macro({0}, {1})".format(bytecode["name"], length))
198                 firstMacro = False
199                 bytecodeNum = bytecodeNum + 1
200
201             bytecodeHFile.write("\n\n")
202             bytecodeHFile.write("#define NUMBER_OF_{0}_IDS {1}\n\n".format(section["macroNameComponent"], bytecodeNum))
203
204         if bytecodeHFilename and section['emitOpcodeIDStringValuesInHFile']:
205             bytecodeNum = 0
206             for bytecode in section["bytecodes"]:
207                 bytecodeHFile.write("#define {0}_value_string \"{1}\"\n".format(bytecode["name"], bytecodeNum))
208                 firstMacro = False
209                 bytecodeNum = bytecodeNum + 1
210
211             bytecodeHFile.write("\n")            
212
213         if initASMFileName and section['emitInASMFile']:
214             prefix = ""
215             if "asmPrefix" in section:
216                 prefix = section["asmPrefix"]
217             for bytecode in section["bytecodes"]:
218                 initBytecodesFile.write("setEntryAddress({0}, _{1}{2})\n".format(initASMBytecodeNum, prefix, bytecode["name"]))
219                 initASMBytecodeNum = initASMBytecodeNum + 1
220
221     if bytecodeHFilename:
222         bytecodeHFile.close()
223
224     if initASMFileName:
225         initBytecodesFile.close()
226
227     bytecodeFile.close()
228
229     exit(0)