Warning

Array functionality is still very basic as you cannot resize arrays (incl. pushing elements) at runtime. You can only get, set, and replace array elements. Future releases of Mun will extend this functionality.

Marshalling Arrays

When embedding Mun in other languages, you will probably want to marshal arrays to and from another language. Mun provides a homogeneous interface for marshalling any array through an ArrayRef- a reference to a heap-allocated array. The Mun Runtime automatically handles the conversion from a function return type into an ArrayRef and function arguments into Mun arrays.

Marshalling reuses the memory allocated by the Mun garbage collector for arrays.

Listing 3-5 shows how to marshal array instances from Mun to Rust and vice versa, using the generate and add_one functions - previously defined.

extern crate mun_runtime;
use mun_runtime::{Runtime, ArrayRef};
use std::env;

fn main() {
    let lib_path = env::args().nth(1).expect("Expected path to a Mun library.");

    // Safety: We assume that the library that is loaded is a valid munlib
    let builder = Runtime::builder(lib_path);
    let mut runtime = unsafe { builder.finish() }
        .expect("Failed to spawn Runtime");

    let input: ArrayRef<'_, u64> = runtime.invoke("generate", ()).unwrap();

    assert_eq!(input.len(), 5);
    assert!(input.capacity() >= 5);

    let output: ArrayRef<'_, u64> = runtime
        .invoke("add_one", (input.clone(), input.len()))
        .unwrap();

    assert_eq!(output.iter().collect::<Vec<_>>(), vec![6, 5, 4, 3, 2]);
}

Listing 3-5: Marshalling array instances

Array methods

The API of ArrayRef contains two other methods for interacting with its data: capacity and len; respectively for retrieving the array's capacity and length:

    let input: ArrayRef<'_, u64> = runtime.invoke("generate", ()).unwrap();

    assert_eq!(input.len(), 5);
    assert!(input.capacity() >= 5);
}

Iterating elements

To obtain an iterator over the ArrayRef instance's elements, you can call the iter function, which returns an impl Iterator:

    let output: ArrayRef<'_, u64> = runtime
        .invoke("add_one", (input.clone(), input.len()))
        .unwrap();

    assert_eq!(output.iter().collect::<Vec<_>>(), vec![6, 5, 4, 3, 2]);