private static unsafe void SetResult(object value, Interop.wasm_val_t *result)
        {
            switch (value)
            {
            case int i:
                result->kind   = Interop.wasm_valkind_t.WASM_I32;
                result->of.i32 = i;
                break;

            case long l:
                result->kind   = Interop.wasm_valkind_t.WASM_I64;
                result->of.i64 = l;
                break;

            case float f:
                result->kind   = Interop.wasm_valkind_t.WASM_F32;
                result->of.f32 = f;
                break;

            case double d:
                result->kind   = Interop.wasm_valkind_t.WASM_F64;
                result->of.f64 = d;
                break;

            default:
                throw new NotSupportedException("Unsupported return value type.");
            }
        }
        private static unsafe void SetArgs(Interop.wasm_val_t *arguments, object[] args)
        {
            for (int i = 0; i < args.Length; ++i)
            {
                var arg = arguments[i];

                switch (arg.kind)
                {
                case Interop.wasm_valkind_t.WASM_I32:
                    args[i] = arg.of.i32;
                    break;

                case Interop.wasm_valkind_t.WASM_I64:
                    args[i] = arg.of.i64;
                    break;

                case Interop.wasm_valkind_t.WASM_F32:
                    args[i] = arg.of.f32;
                    break;

                case Interop.wasm_valkind_t.WASM_F64:
                    args[i] = arg.of.f64;
                    break;

                default:
                    throw new NotSupportedException("Unsupported value type.");
                }
            }
        }
        private static unsafe void SetResults(object value, Interop.wasm_val_t *results)
        {
            var tuple = value as ITuple;

            if (tuple is null)
            {
                SetResult(value, &results[0]);
            }
            else
            {
                for (int i = 0; i < tuple.Length; ++i)
                {
                    SetResults(tuple[i], &results[i]);
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Invokes the WebAssembly function.
        /// </summary>
        /// <param name="arguments">The array of arguments to pass to the function.</param>
        /// <returns>
        ///   Returns null if the function has no return value.
        ///   Returns the value if the function returns a single value.
        ///   Returns an array of values if the function returns more than one value.
        /// </returns>
        public object Invoke(params object[] arguments)
        {
            if (arguments.Length != Parameters.Count)
            {
                throw new WasmtimeException($"Argument mismatch when invoking function '{Name}': requires {Parameters.Count} but was given {arguments.Length}.");
            }

            unsafe
            {
                Interop.wasm_val_t *args    = stackalloc Interop.wasm_val_t[Parameters.Count];
                Interop.wasm_val_t *results = stackalloc Interop.wasm_val_t[Results.Count];

                for (int i = 0; i < arguments.Length; ++i)
                {
                    args[i] = Interop.ToValue(arguments[i], Parameters[i]);
                }

                var trap = Interop.wasm_func_call(_func, args, results);
                if (trap != IntPtr.Zero)
                {
                    throw TrapException.FromOwnedTrap(trap);
                }

                if (Results.Count == 0)
                {
                    return(null);
                }

                if (Results.Count == 1)
                {
                    return(Interop.ToObject(&results[0]));
                }

                var ret = new object[Results.Count];
                for (int i = 0; i < Results.Count; ++i)
                {
                    ret[i] = Interop.ToObject(&results[i]);
                }
                return(ret);
            }
        }