Path: blob/main/tests/all/component_model/bindgen/ownership.rs
1692 views
use super::{super::REALLOC_AND_FREE, engine};1use anyhow::Result;2use wasmtime::{3Store,4component::{Component, Linker},5};67fn component() -> String {8format!(9r#"10(component11(core module $libc12(memory (export "memory") 1)13{REALLOC_AND_FREE}14)15(core instance $libc (instantiate $libc))16(core module $m17(import "libc" "memory" (memory 0))18(import "libc" "realloc" (func $realloc (param i32 i32 i32 i32) (result i32)))19(func (export "core_foo_export") (param i32 i32) (result i32)20(local $retptr i32)21(local.set $retptr22(call $realloc23(i32.const 0)24(i32.const 0)25(i32.const 4)26(i32.const 8)))27(i32.store offset=0 (local.get $retptr) (local.get 0))28(i32.store offset=4 (local.get $retptr) (local.get 1))29(local.get $retptr)30)31(func (export "core_bar_export") (param i32 i32 i32 i32))32(func (export "core_baz_export") (param i32 i32 i32 i32) (result i32)33(local $retptr i32)34(local.set $retptr35(call $realloc36(i32.const 0)37(i32.const 0)38(i32.const 4)39(i32.const 16)))40(i32.store offset=0 (local.get $retptr) (local.get 0))41(i32.store offset=4 (local.get $retptr) (local.get 1))42(i32.store offset=8 (local.get $retptr) (local.get 2))43(i32.store offset=12 (local.get $retptr) (local.get 3))44(local.get $retptr)45)46)47(core instance $i (instantiate $m48(with "libc" (instance $libc))49))5051(func $f_foo52(param "a" (list (list string)))53(result (list (list string)))54(canon lift (core func $i "core_foo_export") (memory $libc "memory")55(realloc (func $libc "realloc"))56)57)5859(type $thing (record (field "name" string) (field "value" (list string))))6061(func $f_bar62(param "a" $thing)63(canon lift (core func $i "core_bar_export") (memory $libc "memory")64(realloc (func $libc "realloc"))65)66)6768(func $f_baz69(param "a" $thing)70(result $thing)71(canon lift (core func $i "core_baz_export") (memory $libc "memory")72(realloc (func $libc "realloc"))73)74)7576(component $c_lists77(import "import-foo" (func $f78(param "a" (list (list string)))79(result (list (list string)))80))81(export "foo" (func $f))82)83(instance $i_lists (instantiate $c_lists84(with "import-foo" (func $f_foo))85))86(export "lists" (instance $i_lists))8788(component $c_thing_in89(import "import-thing" (type $import-thing (eq $thing)))90(import "import-bar" (func $f (param "a" $import-thing)))91(export $export-thing "thing" (type $thing))92(export "bar" (func $f) (func (param "a" $export-thing)))93)94(instance $i_thing_in (instantiate $c_thing_in95(with "import-thing" (type $thing))96(with "import-bar" (func $f_bar))97))98(export "thing-in" (instance $i_thing_in))99100(component $c_thing_in_and_out101(import "import-thing" (type $import-thing (eq $thing)))102(import "import-baz" (func $f (param "a" $import-thing) (result $import-thing)))103(export $export-thing "thing" (type $thing))104(export "baz" (func $f) (func (param "a" $export-thing) (result $export-thing)))105)106(instance $i_thing_in_and_out (instantiate $c_thing_in_and_out107(with "import-thing" (type $thing))108(with "import-baz" (func $f_baz))109))110(export "thing-in-and-out" (instance $i_thing_in_and_out))111)112"#113)114}115116mod owning {117use super::*;118119wasmtime::component::bindgen!({120inline: "121package inline:inline;122world test {123export lists: interface {124foo: func(a: list<list<string>>) -> list<list<string>>;125}126127export thing-in: interface {128record thing {129name: string,130value: list<string>131}132133bar: func(a: thing);134}135136export thing-in-and-out: interface {137record thing {138name: string,139value: list<string>140}141142baz: func(a: thing) -> thing;143}144}",145ownership: Owning146});147148impl PartialEq for exports::thing_in::Thing {149fn eq(&self, other: &Self) -> bool {150self.name == other.name && self.value == other.value151}152}153154impl PartialEq for exports::thing_in_and_out::Thing {155fn eq(&self, other: &Self) -> bool {156self.name == other.name && self.value == other.value157}158}159160#[test]161fn owning() -> Result<()> {162let engine = engine();163let component = Component::new(&engine, component())?;164165let linker = Linker::new(&engine);166let mut store = Store::new(&engine, ());167let test = Test::instantiate(&mut store, &component, &linker)?;168169let value = vec![vec!["a".to_owned(), "b".to_owned()]];170assert_eq!(value, test.lists().call_foo(&mut store, &value)?);171172let value = exports::thing_in::Thing {173name: "thing 1".to_owned(),174value: vec!["some value".to_owned(), "another value".to_owned()],175};176test.thing_in().call_bar(&mut store, &value)?;177178let value = exports::thing_in_and_out::Thing {179name: "thing 1".to_owned(),180value: vec!["some value".to_owned(), "another value".to_owned()],181};182assert_eq!(value, test.thing_in_and_out().call_baz(&mut store, &value)?);183184Ok(())185}186}187188mod borrowing_no_duplication {189use super::*;190wasmtime::component::bindgen!({191inline: "192package inline:inline;193world test {194export lists: interface {195foo: func(a: list<list<string>>) -> list<list<string>>;196}197198export thing-in: interface {199record thing {200name: string,201value: list<string>202}203204bar: func(a: thing);205}206207export thing-in-and-out: interface {208record thing {209name: string,210value: list<string>211}212213baz: func(a: thing) -> thing;214}215}",216ownership: Borrowing {217duplicate_if_necessary: false218}219});220221impl PartialEq for exports::thing_in::Thing<'_> {222fn eq(&self, other: &Self) -> bool {223self.name == other.name && self.value == other.value224}225}226227impl PartialEq for exports::thing_in_and_out::Thing {228fn eq(&self, other: &Self) -> bool {229self.name == other.name && self.value == other.value230}231}232233#[test]234fn borrowing_no_duplication() -> Result<()> {235let engine = engine();236let component = Component::new(&engine, component())?;237238let linker = Linker::new(&engine);239let mut store = Store::new(&engine, ());240let test = Test::instantiate(&mut store, &component, &linker)?;241242let value = &[&["a", "b"] as &[_]] as &[_];243assert_eq!(value, test.lists().call_foo(&mut store, value)?);244245let value = exports::thing_in::Thing {246name: "thing 1",247value: &["some value", "another value"],248};249test.thing_in().call_bar(&mut store, value)?;250251let value = exports::thing_in_and_out::Thing {252name: "thing 1".to_owned(),253value: vec!["some value".to_owned(), "another value".to_owned()],254};255assert_eq!(value, test.thing_in_and_out().call_baz(&mut store, &value)?);256257Ok(())258}259}260261mod borrowing_with_duplication {262use super::*;263264wasmtime::component::bindgen!({265inline: "266package inline:inline;267world test {268export lists: interface {269foo: func(a: list<list<string>>) -> list<list<string>>;270}271272export thing-in: interface {273record thing {274name: string,275value: list<string>276}277278bar: func(a: thing);279}280281export thing-in-and-out: interface {282record thing {283name: string,284value: list<string>285}286287baz: func(a: thing) -> thing;288}289}",290ownership: Borrowing {291duplicate_if_necessary: true292}293});294295impl PartialEq for exports::thing_in::Thing<'_> {296fn eq(&self, other: &Self) -> bool {297self.name == other.name && self.value == other.value298}299}300301impl PartialEq for exports::thing_in_and_out::ThingResult {302fn eq(&self, other: &Self) -> bool {303self.name == other.name && self.value == other.value304}305}306307#[test]308fn borrowing_with_duplication() -> Result<()> {309let engine = engine();310let component = Component::new(&engine, component())?;311312let linker = Linker::new(&engine);313let mut store = Store::new(&engine, ());314let test = Test::instantiate(&mut store, &component, &linker)?;315316let value = &[&["a", "b"] as &[_]] as &[_];317assert_eq!(value, test.lists().call_foo(&mut store, value)?);318319let value = exports::thing_in::Thing {320name: "thing 1",321value: &["some value", "another value"],322};323test.thing_in().call_bar(&mut store, value)?;324325let value = exports::thing_in_and_out::ThingParam {326name: "thing 1",327value: &["some value", "another value"],328};329assert_eq!(330exports::thing_in_and_out::ThingResult {331name: "thing 1".to_owned(),332value: vec!["some value".to_owned(), "another value".to_owned()],333},334test.thing_in_and_out().call_baz(&mut store, value)?335);336337Ok(())338}339}340341342