feat: add a histrical wit-bindgen
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
invalid-u8: func()
|
||||
invalid-s8: func()
|
||||
invalid-u16: func()
|
||||
invalid-s16: func()
|
||||
invalid-char: func()
|
||||
invalid-bool: func()
|
||||
invalid-enum: func()
|
||||
invalid-handle: func()
|
||||
invalid-handle-close: func()
|
||||
@@ -0,0 +1,74 @@
|
||||
from exports.bindings import Exports
|
||||
from imports.bindings import add_imports_to_linker, Imports
|
||||
from typing import Callable
|
||||
import imports.bindings as i
|
||||
import sys
|
||||
import wasmtime
|
||||
|
||||
class MyImports(Imports):
|
||||
def roundtrip_u8(self, x: int) -> int:
|
||||
raise Exception('unreachable')
|
||||
|
||||
def roundtrip_s8(self, x: int) -> int:
|
||||
raise Exception('unreachable')
|
||||
|
||||
def roundtrip_u16(self, x: int) -> int:
|
||||
raise Exception('unreachable')
|
||||
|
||||
def roundtrip_s16(self, x: int) -> int:
|
||||
raise Exception('unreachable')
|
||||
|
||||
def roundtrip_bool(self, x: bool) -> bool:
|
||||
raise Exception('unreachable')
|
||||
|
||||
def roundtrip_char(self, x: str) -> str:
|
||||
raise Exception('unreachable')
|
||||
|
||||
def roundtrip_enum(self, x: i.E) -> i.E:
|
||||
raise Exception('unreachable')
|
||||
|
||||
def get_internal(self, x: i.HostState) -> int:
|
||||
raise Exception('unreachable')
|
||||
|
||||
def run(wasm_file: str) -> None:
|
||||
store = wasmtime.Store()
|
||||
module = wasmtime.Module.from_file(store.engine, wasm_file)
|
||||
linker = wasmtime.Linker(store.engine)
|
||||
linker.define_wasi()
|
||||
wasi = wasmtime.WasiConfig()
|
||||
wasi.inherit_stdout()
|
||||
wasi.inherit_stderr()
|
||||
store.set_wasi(wasi)
|
||||
|
||||
imports = MyImports()
|
||||
add_imports_to_linker(linker, store, imports)
|
||||
wasm = Exports(store, linker, module)
|
||||
|
||||
def assert_throws(f: Callable, msg: str) -> None:
|
||||
try:
|
||||
f()
|
||||
raise RuntimeError('expected exception')
|
||||
except TypeError as e:
|
||||
actual = str(e)
|
||||
except OverflowError as e:
|
||||
actual = str(e)
|
||||
except ValueError as e:
|
||||
actual = str(e)
|
||||
except IndexError as e:
|
||||
actual = str(e)
|
||||
if not msg in actual:
|
||||
print(actual)
|
||||
assert(msg in actual)
|
||||
|
||||
assert_throws(lambda: wasm.invalid_bool(store), 'invalid variant discriminant for bool')
|
||||
assert_throws(lambda: wasm.invalid_u8(store), 'must be between')
|
||||
assert_throws(lambda: wasm.invalid_s8(store), 'must be between')
|
||||
assert_throws(lambda: wasm.invalid_u16(store), 'must be between')
|
||||
assert_throws(lambda: wasm.invalid_s16(store), 'must be between')
|
||||
assert_throws(lambda: wasm.invalid_char(store), 'not a valid char')
|
||||
assert_throws(lambda: wasm.invalid_enum(store), 'not a valid E')
|
||||
assert_throws(lambda: wasm.invalid_handle(store), 'handle index not valid')
|
||||
assert_throws(lambda: wasm.invalid_handle_close(store), 'handle index not valid')
|
||||
|
||||
if __name__ == '__main__':
|
||||
run(sys.argv[1])
|
||||
@@ -0,0 +1,99 @@
|
||||
wit_bindgen_wasmtime::export!("../../tests/runtime/invalid/imports.wit");
|
||||
|
||||
use anyhow::Result;
|
||||
use imports::*;
|
||||
use wasmtime::Trap;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MyImports;
|
||||
|
||||
impl Imports for MyImports {
|
||||
type HostState = ();
|
||||
|
||||
fn roundtrip_u8(&mut self, _: u8) -> u8 {
|
||||
unreachable!()
|
||||
}
|
||||
fn roundtrip_s8(&mut self, _: i8) -> i8 {
|
||||
unreachable!()
|
||||
}
|
||||
fn roundtrip_u16(&mut self, _: u16) -> u16 {
|
||||
unreachable!()
|
||||
}
|
||||
fn roundtrip_s16(&mut self, _: i16) -> i16 {
|
||||
unreachable!()
|
||||
}
|
||||
fn roundtrip_char(&mut self, _: char) -> char {
|
||||
unreachable!()
|
||||
}
|
||||
fn roundtrip_bool(&mut self, _: bool) -> bool {
|
||||
unreachable!()
|
||||
}
|
||||
fn roundtrip_enum(&mut self, _: imports::E) -> imports::E {
|
||||
unreachable!()
|
||||
}
|
||||
fn get_internal(&mut self, _: &()) -> u32 {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
wit_bindgen_wasmtime::import!("../../tests/runtime/invalid/exports.wit");
|
||||
|
||||
fn run(wasm: &str) -> Result<()> {
|
||||
use exports::*;
|
||||
|
||||
let (exports, mut store) = crate::instantiate(
|
||||
wasm,
|
||||
|linker| {
|
||||
imports::add_to_linker(
|
||||
linker,
|
||||
|cx: &mut crate::Context<(MyImports, imports::ImportsTables<MyImports>), _>| {
|
||||
(&mut cx.imports.0, &mut cx.imports.1)
|
||||
},
|
||||
)
|
||||
},
|
||||
|store, module, linker| Exports::instantiate(store, module, linker, |cx| &mut cx.exports),
|
||||
)?;
|
||||
|
||||
assert_err(
|
||||
exports.invalid_bool(&mut store),
|
||||
"invalid discriminant for `bool`",
|
||||
)?;
|
||||
assert_err(
|
||||
exports.invalid_u8(&mut store),
|
||||
"out-of-bounds integer conversion",
|
||||
)?;
|
||||
assert_err(
|
||||
exports.invalid_s8(&mut store),
|
||||
"out-of-bounds integer conversion",
|
||||
)?;
|
||||
assert_err(
|
||||
exports.invalid_u16(&mut store),
|
||||
"out-of-bounds integer conversion",
|
||||
)?;
|
||||
assert_err(
|
||||
exports.invalid_s16(&mut store),
|
||||
"out-of-bounds integer conversion",
|
||||
)?;
|
||||
assert_err(
|
||||
exports.invalid_char(&mut store),
|
||||
"char value out of valid range",
|
||||
)?;
|
||||
assert_err(
|
||||
exports.invalid_enum(&mut store),
|
||||
"invalid discriminant for `E`",
|
||||
)?;
|
||||
assert_err(exports.invalid_handle(&mut store), "invalid handle index")?;
|
||||
assert_err(
|
||||
exports.invalid_handle_close(&mut store),
|
||||
"invalid handle index",
|
||||
)?;
|
||||
return Ok(());
|
||||
|
||||
fn assert_err(result: Result<(), Trap>, err: &str) -> Result<()> {
|
||||
match result {
|
||||
Ok(()) => anyhow::bail!("export didn't trap"),
|
||||
Err(e) if e.to_string().contains(err) => Ok(()),
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { addImportsToImports, Imports } from "./imports.js";
|
||||
import { Exports } from "./exports.js";
|
||||
import { getWasm, addWasiToImports } from "./helpers.js";
|
||||
// @ts-ignore
|
||||
import * as assert from 'assert';
|
||||
|
||||
async function run() {
|
||||
const importObj = {};
|
||||
const imports: Imports = {
|
||||
roundtripU8(x) { throw new Error('unreachable'); },
|
||||
roundtripS8(x) { throw new Error('unreachable'); },
|
||||
roundtripU16(x) { throw new Error('unreachable'); },
|
||||
roundtripS16(x) { throw new Error('unreachable'); },
|
||||
roundtripBool(x) { throw new Error('unreachable'); },
|
||||
roundtripChar(x) { throw new Error('unreachable'); },
|
||||
roundtripEnum(x) { throw new Error('unreachable'); },
|
||||
getInternal(x) { throw new Error('unreachable'); },
|
||||
};
|
||||
let instance: WebAssembly.Instance;
|
||||
addImportsToImports(importObj, imports);
|
||||
const wasi = addWasiToImports(importObj);
|
||||
|
||||
const wasm = new Exports();
|
||||
await wasm.instantiate(getWasm(), importObj);
|
||||
wasi.start(wasm.instance);
|
||||
instance = wasm.instance;
|
||||
|
||||
assert.throws(() => wasm.invalidBool(), /invalid variant discriminant for bool/);
|
||||
assert.throws(() => wasm.invalidU8(), /must be between/);
|
||||
assert.throws(() => wasm.invalidS8(), /must be between/);
|
||||
assert.throws(() => wasm.invalidU16(), /must be between/);
|
||||
assert.throws(() => wasm.invalidS16(), /must be between/);
|
||||
assert.throws(() => wasm.invalidChar(), /not a valid char/);
|
||||
assert.throws(() => wasm.invalidEnum(), /invalid discriminant specified for E/);
|
||||
assert.throws(() => wasm.invalidHandle(), /handle index not valid/);
|
||||
assert.throws(() => wasm.invalidHandleClose(), /handle index not valid/);
|
||||
}
|
||||
|
||||
await run()
|
||||
@@ -0,0 +1,13 @@
|
||||
roundtrip-u8: func(a: u8) -> u8
|
||||
roundtrip-s8: func(a: s8) -> s8
|
||||
roundtrip-u16: func(a: u16) -> u16
|
||||
roundtrip-s16: func(a: s16) -> s16
|
||||
roundtrip-char: func(a: char) -> char
|
||||
|
||||
enum e { a, b, c }
|
||||
roundtrip-enum: func(a: e) -> e
|
||||
|
||||
roundtrip-bool: func(a: bool) -> bool
|
||||
|
||||
resource host-state
|
||||
get-internal: func(a: host-state) -> u32
|
||||
@@ -0,0 +1,88 @@
|
||||
wit_bindgen_rust::export!("../../tests/runtime/invalid/exports.wit");
|
||||
|
||||
#[link(wasm_import_module = "imports")]
|
||||
extern "C" {
|
||||
#[link_name = "roundtrip-bool"]
|
||||
fn roundtrip_bool(a: i32) -> i32;
|
||||
#[link_name = "roundtrip-u16"]
|
||||
fn roundtrip_u16(a: i32) -> i32;
|
||||
#[link_name = "roundtrip-u8"]
|
||||
fn roundtrip_u8(a: i32) -> i32;
|
||||
#[link_name = "roundtrip-s16"]
|
||||
fn roundtrip_s16(a: i32) -> i32;
|
||||
#[link_name = "roundtrip-s8"]
|
||||
fn roundtrip_s8(a: i32) -> i32;
|
||||
#[link_name = "roundtrip-char"]
|
||||
fn roundtrip_char(a: i32) -> i32;
|
||||
#[link_name = "roundtrip-enum"]
|
||||
fn roundtrip_enum(a: i32) -> i32;
|
||||
#[link_name = "get-internal"]
|
||||
fn get_internal(a: i32) -> i32;
|
||||
}
|
||||
|
||||
#[link(wasm_import_module = "canonical_abi")]
|
||||
extern "C" {
|
||||
#[link_name = "resource_drop_host-state"]
|
||||
fn resource_drop_host_state(a: i32);
|
||||
}
|
||||
|
||||
struct Exports;
|
||||
|
||||
impl exports::Exports for Exports {
|
||||
fn invalid_u8() {
|
||||
unsafe {
|
||||
roundtrip_u8(i32::MAX);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
fn invalid_s8() {
|
||||
unsafe {
|
||||
roundtrip_s8(i32::MAX);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
fn invalid_u16() {
|
||||
unsafe {
|
||||
roundtrip_u16(i32::MAX);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
fn invalid_s16() {
|
||||
unsafe {
|
||||
roundtrip_s16(i32::MAX);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
fn invalid_char() {
|
||||
unsafe {
|
||||
roundtrip_char(0xd800);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
fn invalid_bool() {
|
||||
unsafe {
|
||||
roundtrip_bool(2);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
fn invalid_enum() {
|
||||
unsafe {
|
||||
roundtrip_enum(400);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
fn invalid_handle() {
|
||||
unsafe {
|
||||
get_internal(100);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
fn invalid_handle_close() {
|
||||
unsafe {
|
||||
resource_drop_host_state(100);
|
||||
}
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user