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);
        }
示例#2
0
        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();
            }
        }