internal static WebAssemblyType GetInitExprType(InitExpr init) { if (init.expr.Length < 1) { throw new Exception("Unexpected init expression."); } switch (init.expr[0]) { case (byte)WebAssemblyOpcode.I32_CONST: return(WebAssemblyType.i32); case (byte)WebAssemblyOpcode.I64_CONST: return(WebAssemblyType.i64); case (byte)WebAssemblyOpcode.F32_CONST: return(WebAssemblyType.f32); case (byte)WebAssemblyOpcode.F64_CONST: return(WebAssemblyType.f64); default: throw new Exception("Invalid init expression. Expected only simple constant load instruction."); } }
public GlobalVariable(BinaryReader reader) { type = new GlobalType(reader); init = new InitExpr(reader); if (type.content_type != WebAssemblyHelper.GetInitExprType(init)) { throw new Exception("Global variable type and expression mismatch."); } }
public GlobalVariable(GlobalType type, InitExpr init) { this.type = type ?? throw new ArgumentException(nameof(type)); this.init = init ?? throw new ArgumentException(nameof(init)); if (type.content_type != WebAssemblyHelper.GetInitExprType(init)) { throw new Exception("Global variable type and expression mismatch."); } }
public DataSegment(BinaryReader reader) { memory_index = LEB128.ReadUInt32(reader); offset = new InitExpr(reader); uint count = LEB128.ReadUInt32(reader); if (count > int.MaxValue) { throw new NotImplementedException($"Count larger than {int.MaxValue} bytes not supported."); } data = reader.ReadBytes((int)count); }
public ElementSegment(BinaryReader reader) { table_index = LEB128.ReadUInt32(reader); offset = new InitExpr(reader); uint num_elem = LEB128.ReadUInt32(reader); function_index = new uint[num_elem]; for (uint i = 0; i < num_elem; i++) { function_index[i] = LEB128.ReadUInt32(reader); } }
internal static ValueObject GetInitExpr(InitExpr init, List <GlobalInstance> initialized_globals) { if (init.expr.Length < 3) { throw new Exception("Unexpected init expression."); } uint pc = 0; ValueObject ret = null; switch (init.expr[0]) { case (byte)WebAssemblyOpcode.I32_CONST: ret = new ValueObject(LEB128.ReadUInt32(init.expr, ref pc)); break; case (byte)WebAssemblyOpcode.I64_CONST: ret = new ValueObject(LEB128.ReadUInt64(init.expr, ref pc)); break; case (byte)WebAssemblyOpcode.F32_CONST: ret = new ValueObject(BitConverter.ToSingle(init.expr, (int)pc)); break; case (byte)WebAssemblyOpcode.F64_CONST: ret = new ValueObject(BitConverter.ToDouble(init.expr, (int)pc)); break; case (byte)WebAssemblyOpcode.GLOBAL_GET: GlobalInstance gi = initialized_globals[LEB128.ReadInt32(init.expr, ref pc)]; if (!gi.is_mutable) { throw new Exception("Unexpected init expression."); } ret = gi.value; break; default: throw new Exception("Invalid init expression. Expected only simple constant load instruction or global get."); } pc++; if (init.expr[pc] != (byte)WebAssemblyOpcode.END || init.expr.Length > pc) { throw new Exception("Invalid init expression."); } return(ret); }
internal static uint GetOffset(InitExpr init) { if (init.expr.Length < 3 || init.expr.Length > 6 || init.expr[0] != (byte)WebAssemblyOpcode.I32_CONST || init.expr[init.expr.Length - 1] != (byte)WebAssemblyOpcode.END) { throw new Exception("Unexpected init expression."); } uint value = 0; for (int i = init.expr.Length - 2; i > 0; i--) { value = value << 8 | init.expr[i]; } return(value); }
public ElementSegment(uint table_index, InitExpr offset, uint[] function_index) { this.table_index = table_index; this.offset = offset ?? throw new ArgumentException(nameof(offset)); this.function_index = function_index ?? throw new ArgumentException(nameof(function_index)); }
public DataSegment(uint memory_index, InitExpr offset, byte[] data) { this.memory_index = memory_index; this.offset = offset ?? throw new ArgumentException(nameof(offset)); this.data = data ?? throw new ArgumentException(nameof(data)); }