Source code

Revision control

Copy as Markdown

Other Tools

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/GenerateBuiltinModules.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()
return yaml.safe_load(contents)
def cppBool(v):
if v:
return "true"
return "false"
def specTypeToMIRType(specType):
if specType == "i32" or specType == "i64" or specType == "f32" or specType == "f64":
return f"ValType::{specType}().toMIRType()"
if (
specType == "externref"
or specType == "anyref"
or specType == "funcref"
or isinstance(specType, dict)
):
return "MIRType::WasmAnyRef"
raise ValueError()
def specHeapTypeToTypeCode(specHeapType):
if specHeapType == "func":
return "Func"
if specHeapType == "any":
return "Any"
if specHeapType == "extern":
return "Extern"
if specHeapType == "array":
return "Array"
if specHeapType == "struct":
return "Struct"
raise ValueError()
def specTypeToValType(specType):
if specType == "i32" or specType == "i64" or specType == "f32" or specType == "f64":
return f"ValType::{specType}()"
if specType == "externref":
return "ValType(RefType::extern_())"
if specType == "anyref":
return "ValType(RefType::any())"
if specType == "funcref":
return "ValType(RefType::func())"
if isinstance(specType, dict):
nullable = cppBool(specType["nullable"])
if "type" in specType:
ref = specType["type"]
return f"ValType(RefType::fromTypeDef({ref}, {nullable}))"
else:
code = specType["code"]
return f"ValType(RefType::fromTypeCode(TypeCode(RefType::{specHeapTypeToTypeCode(code)}), {nullable}))"
raise ValueError()
def main(c_out, yaml_path):
data = load_yaml(yaml_path)
# Iterate for all defined builtin methods
contents = "#define FOR_EACH_BUILTIN_MODULE_FUNC(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']}, {cppBool(op['uses_memory'])}, {i})\\\n"
)
contents += "\n"
for op in data:
# Define DECLARE_BUILTIN_MODULE_FUNC_PARAM_VALTYPES_<op> as:
# `{ValType::I32, ValType::I32, ...}`.
valTypes = ", ".join(specTypeToValType(p) for p in op["params"])
contents += (
f"#define DECLARE_BUILTIN_MODULE_FUNC_PARAM_VALTYPES_{op['op']} "
f"{{{valTypes}}}\n"
)
# Define DECLARE_BUILTIN_MODULE_FUNC_PARAM_MIRTYPES_<op> as:
# `<num_types>, {MIRType::Pointer, _I32, ..., MIRType::Pointer, _END}`.
num_types = len(op["params"]) + 1
mir_types = "{MIRType::Pointer"
mir_types += "".join(", " + specTypeToMIRType(p) for p in op["params"])
if op["uses_memory"]:
mir_types += ", MIRType::Pointer"
num_types += 1
# Add the end marker
mir_types += ", MIRType::None}"
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_PARAM_MIRTYPES_{op['op']} {num_types}, {mir_types}\n"
# Define DECLARE_BUILTIN_MODULE_FUNC_RESULT_VALTYPE_<op> as:
# `Some(X)` if present, or else `Nothing()`.
result_valtype = ""
if "result" in op:
result_valtype = f"Some({specTypeToValType(op['result'])})\n"
else:
result_valtype = "Nothing()"
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_RESULT_VALTYPE_{op['op']} {result_valtype}\n"
# Define DECLARE_BUILTIN_MODULE_FUNC_RESULT_MIRTYPE_<op> as:
# `X` if present, or else `MIRType::None`.
result_mirtype = ""
if "result" in op:
result_mirtype = specTypeToMIRType(op["result"]) + "\n"
else:
result_mirtype = "MIRType::None"
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_RESULT_MIRTYPE_{op['op']} {result_mirtype}\n"
# Define DECLARE_BUILTIN_MODULE_FUNC_FAILMODE_<op> as:
# `FailureMode::X`.
contents += f"#define DECLARE_BUILTIN_MODULE_FUNC_FAILMODE_{op['op']} FailureMode::{op['fail_mode']}\n"
generate_header(c_out, "wasm_WasmBuiltinModuleGenerated_h", contents)