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

Unable to create a function with parameter when Type.IsValueType is true #174

Open
hiinaspace opened this issue Nov 3, 2022 · 3 comments

Comments

@hiinaspace
Copy link

I have a really simple adaption of the externref sample, running inside unity 2021.3, whose csharp runtime is ostensibly .NET standard 2.1 compatible:

(module
  (import "" "getX" (func $.getX (param externref) (result f32)))
  (func (export "run") (param externref) (result f32)
    local.get 0
    call $.getX
  )
)
public class WasmTest : MonoBehaviour
{
    public TextAsset watSource;

    void Start()
    {
        var engine = new Engine();

        var module = Module.FromText(
            engine,
            watSource.name,
            watSource.text
        );

        var linker = new Linker(engine);
        var store = new Store(engine);

        linker.Define(
            "",
            "getX",
            Function.FromCallback(store, (Vector3 vec) => ((Vector3)vec).x)
        );

        var instance = linker.Instantiate(store, module);
        var run = instance.GetFunction<object, float>("run");
        float res = run(transform.position);
        Debug.Log($"the x is {res}");
    }
}

However, as written, I get

WasmtimeException: Unable to create a function with parameter of type 'UnityEngine.Vector3'.
Wasmtime.Function.GetFunctionType (System.Type type, System.Boolean hasReturn, System.Collections.Generic.List`1[T] parameters, System.Collections.Generic.List`1[T] results, System.Boolean& hasCaller, System.Boolean& returnsTuple) (at C:/Users/s/source/repos/wasmtime-dotnet/src/Function.cs:2411)
Wasmtime.Function..ctor (Wasmtime.IStore store, System.Delegate callback, System.Boolean hasReturn) (at C:/Users/s/source/repos/wasmtime-dotnet/src/Function.cs:2242)
Wasmtime.Function.FromCallback[T,TResult] (Wasmtime.IStore store, System.Func`2[T,TResult] callback) (at C:/Users/s/source/repos/wasmtime-dotnet/src/Function.cs:300)
WasmTest.Start () (at Assets/wasmtest/WasmTest.cs:25)

If I change the function argument type from Vector3 to just object and do the cast manually, it works as expected. Looks like it's because it falls out of Value.TryGetKind at

if (!type.IsValueType)
, because unity sets Type.IsValueType == true.

Is that test of IsValueType necessary? I don't know if this is just a weird unity environment thing.

@peterhuene
Copy link
Member

peterhuene commented Nov 8, 2022

Hi @hiinaspace:

The intention behind this is that externref is a reference to an external (host) object, so it is intentionally limiting the support for .NET types to those that are reference types. It also prevents unintentional boxing of value types were they implicitly allowed.

As Vector3 is a value type, it gets rejected. Using object and manually boxing a Vector3, as you've discovered, should work.

I think you'll have to stick with using object and doing an explicit boxing/unboxing of the value until I'm convinced that implicitly boxing value types for externref is the right approach.

@peterhuene
Copy link
Member

At a bare minimum, we should improve this exception message to note that it's because the type is a value type and .NET types are required to be reference types to work with externref.

@hiinaspace
Copy link
Author

I see, thanks for the clarification. My java background assuming that all non-primitives are references doesn't work in c#...

I agree that a better error message would be nice, in lieu of autoboxing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants