feat: add a histrical wit-bindgen

This commit is contained in:
2023-01-01 00:25:48 +08:00
parent 01e8f5a959
commit aa50d63aec
419 changed files with 45283 additions and 1 deletions

View File

@@ -0,0 +1,18 @@
module.exports = {
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
// allow this since we generate `const {} = e;` for empty structs
"no-empty-pattern": 0,
// TODO: we generate some unused functions by accident, let's fix that later
"no-unused-vars": 0,
}
};

View File

@@ -0,0 +1,17 @@
[package]
name = "wit-bindgen-gen-js"
version = "0.1.0"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
edition = "2018"
[lib]
doctest = false
test = false
[dependencies]
wit-bindgen-gen-core = { path = '../gen-core', version = '0.1.0' }
heck = "0.3"
structopt = { version = "0.3", default-features = false, optional = true }
[dev-dependencies]
test-helpers = { path = '../test-helpers', features = ['wit-bindgen-gen-js'] }

View File

@@ -0,0 +1,4 @@
fn main() {
println!("cargo:rerun-if-changed=build.rs");
// this build script is currently only here so OUT_DIR is set for testing.
}

View File

@@ -0,0 +1,9 @@
{
"devDependencies": {
"@types/node": "^15.12.2",
"@typescript-eslint/eslint-plugin": "^4.27.0",
"@typescript-eslint/parser": "^4.27.0",
"eslint": "^7.28.0",
"typescript": "^4.3.2"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
use std::path::Path;
use std::process::Command;
mod exports {
test_helpers::codegen_js_export!(
// ...
"*.wit"
);
}
mod imports {
test_helpers::codegen_js_import!(
"*.wit"
// This uses buffers, which we don't support in imports just yet
// TODO: should support this
"!wasi-next.wit"
"!host.wit"
);
}
fn verify(dir: &str, name: &str) {
let (cmd, args) = if cfg!(windows) {
("cmd.exe", &["/c", "npx.cmd"] as &[&str])
} else {
("npx", &[] as &[&str])
};
let status = Command::new(cmd)
.args(args)
.arg("eslint")
.arg("-c")
.arg(".eslintrc.js")
.arg(Path::new(dir).join(&format!("{}.js", name)))
.status()
.unwrap();
assert!(status.success());
}

View File

@@ -0,0 +1,7 @@
export function getWasm(): Uint8Array;
export interface Wasi {
start(instance: WebAssembly.Instance): void;
}
export function addWasiToImports(importObj: any): Wasi;

View File

@@ -0,0 +1,26 @@
import { readFileSync } from 'fs';
import { WASI } from 'wasi';
export function getWasm() {
return readFileSync(process.argv[2]);
}
class MyWasi {
constructor(wasi) {
this.wasi = wasi;
}
start(instance) {
if ('_start' in instance.exports) {
this.wasi.start(instance);
} else {
this.wasi.initialize(instance);
}
}
}
export function addWasiToImports(importObj) {
const wasi = new WASI();
importObj.wasi_snapshot_preview1 = wasi.wasiImport;
return new MyWasi(wasi);
}

View File

@@ -0,0 +1,99 @@
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
use wit_bindgen_gen_core::Generator;
test_helpers::runtime_tests!("ts");
fn execute(name: &str, wasm: &Path, ts: &Path, imports: &Path, exports: &Path) {
let mut dir = PathBuf::from(env!("OUT_DIR"));
dir.push(name);
drop(fs::remove_dir_all(&dir));
fs::create_dir_all(&dir).unwrap();
println!("OUT_DIR = {:?}", dir);
println!("Generating bindings...");
// We call `generate_all` with exports from the imports.wit file, and
// imports from the exports.wit wit file. It's reversed because we're
// implementing the host side of these APIs.
let imports = wit_bindgen_gen_core::wit_parser::Interface::parse_file(imports).unwrap();
let exports = wit_bindgen_gen_core::wit_parser::Interface::parse_file(exports).unwrap();
let mut files = Default::default();
wit_bindgen_gen_js::Opts::default()
.build()
.generate_all(&[exports], &[imports], &mut files);
for (file, contents) in files.iter() {
fs::write(dir.join(file), contents).unwrap();
}
let (cmd, args) = if cfg!(windows) {
("cmd.exe", &["/c", "npx.cmd"] as &[&str])
} else {
("npx", &[] as &[&str])
};
fs::copy(ts, dir.join("host.ts")).unwrap();
fs::copy("tests/helpers.d.ts", dir.join("helpers.d.ts")).unwrap();
fs::copy("tests/helpers.js", dir.join("helpers.js")).unwrap();
let config = dir.join("tsconfig.json");
fs::write(
&config,
format!(
r#"
{{
"files": ["host.ts"],
"compilerOptions": {{
"module": "esnext",
"target": "es2020",
"strict": true,
"strictNullChecks": true,
"baseUrl": {0:?},
"outDir": {0:?}
}}
}}
"#,
dir,
),
)
.unwrap();
run(Command::new(cmd)
.args(args)
.arg("tsc")
.arg("--project")
.arg(&config));
// Currently there's mysterious uvwasi errors creating a `WASI` on Windows.
// Unsure what's happening so let's ignore these tests for now since there's
// not much Windows-specific here anyway.
if cfg!(windows) {
return;
}
fs::write(dir.join("package.json"), "{\"type\":\"module\"}").unwrap();
let mut path = Vec::new();
path.push(env::current_dir().unwrap());
path.push(dir.clone());
println!("{:?}", std::env::join_paths(&path));
run(Command::new("node")
.arg("--experimental-wasi-unstable-preview1")
.arg(dir.join("host.js"))
.env("NODE_PATH", std::env::join_paths(&path).unwrap())
.arg(wasm));
}
fn run(cmd: &mut Command) {
println!("running {:?}", cmd);
let output = cmd.output().expect("failed to executed");
println!("status: {}", output.status);
println!(
"stdout:\n {}",
String::from_utf8_lossy(&output.stdout).replace("\n", "\n ")
);
println!(
"stderr:\n {}",
String::from_utf8_lossy(&output.stderr).replace("\n", "\n ")
);
assert!(output.status.success());
}