rust-diplomat / diplomat

Experimental Rust tool for generating FFI definitions allowing many other languages to call Rust code
https://rust-diplomat.github.io/book/
Other
532 stars 51 forks source link

Fixing bug in opaque/struct cleanup codegen in kotlin #690

Closed emarteca closed 2 months ago

emarteca commented 2 months ago

Previously there was a bug where the memory cleanup for multiple pass-by-reference arguments would end up on the same line (note: the cleanup code is only generated if the function in question returns a rust-owned object). This PR fixes it.

Example of bug: Rust

#[diplomat::bridge]
mod ffi {
    #[diplomat::opaque]
    struct ExampleStruct {
        notempty: bool,
    }

    #[diplomat::opaque]
    struct RustOwnedBytes {
        my_bytes: Vec<u8>,
    }

    impl ExampleStruct {
        pub fn testing(&self, a: &[u8], b: &[u8]) -> Box<RustOwnedBytes> {
            return Box::new(RustOwnedBytes{my_bytes: a.to_vec()})
        }
    }
}

This would generate the following bug in Kotlin (buggy line commented):

 fun testing(a: UByteArray, b: UByteArray): RustOwnedBytes {
        val (aMem, aSlice) = PrimitiveArrayTools.native(a)
        val (bMem, bSlice) = PrimitiveArrayTools.native(b)

        val returnVal = lib.ExampleStruct_testing(handle, aSlice, bSlice);
        val selfEdges: List<Any> = listOf()
        val handle = returnVal 
        val returnOpaque = RustOwnedBytes(handle, selfEdges)
        CLEANER.register(returnOpaque, RustOwnedBytes.RustOwnedBytesCleaner(handle, RustOwnedBytes.lib));
        aMem.close()bMem.close() // THIS IS THE BUG THE CLEANUP LINES ARE ON THE SAME LINE
        return returnOpaque
    }