feat: add a histrical wit-bindgen
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
test-imports: func()
|
||||
|
||||
resource wasm-state
|
||||
resource wasm-state2
|
||||
|
||||
wasm-state-create: func() -> wasm-state
|
||||
wasm-state-get-val: func(a: wasm-state) -> u32
|
||||
|
||||
wasm-state2-create: func() -> wasm-state2
|
||||
wasm-state2-saw-close: func() -> bool
|
||||
two-wasm-states: func(a: wasm-state, b: wasm-state2) -> tuple<wasm-state, wasm-state2>
|
||||
|
||||
record wasm-state-param-record { a: wasm-state2 }
|
||||
wasm-state2-param-record: func(a: wasm-state-param-record)
|
||||
|
||||
type wasm-state-param-tuple = tuple<wasm-state2>
|
||||
wasm-state2-param-tuple: func(a: wasm-state-param-tuple)
|
||||
|
||||
type wasm-state-param-option = option<wasm-state2>
|
||||
wasm-state2-param-option: func(a: wasm-state-param-option)
|
||||
|
||||
type wasm-state-param-result = expected<wasm-state2, u32>
|
||||
wasm-state2-param-result: func(a: wasm-state-param-result)
|
||||
|
||||
union wasm-state-param-variant { wasm-state2, u32 }
|
||||
wasm-state2-param-variant: func(a: wasm-state-param-variant)
|
||||
|
||||
wasm-state2-param-list: func(a: list<wasm-state2>)
|
||||
|
||||
|
||||
record wasm-state-result-record { a: wasm-state2 }
|
||||
wasm-state2-result-record: func() -> wasm-state-result-record
|
||||
|
||||
type wasm-state-result-tuple = tuple<wasm-state2>
|
||||
wasm-state2-result-tuple: func() -> wasm-state-result-tuple
|
||||
|
||||
type wasm-state-result-option = option<wasm-state2>
|
||||
wasm-state2-result-option: func() -> wasm-state-result-option
|
||||
|
||||
type wasm-state-result-result = expected<wasm-state2, u32>
|
||||
wasm-state2-result-result: func() -> wasm-state-result-result
|
||||
|
||||
union wasm-state-result-variant { wasm-state2, u32 }
|
||||
wasm-state2-result-variant: func() -> wasm-state-result-variant
|
||||
|
||||
wasm-state2-result-list: func() -> list<wasm-state2>
|
||||
|
||||
resource markdown {
|
||||
static create: func() -> option<markdown>
|
||||
append: func(buf: string)
|
||||
render: func() -> string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
from dataclasses import dataclass
|
||||
from exports.bindings import Exports
|
||||
from imports.bindings import add_imports_to_linker, Imports
|
||||
from typing import Tuple, List
|
||||
import exports.bindings as e
|
||||
import imports.bindings as i
|
||||
import sys
|
||||
import wasmtime
|
||||
|
||||
@dataclass
|
||||
class HostState(i.HostState):
|
||||
val: int
|
||||
|
||||
def __init__(self, val: int) -> None:
|
||||
self.val = val
|
||||
|
||||
|
||||
HOST_STATE2_CLOSED = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class HostState2(i.HostState2):
|
||||
val: int
|
||||
|
||||
def __init__(self, val: int) -> None:
|
||||
self.val = val
|
||||
|
||||
def drop(self) -> None:
|
||||
global HOST_STATE2_CLOSED
|
||||
HOST_STATE2_CLOSED = True
|
||||
|
||||
|
||||
@dataclass
|
||||
class Markdown(i.Markdown2):
|
||||
buf: str = ''
|
||||
|
||||
def append(self, data: str) -> None:
|
||||
self.buf += data
|
||||
|
||||
def render(self) -> str:
|
||||
return self.buf.replace('red', 'green')
|
||||
|
||||
|
||||
class OddName(i.OddName):
|
||||
def frob_the_odd(self) -> None:
|
||||
pass
|
||||
|
||||
|
||||
class MyImports:
|
||||
def host_state_create(self) -> i.HostState:
|
||||
return HostState(100)
|
||||
|
||||
def host_state_get(self, a: i.HostState) -> int:
|
||||
assert(isinstance(a, HostState))
|
||||
return a.val
|
||||
|
||||
def host_state2_create(self) -> i.HostState2:
|
||||
return HostState2(101)
|
||||
|
||||
def host_state2_saw_close(self) -> bool:
|
||||
return HOST_STATE2_CLOSED
|
||||
|
||||
def two_host_states(self, a: i.HostState, b: i.HostState2) -> Tuple[i.HostState, i.HostState2]:
|
||||
return (b, a)
|
||||
|
||||
def host_state2_param_record(self, a: i.HostStateParamRecord) -> None:
|
||||
pass
|
||||
|
||||
def host_state2_param_tuple(self, a: i.HostStateParamTuple) -> None:
|
||||
pass
|
||||
|
||||
def host_state2_param_option(self, a: i.HostStateParamOption) -> None:
|
||||
pass
|
||||
|
||||
def host_state2_param_result(self, a: i.HostStateParamResult) -> None:
|
||||
pass
|
||||
|
||||
def host_state2_param_variant(self, a: i.HostStateParamVariant) -> None:
|
||||
pass
|
||||
|
||||
def host_state2_param_list(self, a: List[i.HostState2]) -> None:
|
||||
pass
|
||||
|
||||
def host_state2_result_record(self) -> i.HostStateResultRecord:
|
||||
return i.HostStateResultRecord(HostState(2))
|
||||
|
||||
def host_state2_result_tuple(self) -> i.HostStateResultTuple:
|
||||
return (HostState(2),)
|
||||
|
||||
def host_state2_result_option(self) -> i.HostStateResultOption:
|
||||
return HostState(2)
|
||||
|
||||
def host_state2_result_result(self) -> i.HostStateResultResult:
|
||||
return i.Ok(HostState2(2))
|
||||
|
||||
def host_state2_result_variant(self) -> i.HostStateResultVariant:
|
||||
return HostState2(2)
|
||||
|
||||
def host_state2_result_list(self) -> List[i.HostState2]:
|
||||
return [HostState2(2), HostState2(5)]
|
||||
|
||||
def markdown2_create(self) -> i.Markdown2:
|
||||
return Markdown()
|
||||
|
||||
def odd_name_create(self) -> i.OddName:
|
||||
return OddName()
|
||||
|
||||
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)
|
||||
|
||||
wasm.test_imports(store)
|
||||
|
||||
# Param/result of a handle works in a simple fashion
|
||||
s: e.WasmState = wasm.wasm_state_create(store)
|
||||
assert(wasm.wasm_state_get_val(store, s) == 100)
|
||||
|
||||
# Deterministic destruction is possible
|
||||
assert(wasm.wasm_state2_saw_close(store) == False)
|
||||
s2: e.WasmState2 = wasm.wasm_state2_create(store)
|
||||
assert(wasm.wasm_state2_saw_close(store) == False)
|
||||
s2.drop(store)
|
||||
assert(wasm.wasm_state2_saw_close(store) == True)
|
||||
|
||||
arg1 = wasm.wasm_state_create(store)
|
||||
arg2 = wasm.wasm_state2_create(store)
|
||||
c, d = wasm.two_wasm_states(store, arg1, arg2)
|
||||
arg1.drop(store)
|
||||
arg2.drop(store)
|
||||
|
||||
wasm.wasm_state2_param_record(store, e.WasmStateParamRecord(d))
|
||||
wasm.wasm_state2_param_tuple(store, (d,))
|
||||
wasm.wasm_state2_param_option(store, d)
|
||||
wasm.wasm_state2_param_option(store, None)
|
||||
wasm.wasm_state2_param_result(store, e.Ok(d))
|
||||
wasm.wasm_state2_param_result(store, e.Err(2))
|
||||
wasm.wasm_state2_param_variant(store, d)
|
||||
wasm.wasm_state2_param_variant(store, 2)
|
||||
wasm.wasm_state2_param_list(store, [])
|
||||
wasm.wasm_state2_param_list(store, [d])
|
||||
wasm.wasm_state2_param_list(store, [d, d])
|
||||
|
||||
c.drop(store)
|
||||
d.drop(store)
|
||||
|
||||
wasm.wasm_state2_result_record(store).a.drop(store)
|
||||
wasm.wasm_state2_result_tuple(store)[0].drop(store)
|
||||
opt = wasm.wasm_state2_result_option(store)
|
||||
assert(opt is not None)
|
||||
opt.drop(store)
|
||||
result = wasm.wasm_state2_result_result(store)
|
||||
assert(isinstance(result, e.Ok))
|
||||
result.value.drop(store)
|
||||
variant = wasm.wasm_state2_result_variant(store)
|
||||
print(variant)
|
||||
assert(isinstance(variant, e.WasmState2))
|
||||
variant.drop(store)
|
||||
for val in wasm.wasm_state2_result_list(store):
|
||||
val.drop(store)
|
||||
|
||||
s.drop(store)
|
||||
|
||||
md = e.Markdown.create(store, wasm)
|
||||
if md:
|
||||
md.append(store, "red is the best color")
|
||||
assert(md.render(store) == "green is the best color")
|
||||
md.drop(store)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run(sys.argv[1])
|
||||
@@ -0,0 +1,156 @@
|
||||
wit_bindgen_wasmtime::export!("../../tests/runtime/handles/imports.wit");
|
||||
|
||||
use anyhow::Result;
|
||||
use imports::*;
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MyImports {
|
||||
host_state2_closed: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SuchState(u32);
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct Markdown {
|
||||
buf: RefCell<String>,
|
||||
}
|
||||
|
||||
impl Imports for MyImports {
|
||||
type HostState = SuchState;
|
||||
type HostState2 = ();
|
||||
type Markdown2 = Markdown;
|
||||
type OddName = ();
|
||||
|
||||
fn host_state_create(&mut self) -> SuchState {
|
||||
SuchState(100)
|
||||
}
|
||||
|
||||
fn host_state_get(&mut self, state: &SuchState) -> u32 {
|
||||
state.0
|
||||
}
|
||||
|
||||
fn host_state2_create(&mut self) {}
|
||||
|
||||
fn host_state2_saw_close(&mut self) -> bool {
|
||||
self.host_state2_closed
|
||||
}
|
||||
|
||||
fn drop_host_state2(&mut self, _state: ()) {
|
||||
self.host_state2_closed = true;
|
||||
}
|
||||
|
||||
fn two_host_states(&mut self, _a: &SuchState, _b: &()) -> (SuchState, ()) {
|
||||
(SuchState(2), ())
|
||||
}
|
||||
|
||||
fn host_state2_param_record(&mut self, _a: HostStateParamRecord<'_, Self>) {}
|
||||
fn host_state2_param_tuple(&mut self, _a: (&'_ (),)) {}
|
||||
fn host_state2_param_option(&mut self, _a: Option<&'_ ()>) {}
|
||||
fn host_state2_param_result(&mut self, _a: Result<&'_ (), u32>) {}
|
||||
fn host_state2_param_variant(&mut self, _a: HostStateParamVariant<'_, Self>) {}
|
||||
fn host_state2_param_list(&mut self, _a: Vec<&()>) {}
|
||||
|
||||
fn host_state2_result_record(&mut self) -> HostStateResultRecord<Self> {
|
||||
HostStateResultRecord { a: () }
|
||||
}
|
||||
fn host_state2_result_tuple(&mut self) -> ((),) {
|
||||
((),)
|
||||
}
|
||||
fn host_state2_result_option(&mut self) -> Option<()> {
|
||||
Some(())
|
||||
}
|
||||
fn host_state2_result_result(&mut self) -> Result<(), u32> {
|
||||
Ok(())
|
||||
}
|
||||
fn host_state2_result_variant(&mut self) -> HostStateResultVariant<Self> {
|
||||
HostStateResultVariant::HostState2(())
|
||||
}
|
||||
fn host_state2_result_list(&mut self) -> Vec<()> {
|
||||
vec![(), ()]
|
||||
}
|
||||
|
||||
fn markdown2_create(&mut self) -> Markdown {
|
||||
Markdown::default()
|
||||
}
|
||||
|
||||
fn markdown2_append(&mut self, md: &Markdown, buf: &str) {
|
||||
md.buf.borrow_mut().push_str(buf);
|
||||
}
|
||||
|
||||
fn markdown2_render(&mut self, md: &Markdown) -> String {
|
||||
md.buf.borrow().replace("red", "green")
|
||||
}
|
||||
|
||||
fn odd_name_create(&mut self) {}
|
||||
fn odd_name_frob_the_odd(&mut self, _: &()) {}
|
||||
}
|
||||
|
||||
wit_bindgen_wasmtime::import!("../../tests/runtime/handles/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),
|
||||
)?;
|
||||
|
||||
exports.test_imports(&mut store)?;
|
||||
|
||||
let s: WasmState = exports.wasm_state_create(&mut store)?;
|
||||
assert_eq!(exports.wasm_state_get_val(&mut store, &s)?, 100);
|
||||
exports.drop_wasm_state(&mut store, s)?;
|
||||
|
||||
assert_eq!(exports.wasm_state2_saw_close(&mut store)?, false);
|
||||
let s: WasmState2 = exports.wasm_state2_create(&mut store)?;
|
||||
assert_eq!(exports.wasm_state2_saw_close(&mut store)?, false);
|
||||
exports.drop_wasm_state2(&mut store, s)?;
|
||||
assert_eq!(exports.wasm_state2_saw_close(&mut store)?, true);
|
||||
|
||||
let a = exports.wasm_state_create(&mut store)?;
|
||||
let b = exports.wasm_state2_create(&mut store)?;
|
||||
let (s1, s2) = exports.two_wasm_states(&mut store, &a, &b)?;
|
||||
exports.drop_wasm_state(&mut store, a)?;
|
||||
exports.drop_wasm_state(&mut store, s1)?;
|
||||
exports.drop_wasm_state2(&mut store, b)?;
|
||||
|
||||
exports.wasm_state2_param_record(&mut store, WasmStateParamRecord { a: &s2 })?;
|
||||
exports.wasm_state2_param_tuple(&mut store, (&s2,))?;
|
||||
exports.wasm_state2_param_option(&mut store, Some(&s2))?;
|
||||
exports.wasm_state2_param_option(&mut store, None)?;
|
||||
exports.wasm_state2_param_result(&mut store, Ok(&s2))?;
|
||||
exports.wasm_state2_param_result(&mut store, Err(2))?;
|
||||
exports.wasm_state2_param_variant(&mut store, WasmStateParamVariant::WasmState2(&s2))?;
|
||||
exports.wasm_state2_param_variant(&mut store, WasmStateParamVariant::U32(2))?;
|
||||
exports.wasm_state2_param_list(&mut store, &[])?;
|
||||
exports.wasm_state2_param_list(&mut store, &[&s2])?;
|
||||
exports.wasm_state2_param_list(&mut store, &[&s2, &s2])?;
|
||||
exports.drop_wasm_state2(&mut store, s2)?;
|
||||
|
||||
let s = exports.wasm_state2_result_record(&mut store)?.a;
|
||||
exports.drop_wasm_state2(&mut store, s)?;
|
||||
let s = exports.wasm_state2_result_tuple(&mut store)?.0;
|
||||
exports.drop_wasm_state2(&mut store, s)?;
|
||||
let s = exports.wasm_state2_result_option(&mut store)?.unwrap();
|
||||
exports.drop_wasm_state2(&mut store, s)?;
|
||||
let s = exports.wasm_state2_result_result(&mut store)?.unwrap();
|
||||
match exports.wasm_state2_result_variant(&mut store)? {
|
||||
WasmStateResultVariant::WasmState2(s) => exports.drop_wasm_state2(&mut store, s)?,
|
||||
WasmStateResultVariant::U32(_) => panic!(),
|
||||
}
|
||||
exports.drop_wasm_state2(&mut store, s)?;
|
||||
for s in exports.wasm_state2_result_list(&mut store)? {
|
||||
exports.drop_wasm_state2(&mut store, s)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import { addImportsToImports, Imports } from "./imports.js";
|
||||
import { Exports } from "./exports.js";
|
||||
import * as exports from "./exports.js";
|
||||
import { getWasm, addWasiToImports } from "./helpers.js";
|
||||
// @ts-ignore
|
||||
import * as assert from 'assert';
|
||||
|
||||
async function run() {
|
||||
const importObj = {};
|
||||
let sawClose = false;
|
||||
const imports: Imports = {
|
||||
hostStateCreate() { return 100; },
|
||||
hostStateGet(x) { return x as number; },
|
||||
hostState2Create() { return 101; },
|
||||
hostState2SawClose() { return sawClose; },
|
||||
dropHostState2(state) { sawClose = true; },
|
||||
twoHostStates(a, b) { return [b, a]; },
|
||||
hostState2ParamRecord(x) {},
|
||||
hostState2ParamTuple(x) {},
|
||||
hostState2ParamOption(x) {},
|
||||
hostState2ParamResult(x) {},
|
||||
hostState2ParamVariant(x) {},
|
||||
hostState2ParamList(x) {},
|
||||
|
||||
hostState2ResultRecord() { return { a: {} }; },
|
||||
hostState2ResultTuple() { return [{}]; },
|
||||
hostState2ResultOption() { return 102; },
|
||||
hostState2ResultResult() { return { tag: 'ok', val: {} }; },
|
||||
hostState2ResultVariant() { return { tag: 0, val: {} }; },
|
||||
hostState2ResultList() { return [{}, 3]; },
|
||||
|
||||
markdown2Create() {
|
||||
class Markdown {
|
||||
buf: string;
|
||||
|
||||
constructor() {
|
||||
this.buf = '';
|
||||
}
|
||||
append(extra: string) {
|
||||
this.buf += extra;
|
||||
}
|
||||
render() {
|
||||
return this.buf.replace('red', 'green');
|
||||
}
|
||||
}
|
||||
|
||||
return new Markdown();
|
||||
},
|
||||
|
||||
oddNameCreate() {
|
||||
class OddName {
|
||||
frobTheOdd() {}
|
||||
}
|
||||
return new OddName();
|
||||
}
|
||||
};
|
||||
let instance: WebAssembly.Instance;
|
||||
addImportsToImports(importObj, imports, name => instance.exports[name]);
|
||||
const wasi = addWasiToImports(importObj);
|
||||
|
||||
const wasm = new Exports();
|
||||
await wasm.instantiate(getWasm(), importObj);
|
||||
wasi.start(wasm.instance);
|
||||
instance = wasm.instance;
|
||||
|
||||
wasm.testImports();
|
||||
|
||||
// Param/result of a handle works in a simple fashion
|
||||
const s: exports.WasmState = wasm.wasmStateCreate();
|
||||
assert.strictEqual(wasm.wasmStateGetVal(s), 100);
|
||||
|
||||
// Deterministic destruction is possible
|
||||
assert.strictEqual(wasm.wasmState2SawClose(), false);
|
||||
const s2: exports.WasmState2 = wasm.wasmState2Create();
|
||||
assert.strictEqual(wasm.wasmState2SawClose(), false);
|
||||
s2.drop();
|
||||
assert.strictEqual(wasm.wasmState2SawClose(), true);
|
||||
|
||||
const arg1 = wasm.wasmStateCreate();
|
||||
const arg2 = wasm.wasmState2Create();
|
||||
const [c, d] = wasm.twoWasmStates(arg1, arg2);
|
||||
arg1.drop();
|
||||
arg2.drop();
|
||||
|
||||
wasm.wasmState2ParamRecord({ a: d });
|
||||
wasm.wasmState2ParamTuple([d]);
|
||||
wasm.wasmState2ParamOption(d);
|
||||
wasm.wasmState2ParamOption(null);
|
||||
wasm.wasmState2ParamResult({ tag: 'ok', val: d });
|
||||
wasm.wasmState2ParamResult({ tag: 'err', val: 2 });
|
||||
wasm.wasmState2ParamVariant({ tag: 0, val: d });
|
||||
wasm.wasmState2ParamVariant({ tag: 1, val: 2 });
|
||||
wasm.wasmState2ParamList([]);
|
||||
wasm.wasmState2ParamList([d]);
|
||||
wasm.wasmState2ParamList([d, d]);
|
||||
|
||||
c.drop();
|
||||
d.drop();
|
||||
|
||||
wasm.wasmState2ResultRecord().a?.drop();
|
||||
wasm.wasmState2ResultTuple()[0].drop();
|
||||
const opt = wasm.wasmState2ResultOption();
|
||||
if (opt === null)
|
||||
throw new Error('should be some');
|
||||
opt.drop();
|
||||
const result = wasm.wasmState2ResultResult();
|
||||
if (result.tag === 'err')
|
||||
throw new Error('should be ok');
|
||||
result.val.drop();
|
||||
const variant = wasm.wasmState2ResultVariant();
|
||||
if (variant.tag === 1)
|
||||
throw new Error('should be 0');
|
||||
variant.val.drop();
|
||||
for (let val of wasm.wasmState2ResultList())
|
||||
val.drop();
|
||||
|
||||
s.drop();
|
||||
|
||||
const md = exports.Markdown.create(wasm);
|
||||
if (md) {
|
||||
md.append("red is the best color");
|
||||
assert.strictEqual(md.render(), "green is the best color");
|
||||
md.drop();
|
||||
}
|
||||
}
|
||||
|
||||
await run()
|
||||
@@ -0,0 +1,55 @@
|
||||
resource host-state
|
||||
resource host-state2
|
||||
|
||||
host-state-create: func() -> host-state
|
||||
host-state-get: func(a: host-state) -> u32
|
||||
|
||||
host-state2-create: func() -> host-state2
|
||||
host-state2-saw-close: func() -> bool
|
||||
two-host-states: func(a: host-state, b: host-state2) -> tuple<host-state, host-state2>
|
||||
|
||||
record host-state-param-record { a: host-state2 }
|
||||
host-state2-param-record: func(a: host-state-param-record)
|
||||
|
||||
type host-state-param-tuple = tuple<host-state2>
|
||||
host-state2-param-tuple: func(a: host-state-param-tuple)
|
||||
|
||||
type host-state-param-option = option<host-state2>
|
||||
host-state2-param-option: func(a: host-state-param-option)
|
||||
|
||||
type host-state-param-result = expected<host-state2, u32>
|
||||
host-state2-param-result: func(a: host-state-param-result)
|
||||
|
||||
union host-state-param-variant { host-state2, u32 }
|
||||
host-state2-param-variant: func(a: host-state-param-variant)
|
||||
|
||||
host-state2-param-list: func(a: list<host-state2>)
|
||||
|
||||
|
||||
record host-state-result-record { a: host-state2 }
|
||||
host-state2-result-record: func() -> host-state-result-record
|
||||
|
||||
type host-state-result-tuple = tuple<host-state2>
|
||||
host-state2-result-tuple: func() -> host-state-result-tuple
|
||||
|
||||
type host-state-result-option = option<host-state2>
|
||||
host-state2-result-option: func() -> host-state-result-option
|
||||
|
||||
type host-state-result-result = expected<host-state2, u32>
|
||||
host-state2-result-result: func() -> host-state-result-result
|
||||
|
||||
union host-state-result-variant { host-state2, u32 }
|
||||
host-state2-result-variant: func() -> host-state-result-variant
|
||||
|
||||
host-state2-result-list: func() -> list<host-state2>
|
||||
|
||||
resource markdown2 {
|
||||
static create: func() -> markdown2
|
||||
append: func(buf: string)
|
||||
render: func() -> string
|
||||
}
|
||||
|
||||
resource %odd-name {
|
||||
static create: func() -> %odd-name
|
||||
%frob-the-odd: func()
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
#include <assert.h>
|
||||
#include <exports.h>
|
||||
#include <imports.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void exports_test_imports() {
|
||||
imports_host_state_t s = imports_host_state_create();
|
||||
assert(imports_host_state_get(s) == 100);
|
||||
imports_host_state_free(&s);
|
||||
|
||||
assert(imports_host_state2_saw_close() == false);
|
||||
imports_host_state2_t s2 = imports_host_state2_create();
|
||||
assert(imports_host_state2_saw_close() == false);
|
||||
imports_host_state2_free(&s2);
|
||||
assert(imports_host_state2_saw_close() == true);
|
||||
|
||||
{
|
||||
imports_host_state_t a, b;
|
||||
imports_host_state2_t c, d;
|
||||
|
||||
a = imports_host_state_create();
|
||||
c = imports_host_state2_create();
|
||||
imports_two_host_states(a, c, &b, &d);
|
||||
imports_host_state_free(&a);
|
||||
imports_host_state_free(&b);
|
||||
imports_host_state2_free(&c);
|
||||
|
||||
{
|
||||
imports_host_state_param_record_t a;
|
||||
a.a = d;
|
||||
imports_host_state2_param_record(&a);
|
||||
}
|
||||
{
|
||||
imports_host_state_param_tuple_t a;
|
||||
a.f0 = d;
|
||||
imports_host_state2_param_tuple(&a);
|
||||
}
|
||||
{
|
||||
imports_host_state_param_option_t a;
|
||||
a.is_some = true;
|
||||
a.val = d;
|
||||
imports_host_state2_param_option(&a);
|
||||
}
|
||||
{
|
||||
imports_host_state_param_result_t a;
|
||||
a.is_err = false;
|
||||
a.val.ok = d;
|
||||
imports_host_state2_param_result(&a);
|
||||
a.is_err = true;
|
||||
a.val.err = 2;
|
||||
imports_host_state2_param_result(&a);
|
||||
}
|
||||
{
|
||||
imports_host_state_param_variant_t a;
|
||||
a.tag = 0;
|
||||
a.val.f0 = d;
|
||||
imports_host_state2_param_variant(&a);
|
||||
a.tag = 1;
|
||||
a.val.f1 = 2;
|
||||
imports_host_state2_param_variant(&a);
|
||||
}
|
||||
{
|
||||
imports_host_state2_t arr[2];
|
||||
arr[0] = d;
|
||||
arr[1] = d;
|
||||
imports_list_host_state2_t list;
|
||||
list.len = 0;
|
||||
list.ptr = arr;
|
||||
imports_host_state2_param_list(&list);
|
||||
list.len = 1;
|
||||
imports_host_state2_param_list(&list);
|
||||
list.len = 2;
|
||||
imports_host_state2_param_list(&list);
|
||||
}
|
||||
|
||||
imports_host_state2_free(&d);
|
||||
}
|
||||
|
||||
{
|
||||
imports_host_state_result_record_t a;
|
||||
imports_host_state2_result_record(&a);
|
||||
imports_host_state2_free(&a.a);
|
||||
}
|
||||
{
|
||||
imports_host_state2_t a;
|
||||
imports_host_state2_result_tuple(&a);
|
||||
imports_host_state2_free(&a);
|
||||
}
|
||||
{
|
||||
imports_host_state2_t a;
|
||||
assert(imports_host_state2_result_option(&a));
|
||||
imports_host_state2_free(&a);
|
||||
}
|
||||
{
|
||||
imports_host_state_result_result_t a;
|
||||
imports_host_state2_result_result(&a);
|
||||
assert(!a.is_err);
|
||||
imports_host_state2_free(&a.val.ok);
|
||||
}
|
||||
{
|
||||
imports_host_state_result_variant_t a;
|
||||
imports_host_state2_result_variant(&a);
|
||||
assert(a.tag == 0);
|
||||
imports_host_state2_free(&a.val.f0);
|
||||
}
|
||||
{
|
||||
imports_list_host_state2_t a;
|
||||
imports_host_state2_result_list(&a);
|
||||
imports_list_host_state2_free(&a);
|
||||
}
|
||||
{
|
||||
imports_markdown2_t a = imports_markdown2_create();
|
||||
imports_string_t s;
|
||||
imports_string_set(&s, "red is the best color");
|
||||
imports_markdown2_append(a, &s);
|
||||
imports_markdown2_render(a, &s);
|
||||
|
||||
const char *expected = "green is the best color";
|
||||
assert(s.len == strlen(expected));
|
||||
assert(memcmp(s.ptr, expected, s.len) == 0);
|
||||
imports_string_free(&s);
|
||||
imports_markdown2_free(&a);
|
||||
}
|
||||
}
|
||||
|
||||
exports_wasm_state_t exports_wasm_state_create(void) {
|
||||
return exports_wasm_state_new((void*) 100);
|
||||
}
|
||||
|
||||
uint32_t exports_wasm_state_get_val(exports_wasm_state_t a) {
|
||||
uint32_t ret = (uint32_t) exports_wasm_state_get(&a);
|
||||
exports_wasm_state_free(&a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
exports_wasm_state2_t exports_wasm_state2_create(void) {
|
||||
return exports_wasm_state2_new((void*) 33);
|
||||
}
|
||||
|
||||
static bool WASM_STATE2_CLOSED = false;
|
||||
|
||||
bool exports_wasm_state2_saw_close(void) {
|
||||
return WASM_STATE2_CLOSED;
|
||||
}
|
||||
|
||||
void exports_wasm_state2_dtor(void *data) {
|
||||
WASM_STATE2_CLOSED = true;
|
||||
}
|
||||
|
||||
void exports_two_wasm_states(exports_wasm_state_t a, exports_wasm_state2_t b, exports_wasm_state_t *ret0, exports_wasm_state2_t *ret1) {
|
||||
exports_wasm_state_free(&a);
|
||||
exports_wasm_state2_free(&b);
|
||||
|
||||
*ret0 = exports_wasm_state_new((void*) 101);
|
||||
*ret1 = exports_wasm_state2_new((void*) 102);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_param_record(exports_wasm_state_param_record_t *a) {
|
||||
exports_wasm_state_param_record_free(a);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_param_tuple(exports_wasm_state_param_tuple_t *a) {
|
||||
exports_wasm_state_param_tuple_free(a);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_param_option(exports_wasm_state_param_option_t *a) {
|
||||
exports_wasm_state_param_option_free(a);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_param_result(exports_wasm_state_param_result_t *a) {
|
||||
exports_wasm_state_param_result_free(a);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_param_variant(exports_wasm_state_param_variant_t *a) {
|
||||
exports_wasm_state_param_variant_free(a);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_param_list(exports_list_wasm_state2_t *a) {
|
||||
exports_list_wasm_state2_free(a);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_result_record(exports_wasm_state_result_record_t *ret0) {
|
||||
ret0->a = exports_wasm_state2_new((void*) 222);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_result_tuple(exports_wasm_state2_t *ret0) {
|
||||
*ret0 = exports_wasm_state2_new((void*) 333);
|
||||
}
|
||||
|
||||
bool exports_wasm_state2_result_option(exports_wasm_state2_t *ret0) {
|
||||
*ret0 = exports_wasm_state2_new((void*) 444);
|
||||
return true;
|
||||
}
|
||||
|
||||
void exports_wasm_state2_result_result(exports_wasm_state_result_result_t *ret0) {
|
||||
ret0->is_err = false;
|
||||
ret0->val.ok = exports_wasm_state2_new((void*) 555);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_result_variant(exports_wasm_state_result_variant_t *ret0) {
|
||||
ret0->tag = 0;
|
||||
ret0->val.f0 = exports_wasm_state2_new((void*) 666);
|
||||
}
|
||||
|
||||
void exports_wasm_state2_result_list(exports_list_wasm_state2_t *ret0) {
|
||||
ret0->len = 2;
|
||||
ret0->ptr = malloc(2 * sizeof(exports_wasm_state2_t));
|
||||
ret0->ptr[0] = exports_wasm_state2_new((void*) 777);
|
||||
ret0->ptr[1] = exports_wasm_state2_new((void*) 888);
|
||||
}
|
||||
|
||||
bool exports_markdown_create(exports_markdown_t *md) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void exports_markdown_append(exports_markdown_t md, exports_string_t *s) {
|
||||
abort();
|
||||
}
|
||||
|
||||
void exports_markdown_render(exports_markdown_t md, exports_string_t *ret) {
|
||||
abort();
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
wit_bindgen_rust::import!("../../tests/runtime/handles/imports.wit");
|
||||
wit_bindgen_rust::export!("../../tests/runtime/handles/exports.wit");
|
||||
|
||||
use exports::*;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::atomic::{AtomicU32, Ordering::SeqCst};
|
||||
use wit_bindgen_rust::Handle;
|
||||
|
||||
struct Exports;
|
||||
|
||||
static CLOSED: AtomicU32 = AtomicU32::new(0);
|
||||
|
||||
pub struct WasmState(u32);
|
||||
|
||||
pub struct WasmState2(u32);
|
||||
|
||||
impl exports::Exports for Exports {
|
||||
fn test_imports() {
|
||||
use imports::*;
|
||||
|
||||
let s: HostState = host_state_create();
|
||||
assert_eq!(host_state_get(&s), 100);
|
||||
assert_eq!(host_state2_saw_close(), false);
|
||||
let s: HostState2 = host_state2_create();
|
||||
assert_eq!(host_state2_saw_close(), false);
|
||||
drop(s);
|
||||
assert_eq!(host_state2_saw_close(), true);
|
||||
|
||||
let (_a, s2) = two_host_states(&host_state_create(), &host_state2_create());
|
||||
|
||||
host_state2_param_record(HostStateParamRecord { a: &s2 });
|
||||
host_state2_param_tuple((&s2,));
|
||||
host_state2_param_option(Some(&s2));
|
||||
host_state2_param_option(None);
|
||||
host_state2_param_result(Ok(&s2));
|
||||
host_state2_param_result(Err(2));
|
||||
host_state2_param_variant(HostStateParamVariant::HostState2(&s2));
|
||||
host_state2_param_variant(HostStateParamVariant::U32(2));
|
||||
host_state2_param_list(&[]);
|
||||
host_state2_param_list(&[&s2]);
|
||||
host_state2_param_list(&[&s2, &s2]);
|
||||
|
||||
drop(host_state2_result_record().a);
|
||||
drop(host_state2_result_tuple().0);
|
||||
drop(host_state2_result_option().unwrap());
|
||||
drop(host_state2_result_result().unwrap());
|
||||
drop(host_state2_result_variant());
|
||||
drop(host_state2_result_list());
|
||||
|
||||
let md = Markdown2::create();
|
||||
md.append("red is the best color");
|
||||
assert_eq!(md.render(), "green is the best color");
|
||||
|
||||
let odd = OddName::create();
|
||||
odd.frob_the_odd();
|
||||
}
|
||||
|
||||
fn wasm_state_create() -> Handle<WasmState> {
|
||||
WasmState(100).into()
|
||||
}
|
||||
|
||||
fn wasm_state_get_val(state: Handle<WasmState>) -> u32 {
|
||||
state.0
|
||||
}
|
||||
|
||||
fn wasm_state2_create() -> Handle<WasmState2> {
|
||||
WasmState2(33).into()
|
||||
}
|
||||
|
||||
fn wasm_state2_saw_close() -> bool {
|
||||
CLOSED.load(SeqCst) != 0
|
||||
}
|
||||
|
||||
fn drop_wasm_state2(_state: WasmState2) {
|
||||
CLOSED.store(1, SeqCst);
|
||||
}
|
||||
|
||||
fn two_wasm_states(
|
||||
_a: Handle<WasmState>,
|
||||
_b: Handle<WasmState2>,
|
||||
) -> (Handle<WasmState>, Handle<WasmState2>) {
|
||||
(WasmState(101).into(), WasmState2(102).into())
|
||||
}
|
||||
|
||||
fn wasm_state2_param_record(_a: WasmStateParamRecord) {}
|
||||
fn wasm_state2_param_tuple(_a: (Handle<WasmState2>,)) {}
|
||||
fn wasm_state2_param_option(_a: Option<Handle<WasmState2>>) {}
|
||||
fn wasm_state2_param_result(_a: Result<Handle<WasmState2>, u32>) {}
|
||||
fn wasm_state2_param_variant(_a: WasmStateParamVariant) {}
|
||||
fn wasm_state2_param_list(_a: Vec<Handle<WasmState2>>) {}
|
||||
|
||||
fn wasm_state2_result_record() -> WasmStateResultRecord {
|
||||
WasmStateResultRecord {
|
||||
a: WasmState2(222).into(),
|
||||
}
|
||||
}
|
||||
fn wasm_state2_result_tuple() -> (Handle<WasmState2>,) {
|
||||
(WasmState2(333).into(),)
|
||||
}
|
||||
fn wasm_state2_result_option() -> Option<Handle<WasmState2>> {
|
||||
Some(WasmState2(444).into())
|
||||
}
|
||||
fn wasm_state2_result_result() -> Result<Handle<WasmState2>, u32> {
|
||||
Ok(WasmState2(555).into())
|
||||
}
|
||||
fn wasm_state2_result_variant() -> WasmStateResultVariant {
|
||||
WasmStateResultVariant::WasmState2(Handle::new(WasmState2(666)))
|
||||
}
|
||||
fn wasm_state2_result_list() -> Vec<Handle<WasmState2>> {
|
||||
vec![WasmState2(777).into(), WasmState2(888).into()]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Markdown {
|
||||
buf: RefCell<String>,
|
||||
}
|
||||
|
||||
impl exports::Markdown for Markdown {
|
||||
fn create() -> Option<Handle<Markdown>> {
|
||||
Some(Markdown::default().into())
|
||||
}
|
||||
|
||||
fn append(&self, input: String) {
|
||||
self.buf.borrow_mut().push_str(&input);
|
||||
}
|
||||
|
||||
fn render(&self) -> String {
|
||||
self.buf.borrow().replace("red", "green")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user