public MosaType GetStackTypeFromCode(StackTypeCode code) { switch (code) { case StackTypeCode.Int32: return(TypeSystem.BuiltIn.I4); case StackTypeCode.Int64: return(TypeSystem.BuiltIn.I8); case StackTypeCode.N: return(TypeSystem.BuiltIn.I); case StackTypeCode.F: return(TypeSystem.BuiltIn.R8); case StackTypeCode.O: return(TypeSystem.BuiltIn.Object); case StackTypeCode.UnmanagedPointer: return(TypeSystem.BuiltIn.Pointer); case StackTypeCode.ManagedPointer: return(TypeSystem.BuiltIn.Object.ToManagedPointer()); } throw new CompilerException($"Can't convert stack type code {code} to type"); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="context">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context context, BaseMethodCompiler compiler) { if (context == null) { throw new ArgumentNullException(nameof(context)); } base.Resolve(context, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (opcode) { case OpCode.Add_ovf_un: result = addovfunTable[(int)context.Operand1.Type.GetStackTypeCode()][(int)context.Operand2.Type.GetStackTypeCode()]; break; case OpCode.Sub_ovf_un: result = subovfunTable[(int)context.Operand1.Type.GetStackTypeCode()][(int)context.Operand2.Type.GetStackTypeCode()]; break; default: result = operandTable[(int)context.Operand1.Type.GetStackTypeCode()][(int)context.Operand2.Type.GetStackTypeCode()]; break; } if (StackTypeCode.Unknown == result) { throw new InvalidOperationException("Invalid operand types passed to " + opcode); } context.Result = compiler.CreateVirtualRegister(compiler.TypeSystem.GetStackTypeFromCode(result)); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, IMethodCompiler compiler) { base.Validate(ctx, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (_opcode) { case OpCode.Add_ovf_un: result = _addovfunTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; case OpCode.Sub_ovf_un: result = _subovfunTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; default: result = _operandTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; } if (StackTypeCode.Unknown == result) { throw new InvalidOperationException("Invalid operand types passed to " + _opcode); } ctx.Result = compiler.CreateTemporary(Operand.SigTypeFromStackType(result)); }
/// <summary> /// Retrieves the stack type From a sig type. /// </summary> /// <param name="type">The signature type to convert to a stack type code.</param> /// <returns>The equivalent stack type code.</returns> public static StackTypeCode StackTypeFromSigType(SigType type) { StackTypeCode result = StackTypeCode.Unknown; switch (type.Type) { case CilElementType.Void: break; case CilElementType.Boolean: result = StackTypeCode.Int32; break; case CilElementType.Char: result = StackTypeCode.Int32; break; case CilElementType.I1: result = StackTypeCode.Int32; break; case CilElementType.U1: result = StackTypeCode.Int32; break; case CilElementType.I2: result = StackTypeCode.Int32; break; case CilElementType.U2: result = StackTypeCode.Int32; break; case CilElementType.I4: result = StackTypeCode.Int32; break; case CilElementType.U4: result = StackTypeCode.Int32; break; case CilElementType.I8: result = StackTypeCode.Int64; break; case CilElementType.U8: result = StackTypeCode.Int64; break; case CilElementType.R4: result = StackTypeCode.F; break; case CilElementType.R8: result = StackTypeCode.F; break; case CilElementType.I: result = StackTypeCode.N; break; case CilElementType.U: result = StackTypeCode.N; break; case CilElementType.Ptr: result = StackTypeCode.Ptr; break; case CilElementType.ByRef: result = StackTypeCode.Ptr; break; case CilElementType.Object: result = StackTypeCode.O; break; case CilElementType.String: result = StackTypeCode.O; break; case CilElementType.ValueType: result = StackTypeCode.O; break; case CilElementType.Type: result = StackTypeCode.O; break; case CilElementType.Class: result = StackTypeCode.O; break; default: throw new NotSupportedException(@"Can't transform SigType to StackTypeCode."); } return(result); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, IMethodCompiler compiler) { base.Validate(ctx, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (_opcode) { case OpCode.Add: result = _addTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; case OpCode.Sub: result = _subTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; default: result = _operandTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; break; } if (StackTypeCode.Unknown == result) { throw new InvalidOperationException("Invalid operand types passed to " + _opcode); } SigType resultType; if (result != StackTypeCode.Ptr) { resultType = Operand.SigTypeFromStackType(result); } else { // Copy the pointer element type PtrSigType op0 = ctx.Operand1.Type as PtrSigType; PtrSigType op1 = ctx.Operand2.Type as PtrSigType; if (op0 != null) { resultType = new PtrSigType(op0.CustomMods, op0.ElementType); } else if (op1 != null) { resultType = new PtrSigType(op1.CustomMods, op1.ElementType); } else { throw new InvalidOperationException(); } } ctx.Result = compiler.CreateTemporary(resultType); }
public static Operand CreateResultOperand(IInstructionDecoder decoder, StackTypeCode operandType, SigType operandSigType) { if (operandType == StackTypeCode.O || operandType == StackTypeCode.Ptr || operandType == StackTypeCode.F) { return decoder.Compiler.CreateVirtualRegister(operandSigType); } else { return decoder.Compiler.CreateVirtualRegister(Operand.SigTypeFromStackType(operandType)); } }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, IMethodCompiler compiler) { base.Validate(ctx, compiler); StackTypeCode result = _opTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; if (result == StackTypeCode.Unknown) { throw new ExecutionEngineException("Invalid stack result of instruction."); } ctx.Result = compiler.CreateTemporary(Operand.SigTypeFromStackType(result)); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Resolve(Context ctx, BaseMethodCompiler compiler) { base.Resolve(ctx, compiler); StackTypeCode result = StackTypeCode.Unknown; switch (opcode) { case OpCode.Add: result = addTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; case OpCode.Sub: result = subTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; default: result = operandTable[(int)ctx.Operand1.Type.GetStackTypeCode()][(int)ctx.Operand2.Type.GetStackTypeCode()]; break; } if (result == StackTypeCode.Unknown) { throw new InvalidOperationException(@"Invalid operand types passed to " + opcode); } MosaType resultType = null; if (StackTypeCode.UnmanagedPointer != result) { resultType = compiler.TypeSystem.GetStackTypeFromCode(result); if (result == StackTypeCode.F && ctx.Operand1.Type.IsR4 && ctx.Operand2.Type.IsR4) { resultType = compiler.TypeSystem.BuiltIn.R4; } } else { if (ctx.Operand1.Type.IsPointer) { resultType = ctx.Operand1.Type; } else if (ctx.Operand2.Type.IsPointer) { resultType = ctx.Operand2.Type; } else { throw new InvalidOperationException(@"Invalid operand types passed to " + opcode); } } //Debug.Assert(resultType != null, ctx.ToString()); ctx.Result = compiler.CreateVirtualRegister(resultType); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx"></param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, IMethodCompiler compiler) { base.Validate(ctx, compiler); // Validate the operand StackTypeCode result = _typeCodes[(int)ctx.Operand1.StackType]; if (StackTypeCode.Unknown == result) { throw new InvalidOperationException(@"Invalid operand to Neg instruction."); } ctx.Result = compiler.CreateTemporary(ctx.Operand1.Type); }
/// <summary> /// Validates the instruction operands and creates a matching variable for the result. /// </summary> /// <param name="ctx">The context.</param> /// <param name="compiler">The compiler.</param> public override void Validate(Context ctx, IMethodCompiler compiler) { base.Validate(ctx, compiler); StackTypeCode result = _operandTable[(int)ctx.Operand1.StackType][(int)ctx.Operand2.StackType]; Debug.Assert(StackTypeCode.Unknown != result, @"Can't shift with the given stack operands."); if (StackTypeCode.Unknown == result) { throw new ExecutionEngineException(@"Invalid stack state."); } ctx.Result = compiler.CreateTemporary(Operand.SigTypeFromStackType(result)); }
public static Operand CreateResultOperand(IInstructionDecoder decoder, StackTypeCode operandType, SigType operandSigType) { Operand result; if (operandType == StackTypeCode.O || operandType == StackTypeCode.Ptr || operandType == StackTypeCode.F) { result = decoder.Compiler.CreateTemporary(operandSigType); } else { result = decoder.Compiler.CreateTemporary(Operand.SigTypeFromStackType(operandType)); } return result; }
public static Operand CreateResultOperand(IInstructionDecoder decoder, StackTypeCode operandType, SigType operandSigType) { Operand result; if (operandType == StackTypeCode.O || operandType == StackTypeCode.Ptr || operandType == StackTypeCode.F) { result = decoder.Compiler.CreateTemporary(operandSigType); } else { result = decoder.Compiler.CreateTemporary(Operand.SigTypeFromStackType(operandType)); } return(result); }
/// <summary> /// Decodes the specified instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> public override void Decode(Context ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); // Do we have a type? if (this.elementType == null) { // No, retrieve a type reference from the immediate argument Token token = decoder.DecodeTokenType(); this.elementType = new ClassSigType(token); } StackTypeCode stackType = Operand.StackTypeFromSigType(this.elementType); Operand result = LoadInstruction.CreateResultOperand(decoder, stackType, this.elementType); ctx.Result = result; }
/// <summary> /// Sigs the type of the type From stack. /// </summary> /// <param name="typeCode">The type code.</param> /// <returns></returns> public static SigType SigTypeFromStackType(StackTypeCode typeCode) { SigType result = null; switch (typeCode) { case StackTypeCode.Int32: result = new SigType(CilElementType.I4); break; case StackTypeCode.Int64: result = new SigType(CilElementType.I8); break; case StackTypeCode.F: result = new SigType(CilElementType.R8); break; case StackTypeCode.O: result = new SigType(CilElementType.Object); break; case StackTypeCode.N: result = new SigType(CilElementType.I); break; default: throw new NotSupportedException(@"Can't convert stack type code to SigType."); } return(result); }
/// <summary> /// Sigs the type of the type From stack. /// </summary> /// <param name="typeCode">The type code.</param> /// <returns></returns> public static SigType SigTypeFromStackType(StackTypeCode typeCode) { switch (typeCode) { case StackTypeCode.Int32: return BuiltInSigType.Int32; case StackTypeCode.Int64: return BuiltInSigType.Int64; case StackTypeCode.F: return BuiltInSigType.Double; case StackTypeCode.O: return BuiltInSigType.Object; case StackTypeCode.N: return BuiltInSigType.IntPtr; default: throw new NotSupportedException(@"Can't convert stack type code to SigType."); } }
public static StackType GetStackType(StackTypeCode code, TypeSig type, IList <TypeSig> genArgs = null) { return(new StackType { Code = code, Name = EscapeVariableTypeName(type, genArgs: genArgs), TypeSig = type, GenArgs = genArgs }); }
public static MosaType GetStackTypeFromCode(this TypeSystem typeSystem, StackTypeCode code) { switch (code) { case StackTypeCode.Int32: return typeSystem.BuiltIn.I4; case StackTypeCode.Int64: return typeSystem.BuiltIn.I8; case StackTypeCode.N: return typeSystem.BuiltIn.I; case StackTypeCode.F: return typeSystem.BuiltIn.R8; case StackTypeCode.O: return typeSystem.BuiltIn.Object; case StackTypeCode.UnmanagedPointer: return typeSystem.BuiltIn.Pointer; case StackTypeCode.ManagedPointer: return typeSystem.BuiltIn.Object.ToManagedPointer(); } throw new CompilerException("Can't convert stack type code'" + code + "' to type."); }
/// <summary> /// Sigs the type of the type From stack. /// </summary> /// <param name="typeCode">The type code.</param> /// <returns></returns> public static SigType SigTypeFromStackType(StackTypeCode typeCode) { SigType result = null; switch (typeCode) { case StackTypeCode.Int32: result = BuiltInSigType.Int32; break; case StackTypeCode.Int64: result = BuiltInSigType.Int64; break; case StackTypeCode.F: result = BuiltInSigType.Double; break; case StackTypeCode.O: result = BuiltInSigType.Object; break; case StackTypeCode.N: result = BuiltInSigType.IntPtr; break; default: throw new NotSupportedException(@"Can't convert stack type code to SigType."); } return result; }