/// <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); } }
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)); }
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; }
public LocalEntry(uint count, WebAssemblyType type) { if (!Enum.IsDefined(typeof(WebAssemblyType), type)) { throw new ArgumentException(nameof(type)); } this.count = count; this.type = type; }
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); }
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); }
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; }
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); } }
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; }
public TableInstance(WebAssemblyType type, uint initial, uint?maximum) { this.type = type; mem = new WebAssemblyMemoryManager(initial, maximum ?? uint.MaxValue); }
public GlobalInstance(bool is_mutable, WebAssemblyType type, ValueObject value) { this.is_mutable = is_mutable; this.type = type; this.value = value; }
public ValueObject(double value) { type = WebAssemblyType.f64; this.value = value; }
public ValueObject(float value) { type = WebAssemblyType.f32; this.value = value; }
public ValueObject(ulong value) { type = WebAssemblyType.i64; this.value = value; }
public ValueObject(uint value) { type = WebAssemblyType.i32; this.value = value; }
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); }