tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GenerateBuiltinModules.py (5752B)


      1 import io
      2 
      3 import buildconfig
      4 import yaml
      5 from mozbuild.preprocessor import Preprocessor
      6 
      7 HEADER_TEMPLATE = """\
      8 /* This Source Code Form is subject to the terms of the Mozilla Public
      9 * License, v. 2.0. If a copy of the MPL was not distributed with this
     10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     11 
     12 #ifndef %(includeguard)s
     13 #define %(includeguard)s
     14 
     15 /* This file is generated by wasm/GenerateBuiltinModules.py. Do not edit! */
     16 
     17 %(contents)s
     18 
     19 #endif // %(includeguard)s
     20 """
     21 
     22 
     23 def generate_header(c_out, includeguard, contents):
     24    c_out.write(
     25        HEADER_TEMPLATE
     26        % {
     27            "includeguard": includeguard,
     28            "contents": contents,
     29        }
     30    )
     31 
     32 
     33 def load_yaml(yaml_path):
     34    # First invoke preprocessor.py so that we can use #ifdef JS_SIMULATOR in
     35    # the YAML file.
     36    pp = Preprocessor()
     37    pp.context.update(buildconfig.defines["ALLDEFINES"])
     38    pp.out = io.StringIO()
     39    pp.do_filter("substitution")
     40    pp.do_include(yaml_path)
     41    contents = pp.out.getvalue()
     42    return yaml.safe_load(contents)
     43 
     44 
     45 def cppBool(v):
     46    if v:
     47        return "true"
     48    return "false"
     49 
     50 
     51 def specTypeToMIRType(specType):
     52    if isinstance(specType, dict):
     53        return "MIRType::WasmAnyRef"
     54    if specType in {"i32", "i64", "f32", "f64"}:
     55        return f"ValType::{specType}().toMIRType()"
     56    if specType in {"externref", "anyref", "funcref", "exnref"}:
     57        return "MIRType::WasmAnyRef"
     58    raise ValueError()
     59 
     60 
     61 def specHeapTypeToTypeCode(specHeapType):
     62    if specHeapType == "func":
     63        return "Func"
     64    if specHeapType == "any":
     65        return "Any"
     66    if specHeapType == "extern":
     67        return "Extern"
     68    if specHeapType == "exn":
     69        return "Exn"
     70    if specHeapType == "array":
     71        return "Array"
     72    if specHeapType == "struct":
     73        return "Struct"
     74    raise ValueError()
     75 
     76 
     77 def specTypeToValType(specType):
     78    if isinstance(specType, dict):
     79        nullable = cppBool(specType["nullable"])
     80        if "type" in specType:
     81            ref = specType["type"]
     82            return f"ValType(RefType::fromTypeDef({ref}, {nullable}))"
     83        else:
     84            code = specType["code"]
     85            return f"ValType(RefType::fromTypeCode(TypeCode(RefType::{specHeapTypeToTypeCode(code)}), {nullable}))"
     86 
     87    if specType in {"i32", "i64", "f32", "f64"}:
     88        return f"ValType::{specType}()"
     89 
     90    if specType == "externref":
     91        return "ValType(RefType::extern_())"
     92 
     93    if specType == "exnref":
     94        return "ValType(RefType::exn())"
     95 
     96    if specType == "anyref":
     97        return "ValType(RefType::any())"
     98 
     99    if specType == "funcref":
    100        return "ValType(RefType::func())"
    101 
    102    raise ValueError()
    103 
    104 
    105 def failureTrap(op):
    106    if not "fail_trap" in op:
    107        if op["fail_mode"] == "Infallible":
    108            return "Limit"
    109        return "ThrowReported"
    110    return op["fail_trap"]
    111 
    112 
    113 def main(c_out, yaml_path):
    114    data = load_yaml(yaml_path)
    115 
    116    # Iterate for all defined builtin methods
    117    contents = "#define FOR_EACH_BUILTIN_MODULE_FUNC(M) \\\n"
    118    for i in range(len(data)):
    119        op = data[i]
    120        sa = op["symbolic_address"]
    121        inlineOp = "BuiltinInlineOp::None"
    122        if "inline_op" in op:
    123            inlineOp = f"BuiltinInlineOp::{op['inline_op']}"
    124        contents += (
    125            f'    M({op["op"]}, "{op["export"]}", '
    126            f"{sa['name']}, {sa['type']}, {cppBool(sa['needs_thunk'])}, {op['entry']}, {cppBool(op['uses_memory'])}, {inlineOp}, {i})\\\n"
    127        )
    128    contents += "\n"
    129 
    130    for op in data:
    131        # Define DECLARE_BUILTIN_MODULE_FUNC_PARAM_VALTYPES_<op> as:
    132        # `{ValType::I32, ValType::I32, ...}`.
    133        valTypes = ", ".join(specTypeToValType(p) for p in op["params"])
    134        contents += (
    135            f"#define DECLARE_BUILTIN_MODULE_FUNC_PARAM_VALTYPES_{op['op']} "
    136            f"{{{valTypes}}}\n"
    137        )
    138 
    139        # Define DECLARE_BUILTIN_MODULE_FUNC_PARAM_MIRTYPES_<op> as:
    140        # `<num_types>, {MIRType::Pointer, _I32, ..., MIRType::Pointer, _END}`.
    141        num_types = len(op["params"]) + 1
    142        mir_types = "{MIRType::Pointer"
    143        mir_types += "".join(", " + specTypeToMIRType(p) for p in op["params"])
    144        if op["uses_memory"]:
    145            mir_types += ", MIRType::Pointer"
    146            num_types += 1
    147        # Add the end marker
    148        mir_types += ", MIRType::None}"
    149 
    150        contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_PARAM_MIRTYPES_{op['op']} {num_types}, {mir_types}\n"
    151 
    152        # Define DECLARE_BUILTIN_MODULE_FUNC_RESULT_VALTYPE_<op> as:
    153        # `Some(X)` if present, or else `Nothing()`.
    154        result_valtype = ""
    155        if "result" in op:
    156            result_valtype = f"mozilla::Some({specTypeToValType(op['result'])})\n"
    157        else:
    158            result_valtype = "mozilla::Nothing()"
    159        contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_RESULT_VALTYPE_{op['op']} {result_valtype}\n"
    160 
    161        # Define DECLARE_BUILTIN_MODULE_FUNC_RESULT_MIRTYPE_<op> as:
    162        # `X` if present, or else `MIRType::None`.
    163        result_mirtype = ""
    164        if "result" in op:
    165            result_mirtype = specTypeToMIRType(op["result"]) + "\n"
    166        else:
    167            result_mirtype = "MIRType::None"
    168        contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_RESULT_MIRTYPE_{op['op']} {result_mirtype}\n"
    169 
    170        # Define DECLARE_BUILTIN_MODULE_FUNC_FAILMODE_<op> as:
    171        # `FailureMode::X`.
    172        contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_FAILMODE_{op['op']} FailureMode::{op['fail_mode']}\n"
    173 
    174        # Define DECLARE_BUILTIN_MODULE_FUNC_FAILTRAP_<op> as:
    175        # `Trap::X`.
    176        contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_FAILTRAP_{op['op']} Trap::{failureTrap(op)}\n"
    177 
    178    generate_header(c_out, "wasm_WasmBuiltinModuleGenerated_h", contents)