#! /usr/bin/env python # Copyright (C) 2016-2017 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This tool has a couple of helpful macros to process Wasm files from the wasm.json. import json import math import re class Wasm: def __init__(self, scriptName, jsonPath): wasmFile = open(jsonPath, "r") wasm = json.load(open(jsonPath, "r")) wasmFile.close() for pre in wasm["preamble"]: if pre["name"] == "version": self.expectedVersionNumber = str(pre["value"]) self.preamble = wasm["preamble"] self.types = wasm["type"] self.opcodes = wasm["opcode"] self.header = """/* * Copyright (C) 2016-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // DO NO EDIT! - This file was generated by """ + scriptName def opcodeIterator(self, filter, ret=None): # We need to do this because python is dumb and won't let me use self in the lambda, which is ridiculous. if ret == None: ret = lambda op: {"name": op, "opcode": self.opcodes[op]} for op in self.opcodes.keys(): if filter(self.opcodes[op]): yield ret(op) def toCpp(self, name): camelCase = re.sub(r'([^a-z0-9].)', lambda c: c.group(0)[1].upper(), name) CamelCase = camelCase[:1].upper() + camelCase[1:] return CamelCase def isNormal(op): return op["category"] == "arithmetic" or op["category"] == "comparison" or op["category"] == "conversion" def isUnary(op): return isNormal(op) and len(op["parameter"]) == 1 def isBinary(op): return isNormal(op) and len(op["parameter"]) == 2 def isSimple(op): return "b3op" in op def memoryLog2Alignment(op): assert op["opcode"]["category"] == "memory" match = re.match(r'^[if]([36][24])\.[^0-9]+([0-9]+)?_?[us]?$', op["name"]) memoryBits = int(match.group(2) if match.group(2) else match.group(1)) assert 2 ** math.log(memoryBits, 2) == memoryBits return str(int(math.log(memoryBits / 8, 2)))