# How to pass rich data from a Wasm host to a Kotlin guest?

**URL:** https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527
**Category:** WebAssembly
**Created:** [November 15, 2024, 1:47pm UTC](https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527 "2024-11-15T13:47:40Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![upastorm](https://avatars.discourse-cdn.com/v4/letter/u/91b2a8/32.png) [@upastorm](https://discuss.kotlinlang.org/u/upastorm)
#### Post date: [November 15, 2024, 1:47pm UTC](https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527/1 "2024-11-15T13:47:40Z")

</div>

I’m experimenting with using Kotlin compilation to Wasm to run it in an embeddable Wasm runtime like WasmEdge. Rich data exchange usually happens through linear memory. For example, TinyGo compiled-guests export `malloc` and `free` functions which makes it possible for a host to allocate memory up front and then pass the pointer to it when calling a guest function.

Kotlin doesn’t export anything like `malloc` and it doesn’t seem to provide any means to implement it. Manual memory allocation can only happen inside a `withScopedMemoryAllocator {}` so how the host is supposed to pass any non-primitive data to a guest?

Is it supposed to be something like this?:

```auto
@OptIn(UnsafeWasmMemoryApi::class)
@WasmExport("func_with_string_arg")
fun funcWithStringArg(stringSize: Int) = withScopedMemoryAllocator { allocator ->
    val ptr = allocator.allocate(stringSize)
    storeData(ptr.address.toInt()) // this calls the host which should now store the string at the provided address
    // read the data at ptr
}

```

This would mean the host would have to store some sort of context that should be available for the duration of the guest call. Is it the only option?

---

<div class="post-metadata">

### Author: ![upastorm](https://avatars.discourse-cdn.com/v4/letter/u/91b2a8/32.png) [@upastorm](https://discuss.kotlinlang.org/u/upastorm)
#### Post date: [November 15, 2024, 2:49pm UTC](https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527/2 "2024-11-15T14:49:50Z")

</div>

It’s also not clear how to return rich data out of a function call. If I understand correctly, all allocated memory will be garbage collected on exit so returning a pointer to it wouldn’t work.

---

<div class="post-metadata">

### Author: ![bashor](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/bashor/32/1431_2.png) [@bashor](https://discuss.kotlinlang.org/u/bashor)
#### Post date: [November 19, 2024, 8:45pm UTC](https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527/3 "2024-11-19T20:45:32Z")

</div>

Right, the only safe way now to work with linear memory is within the `withScopedMemoryAllocator` block.

---

<div class="post-metadata">

### Author: ![upastorm](https://avatars.discourse-cdn.com/v4/letter/u/91b2a8/32.png) [@upastorm](https://discuss.kotlinlang.org/u/upastorm)
#### Post date: [November 20, 2024, 1:49pm UTC](https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527/4 "2024-11-20T13:49:00Z")

</div>

@bashor, thanks, so to clarify the only way to return rich data from a Kotlin guest function call would be to call some host function that would store the result, i.e. something like this?

```auto
fun funcWithStringArg(stringSize: Int, callId Int) = withScopedMemoryAllocator { allocator ->
    // allocate a buffer for the argument
    callHostToStoreArgumentData(argBufPtr.address.toInt(), callId) // host can understand by callId arguments of which call are requested
    // execute the function body
   // store the function result data in the linear memory
    callHostToReturnResultData(resultDataPtr.address.toInt(), callId) // host can understand by callId which call returned the result
}

```

Is it possible in the future there will be other options, maybe something like a global allocator that allows allocations that can outlive a function call?

---

<div class="post-metadata">

### Author: ![bashor](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/bashor/32/1431_2.png) [@bashor](https://discuss.kotlinlang.org/u/bashor)
#### Post date: [November 20, 2024, 2:50pm UTC](https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527/5 "2024-11-20T14:50:18Z")

</div>

Yes, it’s the proper way right now.  
Basically, it’s not that bad – execution will cross a host-guest boundary the same times as if we had exported `allocate` function.

It’s not like only way, but others may have their own disadvantages, depending on your case, e.g.

- you can define and export `array_get(array, index)`, `array_set(array, index, value) ` function and use GC array, or maybe your VM provide API to work with GC arrays out of the box.
- you can rely on some implementation details of Kotlin’s allocator, but it will require you to be more accurate and keep in mind that implementation details may change in the future.

---

<div class="post-metadata">

### Author: ![bashor](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/bashor/32/1431_2.png) [@bashor](https://discuss.kotlinlang.org/u/bashor)
#### Post date: [November 20, 2024, 3:08pm UTC](https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527/6 "2024-11-20T15:08:15Z")

</div>

> [@upastorm](#):
>
> Is it possible in the future there will be other options, maybe something like a global allocator that allows allocations that can outlive a function call?

Maybe, but no ETAs.  
Something close to your needs should be done for Component Model, see [KT-65030](https://youtrack.jetbrains.com/issue/KT-65030).  
Aside from that, I’ve created a bunch of issues around memory, following ones could be interesting for your case:

- [KT-73261](https://youtrack.jetbrains.com/issue/KT-73261) K/Wasm: provide an Allocator API not limited by scope
- [KT-73262](https://youtrack.jetbrains.com/issue/KT-73262) K/Wasm: expose Allocator API
- [KT-73236](https://youtrack.jetbrains.com/issue/KT-73236) K/Wasm: add an ability to use imported memory instead of defining one inside

Feel free to vote and star issues to get notifications about future updates.

---

<div class="post-metadata">

### Author: ![upastorm](https://avatars.discourse-cdn.com/v4/letter/u/91b2a8/32.png) [@upastorm](https://discuss.kotlinlang.org/u/upastorm)
#### Post date: [November 21, 2024, 7:55am UTC](https://discuss.kotlinlang.org/t/how-to-pass-rich-data-from-a-wasm-host-to-a-kotlin-guest/29527/7 "2024-11-21T07:55:25Z")

</div>

Thank you!

> [@bashor](#):
>
> It’s not like only way, but others may have their own disadvantages, depending on your case, e.g.
> 
> - you can define and export `array_get(array, index)`, `array_set(array, index, value) ` function and use GC array, or maybe your VM provide API to work with GC arrays out of the box.
> - you can rely on some implementation details of Kotlin’s allocator, but it will require you to be more accurate and keep in mind that implementation details may change in the future.

All low-level functions for working with memory that Kotlin’s allocator use are marked as internal as far as I can see so not sure if it would be possible to implement such functions at the moment.

Thank you, I will keep an eye on the issues listed!
