in platforms, having more than one required function panics with "thread 'main' panicked at 'There were still outstanding Arc references to module_ids', crates/compiler/load_internal/src/file.rs:1842:37"
platform "hello world"
requires {} { first : arg -> ret, second : arg -> ret}
removing second solves it
am i.. not supposed to have two decls there?
Just not supported yet. The apps with multiple declarations use a record of declarations. Kinda hacky and not always done correctly. I wonder if we have a tracking bug for this, super old issue.
oof i wanted it so i could have multiple methods as interop examples
is this a big deal to implement? perhaps i could take a look
I mean you can have multiple method currently, just via a workaround.
and no idea on difficulty
Brendan Hansknecht said:
ohhh now i see what u mean
nice that's not even that bad
There are gotcha on the platform side around implementation depending if those return functions are closures or pure functions with no extra data. If you can make sure they are pure with no extra data it will avoid issues.
As in this may cause you problems depending on how you implement the host:
main = \_ ->
someDat = [1,2,3]
{
getDataForHost: \_ -> someData
}
vs the below shouldn't have any gotchas:
main = \_ ->
{
getDataForHost: \_ ->
someDat = [1,2,3]
someData
}
oh yea i think i ran into something like that in another code
ill be careful of that then
tnx
uhhh the program
trick makes it much harder to work with image.png
now im actually not sure what extern function to expect in the host code
Did you use as
to name each function in the record?
oh no i forgot
hold up ill see if it makes it better
Basically do that. They each function will be exposed the same way mainForHost normally is.
As long as they are implement without capture data. They can be called the same way as mainForHost
Of course with their own arguments and return type.
Brendan Hansknecht said:
As long as they are implement without capture data. They can be called the same way as mainForHost
capture data in what way?
the functions you expose should be top-level functions
Brendan Hansknecht said:
Basically do that. They each function will be exposed the same way mainForHost normally is.
um i see now the names i defined
got some _result_size
suffix now
Like i showed above with someData
Folkert de Vries said:
the functions you expose should be top-level functions
ohh yea no closures here so we're good
um why actually do they get a result_size suffix?
maybe it's something else
I think you should be able to ignore those and just use the same equivalent functions as with mainForHost.
It just returns the number of bytes the result is
no they're not the same
Which you probably already know
at least not named the same
_1_exposed_generic
suffix is only on the program now, see?
Can you share your current code
Just the platform def
Like programForHost type and definition
sure
platform "jvm-interop"
requires {} { program : _ }
exposes []
packages {}
imports []
provides [programForHost]
programForHost : {
interpolateString : Str -> Str as InterpolateString,
mulArrByScalar : List I32 -> List I32 as MulArrByScalar,
}
programForHost = program
Put parens around the function types and try again.
yes the as
here binds only to the return type
(put parens not including the as
right?)
does look a bit different
image.png
it needs to apply to the whole function type, so (Foo -> Bar) as Fx
Folkert de Vries said:
it needs to apply to the whole function type, so
(Foo -> Bar) as Fx
yea that's what i did
is _caller
what im after now?
yep
nicee thanks guys
If this helps at all: https://github.com/roc-lang/roc/blob/main/examples/gui/breakout/platform/src/roc.rs
Example of use in rust.
You can see how the multiple functions all look the same more or less in how they get called. Which is very similar to mainForHost
in other apps.
Actual call example: https://github.com/roc-lang/roc/blob/main/examples/gui/breakout/platform/src/roc.rs#L358-L370
Though if you have a static result_size, I don't think you need to call that function.
so is _1_exposed_generic
just for unnamed scenarios?
essentially. Thouhgh it can never have closure capture data.
These technically could.
Then you would have to call them in a slightly more complex way.
is that implemented?
wonder how you'd do that
You call programForHost
Then take the closure data that it returns and split it up into the closure data for each function and make sure to give that to each function.
If the methods are called more than once, you may also need to deal with refcounts updating, not sure though.
This is all of the stuff where fully working glue will be amazing
Should all be generated correctly for you without needing to know all these details and byte offsets.
seems that the _caller symbol offset is.. off
i keep crashing the jvm now
munmap_chunk(): invalid pointer
fish: Job 1, 'java javaSource.Greeter' terminated by signal SIGABRT (Abort)
though actually what happened before (and worked) is that i wrapped the required functions in new functions (because you cant re-export, at least that's what the compiler said) and exposed those
now that we turn over the same, it can't find the functions, ig
dank said:
sure
platform "jvm-interop" requires {} { program : _ } exposes [] packages {} imports [] provides [programForHost] programForHost : { interpolateString : (Str -> Str) as InterpolateString, } programForHost = program
to make stuff clear, this ^ doesn't work
but this V does
platform "jvm-interop"
requires {} { interpolateString : arg -> ret }
exposes []
packages {}
imports []
provides [interpolateStringy] # (y suffix name change for convenience, updated accordingly in host while testing so it doesnt matter)
interpolateStringy = \arg -> interpolateString arg
interesting bug
It would surprise me if the symbol offsets are wrong. Probably a different root cause
well idk. ill call it a night for now but look at it some more tomorrow
at least i found 6 (mostly parser) issues! also learned a shitton on platforms, so that's nice
am i mad or does using a record in requires causes a different memory layout
image.png
image.png
Best way to tell would be to use --debug
and look at the llvm ir.
Last updated: Jul 06 2025 at 12:14 UTC