示例#1
0
        private static Instruction GetInstuction(NormalizedByteCode bc)
        {
            Instruction instruction = new Instruction();

            instruction.PatchOpCode(bc);
            return(instruction);
        }
示例#2
0
        private static Instruction GetInstuction(NormalizedByteCode bc, int arg1, short arg2)
        {
            Instruction instruction = new Instruction();

            instruction.PatchOpCode(bc, arg1, arg2);
            return(instruction);
        }
示例#3
0
    internal static bool CanThrowException(NormalizedByteCode bc)
    {
        switch (bc)
        {
        case NormalizedByteCode.__dynamic_invokeinterface:
        case NormalizedByteCode.__dynamic_invokestatic:
        case NormalizedByteCode.__dynamic_invokevirtual:
        case NormalizedByteCode.__dynamic_getstatic:
        case NormalizedByteCode.__dynamic_putstatic:
        case NormalizedByteCode.__dynamic_getfield:
        case NormalizedByteCode.__dynamic_putfield:
        case NormalizedByteCode.__clone_array:
        case NormalizedByteCode.__static_error:
        case NormalizedByteCode.__methodhandle_invoke:
        case NormalizedByteCode.__methodhandle_link:
            return(true);

        case NormalizedByteCode.__iconst:
        case NormalizedByteCode.__ldc_nothrow:
            return(false);

        default:
            return((data[(int)bc].flags & ByteCodeFlags.CannotThrow) == 0);
        }
    }
示例#4
0
 private static bool IsStoreLocal(NormalizedByteCode bc)
 {
     return(bc == NormalizedByteCode.__astore ||
            bc == NormalizedByteCode.__istore ||
            bc == NormalizedByteCode.__lstore ||
            bc == NormalizedByteCode.__fstore ||
            bc == NormalizedByteCode.__dstore);
 }
示例#5
0
 private static bool IsLoadLocal(NormalizedByteCode bc)
 {
     return(bc == NormalizedByteCode.__aload ||
            bc == NormalizedByteCode.__iload ||
            bc == NormalizedByteCode.__lload ||
            bc == NormalizedByteCode.__fload ||
            bc == NormalizedByteCode.__dload ||
            bc == NormalizedByteCode.__iinc ||
            bc == NormalizedByteCode.__ret);
 }
示例#6
0
 private ByteCodeMetaData(ByteCode bc, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
 {
     this.reg    = reg;
     this.wide   = wide;
     this.normbc = (NormalizedByteCode)bc;
     this.arg    = 0;
     this.flags  = ByteCodeFlags.None;
     if (cannotThrow)
     {
         this.flags |= ByteCodeFlags.CannotThrow;
     }
     data[(int)bc] = this;
 }
示例#7
0
 private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, int arg, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
 {
     this.reg    = reg;
     this.wide   = wide;
     this.normbc = normbc;
     this.arg    = arg;
     this.flags  = ByteCodeFlags.FixedArg;
     if (cannotThrow)
     {
         this.flags |= ByteCodeFlags.CannotThrow;
     }
     data[(int)bc] = this;
 }
示例#8
0
    internal static bool IsBranch(NormalizedByteCode bc)
    {
        switch (data[(int)bc].reg)
        {
        case ByteCodeMode.Branch_2:
        case ByteCodeMode.Branch_4:
        case ByteCodeMode.Lookupswitch:
        case ByteCodeMode.Tableswitch:
            return(true);

        default:
            return(false);
        }
    }
示例#9
0
    internal static ByteCodeFlowControl GetFlowControl(NormalizedByteCode bc)
    {
        switch (bc)
        {
        case NormalizedByteCode.__tableswitch:
        case NormalizedByteCode.__lookupswitch:
            return(ByteCodeFlowControl.Switch);

        case NormalizedByteCode.__goto:
        case NormalizedByteCode.__goto_finally:
            return(ByteCodeFlowControl.Branch);

        case NormalizedByteCode.__ifeq:
        case NormalizedByteCode.__ifne:
        case NormalizedByteCode.__iflt:
        case NormalizedByteCode.__ifge:
        case NormalizedByteCode.__ifgt:
        case NormalizedByteCode.__ifle:
        case NormalizedByteCode.__if_icmpeq:
        case NormalizedByteCode.__if_icmpne:
        case NormalizedByteCode.__if_icmplt:
        case NormalizedByteCode.__if_icmpge:
        case NormalizedByteCode.__if_icmpgt:
        case NormalizedByteCode.__if_icmple:
        case NormalizedByteCode.__if_acmpeq:
        case NormalizedByteCode.__if_acmpne:
        case NormalizedByteCode.__ifnull:
        case NormalizedByteCode.__ifnonnull:
            return(ByteCodeFlowControl.CondBranch);

        case NormalizedByteCode.__ireturn:
        case NormalizedByteCode.__lreturn:
        case NormalizedByteCode.__freturn:
        case NormalizedByteCode.__dreturn:
        case NormalizedByteCode.__areturn:
        case NormalizedByteCode.__return:
            return(ByteCodeFlowControl.Return);

        case NormalizedByteCode.__athrow:
        case NormalizedByteCode.__athrow_no_unmap:
        case NormalizedByteCode.__static_error:
            return(ByteCodeFlowControl.Throw);

        default:
            return(ByteCodeFlowControl.Next);
        }
    }
示例#10
0
 internal void PatchOpCode(int offset, NormalizedByteCode opc)
 {
     Code[OpcodeIndex + offset].PatchOpCode(opc);
 }
示例#11
0
	private static bool IsStoreLocal(NormalizedByteCode bc)
	{
		return bc == NormalizedByteCode.__astore ||
			bc == NormalizedByteCode.__istore ||
			bc == NormalizedByteCode.__lstore ||
			bc == NormalizedByteCode.__fstore ||
			bc == NormalizedByteCode.__dstore;
	}
示例#12
0
	private static bool IsLoadLocal(NormalizedByteCode bc)
	{
		return bc == NormalizedByteCode.__aload ||
			bc == NormalizedByteCode.__iload ||
			bc == NormalizedByteCode.__lload ||
			bc == NormalizedByteCode.__fload ||
			bc == NormalizedByteCode.__dload ||
			bc == NormalizedByteCode.__iinc ||
			bc == NormalizedByteCode.__ret;
	}
示例#13
0
    internal static ByteCodeFlowControl GetFlowControl(NormalizedByteCode bc)
    {
        switch (bc)
        {
            case NormalizedByteCode.__tableswitch:
            case NormalizedByteCode.__lookupswitch:
                return ByteCodeFlowControl.Switch;

            case NormalizedByteCode.__goto:
            case NormalizedByteCode.__goto_finally:
                return ByteCodeFlowControl.Branch;

            case NormalizedByteCode.__ifeq:
            case NormalizedByteCode.__ifne:
            case NormalizedByteCode.__iflt:
            case NormalizedByteCode.__ifge:
            case NormalizedByteCode.__ifgt:
            case NormalizedByteCode.__ifle:
            case NormalizedByteCode.__if_icmpeq:
            case NormalizedByteCode.__if_icmpne:
            case NormalizedByteCode.__if_icmplt:
            case NormalizedByteCode.__if_icmpge:
            case NormalizedByteCode.__if_icmpgt:
            case NormalizedByteCode.__if_icmple:
            case NormalizedByteCode.__if_acmpeq:
            case NormalizedByteCode.__if_acmpne:
            case NormalizedByteCode.__ifnull:
            case NormalizedByteCode.__ifnonnull:
                return ByteCodeFlowControl.CondBranch;

            case NormalizedByteCode.__ireturn:
            case NormalizedByteCode.__lreturn:
            case NormalizedByteCode.__freturn:
            case NormalizedByteCode.__dreturn:
            case NormalizedByteCode.__areturn:
            case NormalizedByteCode.__return:
                return ByteCodeFlowControl.Return;

            case NormalizedByteCode.__athrow:
            case NormalizedByteCode.__athrow_no_unmap:
            case NormalizedByteCode.__static_error:
                return ByteCodeFlowControl.Throw;

            default:
                return ByteCodeFlowControl.Next;
        }
    }
示例#14
0
 internal static bool IsBranch(NormalizedByteCode bc)
 {
     switch (data[(int)bc].reg)
     {
         case ByteCodeMode.Branch_2:
         case ByteCodeMode.Branch_4:
         case ByteCodeMode.Lookupswitch:
         case ByteCodeMode.Tableswitch:
             return true;
         default:
             return false;
     }
 }
示例#15
0
 private ByteCodeMetaData(ByteCode bc, NormalizedByteCode normbc, int arg, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
 {
     this.reg = reg;
     this.wide = wide;
     this.normbc = normbc;
     this.arg = arg;
     this.flags = ByteCodeFlags.FixedArg;
     if(cannotThrow)
     {
         this.flags |= ByteCodeFlags.CannotThrow;
     }
     data[(int)bc] = this;
 }
示例#16
0
 internal static bool CanThrowException(NormalizedByteCode bc)
 {
     switch(bc)
     {
         case NormalizedByteCode.__dynamic_invokeinterface:
         case NormalizedByteCode.__dynamic_invokestatic:
         case NormalizedByteCode.__dynamic_invokevirtual:
         case NormalizedByteCode.__dynamic_getstatic:
         case NormalizedByteCode.__dynamic_putstatic:
         case NormalizedByteCode.__dynamic_getfield:
         case NormalizedByteCode.__dynamic_putfield:
         case NormalizedByteCode.__clone_array:
         case NormalizedByteCode.__static_error:
             return true;
         case NormalizedByteCode.__iconst:
             return false;
         default:
             return (data[(int)bc].flags & ByteCodeFlags.CannotThrow) == 0;
     }
 }
示例#17
0
				internal void SetHardError(HardError error, int messageId)
				{
					normopcode = NormalizedByteCode.__static_error;
					arg2 = (short)error;
					arg1 = messageId;
				}
示例#18
0
 private ByteCodeMetaData(ByteCode bc, ByteCodeMode reg, ByteCodeModeWide wide, bool cannotThrow)
 {
     this.reg = reg;
     this.wide = wide;
     this.normbc = (NormalizedByteCode)bc;
     this.arg = 0;
     this.flags = ByteCodeFlags.None;
     if(cannotThrow)
     {
         this.flags |= ByteCodeFlags.CannotThrow;
     }
     data[(int)bc] = this;
 }
示例#19
0
				internal void PatchOpCode(NormalizedByteCode bc)
				{
					this.normopcode = bc;
				}
示例#20
0
				internal void PatchOpCode(NormalizedByteCode bc, int arg1, short arg2)
				{
					this.normopcode = bc;
					this.arg1 = arg1;
					this.arg2 = arg2;
				}
示例#21
0
 internal bool Match(int offset, NormalizedByteCode opcode)
 {
     return(Code[OpcodeIndex + offset].NormalizedOpCode == opcode);
 }
示例#22
0
				internal void SetTermNop(ushort pc)
				{
					// TODO what happens if we already have exactly the maximum number of instructions?
					this.pc = pc;
					this.normopcode = NormalizedByteCode.__nop;
				}
示例#23
0
				internal void Read(ushort pc, BigEndianBinaryReader br, ClassFile classFile)
				{
					this.pc = pc;
					ByteCode bc = (ByteCode)br.ReadByte();
					switch(ByteCodeMetaData.GetMode(bc))
					{
						case ByteCodeMode.Simple:
							break;
						case ByteCodeMode.Constant_1:
							arg1 = br.ReadByte();
							classFile.MarkLinkRequiredConstantPoolItem(arg1);
							break;
						case ByteCodeMode.Local_1:
							arg1 = br.ReadByte();
							break;
						case ByteCodeMode.Constant_2:
							arg1 = br.ReadUInt16();
							classFile.MarkLinkRequiredConstantPoolItem(arg1);
							break;
						case ByteCodeMode.Branch_2:
							arg1 = br.ReadInt16();
							break;
						case ByteCodeMode.Branch_4:
							arg1 = br.ReadInt32();
							break;
						case ByteCodeMode.Constant_2_1_1:
							arg1 = br.ReadUInt16();
							classFile.MarkLinkRequiredConstantPoolItem(arg1);
							arg2 = br.ReadByte();
							if(br.ReadByte() != 0)
							{
								throw new ClassFormatError("invokeinterface filler must be zero");
							}
							break;
						case ByteCodeMode.Immediate_1:
							arg1 = br.ReadSByte();
							break;
						case ByteCodeMode.Immediate_2:
							arg1 = br.ReadInt16();
							break;
						case ByteCodeMode.Local_1_Immediate_1:
							arg1 = br.ReadByte();
							arg2 = br.ReadSByte();
							break;
						case ByteCodeMode.Constant_2_Immediate_1:
							arg1 = br.ReadUInt16();
							classFile.MarkLinkRequiredConstantPoolItem(arg1);
							arg2 = br.ReadSByte();
							break;
						case ByteCodeMode.Tableswitch:
						{
							// skip the padding
							uint p = pc + 1u;
							uint align = ((p + 3) & 0x7ffffffc) - p;
							br.Skip(align);
							int default_offset = br.ReadInt32();
							this.arg1 = default_offset;
							int low = br.ReadInt32();
							int high = br.ReadInt32();
							if(low > high || high > 16384L + low)
							{
								throw new ClassFormatError("Incorrect tableswitch");
							}
							SwitchEntry[] entries = new SwitchEntry[high - low + 1];
							for(int i = low; i < high; i++)
							{
								entries[i - low].value = i;
								entries[i - low].target = br.ReadInt32();
							}
							// do the last entry outside the loop, to avoid overflowing "i", if high == int.MaxValue
							entries[high - low].value = high;
							entries[high - low].target = br.ReadInt32();
							this.switch_entries = entries;
							break;
						}
						case ByteCodeMode.Lookupswitch:
						{
							// skip the padding
							uint p = pc + 1u;
							uint align = ((p + 3) & 0x7ffffffc) - p;
							br.Skip(align);
							int default_offset = br.ReadInt32();
							this.arg1 = default_offset;
							int count = br.ReadInt32();
							if(count < 0 || count > 16384)
							{
								throw new ClassFormatError("Incorrect lookupswitch");
							}
							SwitchEntry[] entries = new SwitchEntry[count];
							for(int i = 0; i < count; i++)
							{
								entries[i].value = br.ReadInt32();
								entries[i].target = br.ReadInt32();
							}
							this.switch_entries = entries;
							break;
						}
						case ByteCodeMode.WidePrefix:
							bc = (ByteCode)br.ReadByte();
							// NOTE the PC of a wide instruction is actually the PC of the
							// wide prefix, not the following instruction (vmspec 4.9.2)
						switch(ByteCodeMetaData.GetWideMode(bc))
						{
							case ByteCodeModeWide.Local_2:
								arg1 = br.ReadUInt16();
								break;
							case ByteCodeModeWide.Local_2_Immediate_2:
								arg1 = br.ReadUInt16();
								arg2 = br.ReadInt16();
								break;
							default:
								throw new ClassFormatError("Invalid wide prefix on opcode: {0}", bc);
						}
							break;
						default:
							throw new ClassFormatError("Invalid opcode: {0}", bc);
					}
					this.normopcode = ByteCodeMetaData.GetNormalizedByteCode(bc);
					arg1 = ByteCodeMetaData.GetArg(bc, arg1);
				}
示例#24
0
 internal bool Match(int offset, NormalizedByteCode opcode, int arg)
 {
     return(Code[OpcodeIndex + offset].NormalizedOpCode == opcode && Code[OpcodeIndex + offset].Arg1 == arg);
 }
示例#25
0
 private static bool MatchInvoke(EmitIntrinsicContext eic, ref Instruction instr, NormalizedByteCode opcode, string clazz, string name, string sig)
 {
     if (instr.NormalizedOpCode == opcode)
     {
         ClassFile.ConstantPoolItemMI method = eic.ClassFile.GetMethodref(instr.Arg1);
         return(method.Class == clazz &&
                method.Name == name &&
                method.Signature == sig);
     }
     return(false);
 }