diff --git a/crates/spidermonkey-embedding-splicer/src/bindgen.rs b/crates/spidermonkey-embedding-splicer/src/bindgen.rs index 36be7fdc..5137898e 100644 --- a/crates/spidermonkey-embedding-splicer/src/bindgen.rs +++ b/crates/spidermonkey-embedding-splicer/src/bindgen.rs @@ -587,15 +587,17 @@ impl JsBindgen<'_> { .. } => { let iface = &self.resolve.interfaces[*i]; + let mut resource_function_groups = BTreeMap::<_, Vec<_>>::new(); for id in iface.types.values() { if let TypeDefKind::Resource = &self.resolve.types[*id].kind { self.resource_directions .insert(*id, AbiVariant::GuestImport); + resource_function_groups.entry(Some(*id)).or_default(); } } let by_resource = iface.functions.iter().fold( - BTreeMap::<_, Vec<_>>::new(), + resource_function_groups, |mut map, (name, func)| { map.entry(match &func.kind { FunctionKind::Freestanding | FunctionKind::AsyncFreestanding => { diff --git a/test/cases/opaque-resource-import/opaque-resource-import.js b/test/cases/opaque-resource-import/opaque-resource-import.js new file mode 100644 index 00000000..77d93d47 --- /dev/null +++ b/test/cases/opaque-resource-import/opaque-resource-import.js @@ -0,0 +1,14 @@ +export let drops = 0; + +export class Item { + constructor(value) { + this.value = value; + } + + [Symbol.dispose]() { + drops += 1; + } +} + +export const make = value => new Item(value); +export const value = item => item.value; diff --git a/test/cases/opaque-resource-import/source.js b/test/cases/opaque-resource-import/source.js new file mode 100644 index 00000000..a05d5413 --- /dev/null +++ b/test/cases/opaque-resource-import/source.js @@ -0,0 +1,10 @@ +import { make, value } from 'test:test/opaque-resource-import'; + +export function test() { + const item = make(42); + try { + return value(item); + } finally { + item[Symbol.dispose](); + } +} diff --git a/test/cases/opaque-resource-import/test.js b/test/cases/opaque-resource-import/test.js new file mode 100644 index 00000000..26495df1 --- /dev/null +++ b/test/cases/opaque-resource-import/test.js @@ -0,0 +1,7 @@ +import { strictEqual } from 'node:assert'; +import { drops } from './opaque-resource-import.js'; + +export function test(instance) { + strictEqual(instance.test(), 42); + strictEqual(drops, 1); +} diff --git a/test/cases/opaque-resource-import/world.wit b/test/cases/opaque-resource-import/world.wit new file mode 100644 index 00000000..c9b705fe --- /dev/null +++ b/test/cases/opaque-resource-import/world.wit @@ -0,0 +1,12 @@ +package test:test; + +interface opaque-resource-import { + resource item; + make: func(value: u32) -> item; + value: func(item: borrow) -> u32; +} + +world test { + import opaque-resource-import; + export test: func() -> u32; +}