| #!/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. | 
 |  | 
 | from generateWasm import * | 
 | import optparse | 
 | import sys | 
 |  | 
 | parser = optparse.OptionParser(usage="usage: %prog <wasm.json> <WasmOps.h>") | 
 | (options, args) = parser.parse_args(sys.argv[0:]) | 
 | if len(args) != 3: | 
 |     parser.error(parser.usage) | 
 |  | 
 | wasm = Wasm(args[0], args[1]) | 
 | opcodes = wasm.opcodes | 
 | wasmValidateInlinesHFile = open(args[2], "w") | 
 |  | 
 |  | 
 | def cppType(name): | 
 |     result = { | 
 |         "bool": "I32", | 
 |         "addr": "I32", | 
 |         "i32": "I32", | 
 |         "i64": "I64", | 
 |         "f32": "F32", | 
 |         "f64": "F64", | 
 |     }.get(name, None) | 
 |     if result == None: | 
 |         raise ValueError("Unknown type name: " + name) | 
 |     return result | 
 |  | 
 |  | 
 | def toCpp(name): | 
 |     return wasm.toCpp(name) | 
 |  | 
 |  | 
 | def unaryMacro(name): | 
 |     op = opcodes[name] | 
 |     return """ | 
 | template<> auto Validate::addOp<OpType::""" + toCpp(name) + """>(ExpressionType value, ExpressionType& result) -> Result | 
 | { | 
 |     if (UNLIKELY(value != """ + cppType(op["parameter"][0]) + """)) | 
 |         return Unexpected<Result::error_type>("validation failed: """ + name + """ value type mismatch"); | 
 |  | 
 |     result = """ + cppType(op["return"][0]) + """; | 
 |     return { }; | 
 | } | 
 | """ | 
 |  | 
 |  | 
 | def binaryMacro(name): | 
 |     op = opcodes[name] | 
 |     return """ | 
 | template<> auto Validate::addOp<OpType::""" + toCpp(name) + """>(ExpressionType left, ExpressionType right, ExpressionType& result) -> Result | 
 | { | 
 |     if (UNLIKELY(left != """ + cppType(op["parameter"][0]) + """)) | 
 |         return Unexpected<Result::error_type>("validation failed: """ + name + """ left value type mismatch"); | 
 |  | 
 |     if (UNLIKELY(right != """ + cppType(op["parameter"][1]) + """)) | 
 |         return Unexpected<Result::error_type>("validation failed: """ + name + """ right value type mismatch"); | 
 |  | 
 |     result = """ + cppType(op["return"][0]) + """; | 
 |     return { }; | 
 | } | 
 | """ | 
 |  | 
 | def loadMacro(name): | 
 |     op = opcodes[name] | 
 |     return """ | 
 |     case LoadOpType::""" + toCpp(name) + """: { | 
 |         if (UNLIKELY(pointer != """ + cppType(op["parameter"][0]) + """)) | 
 |             return Unexpected<Result::error_type>("validation failed: """ + name + """ pointer type mismatch"); | 
 |  | 
 |         result = """ + cppType(op["return"][0]) + """; | 
 |         return { }; | 
 |     }""" | 
 |  | 
 |  | 
 | def storeMacro(name): | 
 |     op = opcodes[name] | 
 |     return """ | 
 |     case StoreOpType::""" + toCpp(name) + """: { | 
 |         if (UNLIKELY(pointer != """ + cppType(op["parameter"][0]) + """)) | 
 |             return Unexpected<Result::error_type>("validation failed: """ + name + """ pointer type mismatch"); | 
 |  | 
 |         if (UNLIKELY(value != """ + cppType(op["parameter"][1]) + """)) | 
 |             return Unexpected<Result::error_type>("validation failed: """ + name + """ value type mismatch"); | 
 |  | 
 |         return { }; | 
 |     }""" | 
 |  | 
 |  | 
 | unarySpecializations = "".join([op for op in wasm.opcodeIterator(isUnary, unaryMacro)]) | 
 | binarySpecializations = "".join([op for op in wasm.opcodeIterator(isBinary, binaryMacro)]) | 
 | loadCases = "".join([op for op in wasm.opcodeIterator(lambda op: op["category"] == "memory" and len(op["return"]) == 1, loadMacro)]) | 
 | storeCases = "".join([op for op in wasm.opcodeIterator(lambda op: op["category"] == "memory" and len(op["return"]) == 0, storeMacro)]) | 
 |  | 
 | contents = wasm.header + """ | 
 | // This file is intended to be inlined by WasmValidate.cpp only! It should not be included elsewhere. | 
 |  | 
 | #pragma once | 
 |  | 
 | #if ENABLE(WEBASSEMBLY) | 
 |  | 
 | #include <wtf/StdLibExtras.h> | 
 |  | 
 | #if ASSERT_DISABLED | 
 | IGNORE_RETURN_TYPE_WARNINGS_BEGIN | 
 | #endif | 
 |  | 
 | namespace JSC { namespace Wasm { | 
 |  | 
 | """ + unarySpecializations + binarySpecializations + """ | 
 |  | 
 | auto Validate::load(LoadOpType op, ExpressionType pointer, ExpressionType& result, uint32_t) -> Result | 
 | { | 
 |     if (UNLIKELY(!hasMemory())) | 
 |         return Unexpected<Result::error_type>("validation failed: load instruction without memory"); | 
 |  | 
 |     switch (op) { | 
 | """ + loadCases + """ | 
 |     } | 
 |     ASSERT_NOT_REACHED(); | 
 | } | 
 |  | 
 | auto Validate::store(StoreOpType op, ExpressionType pointer, ExpressionType value, uint32_t) -> Result | 
 | { | 
 |     if (UNLIKELY(!hasMemory())) | 
 |         return Unexpected<Result::error_type>("validation failed: store instruction without memory"); | 
 |  | 
 |     switch (op) { | 
 | """ + storeCases + """ | 
 |     } | 
 |     ASSERT_NOT_REACHED(); | 
 | } | 
 |  | 
 | } } // namespace JSC::Wasm | 
 |  | 
 | #if ASSERT_DISABLED | 
 | IGNORE_RETURN_TYPE_WARNINGS_END | 
 | #endif | 
 |  | 
 | #endif // ENABLE(WEBASSEMBLY) | 
 |  | 
 | """ | 
 |  | 
 | wasmValidateInlinesHFile.write(contents) | 
 | wasmValidateInlinesHFile.close() |