diff --git a/crates/csharp/src/lib.rs b/crates/csharp/src/lib.rs index 7b9253ed7..e4d574d3b 100644 --- a/crates/csharp/src/lib.rs +++ b/crates/csharp/src/lib.rs @@ -1444,6 +1444,11 @@ impl InterfaceGenerator<'_> { .map(|key| self.resolve.name_world_key(key)) .unwrap_or_else(|| "$root".into()); + // As of this writing, we cannot safely drop a handle to an imported resource from a .NET finalizer + // because it may still have one or more open child resources. Once WIT has explicit syntax for + // indicating parent/child relationships, we should be able to use that information to keep track + // of child resources automatically in generated code, at which point we'll be able to drop them in + // the correct order from finalizers. uwriteln!( self.src, r#" @@ -1458,22 +1463,17 @@ impl InterfaceGenerator<'_> { public void Dispose() {{ Dispose(true); - GC.SuppressFinalize(this); }} [DllImport("{module_name}", EntryPoint = "[resource-drop]{name}"), WasmImportLinkage] private static extern void wasmImportResourceDrop(int p0); protected virtual void Dispose(bool disposing) {{ - if (Handle != 0) {{ + if (disposing && Handle != 0) {{ wasmImportResourceDrop(Handle); Handle = 0; }} }} - - ~{upper_camel}() {{ - Dispose(false); - }} "# ); } diff --git a/crates/moonbit/src/lib.rs b/crates/moonbit/src/lib.rs index 86379d270..5fd190fff 100644 --- a/crates/moonbit/src/lib.rs +++ b/crates/moonbit/src/lib.rs @@ -149,14 +149,35 @@ pub extern "wasm" fn ptr2int_array(ptr : Int) -> FixedArray[Int] = pub extern "wasm" fn ptr2float_array(ptr : Int) -> FixedArray[Float] = #|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.const 241 i32.store8 local.get 0 i32.const 8 i32.sub) -pub extern "wasm" fn ptr2uint64_array(ptr : Int) -> FixedArray[UInt64] = - #|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.load i32.const 1 i32.shr_u i32.const 241 i32.or local.get 0 i32.const 4 i32.sub i32.store local.get 0 i32.const 8 i32.sub) +extern "wasm" fn ptr2uint64_array_ffi(ptr : Int) -> FixedArray[UInt64] = + #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) + +pub fn ptr2uint64_array(ptr : Int) -> FixedArray[UInt64] { + set_64_header_ffi(ptr - 4) + ptr2uint64_array_ffi(ptr) +} -pub extern "wasm" fn ptr2int64_array(ptr : Int) -> FixedArray[Int64] = - #|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.load i32.const 1 i32.shr_u i32.const 241 i32.or local.get 0 i32.const 4 i32.sub i32.store local.get 0 i32.const 8 i32.sub) +extern "wasm" fn ptr2int64_array_ffi(ptr : Int) -> FixedArray[Int64] = + #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) + +pub fn ptr2int64_array(ptr : Int) -> FixedArray[Int64] { + set_64_header_ffi(ptr - 4) + ptr2int64_array_ffi(ptr) +} -pub extern "wasm" fn ptr2double_array(ptr : Int) -> FixedArray[Double] = - #|(func (param i32) (result i32) local.get 0 i32.const 4 i32.sub i32.load i32.const 1 i32.shr_u i32.const 241 i32.or local.get 0 i32.const 4 i32.sub i32.store local.get 0 i32.const 8 i32.sub) +extern "wasm" fn ptr2double_array_ffi(ptr : Int) -> FixedArray[Double] = + #|(func (param i32) (result i32) local.get 0 i32.const 8 i32.sub) + +pub fn ptr2double_array(ptr : Int) -> FixedArray[Double] { + set_64_header_ffi(ptr - 4) + ptr2double_array_ffi(ptr) +} + +fn set_64_header_ffi(offset : Int) -> Unit { + let len = load32(offset) + store32(offset, len.lsr(1)) + store8(offset, 241) +} pub trait Any {} pub struct Cleanup {