WebAssembly: validate load / store alignment
[WebKit-https.git] / Source / JavaScriptCore / wasm / generateWasm.py
1 #! /usr/bin/python
2
3 # Copyright (C) 2016-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 has a couple of helpful macros to process Wasm files from the wasm.json.
27
28 import json
29 import math
30 import re
31
32 class Wasm:
33     def __init__(self, scriptName, jsonPath):
34         wasmFile = open(jsonPath, "r")
35         wasm = json.load(open(jsonPath, "r"))
36         wasmFile.close()
37         for pre in wasm["preamble"]:
38             if pre["name"] == "version":
39                 self.expectedVersionNumber = str(pre["value"])
40         self.preamble = wasm["preamble"]
41         self.types = wasm["type"]
42         self.opcodes = wasm["opcode"]
43         self.header = """/*
44  * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions
48  * are met:
49  *
50  * 1.  Redistributions of source code must retain the above copyright
51  *     notice, this list of conditions and the following disclaimer.
52  * 2.  Redistributions in binary form must reproduce the above copyright
53  *     notice, this list of conditions and the following disclaimer in the
54  *     documentation and/or other materials provided with the distribution.
55  *
56  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
57  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
60  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
65  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66  */
67
68 // DO NO EDIT! - This file was generated by """ + scriptName
69
70     def opcodeIterator(self, filter, ret=None):
71         # We need to do this because python is dumb and won't let me use self in the lambda, which is ridiculous.
72         if ret == None:
73             ret = lambda op: {"name": op, "opcode": self.opcodes[op]}
74         for op in self.opcodes.iterkeys():
75             if filter(self.opcodes[op]):
76                 yield ret(op)
77
78     def toCpp(self, name):
79         camelCase = re.sub(r'([^a-z0-9].)', lambda c: c.group(0)[1].upper(), name)
80         CamelCase = camelCase[:1].upper() + camelCase[1:]
81         return CamelCase
82
83
84 def isNormal(op):
85     return op["category"] == "arithmetic" or op["category"] == "comparison" or op["category"] == "conversion"
86
87
88 def isUnary(op):
89     return isNormal(op) and len(op["parameter"]) == 1
90
91
92 def isBinary(op):
93     return isNormal(op) and len(op["parameter"]) == 2
94
95
96 def isSimple(op):
97     return "b3op" in op
98
99
100 def memoryLog2Alignment(op):
101     assert op["opcode"]["category"] == "memory"
102     match = re.match(r'^[if]([36][24])\.[^0-9]+([0-9]+)?_?[us]?$', op["name"])
103     memoryBits = int(match.group(2) if match.group(2) else match.group(1))
104     assert 2 ** math.log(memoryBits, 2) == memoryBits
105     return str(int(math.log(memoryBits, 2)))