internal static GlobalAccessorInstruction Create(BinaryParsingReader reader, bool getter) { uint globalIndex = reader.ReadVarUint32(); OpCodes opcode = getter ? OpCodes.GetGlobal : OpCodes.SetGlobal; if (MaxReusableIndex < globalIndex) { return(new GlobalAccessorInstruction(opcode) { GlobalIndex = globalIndex }); } GlobalAccessorInstruction[] reuseTarget = getter ? _knownGlobalGetters : _knownGlobalSetters; GlobalAccessorInstruction result = reuseTarget[globalIndex]; if (null != result) { _reuseCount++; } else { result = new GlobalAccessorInstruction(opcode) { GlobalIndex = globalIndex }; reuseTarget[globalIndex] = result; } return(result); }
internal Instruction ReadInstruction() { OpCodes opcode = (OpCodes)this.ReadByte(); Instruction result = Instruction.FixedOpCodes[(int)opcode]; if (null != result) { return(result); } switch (opcode) { case OpCodes.Block: return(BlockInstruction.Create(this)); case OpCodes.Loop: return(LoopInstruction.Create(this)); case OpCodes.If: // block_type return(IfInstruction.Create(this)); case OpCodes.Br: case OpCodes.BrIf: // varuint32 return(BranchInstruction.Create(this, opcode)); case OpCodes.BrTable: // custom return(BranchTableInstruction.Create(this)); case OpCodes.Call: case OpCodes.CallIndirect: // varuint32 + varuint1 return(CallInstruction.Create(this, opcode)); case OpCodes.GetLocal: case OpCodes.SetLocal: case OpCodes.TeeLocal: // local_index return(LocalAccessorInstruction.Create(this, opcode)); case OpCodes.GetGlobal: case OpCodes.SetGlobal: // global_index return(GlobalAccessorInstruction.Create(this, (OpCodes.GetGlobal == opcode))); case OpCodes.I32Load: case OpCodes.I64Load: case OpCodes.F32Load: case OpCodes.F64Load: case OpCodes.I32Load8_s: case OpCodes.I32Load8_u: case OpCodes.I32Load16_s: case OpCodes.I32Load16_u: case OpCodes.I64Load8_s: case OpCodes.I64Load8_u: case OpCodes.I64Load16_s: case OpCodes.I64Load16_u: case OpCodes.I64Load32_s: case OpCodes.I64Load32_u: case OpCodes.I32Store: case OpCodes.I64Store: case OpCodes.F32Store: case OpCodes.F64Store: case OpCodes.I32Store8: case OpCodes.I32Store16: case OpCodes.I64Store8: case OpCodes.I64Store16: case OpCodes.I64Store32: // memory_immediate return(MemoryAccessInstruction.Create(this, opcode)); case OpCodes.CurrentMemory: case OpCodes.GrowMemory: // varuint1 return(MemoryControlInstruction.Create(this, opcode)); case OpCodes.I32Const: // varint32 return(ConstantValueInstruction <int> .Create(this, OpCodes.I32Const, this.ReadVarInt32())); case OpCodes.I64Const: // varint64 return(ConstantValueInstruction <long> .Create(this, OpCodes.I64Const, this.ReadVarInt64())); case OpCodes.F32Const: // uint32 return(ConstantValueInstruction <float> .Create(this, OpCodes.F32Const, this.ReadVarFloat32())); case OpCodes.F64Const: // uint64 return(ConstantValueInstruction <double> .Create(this, OpCodes.F64Const, this.ReadVarFloat64())); case OpCodes.F32eq: case OpCodes.F32ge: case OpCodes.F32gt: case OpCodes.F32le: case OpCodes.F32lt: case OpCodes.F32ne: case OpCodes.F64eq: case OpCodes.F64ge: case OpCodes.F64gt: case OpCodes.F64le: case OpCodes.F64lt: case OpCodes.F64ne: case OpCodes.I32eq: case OpCodes.I32ge_s: case OpCodes.I32ge_u: case OpCodes.I32gt_s: case OpCodes.I32gt_u: case OpCodes.I32le_s: case OpCodes.I32le_u: case OpCodes.I32lt_s: case OpCodes.I32lt_u: case OpCodes.I32ne: case OpCodes.I64eq: case OpCodes.I64ge_s: case OpCodes.I64ge_u: case OpCodes.I64gt_s: case OpCodes.I64gt_u: case OpCodes.I64le_s: case OpCodes.I64le_u: case OpCodes.I64lt_s: case OpCodes.I64lt_u: case OpCodes.I64ne: return(RelationalInstruction.GetInstruction(opcode)); case OpCodes.F32Convert_sI32: case OpCodes.F32Convert_uI32: case OpCodes.F32Convert_sI64: case OpCodes.F32Convert_uI64: case OpCodes.F32demoteF64: case OpCodes.F64Convert_sI32: case OpCodes.F64Convert_uI32: case OpCodes.F64Convert_sI64: case OpCodes.F64Convert_uI64: case OpCodes.F64PromoteF32: case OpCodes.I32Trunc_sF32: case OpCodes.I32Trunc_uF32: case OpCodes.I32Trunc_sF64: case OpCodes.I32Trunc_uF64: case OpCodes.I32wrapI64: case OpCodes.I64Extend_sI32: case OpCodes.I64Extend_uI32: case OpCodes.I64Trunc_sF32: case OpCodes.I64Trunc_uF32: case OpCodes.I64Trunc_sF64: case OpCodes.I64Trunc_uF64: return(ConversionInstruction.GetInstruction(opcode)); default: throw new NotSupportedException(); } }