#! /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.iterkeys():
            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)))
