from collections import OrderedDict import buildconfig import six import yaml from mozbuild.preprocessor import Preprocessor HEADER_TEMPLATE = """\ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef %(includeguard)s #define %(includeguard)s /* This file is generated by wasm/GenerateInstrinsic.py. Do not edit! */ %(contents)s #endif // %(includeguard)s """ def generate_header(c_out, includeguard, contents): c_out.write( HEADER_TEMPLATE % { "includeguard": includeguard, "contents": contents, } ) def load_yaml(yaml_path): # First invoke preprocessor.py so that we can use #ifdef JS_SIMULATOR in # the YAML file. pp = Preprocessor() pp.context.update(buildconfig.defines["ALLDEFINES"]) pp.out = six.StringIO() pp.do_filter("substitution") pp.do_include(yaml_path) contents = pp.out.getvalue() # Load into an OrderedDict to ensure order is preserved. Note: Python 3.7+ # also preserves ordering for normal dictionaries. # Code based on https://stackoverflow.com/a/21912744. class OrderedLoader(yaml.Loader): pass def construct_mapping(loader, node): loader.flatten_mapping(node) return OrderedDict(loader.construct_pairs(node)) tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG OrderedLoader.add_constructor(tag, construct_mapping) return yaml.load(contents, OrderedLoader) def main(c_out, yaml_path): data = load_yaml(yaml_path) # Interate for all defined intrinsics contents = "#define FOR_EACH_INTRINSIC(M) \\\n" for i in range(len(data)): op = data[i] sa = op["symbolic_address"] contents += ( f" M({op['op']}, \"{op['export']}\", " f"{sa['name']}, {sa['type']}, {op['entry']}, {i})\\\n" ) contents += "\n" for op in data: # Define DECLARE_INTRINSIC_SAS_PARAM_VALTYPES_ as: # `{ValType::I32, ValType::I32, ...}`. contents += ( f"#define DECLARE_INTRINSIC_SAS_PARAM_VALTYPES_{op['op']} " f"{{ValType::{', ValType::'.join(op['params'])}}}\n" ) # Define DECLARE_INTRINSIC_PARAM_TYPES_ as: # `, {_PTR, _I32, ..., _PTR, _END}`. sas_types = f"{{_PTR{''.join(', _' + p for p in op['params'])}, _PTR, _END}}" num_types = len(op["params"]) + 2 contents += f"#define DECLARE_INTRINSIC_PARAM_TYPES_{op['op']} {num_types}, {sas_types}\n" generate_header(c_out, "wasm_WasmIntrinsicGenerated_h", contents)