Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marshal via arrays #146

Closed
elringus opened this issue Feb 11, 2024 · 1 comment
Closed

Marshal via arrays #146

elringus opened this issue Feb 11, 2024 · 1 comment
Labels
enhancement New feature or enhancement

Comments

@elringus
Copy link
Owner

elringus commented Feb 11, 2024

Instead of JSON, explore marshaling via arrays, similar to Embind (https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#value-types), eg:

public record Record (string Str, int Int, bool Bool, Record? Other);

[JSExport]
private static void ReceiveRecord ([JSMarshalAs<JSType.Any>] object raw)
{
    var record = Unmarshal((object?[])raw);
    Console.WriteLine($"Record({record.Str}, {record.Int}, {record.Bool}, Record({record.Other?.Str},
        {record.Other?.Int}, {record.Other?.Bool}))");

    static Record Unmarshal (object?[] raw) => new(
        (string)raw[0]!,
        (int)(double)raw[1]!,
        (bool)raw[2]!,
        raw[3] != null ? Unmarshal(raw[3..7]) : null
    );
}
exports.Program.ReceiveRecord(["foo", 1, true, "bar", 2, false, null]);

And the other way around:

[JSExport] [return: JSMarshalAs<JSType.Any>]
private static object GetRecord ()
{
    return new object?[] { "foo", 5, true, new object?[] { "bar", 6, false, null } };
}

— returns in JavaScript: ["foo",5,true,["bar",6,false,null]].


Should probably be postponed until #138 is solved; otherwise, we'll break interop with tasks of custom data types, that are currently serialized to JSON.
We can actually send arrays as objects:

[JSExport] [return: JSMarshalAs<JSType.Promise<JSType.Any>>]
private static async Task<object> GetRecordAsync ()
{
    await Task.Delay(1);
    return new object?[] { "foo", 7, true, new object?[] { "bar", 8, false, null } };
}

— the task value is transferred to JavaScript as ["foo",7,true,["bar",8,false,null]].

@elringus elringus added the enhancement New feature or enhancement label Feb 11, 2024
@elringus elringus added this to the First stable release milestone Feb 11, 2024
@elringus
Copy link
Owner Author

Implemented in https://github.com/elringus/bootsharp/tree/arch/marshal-via-arrays.

After testing, it doesn't seem worth it, as perf and min build size are roughly the same, while it adds more pressure to GC due to array allocations and it's not clear whether it's possible to support recursive types marshaling. It also adds limitations on the init scenarios of the marshaled types, eg it's not possible to use constructor overloads, as we're not storing parameter names.

@elringus elringus closed this as not planned Won't fix, can't repro, duplicate, stale May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or enhancement
Projects
None yet
Development

No branches or pull requests

1 participant