Skip to content

Commit

Permalink
Drop () in RustGlue function arguents
Browse files Browse the repository at this point in the history
  • Loading branch information
rtfeldman committed Jul 23, 2023
1 parent 64c49dd commit 759cef0
Showing 1 changed file with 72 additions and 38 deletions.
110 changes: 72 additions & 38 deletions crates/glue/src/RustGlue.roc
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,11 @@ generateEntryPoint = \buf, types, name, id ->
when Types.shape types id is
Function rocFn ->
arguments =
rocFn.args
|> List.mapWithIndex \argId, i ->
toArgStr rocFn.args types \argId, _shape, index ->
type = typeName types argId
c = Num.toStr i
"arg\(c): \(type)"
|> Str.joinWith ", "
indexStr = Num.toStr index

"arg\(indexStr): \(type)"

ret = typeName types rocFn.ret

Expand All @@ -154,16 +153,13 @@ generateEntryPoint = \buf, types, name, id ->
when Types.shape types id is
Function rocFn ->
arguments =
rocFn.args
|> List.map \argId ->
shape = Types.shape types argId
toArgStr rocFn.args types \argId, shape, _index ->
type = typeName types argId

if canDeriveCopy types shape then
"_: \(type)"
else
"_: &mut core::mem::ManuallyDrop<\(type)>"
|> Str.joinWith ", "

ret = typeName types rocFn.ret
"(_: *mut \(ret), \(arguments))"
Expand All @@ -175,16 +171,13 @@ generateEntryPoint = \buf, types, name, id ->
externArguments =
when Types.shape types id is
Function rocFn ->
rocFn.args
|> List.mapWithIndex \argId, index ->
toArgStr rocFn.args types \_argId, shape, index ->
indexStr = Num.toStr index
shape = Types.shape types argId

if canDeriveCopy types shape then
"arg\(indexStr)"
else
"&mut core::mem::ManuallyDrop::new(arg\(indexStr))"
|> Str.joinWith ", "

_ ->
""
Expand Down Expand Up @@ -215,29 +208,40 @@ generateFunction = \buf, types, rocFn ->
lambdaSet = typeName types rocFn.lambdaSet

publicArguments =
rocFn.args
|> List.mapWithIndex \argId, i ->
toArgStr rocFn.args types \argId, _shape, index ->
type = typeName types argId
c = Num.toStr i
"arg\(c): \(type)"
|> Str.joinWith ", "
indexStr = Num.toStr index

"arg\(indexStr): \(type)"

externDefArguments =
rocFn.args
|> List.mapWithIndex \argId, i ->
type = typeName types argId
c = Num.toStr i
"arg\(c): *const \(type)"
|> Str.joinWith ", "
withoutUnit =
toArgStr rocFn.args types \argId, _shape, index ->
type = typeName types argId
indexStr = Num.toStr index

"arg\(indexStr): *const \(type)"

if Str.isEmpty withoutUnit then
# These always have a first argument that's a pointer, even if it's to nothing.
"arg0: *const ()"
else
withoutUnit

externCallArguments =
rocFn.args
|> List.mapWithIndex \_, i ->
c = Num.toStr i
"&arg\(c)"
|> Str.joinWith ", "
withoutUnit =
toArgStr rocFn.args types \_argId, _shape, index ->
indexStr = Num.toStr index

"&arg\(indexStr)"

externComma = if Str.isEmpty publicArguments then "" else ", "
if Str.isEmpty withoutUnit then
# These always have a first argument that's a pointer, even if it's to nothing.
"&()"
else
withoutUnit

publicComma = if Str.isEmpty publicArguments then "" else ", "

ret = typeName types rocFn.ret

Expand All @@ -251,20 +255,20 @@ generateFunction = \buf, types, rocFn ->
}
impl \(name) {
pub fn force_thunk(mut self, \(publicArguments)) -> \(ret) {
pub fn force_thunk(self\(publicComma)\(publicArguments)) -> \(ret) {
extern "C" {
fn \(externName)(\(externDefArguments)\(externComma) closure_data: *mut u8, output: *mut \(ret));
fn \(externName)(\(externDefArguments), closure_data: *mut u8, output: *mut \(ret));
}
let mut output = core::mem::MaybeUninit::uninit();
let ptr = &mut self.closure_data as *mut _ as *mut u8;
let closure_ptr =
(&mut core::mem::ManuallyDrop::new(self.closure_data)) as *mut _ as *mut u8;
unsafe { \(externName)(\(externCallArguments)\(externComma) ptr, output.as_mut_ptr(), ) };
// ownership of the closure is transferred back to roc
core::mem::forget(self.closure_data);
unsafe {
\(externName)(\(externCallArguments), closure_ptr, output.as_mut_ptr());
unsafe { output.assume_init() }
output.assume_init()
}
}
}
"""
Expand Down Expand Up @@ -2065,3 +2069,33 @@ nextMultipleOf = \lhs, rhs ->
when lhs % rhs is
0 -> lhs
r -> lhs + (rhs - r)


isUnit : Shape -> Bool
isUnit = \shape ->
when shape is
Unit -> Bool.true
_ -> Bool.false

toArgStr : List TypeId, Types, (TypeId, Shape, Nat -> Str) -> Str
toArgStr = \args, types, fmt ->
answer = List.walk args { state: "", index: 0 } \{ state, index }, argId ->
newState =
shape = Types.shape types argId

# Drop `()` args; they aren't FFI-safe, and nothing will get passed anyway.
if isUnit shape then
state
else
argStr = fmt argId shape index

if Str.isEmpty state then
argStr # Don't prepend a comma if this is the first one
else
state
|> Str.concat ", "
|> Str.concat argStr

{ state: newState, index: index + 1 }

answer.state

0 comments on commit 759cef0

Please sign in to comment.