Use ManuallyDrop to fix ownership bug in RustGlue

This commit is contained in:
Richard Feldman 2023-07-19 14:36:01 -04:00
parent d93fff043e
commit 77a89a23e1
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B

View file

@ -156,8 +156,13 @@ generateEntryPoint = \buf, types, name, id ->
arguments = arguments =
rocFn.args rocFn.args
|> List.map \argId -> |> List.map \argId ->
shape = Types.shape types argId
type = typeName types argId type = typeName types argId
"_: \(type)"
if canDeriveCopy types shape then
"_: \(type)"
else
"_: &mut core::mem::ManuallyDrop<\(type)>"
|> Str.joinWith ", " |> Str.joinWith ", "
ret = typeName types rocFn.ret ret = typeName types rocFn.ret
@ -171,9 +176,14 @@ generateEntryPoint = \buf, types, name, id ->
when Types.shape types id is when Types.shape types id is
Function rocFn -> Function rocFn ->
rocFn.args rocFn.args
|> List.mapWithIndex \_, i -> |> List.mapWithIndex \argId, index ->
c = Num.toStr i indexStr = Num.toStr index
"arg\(c)" shape = Types.shape types argId
if canDeriveCopy types shape then
"arg\(indexStr)"
else
"&mut core::mem::ManuallyDrop::new(arg\(indexStr))"
|> Str.joinWith ", " |> Str.joinWith ", "
_ -> _ ->
@ -187,11 +197,13 @@ generateEntryPoint = \buf, types, name, id ->
fn roc__\(name)_1_exposed_generic\(externSignature); fn roc__\(name)_1_exposed_generic\(externSignature);
} }
let mut ret = std::mem::MaybeUninit::uninit(); let mut ret = core::mem::MaybeUninit::uninit();
unsafe { roc__\(name)_1_exposed_generic(ret.as_mut_ptr(), \(externArguments)) }; unsafe {
roc__\(name)_1_exposed_generic(ret.as_mut_ptr(), \(externArguments));
unsafe { ret.assume_init() } ret.assume_init()
}
} }
""" """
@ -244,7 +256,7 @@ generateFunction = \buf, types, rocFn ->
fn \(externName)(\(externDefArguments)\(externComma) closure_data: *mut u8, output: *mut \(ret)); fn \(externName)(\(externDefArguments)\(externComma) closure_data: *mut u8, output: *mut \(ret));
} }
let mut output = std::mem::MaybeUninit::uninit(); let mut output = core::mem::MaybeUninit::uninit();
let ptr = &mut self.closure_data as *mut _ as *mut u8; let ptr = &mut self.closure_data as *mut _ as *mut u8;
unsafe { \(externName)(\(externCallArguments)\(externComma) ptr, output.as_mut_ptr(), ) }; unsafe { \(externName)(\(externCallArguments)\(externComma) ptr, output.as_mut_ptr(), ) };