ladybird/Libraries/LibWasm/Rust/build.rs
Andreas Kling f22dec54ef LibWasm: Store opcodes in 32 bits
Wasm opcodes only need one byte plus a 24-bit selector for
prefixed instructions. Store them in u32 instead of u64 and reject
selectors that would not fit. Update the Rust opcode generator to
accept the new integer suffixes used by Opcode.h.
2026-05-14 12:19:38 +02:00

66 lines
2 KiB
Rust

/*
* Copyright (c) 2026-present, the Ladybird developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
use std::env;
use std::error::Error;
use std::fmt::Write;
use std::path::{Path, PathBuf};
fn generate_opcodes(manifest_dir: &Path, out_dir: &Path) -> Result<(), Box<dyn Error>> {
let opcode_h = manifest_dir.join("../Opcode.h");
println!("cargo:rerun-if-changed={}", opcode_h.display());
let contents = std::fs::read_to_string(&opcode_h)?;
let mut output = String::new();
// Grab name and value from _M(name, value, pops, pushes)_ lines
let re = regex::Regex::new(r"M\(\s*(\w+)\s*,\s*(0x[0-9a-fA-F]+)(?:[uUlL]+)?\s*,")?;
for cap in re.captures_iter(&contents) {
let cpp_name = &cap[1];
let value = &cap[2];
// Drop "structured_" and trailing underscrores, then uppercase the whole thing.
let mut name = cpp_name.to_string();
if let Some(stripped) = name.strip_prefix("structured_") {
name = stripped.to_string();
}
if let Some(stripped) = name.strip_suffix('_') {
name = stripped.to_string();
}
let name = name.to_uppercase();
writeln!(output, "pub const {name}: u64 = {value};")?;
}
std::fs::write(out_dir.join("opcodes.rs"), output)?;
Ok(())
}
fn main() -> Result<(), Box<dyn Error>> {
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=cbindgen.toml");
generate_opcodes(&manifest_dir, &out_dir)?;
let ffi_out_dir = env::var("FFI_OUTPUT_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| out_dir.clone());
cbindgen::generate(manifest_dir).map_or_else(
|error| match error {
cbindgen::Error::ParseSyntaxError { .. } => {}
e => panic!("{e:?}"),
},
|bindings| {
bindings.write_to_file(ffi_out_dir.join("CraneliftFFI.h"));
},
);
Ok(())
}