/// <summary>
    /// Creates a new <see cref="FunctionImport"/> instance with the provided <see cref="Delegate"/>.
    /// </summary>
    /// <param name="del">The delegate to use for the import.</param>
    /// <exception cref="ArgumentNullException">No parameters can be null.</exception>
    /// <exception cref="ArgumentException">A parameter or return type is not compatible with WebAssembly.</exception>
    public FunctionImport(Delegate del)
    {
        if (del == null)
        {
            throw new ArgumentNullException(nameof(del));
        }

        var method = (this.Method = del).GetMethodInfo();

        if (method == null)
        {
            throw new ArgumentException("Provided delegate isn't associated with a method.", nameof(del));
        }

        this.Type = new WebAssemblyType();
        if (method.ReturnType != typeof(void))
        {
            if (!method.ReturnType.TryConvertToValueType(out var type))
            {
                throw new ArgumentException($"Return type {method.ReturnType} is not compatible with WebAssembly.", nameof(del));
            }

            this.Type.Returns = new[] { type };
        }

        foreach (var parameter in method.GetParameters())
        {
            if (!parameter.ParameterType.TryConvertToValueType(out var type))
            {
                throw new ArgumentException($"Parameter type {parameter} is not compatible with WebAssembly.", nameof(del));
            }

            this.Type.Parameters.Add(type);
        }
    }
예제 #2
0
 public TableType(WebAssemblyType element_type, ResizeLimit limits)
 {
     if (element_type != WebAssemblyType.anyfunc)
     {
         throw new ArgumentException(nameof(element_type));
     }
     this.element_type = element_type;
     this.limits       = limits ?? throw new ArgumentException(nameof(limits));
 }
예제 #3
0
            public GlobalType(WebAssemblyType content_type, bool mutability)
            {
                if (!WebAssemblyHelper.IsValueType(content_type))
                {
                    throw new ArgumentException(nameof(content_type));
                }

                this.content_type = content_type;
                this.mutability   = mutability;
            }
예제 #4
0
            public LocalEntry(uint count, WebAssemblyType type)
            {
                if (!Enum.IsDefined(typeof(WebAssemblyType), type))
                {
                    throw new ArgumentException(nameof(type));
                }

                this.count = count;
                this.type  = type;
            }
예제 #5
0
            public TableType(BinaryReader reader)
            {
                sbyte type = LEB128.ReadInt7(reader);

                if (type != (int)WebAssemblyType.anyfunc)
                {
                    throw new Exception($"File is invalid. Expected byte '{WebAssemblyType.anyfunc}', received '{type}'.");
                }
                element_type = WebAssemblyType.anyfunc;
                limits       = new ResizeLimit(reader);
            }
예제 #6
0
        private ValueObject GetValueOfTypeOrFail(WebAssemblyType expected_type)
        {
            ValueObject obj = GetValueOrFail();

            if (obj.type != expected_type)
            {
                logger.Debug($"Expected type of {expected_type} but got {obj.type}.");

                Trap("Function stack corrupt.");
            }

            return(obj);
        }
예제 #7
0
            public LocalEntry(BinaryReader reader)
            {
                count = LEB128.ReadUInt32(reader);

                var tmp_type = reader.ReadByte();

                if (!Enum.IsDefined(typeof(WebAssemblyType), tmp_type))
                {
                    throw new Exception($"File is invalid. Expected WebAssemblyType, received '{tmp_type}'.");
                }

                type = (WebAssemblyType)tmp_type;
            }
예제 #8
0
        internal static bool IsValueType(WebAssemblyType type)
        {
            switch (type)
            {
            case WebAssemblyType.i32:
            case WebAssemblyType.i64:
            case WebAssemblyType.f32:
            case WebAssemblyType.f64:
                return(true);

            default:
                return(false);
            }
        }
예제 #9
0
            public GlobalType(BinaryReader reader)
            {
                content_type = (WebAssemblyType)LEB128.ReadUInt7(reader);

                if (!WebAssemblyHelper.IsValueType(content_type))
                {
                    throw new Exception($"File is invalid. Expected value type, received '{content_type}'.");
                }

                byte mut = LEB128.ReadUInt7(reader);

                if (mut != 0 && mut != 1)
                {
                    throw new Exception($"File is invalid. Expected 0 or 1, received '{mut}'.");
                }

                mutability = mut != 0;
            }
예제 #10
0
 public TableInstance(WebAssemblyType type, uint initial, uint?maximum)
 {
     this.type = type;
     mem       = new WebAssemblyMemoryManager(initial, maximum ?? uint.MaxValue);
 }
예제 #11
0
 public GlobalInstance(bool is_mutable, WebAssemblyType type, ValueObject value)
 {
     this.is_mutable = is_mutable;
     this.type       = type;
     this.value      = value;
 }
예제 #12
0
 public ValueObject(double value)
 {
     type       = WebAssemblyType.f64;
     this.value = value;
 }
예제 #13
0
 public ValueObject(float value)
 {
     type       = WebAssemblyType.f32;
     this.value = value;
 }
예제 #14
0
 public ValueObject(ulong value)
 {
     type       = WebAssemblyType.i64;
     this.value = value;
 }
예제 #15
0
 public ValueObject(uint value)
 {
     type       = WebAssemblyType.i32;
     this.value = value;
 }
예제 #16
0
        private (ValueObject value, byte[] memory, int location) StoreOrFail(byte[] code, uint size, WebAssemblyType type, ref uint pc)
        {
            // align is in bytes
            // it tells us how this value is aligned
            // in our implementation, we can disregard alignment
            int  align  = 1 << (int)LEB128.ReadUInt32(code, ref pc);
            uint offset = LEB128.ReadUInt32(code, ref pc);

            ValueObject c  = GetValueOfTypeOrFail(type);
            ValueObject i  = GetValueOfTypeOrFail(WebAssemblyType.i32);
            long        ea = i.AsI32() + offset;
            uint        N  = size / 8;

            if ((ea + N) > ctx.linear_memory[0].size)
            {
                Trap("Illegal memory access");
            }

            logger.ConditionalTrace($"Memory location calculated = {ea}.");

            return(c, ctx.linear_memory[0].memory, (int)ea);
        }