public static string ToProtoTypeString(this VType type) { switch (type) { case VType.Bool: return("bool"); case VType.Int: return("int32"); case VType.Long: return("int64"); case VType.UInt: return("uint32"); case VType.ULong: return("uint64"); case VType.Float: return("float"); case VType.Double: return("double"); case VType.String: return("string"); case VType.ID: return("Uuid"); case VType.None: default: return(null); } }
public Json ToJson(bool withDef = false) { Json json = Json.Create(); json.SetValue("__type", def.Type); json.SetValue("__id", ID.Exist(entityId) ? entityId : ""); json.SetValue("__root", root); int indexCount = def.Indexes.Count; if (withDef) { json.Add("__def", def.ToJson()); } for (int i = 0; i < indexCount; i++) { int ind = def.Indexes[i]; var entry = def.GetEntry(ind); VType type = entry.type.TryConvertToEnum(VType.None); switch (entry.species) { case Def.Entry.Species.Attr: Var attr = GetAttr(entry.name); if (attr.Type != VType.None) { json.Add(ind.ToString(), attr); } else { json.Add(ind.ToString(), ((Entity)attr).ToJson(withDef)); } break; case Def.Entry.Species.List: VarSeq list = _lists[ind]; Json listi = json.CreateChild(ind.ToString()); if (list.itemType != VType.None) { for (int j = 0; j < list.UsedKeys.Count; j++) { Var key = list.keyIndexMap.GetKey(list.UsedKeys[j]); listi.Add(key.Format(null), list[list.UsedKeys[j]]); } } else { for (int j = 0; j < list.UsedKeys.Count; j++) { Var key = list.keyIndexMap.GetKey(list.UsedKeys[j]); listi.Add(key.Format(null), ((Entity)list[list.UsedKeys[j]]).ToJson()); } } break; default: break; } } return(json); }
public static Var DefaultValFormType(this VType type) { switch (type) { case VType.Bool: return(new VBool()); case VType.Int: return(new VInt()); case VType.Long: return(new VLong()); case VType.UInt: return(new VUInt()); case VType.ULong: return(new VULong()); case VType.Float: return(new VFloat()); case VType.Double: return(new VDouble()); case VType.String: return(new VString()); case VType.ID: return(new VID()); case VType.None: default: return(null); } }
public static Var ConverToValByType(object val, VType type) { switch (type) { case VType.Bool: return((bool)val); case VType.Int: return((int)val); case VType.Long: return((long)val); case VType.UInt: return((uint)val); case VType.ULong: return((ulong)val); case VType.Float: return((float)val); case VType.Double: return((double)val); case VType.String: return((string)val); case VType.ID: return((string)val); case VType.None: default: return(null); } }
public static VType VTypeInc(VType vt) { //add 1 to each struct member VType vtx; vtx.v1 = vt.v1 + 1; vtx.v2 = vt.v2 + 1; vtx.v3 = vt.v3 + 1; vtx.v4 = (short)(vt.v4 + 1); //do some nonsense to exercise reg assignment long loc1; long loc2; long loc3; long loc4; long loc5; long loc6; long loc7; long loc8; loc1 = vt.v1 + vt.v2; loc2 = loc1 + vt.v2; loc3 = loc2 + vt.v2; loc4 = loc3 + vt.v2; loc5 = loc4 + vt.v2; loc6 = loc5 + vt.v2; loc7 = loc6 + vt.v2; loc8 = loc7 + loc1 + vt.v2; //nonsense complete Console.WriteLine("should return v2={0:D}", vtx.v2); return(vtx); }
public override int GetHashCode() { int hashcode = 157; unchecked { if ((Key != null)) { hashcode = (hashcode * 397) + Key.GetHashCode(); } hashcode = (hashcode * 397) + VType.GetHashCode(); if ((VStr != null) && __isset.vStr) { hashcode = (hashcode * 397) + VStr.GetHashCode(); } if (__isset.vDouble) { hashcode = (hashcode * 397) + VDouble.GetHashCode(); } if (__isset.vBool) { hashcode = (hashcode * 397) + VBool.GetHashCode(); } if (__isset.vLong) { hashcode = (hashcode * 397) + VLong.GetHashCode(); } if ((VBinary != null) && __isset.vBinary) { hashcode = (hashcode * 397) + VBinary.GetHashCode(); } } return(hashcode); }
/// <summary> /// Create a vertex and connect with last one /// Create a new game object indicator /// </summary> /// <param name="type">Type of the vertex</param> /// <param name="position">Current position</param> /// <param name="last">Previous one</param> /// <returns>A new vertex</returns> Vertex CreateVertex(VType type, Vector3 position, Vertex last) { GameObject obj = null; switch (type) { case VType.Wall: obj = Instantiate(wallObj); break; case VType.OpenCorner: obj = Instantiate(openCornerObj); break; case VType.ClosedCorner: obj = Instantiate(closedCornerObj); break; default: break; } Vertex vertex = new Vertex(position, type, obj); if (last != null) { last.Next(vertex); vertex.Prev(last); } vertices.Add(vertex); return(vertex); }
public static VType VTypeInc(VType vt) { //add 1 to each struct member VType vtx; vtx.v1 = vt.v1 + 1; vtx.v2 = vt.v2 + 1; vtx.v3 = vt.v3 + 1; vtx.v4 = (short)(vt.v4 + 1); //do some nonsense to exercise reg assignment long loc1; long loc2; long loc3; long loc4; long loc5; long loc6; long loc7; long loc8; loc1 = vt.v1 + vt.v2; loc2 = loc1 + vt.v2; loc3 = loc2 + vt.v2; loc4 = loc3 + vt.v2; loc5 = loc4 + vt.v2; loc6 = loc5 + vt.v2; loc7 = loc6 + vt.v2; loc8 = loc7 + loc1 + vt.v2; //nonsense complete Console.WriteLine("should return v2={0:D}", vtx.v2); return vtx; }
/// <summary> /// Transform arg to byte if possible /// </summary> private static object ConformChar(object arg, VType atype) { switch (atype) { case VType.Short: return((char)((short)arg)); case VType.Int: return((char)((int)arg)); case VType.Long: return((char)((long)arg)); case VType.Float: return((char)((float)arg)); case VType.Double: return((char)((double)arg)); case VType.String: return((char)int.Parse((string)arg)); case VType.Byte: return((char)((byte)arg)); case VType.Char: return((char)((char)arg)); default: throw new ArgumentException("could not coerce type " + atype + " to bool"); } }
public bool SetAttrByType(string name, VType type, object val) { Def.Entry entry = def.GetEntry(name); switch (type) { case VType.Bool: return(SetAttrBool(name, (bool)val)); case VType.Int: return(SetAttrInt(name, (int)val)); case VType.Long: return(SetAttrLong(name, (long)val)); case VType.UInt: return(SetAttrUInt(name, (uint)val)); case VType.ULong: return(SetAttrULong(name, (ulong)val)); case VType.Float: return(SetAttrFloat(name, (float)val)); case VType.Double: return(SetAttrDouble(name, (double)val)); case VType.String: return(SetAttrString(name, (string)val)); case VType.ID: return(SetAttrID(name, (ID)val)); case VType.None: default: return(SetAttrEntity(name, val as Entity)); } }
private void checkType(VType t) { if (t != _tcode) { throw new VariantException(t, _tcode); } }
private void checkBaseType(VType t) { if ((t & _tcode) != t) { throw new VariantException(t, _tcode); } }
protected VfpuRuntimeRegister(CpuEmitter cpuEmitter, VReg vReg, VType vType, int vectorSize) { Pc = cpuEmitter._pc; Instruction = cpuEmitter._instruction; VReg = vReg; VType = vType; VectorSize = (vectorSize == 0) ? Instruction.OneTwo : vectorSize; }
/// <summary> /// 保存型号数据 /// </summary> /// <param name="type"></param> /// <returns></returns> public ActionResult TypeEdit(VType type) { //编辑成功后跳转到仓库列表页面 return(RedirectToAction("TypeList")); //编辑不成功跳转到错误页面 //return View("Error"); }
private void SaveVoucherType() { if (MessageBox.Show(string.Format(SaveConfirmText, "Voucher Type"), MessageBoxCaption, MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.No) { return; } try { using (SqlConnection Conn = new SqlConnection(GlobalClass.TConnectionString)) { Conn.Open(); using (SqlTransaction Tran = Conn.BeginTransaction()) { VType.VoucherId = Conn.ExecuteScalar <byte>("SELECT CAST(ISNULL(MAX(VoucherId), 0) + 1 AS TINYINT) FROM VoucherTypes", transaction: Tran); if (VType.Save(Tran)) { GlobalClass.SetUserActivityLog(Tran, "Voucher Type", "New", WorkDetail: "VoucherId : " + VType.VoucherId, Remarks: VType.VoucherName); Tran.Commit(); MessageBox.Show("Voucher Type Saved Successfully.", MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Information); VTypeList.Add(new VoucherType { VoucherId = VType.VoucherId, VoucherName = VType.VoucherName, Rate = VType.Rate, RateStr = VType.RateStr, Value = VType.Value, ValidStart = VType.ValidStart, ValidEnd = VType.ValidEnd, Validity = VType.Validity, VoucherInfo = VType.VoucherInfo, SkipVoucherGeneration = VType.SkipVoucherGeneration, NonVat = VType.NonVat }); ExecuteUndo(null); } else { MessageBox.Show("Voucher Type could not be Saved.", MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Exclamation); } } } } catch (SqlException ex) { if (ex.Number == 2601) { MessageBox.Show("Entered Voucher name already exist in the database. Enter unique name and try again", MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Hand); } else { MessageBox.Show(ex.Number + " : " + ex.Message, MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Error); } } catch (Exception ex) { MessageBox.Show(ex.Message, MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Error); } }
// dummy copy constructor public VUser(VUser user) { userName = user.UserName; fstName = user.FstName; midName = user.MidName; lstName = user.LstName; status = user.Status; usertype = VType.notmade; }
/// <summary> /// Initialize all command class /// </summary> #region InitializeAllCommand private void InitializeAllCommand() { // Initialize normal commands #region AG9Command<,> var derivedTypes = VType.GetDerivedTypes(typeof(AG9Command <, ,>), _commandAssembly).Where(s => s.IsAbstract == false).ToList(); // Instance action for add command data type void AddCommandDataType(string commandName, CommandDataType <TAccount> commandDataType) { _accessToCommandDataTypeCollection.Add(commandName.GenerateStandardCommandName(CommandSize), commandDataType); } derivedTypes.ForEach(oType => { // Check for account type is equal with server account type // Get generic type from base type if (oType.BaseType == null) { return; } var genericAccountArgument = oType.BaseType.GetGenericArguments().Last(); if (genericAccountArgument == typeof(TAccount)) { // Create instance and get method initialize var instance = Activator.CreateInstance(oType); _instanceCommandCollection.Add(oType.Name.GenerateStandardCommandName(CommandSize), instance); var method = oType.GetMethod("InitializeRequirement"); // Initialize command and add to server method?.Invoke(instance, new object[] { (Action <string, CommandDataType <TAccount> >)AddCommandDataType }); if (_logging.CheckLoggingIsActive(LogsType.INFO)) { _logging.LogInformation( $"{LogMessage.AddCommandSuccessfully}\n{LogMessage.CommandName}: {oType.Name}\nPath: {oType.FullName}", G9LogIdentity.ADD_COMMAND, LogMessage.SuccessfulOperation); } } else { if (_logging.CheckLoggingIsActive(LogsType.WARN)) { _logging.LogWarning( $"{LogMessage.FailAddCommandForGenericAccountType}\n{LogMessage.CommandName}: {oType.Name}\nPath: {oType.FullName}", G9LogIdentity.ADD_COMMAND, LogMessage.FailedOperation); } } }); #endregion }
private void UpdateVoucherType() { if (MessageBox.Show(string.Format(UpdateConfirmText, "Voucher Type"), MessageBoxCaption, MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) { return; } try { using (SqlConnection Conn = new SqlConnection(GlobalClass.TConnectionString)) { Conn.Open(); using (SqlTransaction tran = Conn.BeginTransaction()) { string Remarks = Newtonsoft.Json.JsonConvert.SerializeObject(Conn.Query <VoucherType>("SELECT VoucherId, VoucherName, VehicleType, Rate, Value, Validity, ValidStart, ValidEnd, VoucherInfo, SkipVoucherGeneration FROM VoucherTypes WHERE VoucherId = @VoucherId", VType, tran).First()); if (VType.Update(tran)) { GlobalClass.SetUserActivityLog(tran, "Voucher Type", "Edit", WorkDetail: "VoucherId : " + VType.VoucherId, Remarks: Remarks); tran.Commit(); MessageBox.Show("Voucher Type Updated Successfully.", MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Information); var Voucher = VTypeList.First(x => x.VoucherId == VType.VoucherId); Voucher.VoucherName = VType.VoucherName; Voucher.Rate = VType.Rate; Voucher.RateStr = VType.RateStr; Voucher.Value = VType.Value; Voucher.ValidStart = VType.ValidStart; Voucher.ValidEnd = VType.ValidEnd; Voucher.Validity = VType.Validity; Voucher.VoucherInfo = VType.VoucherInfo; Voucher.SkipVoucherGeneration = VType.SkipVoucherGeneration; Voucher.NonVat = VType.NonVat; ExecuteUndo(null); } else { MessageBox.Show("Voucher Type could not be updated.", MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Exclamation); tran.Rollback(); } } } } catch (SqlException ex) { if (ex.Number == 2601) { MessageBox.Show("Entered Voucher name already exist in the database. Enter unique name and try again", MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Hand); } else { MessageBox.Show(ex.Number + " : " + ex.Message, MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Error); } } catch (Exception ex) { MessageBox.Show(GlobalClass.GetRootException(ex).Message, MessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Error); } }
public Wrapper(Byte?b, Mask mask) { _mask = mask != null ? mask : new Mask("###"); if (_mask.MaskType == MType.None) { _mask.MaskType = MType.Nmrc | MType.Right; } _tcode = VType.nByte; _nbyte = b; }
public Array(VType type, byte [] data) { Type = type; Size = (uint)data.Length; item_size = Consts.sizes [type]; Length = (uint)Size / item_size; Value = data; more_dimensions = false; }
public static bool IsVTypeSpillable(VType inputType) { if (inputType.ValType == VType.ValTypeEnum.ConstantReference || inputType.ValType == VType.ValTypeEnum.ConstantValue || inputType.ValType == VType.ValTypeEnum.Null || inputType.ValType == VType.ValTypeEnum.DelegateSimpleMethod || inputType.ValType == VType.ValTypeEnum.DelegateVirtualMethod) return false; return false; }
public Array(VType type, uint length) { Type = type; Length = length; item_size = Consts.sizes [type]; Size = item_size * length; Value = new byte [Size]; more_dimensions = false; }
public bool Define(Token name, VType type) { if (!Values.TryAdd(name.Lexeme, type)) { string definedType = Enum.GetName(typeof(VType), Values[name.Lexeme]); VenaError.ParseError(name, $"Variable '{name.Lexeme}' already defined with type '{definedType}'."); return(false); } return(true); }
public Vertex(Vector3 pos, VType type, GameObject obj = null) { this.type = type; this.pos = pos; this.obj = obj; if (obj != null) { obj.transform.position = pos; } }
public Wrapper(DateTime?b, Mask mask) { _mask = mask != null ? mask : new Mask("yyyy-MM-dd"); if (_mask.MaskType == MType.None) { _mask.MaskType = MType.Date | MType.Left; } _tcode = VType.nDateTime; _ndatetime = b; }
public static VC_ParserResult_Func Paser(VC_PaserResult_Cmd result, ParameterInfo[] paramterInfos) { string cmd = result.parameters; List <string> errors = new List <string>(); List <object> convertedParameters = new List <object>(); foreach (ParameterInfo paramInfo in paramterInfos) { VType vType = VTypeCollection.Get(paramInfo.ParameterType); if (vType == null) { errors.Add(string.Format("No converter found for type: {0}", paramInfo.ParameterType.FullName)); break; } cmd = cmd.Trim(); Match ma = Regex.Match(cmd, string.Format("^{0}", vType.Regex)); if (String.IsNullOrWhiteSpace(ma.Value)) { if (paramInfo.IsOptional) { convertedParameters.Add(paramInfo.DefaultValue); continue; } errors.Add("Invalid parameters"); break; } else { try { convertedParameters.Add(vType.ConvertFrom(ma.Value)); } catch (Exception ex) { errors.Add(string.Format("Failed to convert '{0}' to type {1}.{2}{3}", ma.Value, paramInfo.ParameterType.Name, Environment.NewLine, ex.Message)); break; } // cmd = cmd.Substring(ma.Length); } } if (cmd.TrimEnd().Length > 0 && errors.Count == 0) { errors.Add("Provided parameters do not match with the expected parameters."); } return(new VC_ParserResult_Func(convertedParameters.ToArray(), errors.ToArray())); }
public Wrapper(Int32 b, Mask mask) { _mask = mask != null ? mask : new Mask("#####"); if (_mask.MaskType == MType.None) { _mask.MaskType = MType.Nmrc | MType.Right; } _tcode = VType.Int32; _int32 = b; }
//public Wrapper( UInt64 b, Mask mask ) //{ // _mask = mask; _tcode = VType.UInt64; // _uint64 = b; //} public Wrapper(Int64?b, Mask mask) { _mask = mask != null ? mask : new Mask("#####"); if (_mask.MaskType == MType.None) { _mask.MaskType = MType.Nmrc | MType.Right; } _tcode = VType.nInt64; _nint64 = b; }
public VReg(CppBuilder builder, string prefix, VType vType, int slot, UsageEnum usage) { VType = vType; Slot = slot; Usage = usage; m_isAlive = false; DetermineTraceability(builder); m_basicName = prefix + slot.ToString(); m_slotName = m_basicName; }
public Wrapper(Double?b, Mask mask) { _mask = mask != null ? mask : new Mask("#####.##"); if (_mask.MaskType == MType.None) { _mask.MaskType = MType.Nmrc | MType.Right; } _tcode = VType.nDouble; _ndouble = b; }
public Wrapper(string b, Mask mask) { _mask = mask != null ? mask : new Mask(MType.Strn | MType.Left, 10); if (_mask.MaskType == MType.None) { _mask.MaskType = MType.Strn | MType.Left; } _tcode = VType.String; _string = b; }
public Wrapper(Boolean?b, Mask mask) { _mask = mask != null ? mask : new Mask("V", "F"); if (_mask.MaskType == MType.None) { _mask.MaskType = MType.Bool | MType.Center; } _tcode = VType.nBoolean; _nboolean = b; }
public Wrapper(Decimal?b, Mask mask) { _mask = mask != null ? mask : new Mask("#####.##"); if (_mask.MaskType == MType.None) { _mask.MaskType = MType.Nmrc | MType.Right; } _tcode = VType.nDecimal; _ndecimal = b; }
public CfgOutboundEdgePrototype GenerateCfgEdge() { VType[] types = new VType[m_regs.Count]; SsaRegister[] ssaRegs = new SsaRegister[m_regs.Count]; for (int i = 0; i < types.Length; i++) { types[i] = m_regs[i].VType; ssaRegs[i] = m_regs[i]; } return new CfgOutboundEdgePrototype(types, ssaRegs); }
int AddToFirstEmptySpace(VType vType) // returnera första lediga plats med eventuella nödvändiga platser extra efter varandra { Garage gar = new Garage(1000); var vehiclesParked = (from v in db.Vehicles select v).ToList(); foreach (var veh in vehiclesParked) { gar.AddToParkNr(veh.ParkNr); //om platsen redan finns !!?? //veh.ParkNr=0; //går ju inte } return gar.Add(); }
private void TextBox_TextChanged(object sender, TextChangedEventArgs e) { Window1 w = Utilities.getWindow(this); TextBox tb = (TextBox)sender; Match m = Regex.Match(tb.Text, @"^(?<num>[+-]?(\d+\.?|\d*\.\d+))(?<mul>[CcRr]{0,2})$"); if (!m.Success) { w.LogError(tb); Formula.Inlines.Clear(); return; } this.Coef = Convert.ToDouble(m.Groups["num"].Value); this.CCoef = Utilities.ConvertToVType(m.Groups["mul"].Value); if (w != null) w.RemoveError(tb); if (Formula != null) { Formula.Inlines.Clear(); Formula.Inlines.Add(DisplayFormula()); } }
public VReg AllocReg(VType vType) { VType regVType = StrictStorageType(vType); VReg resultReg = null; foreach (VReg reg in m_registers) { if (!reg.IsAlive && reg.VType.Equals(regVType)) { resultReg = reg; break; } } if (resultReg == null) resultReg = NewDeadReg(regVType, VReg.UsageEnum.Temporary); resultReg.Liven(); return resultReg; }
public void Compile() { CppMethod method = m_cfgNode.CfgBuilder.CppMethod; VReg[] locals = m_cfgNode.CfgBuilder.Locals; VReg[] args = m_cfgNode.CfgBuilder.Args; CfgBuilder cfgBuilder = m_cfgNode.CfgBuilder; CLR.CIL.Method cilMethod = method.MethodDef.Method; List<MidInstruction> midInstrs = new List<MidInstruction>(); bool[] everTargeted = new bool[cilMethod.Instructions.Length]; EvalStackTracker stackTracker = new EvalStackTracker(); Clarity.Rpa.CodeLocationTag codeLocation = new Clarity.Rpa.CodeLocationTag(method.VtableSlotTag, cilMethod.OffsetForInstruction(m_cfgNode.StartInstr)); foreach (VType entryType in m_cfgNode.EntryTypes) { SsaRegister reg = stackTracker.NewReg(entryType); reg.TrySpill(); stackTracker.Push(reg); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.EntryReg, codeLocation, reg)); } int firstInstr = m_cfgNode.StartInstr; int nextInstr = firstInstr; bool isTerminalEdge = false; while (!isTerminalEdge) { int instrNum = nextInstr++; codeLocation = new Clarity.Rpa.CodeLocationTag(method.VtableSlotTag, cilMethod.OffsetForInstruction(instrNum)); if (instrNum != firstInstr && cfgBuilder.InstrIsJumpTarget(instrNum)) { CfgOutboundEdgePrototype edgeProto = stackTracker.GenerateCfgEdge(); OutputFallThroughEdge = new CfgOutboundEdge(codeLocation, cfgBuilder.AddCfgTarget(this, instrNum, edgeProto.OutboundTypes), edgeProto); break; } if (cfgBuilder.EhClusters.ContainsKey((uint)instrNum)) { if (stackTracker.Depth != 0) throw new ParseFailedException("Stack not empty at protected block entry point"); ExceptionHandlingCluster cluster = cfgBuilder.EhClusters[(uint)instrNum]; midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.EnterProtectedBlock, codeLocation, cluster)); VType[] emptyTypesList = new VType[0]; foreach (uint escapePath in cluster.EscapePaths) { if (escapePath >= m_ehRegion.StartInstr && escapePath <= m_ehRegion.EndInstr) { CfgNode targetNode = cfgBuilder.AddCfgTarget(this, (int)escapePath, emptyTypesList); m_ehRegion.AddLeaveTarget(escapePath, targetNode); } else m_ehRegion.AddEscapePath(escapePath); } break; } CLR.CIL.HLInstruction instr = cilMethod.Instructions[instrNum]; switch (instr.Opcode) { case CLR.CIL.HLOpcode.nop: break; case CLR.CIL.HLOpcode.newobj: { CppMethodSpec ctorMethodSpec = CppBuilder.ResolveMethodDefOrRef((CLRTableRow)instr.Arguments.ObjValue); if (ctorMethodSpec.GenericParameters != null) throw new ArgumentException(); CppMethod ctorMethod = ctorMethodSpec.CppMethod; int numParams = ctorMethod.MethodSignature.ParamTypes.Length; CLRTypeSpec instanceSpec = ctorMethod.DeclaredInClassSpec; VType.ValTypeEnum resultValType = CppCilExporter.ValTypeForTypeSpec(m_cppBuilder, instanceSpec); SsaRegister instanceReg = stackTracker.NewReg(new VType(resultValType, instanceSpec)); // Allocate the instance into an SSA reg midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, instanceReg)); stackTracker.SpillStack(); bool isDelegate = false; if (numParams == 2) { SsaRegister param2 = stackTracker.GetFromTop(0); if (param2.VType.ValType == VType.ValTypeEnum.DelegateSimpleMethod || param2.VType.ValType == VType.ValTypeEnum.DelegateVirtualMethod) isDelegate = true; } // Determine the parameter set. // Unlike when making calls, we don't spill here because we already spilled during the AllocObject call SsaRegister[] passedParams = new SsaRegister[numParams]; for (int p = 0; p < numParams; p++) { SsaRegister paramReg = stackTracker.GetFromTop(numParams - 1 - p); passedParams[p] = paramReg; } CppClass cls = CppBuilder.GetCachedClass(instanceSpec); SsaRegister valueOutRegister = null; VReg tempLocal = null; if (cls.IsValueType) { valueOutRegister = instanceReg; tempLocal = GetTemporary(new VType(VType.ValTypeEnum.ValueValue, instanceSpec)); SsaRegister tempClearAddr = new SsaRegister(new VType(VType.ValTypeEnum.ManagedPtr, instanceSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, tempClearAddr)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadRegA, codeLocation, tempLocal, tempClearAddr)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.ZeroFillPtr, codeLocation, tempClearAddr)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, tempClearAddr)); SsaRegister tempUseAddr = new SsaRegister(new VType(VType.ValTypeEnum.ManagedPtr, instanceSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, tempUseAddr)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadRegA, codeLocation, tempLocal, tempUseAddr)); instanceReg = tempUseAddr; } if (isDelegate) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.BindDelegate, codeLocation, passedParams[0], passedParams[1], instanceReg)); else { // Allocate object if (tempLocal == null) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.AllocObject, codeLocation, instanceReg, instanceSpec)); // Make the actual ctor call midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.CallConstructor, codeLocation, ctorMethodSpec, null, null, instanceReg, passedParams)); } // Kill all of the parameter registers for (int p = 0; p < numParams; p++) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, stackTracker.Pop())); if (valueOutRegister != null) { midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadReg_Value, codeLocation, tempLocal, valueOutRegister)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, instanceReg)); instanceReg = valueOutRegister; } // Push the return value on to the stack stackTracker.Push(instanceReg); } break; case CLR.CIL.HLOpcode.ret: if (stackTracker.Depth == 1) { SsaRegister returnValue = stackTracker.Pop(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.ReturnValue, codeLocation, returnValue, method.MethodSignature.RetType)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, returnValue)); } else if (stackTracker.Depth == 0) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.Return, codeLocation)); else throw new ArgumentException(); isTerminalEdge = true; break; case CLR.CIL.HLOpcode.ldarg: { VReg argReg = args[instr.Arguments.U32Value]; SsaRegister evalReg = stackTracker.NewReg(argReg.VType); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, evalReg)); string loadSrc = argReg.SlotName; switch (argReg.VType.ValType) { case VType.ValTypeEnum.ManagedPtr: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadReg_ManagedPtr, codeLocation, argReg, evalReg)); break; case VType.ValTypeEnum.ReferenceValue: case VType.ValTypeEnum.ValueValue: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadReg_Value, codeLocation, argReg, evalReg)); break; default: throw new ArgumentException(); } stackTracker.Push(evalReg); } break; case CLR.CIL.HLOpcode.ldarga: { VReg argReg = args[instr.Arguments.U32Value]; VType outEvalType; MidInstruction.OpcodeEnum opcode; switch (argReg.VType.ValType) { case VType.ValTypeEnum.ReferenceValue: case VType.ValTypeEnum.ValueValue: opcode = MidInstruction.OpcodeEnum.LoadArgA_Value; outEvalType = new VType(VType.ValTypeEnum.ManagedPtr, argReg.VType.TypeSpec); break; default: throw new ArgumentException(); } SsaRegister evalReg = stackTracker.NewReg(outEvalType); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, evalReg)); midInstrs.Add(new MidInstruction(opcode, codeLocation, argReg, evalReg)); stackTracker.Push(evalReg); } break; case CLR.CIL.HLOpcode.starg: { VReg argReg = args[instr.Arguments.U32Value]; SsaRegister valueReg = stackTracker.Pop(); switch (valueReg.VType.ValType) { case VType.ValTypeEnum.ConstantReference: case VType.ValTypeEnum.ReferenceValue: case VType.ValTypeEnum.Null: case VType.ValTypeEnum.ValueValue: case VType.ValTypeEnum.ConstantValue: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreReg_Value, codeLocation, argReg, valueReg)); break; case VType.ValTypeEnum.ManagedPtr: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreReg_ManagedPtr, codeLocation, argReg, valueReg)); break; default: throw new ArgumentException(); } midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, valueReg)); } break; case CLR.CIL.HLOpcode.call: case CLR.CIL.HLOpcode.callvirt: { bool devirtualize = false; CLRTypeSpec constraintType = null; if (instrNum != 0) { CLR.CIL.HLInstruction prevInstr = cilMethod.Instructions[instrNum - 1]; if (prevInstr.Opcode == CLR.CIL.HLOpcode.constrained_pfx) constraintType = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec((CLRTableRow)prevInstr.Arguments.ObjValue); } CppMethodSpec calledMethodSpec = CppBuilder.ResolveMethodDefOrRef((CLRTableRow)instr.Arguments.ObjValue); CppMethod calledMethod = calledMethodSpec.CppMethod; if (!calledMethod.Virtual) devirtualize = true; int numParams = calledMethod.MethodSignature.ParamTypes.Length; SsaRegister returnReg = null; SsaRegister thisReg = null; if (!CppBuilder.TypeSpecIsVoid(calledMethod.MethodSignature.RetType)) { CLRTypeSpec retType = calledMethod.MethodSignature.RetType; returnReg = stackTracker.NewReg(new VType(CppCilExporter.ValTypeForTypeSpec(m_cppBuilder, retType), retType)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, returnReg)); } if (!calledMethod.Static) thisReg = stackTracker.GetFromTop(numParams); MidInstruction.OpcodeEnum midOpcode; if (instr.Opcode == CLR.CIL.HLOpcode.call || devirtualize) { if (constraintType != null) midOpcode = MidInstruction.OpcodeEnum.ConstrainedCallMethod; else midOpcode = MidInstruction.OpcodeEnum.CallMethod; } else if (instr.Opcode == CLR.CIL.HLOpcode.callvirt) { if (constraintType != null) midOpcode = MidInstruction.OpcodeEnum.ConstrainedCallVirtualMethod; else { midOpcode = MidInstruction.OpcodeEnum.CallVirtualMethod; if (calledMethod.NumGenericParameters > 0) { if (calledMethod.DeclaredInClass.Semantics == CLRTypeDefRow.TypeSemantics.Interface) throw new NotSupportedException(method.DeclaredInClassSpec.ToString() + "." + method.Name + " contains an unconstrained call to an interface virtual method, which is not supported."); else if (calledMethod.DeclaredInClass.Semantics == CLRTypeDefRow.TypeSemantics.Class) midOpcode = MidInstruction.OpcodeEnum.CallMethod; else throw new ArgumentException(); } } } else throw new ArgumentException(); SsaRegister[] passedParams = new SsaRegister[numParams]; for (int p = 0; p < numParams; p++) { SsaRegister paramReg = stackTracker.GetFromTop(numParams - 1 - p); passedParams[p] = paramReg; } // Pop the parameters first so that we don't have to spill them into the caller frame. // They won't actually be deadened until after the call. stackTracker.Pop(numParams); stackTracker.SpillStack(); // Emit the actual call midInstrs.Add(new MidInstruction(midOpcode, codeLocation, calledMethodSpec, constraintType, returnReg, thisReg, passedParams)); // Emit parameter deadens (in stack order) for (int p = 0; p < numParams; p++) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, passedParams[numParams - 1 - p])); // Emit "this" deaden and remove it from the stack if (thisReg != null) { midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, thisReg)); if (stackTracker.Pop() != thisReg) throw new ArgumentException(); } // Push the return value if (returnReg != null) stackTracker.Push(returnReg); } break; case CLR.CIL.HLOpcode.stloc: { SsaRegister evalVar = stackTracker.Pop(); VReg localVar = locals[instr.Arguments.U32Value]; switch (localVar.VType.ValType) { case VType.ValTypeEnum.ValueValue: case VType.ValTypeEnum.ReferenceValue: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreReg_Value, codeLocation, localVar, evalVar)); break; case VType.ValTypeEnum.ManagedPtr: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreReg_ManagedPtr, codeLocation, localVar, evalVar)); break; default: throw new ArgumentException(); } midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, evalVar)); } break; case CLR.CIL.HLOpcode.ldloc: { VReg localVar = locals[instr.Arguments.U32Value]; SsaRegister evalReg = stackTracker.NewReg(localVar.VType); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, evalReg)); switch (localVar.VType.ValType) { case VType.ValTypeEnum.ManagedPtr: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadReg_ManagedPtr, codeLocation, localVar, evalReg)); break; case VType.ValTypeEnum.ValueValue: case VType.ValTypeEnum.ReferenceValue: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadReg_Value, codeLocation, localVar, evalReg)); break; default: throw new ArgumentException(); } stackTracker.Push(evalReg); } break; case CLR.CIL.HLOpcode.ldloca: { VReg localVar = locals[instr.Arguments.U32Value]; SsaRegister evalReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ManagedPtr, localVar.VType.TypeSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, evalReg)); switch (localVar.VType.ValType) { case VType.ValTypeEnum.ValueValue: case VType.ValTypeEnum.ReferenceValue: midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadRegA, codeLocation, localVar, evalReg)); break; default: throw new ArgumentException(); } stackTracker.Push(evalReg); } break; case CLR.CIL.HLOpcode.bne: // [.un] { SsaRegister value2 = stackTracker.Pop(); SsaRegister value1 = stackTracker.Pop(); bool isRefComparison = IsComparisonReference(value1.VType, value2.VType); CfgOutboundEdgePrototype edgeProto = stackTracker.GenerateCfgEdge(); CfgNode targetNode = cfgBuilder.AddCfgTarget(this, (int)instr.Arguments.U32Value, edgeProto.OutboundTypes); CfgNode fallThroughNode = cfgBuilder.AddCfgTarget(this, nextInstr, edgeProto.OutboundTypes); midInstrs.Add(new MidInstruction(isRefComparison ? MidInstruction.OpcodeEnum.bne_ref : MidInstruction.OpcodeEnum.bne_val, codeLocation, value1, value2, new CfgOutboundEdge(codeLocation, targetNode, edgeProto), (instr.Flags & CLR.CIL.HLOpFlags.Un) != 0)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value2)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value1)); OutputFallThroughEdge = new CfgOutboundEdge(codeLocation, fallThroughNode, edgeProto); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.beq: // [.un] { SsaRegister value2 = stackTracker.Pop(); SsaRegister value1 = stackTracker.Pop(); CfgOutboundEdgePrototype edgeProto = stackTracker.GenerateCfgEdge(); bool isRefComparison = IsComparisonReference(value1.VType, value2.VType); CfgNode targetNode = cfgBuilder.AddCfgTarget(this, (int)instr.Arguments.U32Value, edgeProto.OutboundTypes); CfgNode fallThroughNode = cfgBuilder.AddCfgTarget(this, nextInstr, edgeProto.OutboundTypes); midInstrs.Add(new MidInstruction(isRefComparison ? MidInstruction.OpcodeEnum.beq_ref : MidInstruction.OpcodeEnum.beq_val, codeLocation, value1, value2, new CfgOutboundEdge(codeLocation, targetNode, edgeProto), (instr.Flags & CLR.CIL.HLOpFlags.Un) != 0)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value2)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value1)); OutputFallThroughEdge = new CfgOutboundEdge(codeLocation, fallThroughNode, edgeProto); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.bge: // [.un] case CLR.CIL.HLOpcode.bgt: // [.un] case CLR.CIL.HLOpcode.ble: // [.un] case CLR.CIL.HLOpcode.blt: // [.un] { SsaRegister value2 = stackTracker.Pop(); SsaRegister value1 = stackTracker.Pop(); CfgOutboundEdgePrototype edgeProto = stackTracker.GenerateCfgEdge(); CfgNode targetNode = cfgBuilder.AddCfgTarget(this, (int)instr.Arguments.U32Value, edgeProto.OutboundTypes); CfgNode fallThroughNode = cfgBuilder.AddCfgTarget(this, nextInstr, edgeProto.OutboundTypes); midInstrs.Add(new MidInstruction(SimpleTranslateInstr(instr.Opcode), codeLocation, value1, value2, new CfgOutboundEdge(codeLocation, targetNode, edgeProto), (instr.Flags & CLR.CIL.HLOpFlags.Un) != 0)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value2)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value1)); OutputFallThroughEdge = new CfgOutboundEdge(codeLocation, fallThroughNode, edgeProto); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.br: { CfgOutboundEdgePrototype edgeProto = stackTracker.GenerateCfgEdge(); CfgNode targetNode = cfgBuilder.AddCfgTarget(this, (int)instr.Arguments.U32Value, edgeProto.OutboundTypes); OutputFallThroughEdge = new CfgOutboundEdge(codeLocation, targetNode, edgeProto); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.leave: { uint escapePath = instr.Arguments.U32Value; m_ehRegion.AddEscapePath(instr.Arguments.U32Value); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.Leave, codeLocation, escapePath)); while (stackTracker.Depth > 0) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, stackTracker.Pop())); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.ceq: { SsaRegister value2 = stackTracker.Pop(); SsaRegister value1 = stackTracker.Pop(); SsaRegister returnValue = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, m_commonTypeLookup.Boolean)); bool isRefComparison = IsComparisonReference(value1.VType, value2.VType); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, returnValue)); midInstrs.Add(new MidInstruction(isRefComparison ? MidInstruction.OpcodeEnum.ceq_ref : MidInstruction.OpcodeEnum.ceq_numeric, codeLocation, returnValue, value1, value2, false)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value2)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value1)); stackTracker.Push(returnValue); } break; case CLR.CIL.HLOpcode.cgt: // [.un] { SsaRegister value2 = stackTracker.Pop(); SsaRegister value1 = stackTracker.Pop(); SsaRegister returnValue = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, m_commonTypeLookup.Boolean)); // Per III.4, cgt.un is used for reference non-equality checks. // For some reason there isn't a cne instruction... bool isRefComparison = IsComparisonReference(value1.VType, value2.VType); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, returnValue)); midInstrs.Add(new MidInstruction(isRefComparison ? MidInstruction.OpcodeEnum.cne_ref : MidInstruction.OpcodeEnum.cgt, codeLocation, returnValue, value1, value2, (instr.Flags & CLR.CIL.HLOpFlags.Un) != 0)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value2)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value1)); stackTracker.Push(returnValue); } break; case CLR.CIL.HLOpcode.clt: // [.un] { SsaRegister value2 = stackTracker.Pop(); SsaRegister value1 = stackTracker.Pop(); SsaRegister returnValue = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, m_commonTypeLookup.Boolean)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, returnValue)); midInstrs.Add(new MidInstruction(SimpleTranslateInstr(instr.Opcode), codeLocation, returnValue, value1, value2, (instr.Flags & CLR.CIL.HLOpFlags.Un) != 0)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value2)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value1)); stackTracker.Push(returnValue); } break; case CLR.CIL.HLOpcode.ldc: { SsaRegister resultReg; switch (instr.Arguments.ArgsType) { case CLR.CIL.HLArguments.ArgsTypeEnum.I32: resultReg = SsaRegister.Constant(new VType(VType.ValTypeEnum.ConstantValue, m_commonTypeLookup.I32, instr.Arguments.S32Value)); break; case CLR.CIL.HLArguments.ArgsTypeEnum.I64: resultReg = SsaRegister.Constant(new VType(VType.ValTypeEnum.ConstantValue, m_commonTypeLookup.I64, instr.Arguments.S64Value)); break; case CLR.CIL.HLArguments.ArgsTypeEnum.F32: resultReg = SsaRegister.Constant(new VType(VType.ValTypeEnum.ConstantValue, m_commonTypeLookup.F32, instr.Arguments.F32Value)); break; case CLR.CIL.HLArguments.ArgsTypeEnum.F64: resultReg = SsaRegister.Constant(new VType(VType.ValTypeEnum.ConstantValue, m_commonTypeLookup.F64, instr.Arguments.F64Value)); break; default: throw new ArgumentException(); } midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, resultReg)); stackTracker.Push(resultReg); } break; case CLR.CIL.HLOpcode.brfalse: case CLR.CIL.HLOpcode.brtrue: { SsaRegister v = stackTracker.Pop(); CfgOutboundEdgePrototype edgeProto = stackTracker.GenerateCfgEdge(); CfgNode targetNode = cfgBuilder.AddCfgTarget(this, (int)instr.Arguments.U32Value, edgeProto.OutboundTypes); CfgNode fallThroughNode = cfgBuilder.AddCfgTarget(this, nextInstr, edgeProto.OutboundTypes); MidInstruction.OpcodeEnum opcode; switch (v.VType.ValType) { case VType.ValTypeEnum.ConstantValue: case VType.ValTypeEnum.ValueValue: if (instr.Opcode == CLR.CIL.HLOpcode.brtrue) opcode = MidInstruction.OpcodeEnum.brnotzero; else opcode = MidInstruction.OpcodeEnum.brzero; break; case VType.ValTypeEnum.ConstantReference: case VType.ValTypeEnum.Null: case VType.ValTypeEnum.ReferenceValue: if (instr.Opcode == CLR.CIL.HLOpcode.brtrue) opcode = MidInstruction.OpcodeEnum.brnotnull; else opcode = MidInstruction.OpcodeEnum.brnull; break; default: throw new Exception("Unsupported stack op type passed to brtrue or brfalse"); } midInstrs.Add(new MidInstruction(opcode, codeLocation, v, new CfgOutboundEdge(codeLocation, targetNode, edgeProto))); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, v)); OutputFallThroughEdge = new CfgOutboundEdge(codeLocation, fallThroughNode, edgeProto); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.ldnull: { SsaRegister constReg = SsaRegister.Constant(new VType(VType.ValTypeEnum.Null, m_commonTypeLookup.Object)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, constReg)); stackTracker.Push(constReg); } break; case CLR.CIL.HLOpcode.@throw: { SsaRegister ex = stackTracker.Pop(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.Throw, codeLocation, ex)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, ex)); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.newarr: { CLRTableRow contentsType = (CLRTableRow)instr.Arguments.ObjValue; CLRTypeSpec contentsTypeSpec = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec(contentsType); CLRTypeSpecSZArray arrayTS = new CLRTypeSpecSZArray(contentsTypeSpec); SsaRegister resultReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ReferenceValue, arrayTS)); // It's OK to pop num elems here since, as an integer, we don't care if it doesn't spill SsaRegister numElemsReg = stackTracker.Pop(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, resultReg)); stackTracker.SpillStack(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.NewSZArray, codeLocation, resultReg, numElemsReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, numElemsReg)); stackTracker.Push(resultReg); } break; case CLR.CIL.HLOpcode.ldfld: { CppField field = ResolveField((CLRTableRow)instr.Arguments.ObjValue); CLRTypeSpec fieldValueSpec = field.Type; VType.ValTypeEnum valType = CppCilExporter.ValTypeForTypeSpec(m_cppBuilder, fieldValueSpec); SsaRegister valueReg = stackTracker.NewReg(new VType(valType, fieldValueSpec)); SsaRegister objReg = stackTracker.Pop(); VType.ValTypeEnum objValType = objReg.VType.ValType; midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, valueReg)); MidInstruction.OpcodeEnum opcode; if (objValType == VType.ValTypeEnum.ManagedPtr) opcode = MidInstruction.OpcodeEnum.LoadField_ManagedPtr; else if (objValType == VType.ValTypeEnum.ReferenceValue) opcode = MidInstruction.OpcodeEnum.LoadField_Object; else if (objValType == VType.ValTypeEnum.ValueValue) opcode = MidInstruction.OpcodeEnum.LoadField_Value; else throw new ArgumentException(); midInstrs.Add(new MidInstruction(opcode, codeLocation, objReg, valueReg, field.Name, field.DeclaredInClassSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, objReg)); stackTracker.Push(valueReg); } break; case CLR.CIL.HLOpcode.ldflda: { SsaRegister objReg = stackTracker.Pop(); CppField field = ResolveField((CLRTableRow)instr.Arguments.ObjValue); CLRTypeSpec fieldValueSpec = field.Type; VType.ValTypeEnum valType = VType.ValTypeEnum.ManagedPtr; bool isManagedPtr = (objReg.VType.ValType == VType.ValTypeEnum.ManagedPtr); if (isManagedPtr) valType = objReg.VType.ValType; SsaRegister valueReg = stackTracker.NewReg(new VType(valType, fieldValueSpec)); VType.ValTypeEnum objValType = objReg.VType.ValType; midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, valueReg)); MidInstruction.OpcodeEnum opcode; if (isManagedPtr) opcode = MidInstruction.OpcodeEnum.LoadFieldA_ManagedPtr; else if (objValType == VType.ValTypeEnum.ReferenceValue) opcode = MidInstruction.OpcodeEnum.LoadFieldA_Object; else throw new ArgumentException(); midInstrs.Add(new MidInstruction(opcode, codeLocation, objReg, valueReg, field.Name, field.DeclaredInClassSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, objReg)); stackTracker.Push(valueReg); } break; case CLR.CIL.HLOpcode.ldsfld: { CppField field = ResolveField((CLRTableRow)instr.Arguments.ObjValue); CLRTypeSpec fieldValueSpec = field.Type; VType.ValTypeEnum valType = CppCilExporter.ValTypeForTypeSpec(m_cppBuilder, fieldValueSpec); SsaRegister valueReg = stackTracker.NewReg(new VType(valType, fieldValueSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadStaticField, codeLocation, valueReg, field.DeclaredInClassSpec, field.Name)); stackTracker.Push(valueReg); } break; case CLR.CIL.HLOpcode.ldsflda: { CppField field = ResolveField((CLRTableRow)instr.Arguments.ObjValue); CLRTypeSpec fieldValueSpec = field.Type; SsaRegister valueReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ManagedPtr, fieldValueSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadStaticFieldAddr, codeLocation, valueReg, field.DeclaredInClassSpec, field.Name)); stackTracker.Push(valueReg); } break; case CLR.CIL.HLOpcode.ldelem: // [.type] case CLR.CIL.HLOpcode.ldelema: { // We just ignore the type suffix and get it from the array instead SsaRegister indexReg = stackTracker.Pop(); SsaRegister arrayReg = stackTracker.Pop(); CLRTypeSpecSZArray arraySpec = (CLRTypeSpecSZArray)arrayReg.VType.TypeSpec; CLRTypeSpec contentsSpec = arraySpec.SubType; VType.ValTypeEnum valType; MidInstruction.OpcodeEnum op; if (instr.Opcode == CLR.CIL.HLOpcode.ldelem) { valType = CppCilExporter.ValTypeForTypeSpec(m_cppBuilder, contentsSpec); op = MidInstruction.OpcodeEnum.LoadArrayElem; } else if (instr.Opcode == CLR.CIL.HLOpcode.ldelema) { valType = VType.ValTypeEnum.ManagedPtr; op = MidInstruction.OpcodeEnum.LoadArrayElemAddr; } else throw new ArgumentException(); SsaRegister contentsReg = stackTracker.NewReg(new VType(valType, contentsSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, contentsReg)); midInstrs.Add(new MidInstruction(op, codeLocation, arrayReg, indexReg, contentsReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, indexReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, arrayReg)); stackTracker.Push(contentsReg); } break; case CLR.CIL.HLOpcode.stelem: // [.type] { // We just ignore the type suffix and get it from the array instead SsaRegister valueReg = stackTracker.Pop(); SsaRegister indexReg = stackTracker.Pop(); SsaRegister arrayReg = stackTracker.Pop(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreArrayElem, codeLocation, arrayReg, indexReg, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, indexReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, arrayReg)); } break; case CLR.CIL.HLOpcode.stfld: { SsaRegister valueReg = stackTracker.Pop(); SsaRegister objReg = stackTracker.Pop(); CppField field = ResolveField((CLRTableRow)instr.Arguments.ObjValue); CLRTypeSpec fieldValueSpec = field.Type; VType.ValTypeEnum valType = CppCilExporter.ValTypeForTypeSpec(m_cppBuilder, fieldValueSpec); VType.ValTypeEnum objValType = objReg.VType.ValType; if (objValType == VType.ValTypeEnum.ManagedPtr) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreField_ManagedPtr, codeLocation, objReg, valueReg, field.Name, field.DeclaredInClassSpec, fieldValueSpec)); else if (objValType == VType.ValTypeEnum.ReferenceValue) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreField_Object, codeLocation, objReg, valueReg, field.Name, field.DeclaredInClassSpec, fieldValueSpec)); else throw new ArgumentException(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, objReg)); } break; case CLR.CIL.HLOpcode.stsfld: { SsaRegister valueReg = stackTracker.Pop(); CppField field = ResolveField((CLRTableRow)instr.Arguments.ObjValue); CLRTypeSpec fieldValueSpec = field.Type; midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreStaticField, codeLocation, valueReg, field.DeclaredInClassSpec, fieldValueSpec, field.Name)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, valueReg)); } break; case CLR.CIL.HLOpcode.ldstr: { SsaRegister constReg = SsaRegister.Constant(new VType(VType.ValTypeEnum.ConstantReference, m_commonTypeLookup.String, instr.Arguments.ObjValue)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, constReg)); stackTracker.Push(constReg); } break; case CLR.CIL.HLOpcode.add: // [.ovf][.un] case CLR.CIL.HLOpcode.sub: // [.ovf][.un] case CLR.CIL.HLOpcode.mul: // [.ovf][.un] case CLR.CIL.HLOpcode.div: // [.ovf][.un] case CLR.CIL.HLOpcode.rem: // [.ovf][.un] case CLR.CIL.HLOpcode.and: case CLR.CIL.HLOpcode.or: case CLR.CIL.HLOpcode.xor: { SsaRegister value2 = stackTracker.Pop(); SsaRegister value1 = stackTracker.Pop(); CLRTypeSpec promoted1 = ArithPromoteValue(value1.VType.TypeSpec); CLRTypeSpec promoted2 = ArithPromoteValue(value2.VType.TypeSpec); MidInstruction.ArithEnum arithMode = ArithModeForBinaryNumericOp(m_commonTypeLookup, promoted1, promoted2); if ((instr.Flags & CLR.CIL.HLOpFlags.Ovf) != 0) arithMode |= MidInstruction.ArithEnum.Flags_Ovf; if ((instr.Flags & CLR.CIL.HLOpFlags.Un) != 0) arithMode |= MidInstruction.ArithEnum.Flags_Un; CLRTypeSpec resultType = TypeSpecForArithModeResult(arithMode); SsaRegister resultReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, resultType)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, resultReg)); midInstrs.Add(new MidInstruction(SimpleTranslateInstr(instr.Opcode), codeLocation, value1, value2, resultReg, arithMode)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value2)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value1)); stackTracker.Push(resultReg); } break; case CLR.CIL.HLOpcode.shl: case CLR.CIL.HLOpcode.shr: // [.un] { SsaRegister value2 = stackTracker.Pop(); SsaRegister value1 = stackTracker.Pop(); CLRTypeSpec promoted1 = ArithPromoteValue(value1.VType.TypeSpec); CLRTypeSpec promoted2 = ArithPromoteValue(value2.VType.TypeSpec); MidInstruction.ArithEnum arithMode = ArithModeForShiftOp(m_commonTypeLookup, promoted1, promoted2); if ((instr.Flags & CLR.CIL.HLOpFlags.Un) != 0) arithMode |= MidInstruction.ArithEnum.Flags_Un; CLRTypeSpec resultType = TypeSpecForArithModeResult(arithMode); SsaRegister resultReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, resultType)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, resultReg)); midInstrs.Add(new MidInstruction(SimpleTranslateInstr(instr.Opcode), codeLocation, value1, value2, resultReg, arithMode)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value2)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, value1)); stackTracker.Push(resultReg); } break; case CLR.CIL.HLOpcode.neg: case CLR.CIL.HLOpcode.not: { SsaRegister v = stackTracker.Pop(); CLRTypeSpec promoted = ArithPromoteValue(v.VType.TypeSpec); MidInstruction.ArithEnum arithMode = ArithModeForUnaryOp(promoted); CLRTypeSpec resultType = TypeSpecForArithModeResult(arithMode); SsaRegister resultReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, resultType)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, resultReg)); midInstrs.Add(new MidInstruction(SimpleTranslateInstr(instr.Opcode), codeLocation, v, resultReg, arithMode)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, v)); stackTracker.Push(resultReg); } break; case CLR.CIL.HLOpcode.isinst: { CLRTypeSpec type = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec((CLRTableRow)instr.Arguments.ObjValue); SsaRegister inputReg = stackTracker.Pop(); SsaRegister resultReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ReferenceValue, type)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, resultReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.TryConvertObj, codeLocation, inputReg, resultReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, inputReg)); stackTracker.Push(resultReg); } break; case CLR.CIL.HLOpcode.castclass: { CLRTypeSpec type = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec((CLRTableRow)instr.Arguments.ObjValue); SsaRegister inputReg = stackTracker.Pop(); SsaRegister resultReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ReferenceValue, type)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, resultReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.ConvertObj, codeLocation, inputReg, resultReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, inputReg)); stackTracker.Push(resultReg); } break; case CLR.CIL.HLOpcode.dup: { SsaRegister top = stackTracker.GetFromTop(0); SsaRegister duplicate = stackTracker.NewReg(top.VType); // WARNING: If you update this sequence, you must update ldvirtftn too! midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, duplicate)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.DuplicateReg, codeLocation, top, duplicate)); stackTracker.Push(duplicate); } break; case CLR.CIL.HLOpcode.ldind: // (.type) case CLR.CIL.HLOpcode.ldobj: { SsaRegister addr = stackTracker.Pop(); if (addr.VType.ValType != VType.ValTypeEnum.ManagedPtr) throw new ArgumentException(); SsaRegister val = stackTracker.NewReg(new VType(CppCilExporter.ValTypeForTypeSpec(m_cppBuilder, addr.VType.TypeSpec), addr.VType.TypeSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, val)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadIndirect, codeLocation, addr, val)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, addr)); stackTracker.Push(val); } break; case CLR.CIL.HLOpcode.stind: // (.type) case CLR.CIL.HLOpcode.stobj: { SsaRegister val = stackTracker.Pop(); SsaRegister addr = stackTracker.Pop(); if (addr.VType.ValType != VType.ValTypeEnum.ManagedPtr) throw new ArgumentException(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.StoreIndirect, codeLocation, addr, val)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, val)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, addr)); } break; case CLR.CIL.HLOpcode.pop: { SsaRegister val = stackTracker.Pop(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, val)); } break; case CLR.CIL.HLOpcode.box: { CLRTableRow typeTok = (CLRTableRow)instr.Arguments.ObjValue; stackTracker.SpillStack(); SsaRegister val = stackTracker.Pop(); if (val.VType.ValType != VType.ValTypeEnum.ConstantValue && val.VType.ValType != VType.ValTypeEnum.ValueValue) throw new ArgumentException(); CLRTypeSpec valueTypeSpec = val.VType.TypeSpec; if (valueTypeSpec is CLRTypeSpecGenericInstantiation) { CLRTypeSpecGenericInstantiation valueGI = (CLRTypeSpecGenericInstantiation)valueTypeSpec; CLRTypeSpecClass valueGIClass = valueGI.GenericType; CLRTypeDefRow typeDef = valueGIClass.TypeDef; if (typeDef.ContainerClass == null && typeDef.TypeNamespace == "System" && typeDef.TypeName == "Nullable`1") valueTypeSpec = valueGI.ArgTypes[0]; } SsaRegister boxed = stackTracker.NewReg(new VType(VType.ValTypeEnum.ReferenceValue, val.VType.TypeSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, boxed)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.Box, codeLocation, val, boxed)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, val)); stackTracker.Push(boxed); } break; case CLR.CIL.HLOpcode.conv: // [.ovf](.type)[.un] { CLRTypeSpec destType; MidInstruction.ArithEnum arithMode; switch (instr.TypeToken) { case CLR.CIL.HLOpType.I1: destType = m_commonTypeLookup.I8; arithMode = MidInstruction.ArithEnum.ArithType_Int32; break; case CLR.CIL.HLOpType.I2: destType = m_commonTypeLookup.I16; arithMode = MidInstruction.ArithEnum.ArithType_Int32; break; case CLR.CIL.HLOpType.I4: destType = m_commonTypeLookup.I32; arithMode = MidInstruction.ArithEnum.ArithType_Int32; break; case CLR.CIL.HLOpType.I8: destType = m_commonTypeLookup.I64; arithMode = MidInstruction.ArithEnum.ArithType_Int64; break; case CLR.CIL.HLOpType.U1: destType = m_commonTypeLookup.U8; arithMode = MidInstruction.ArithEnum.ArithType_Int32; break; case CLR.CIL.HLOpType.U2: destType = m_commonTypeLookup.U16; arithMode = MidInstruction.ArithEnum.ArithType_Int32; break; case CLR.CIL.HLOpType.U4: destType = m_commonTypeLookup.U32; arithMode = MidInstruction.ArithEnum.ArithType_Int32; break; case CLR.CIL.HLOpType.U8: destType = m_commonTypeLookup.U64; arithMode = MidInstruction.ArithEnum.ArithType_Int64; break; case CLR.CIL.HLOpType.R4: destType = m_commonTypeLookup.F32; arithMode = MidInstruction.ArithEnum.ArithType_Float32; break; case CLR.CIL.HLOpType.R: // Used by conv.r.un case CLR.CIL.HLOpType.R8: destType = m_commonTypeLookup.F64; arithMode = MidInstruction.ArithEnum.ArithType_Float64; break; case CLR.CIL.HLOpType.I: destType = m_commonTypeLookup.I; arithMode = MidInstruction.ArithEnum.ArithType_NativeInt; break; case CLR.CIL.HLOpType.U: destType = m_commonTypeLookup.U; arithMode = MidInstruction.ArithEnum.ArithType_NativeInt; break; default: throw new ArgumentException(); } if ((instr.Flags & CLR.CIL.HLOpFlags.Ovf) != 0) arithMode |= MidInstruction.ArithEnum.Flags_Ovf; if ((instr.Flags & CLR.CIL.HLOpFlags.Un) != 0) arithMode |= MidInstruction.ArithEnum.Flags_Un; SsaRegister srcReg = stackTracker.Pop(); SsaRegister destReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, destType)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, destReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.ConvertNumber, codeLocation, srcReg, destReg, arithMode)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, srcReg)); stackTracker.Push(destReg); } break; case CLR.CIL.HLOpcode.ldlen: { SsaRegister arrayReg = stackTracker.Pop(); SsaRegister resultReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, m_commonTypeLookup.U)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, resultReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadArrayLength, codeLocation, arrayReg, resultReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, arrayReg)); stackTracker.Push(resultReg); } break; case CLR.CIL.HLOpcode.ldtoken: { CLRTableRow tokenRow = (CLRTableRow)instr.Arguments.ObjValue; CLRTypeSpec typeResolution = null; CppMethodSpec methodResolution = null; CppField fieldResolution = null; if (tokenRow is CLRTypeRefRow || tokenRow is CLRTypeDefRow || tokenRow is CLRTypeSpecRow) typeResolution = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec(tokenRow); else if (tokenRow is CLRMemberRefRow) { CLRMemberRefRow memberRef = (CLRMemberRefRow)tokenRow; if (memberRef.FieldSig != null) fieldResolution = ResolveField(memberRef); else if (memberRef.MethodSig != null) methodResolution = CppBuilder.ResolveMethodDefOrRef(memberRef); else throw new ArgumentException(); } else if (tokenRow is CLRMethodDefRow) methodResolution = CppBuilder.ResolveMethodDefOrRef(tokenRow); else if (tokenRow is CLRFieldRow) fieldResolution = ResolveField(tokenRow); else throw new ArgumentException(); if (typeResolution != null) { CLRTypeSpec rtDefSpec = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec(m_cppBuilder.Assemblies.RuntimeTypeHandleDef); SsaRegister reg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, rtDefSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, reg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadTypeInfoHandle, codeLocation, reg, typeResolution)); stackTracker.Push(reg); } if (methodResolution != null) { // TODO: nameof support throw new NotImplementedException(); } if (fieldResolution != null) { // Necessary for nameof and static field InitializeArray CLRTypeSpec containerClassSpec = fieldResolution.DeclaredInClassSpec; string fieldName = fieldResolution.Name; CLRTypeSpec fldDefSpec = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec(m_cppBuilder.Assemblies.RuntimeFieldHandleDef); SsaRegister reg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, fldDefSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, reg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LoadFieldInfoHandle, codeLocation, reg, containerClassSpec, fieldName, fieldResolution.Field.Static)); stackTracker.Push(reg); } } break; case CLR.CIL.HLOpcode.@switch: { SsaRegister valueReg = stackTracker.Pop(); List<CfgOutboundEdge> targetOutboundEdges = new List<CfgOutboundEdge>(); CfgOutboundEdgePrototype cfgEdgeProto = stackTracker.GenerateCfgEdge(); foreach (uint targetInstr in (uint[])instr.Arguments.ObjValue) { CfgNode targetNode = cfgBuilder.AddCfgTarget(this, (int)targetInstr, cfgEdgeProto.OutboundTypes); targetOutboundEdges.Add(new CfgOutboundEdge(codeLocation, targetNode, cfgEdgeProto)); } CfgNode fallThroughNode = cfgBuilder.AddCfgTarget(this, nextInstr, cfgEdgeProto.OutboundTypes); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.Switch, codeLocation, valueReg, targetOutboundEdges.ToArray())); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, valueReg)); OutputFallThroughEdge = new CfgOutboundEdge(codeLocation, fallThroughNode, cfgEdgeProto); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.unbox: { CLRTypeSpec typeTok = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec((CLRTableRow)instr.Arguments.ObjValue); SsaRegister objReg = stackTracker.Pop(); SsaRegister valueReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ManagedPtr, typeTok)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.UnboxPtr, codeLocation, objReg, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, objReg)); stackTracker.Push(valueReg); } break; case CLR.CIL.HLOpcode.unbox_any: { CLRTypeSpec typeTok = m_cppBuilder.Assemblies.InternTypeDefOrRefOrSpec((CLRTableRow)instr.Arguments.ObjValue); SsaRegister objReg = stackTracker.Pop(); SsaRegister valueReg = stackTracker.NewReg(new VType(VType.ValTypeEnum.ValueValue, typeTok)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.UnboxValue, codeLocation, objReg, valueReg)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, objReg)); stackTracker.Push(valueReg); } break; case CLR.CIL.HLOpcode.initobj: { SsaRegister objLoc = stackTracker.Pop(); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.ZeroFillPtr, codeLocation, objLoc)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, objLoc)); } break; case CLR.CIL.HLOpcode.ldftn: { CppMethodSpec boundMethodSpec = CppBuilder.ResolveMethodDefOrRef((CLRTableRow)instr.Arguments.ObjValue); SsaRegister ftnReg = SsaRegister.Constant(new VType(VType.ValTypeEnum.DelegateSimpleMethod, null, boundMethodSpec)); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, ftnReg)); stackTracker.Push(ftnReg); } break; case CLR.CIL.HLOpcode.ldvirtftn: { SsaRegister throwawayObjReg = stackTracker.Pop(); CppMethodSpec boundVirtMethod = CppBuilder.ResolveMethodDefOrRef((CLRTableRow)instr.Arguments.ObjValue); SsaRegister ftnReg = SsaRegister.Constant(new VType(VType.ValTypeEnum.DelegateVirtualMethod, null, boundVirtMethod)); stackTracker.Push(ftnReg); // This reverses the preceding dup sequence if (cilMethod.Instructions[instrNum - 1].Opcode != CLR.CIL.HLOpcode.dup || firstInstr == instrNum) throw new ArgumentException(); // WARNING: This must be kept in sync with dup! midInstrs.RemoveRange(midInstrs.Count - 2, 2); midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LivenReg, codeLocation, ftnReg)); } break; case CLR.CIL.HLOpcode.endfinally: { midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.ExitFinally, codeLocation)); while (stackTracker.Depth > 0) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.KillReg, codeLocation, stackTracker.Pop())); isTerminalEdge = true; } break; case CLR.CIL.HLOpcode.constrained_pfx: case CLR.CIL.HLOpcode.readonly_pfx: break; case CLR.CIL.HLOpcode.jmp: case CLR.CIL.HLOpcode.calli: case CLR.CIL.HLOpcode.@break: case CLR.CIL.HLOpcode.cpobj: case CLR.CIL.HLOpcode.refanyval: case CLR.CIL.HLOpcode.ckfinite: case CLR.CIL.HLOpcode.mkrefany: case CLR.CIL.HLOpcode.arglist: case CLR.CIL.HLOpcode.localloc: case CLR.CIL.HLOpcode.endfilter: case CLR.CIL.HLOpcode.unaligned_pfx: case CLR.CIL.HLOpcode.volatile_pfx: case CLR.CIL.HLOpcode.tail_pfx: case CLR.CIL.HLOpcode.cpblk: case CLR.CIL.HLOpcode.initblk: case CLR.CIL.HLOpcode.no_pfx: case CLR.CIL.HLOpcode.rethrow: case CLR.CIL.HLOpcode.@sizeof: case CLR.CIL.HLOpcode.refanytype: throw new NotImplementedException("Unimplemented opcode: " + instr.Opcode.ToString()); break; } } // Post-terminal-edge cleanup // Leak any registers alive past the terminal edge while (stackTracker.Depth > 0) midInstrs.Add(new MidInstruction(MidInstruction.OpcodeEnum.LeakReg, codeLocation, stackTracker.Pop())); OutputInstructions = midInstrs.ToArray(); }
public SsaRegister(VType vt) { m_isSpilled = false; m_vType = vt; }
public static SsaRegister Constant(VType vt) { if (vt.ConstantValue != null && vt.ConstantValue.GetType() == typeof(ulong)) throw new Exception(); return new SsaRegister(vt); }
private VReg NewDeadReg(VType vType, VReg.UsageEnum usage) { VReg newReg = new VReg(m_builder, "bVReg", vType, m_registers.Count, usage); m_registers.Add(newReg); return newReg; }
public bool TryConverge(VType.ValTypeEnum source1, VType.ValTypeEnum source2, ref VType.ValTypeEnum converged, ref bool typeMustMatch) { if ((source1 == m_source1 && source2 == m_source2) || (source2 == m_source1 && source1 == m_source2)) { converged = m_converged; typeMustMatch = m_typeMustMatch; return true; } return false; }
public static string ConvertFromVType(VType v) { if (v == VType.Channel) return "c"; if (v == VType.Random) return "r"; if (v == VType.Both) return "cr"; return ""; }
public static Inline Num1(double v, VType c) { Span s = new Span(); if (v == 1D && c == VType.None) s.Inlines.Add(""); else if (v == -1D && c == VType.None) s.Inlines.Add("-"); else { s.Inlines.Add(v.ToString("G6")); Span sub = new Span(new Run(Utilities.ConvertFromVType(c))); sub.Typography.Variants = System.Windows.FontVariants.Subscript; s.Inlines.Add(sub); } return s; }
public void UpdateEntryEdge(CfgNodeCompiler nodeCompiler, VType[] newEntryTypes, out bool outNeedsReparse) { bool needReparse = false; int numVTypes = newEntryTypes.Length; if (numVTypes != m_entryTypes.Length) throw new ArgumentException("Mismatched CFG edge"); bool anyDifferent = false; for (int i = 0; i < numVTypes; i++) { if (!newEntryTypes[i].Equals(m_entryTypes[i])) { anyDifferent = true; break; } } if (anyDifferent) { needReparse = true; VType[] newTypes = new VType[m_entryTypes.Length]; for (int i = 0; i < numVTypes; i++) newTypes[i] = ConvergeVTypes(nodeCompiler, m_entryTypes[i], newEntryTypes[i]); m_entryTypes = newTypes; } outNeedsReparse = needReparse; }
public CfgNode AddCfgTarget(CfgNodeCompiler nodeCompiler, int startInstr, VType[] entryTypes) { CfgNode node; bool needsReparse = false; if (m_cfgNodes.TryGetValue(startInstr, out node)) node.UpdateEntryEdge(nodeCompiler, entryTypes, out needsReparse); else { node = new CfgNode(this, startInstr, entryTypes); needsReparse = true; m_cfgNodes.Add(startInstr, node); } if (needsReparse) { if (!m_pendingNodesSet.Contains(startInstr)) { m_pendingNodesSet.Add(startInstr); m_pendingNodesQueue.Enqueue(startInstr); } } return node; }
public CfgNode(CfgBuilder builder, int startInstr, VType[] entryTypes) { m_builder = builder; m_startInstr = startInstr; m_entryTypes = entryTypes; }
private VReg GetTemporary(VType vType) { foreach (VReg vReg in m_temporaries) if (vReg.VType.Equals(vType)) return vReg; int slot = m_temporaries.Count + m_cfgNode.CfgBuilder.Locals.Length + m_cfgNode.CfgBuilder.Args.Length; VReg newVReg = new VReg(m_cppBuilder, "temp_", vType, slot, VReg.UsageEnum.Temporary); m_temporaries.Add(newVReg); return newVReg; }
private VType ConvergeVTypes(CfgNodeCompiler nodeCompiler, VType vType1, VType vType2) { VType.ValTypeEnum convergedValType = VType.ValTypeEnum.Invalid; if (vType1.Equals(vType2)) return vType1; if (vType1.ValType == VType.ValTypeEnum.Null) { if (vType2.ValType == VType.ValTypeEnum.ReferenceValue || vType2.ValType == VType.ValTypeEnum.ConstantReference) return new VType(VType.ValTypeEnum.ReferenceValue, vType1.TypeSpec); else throw new ArgumentException(); // Both null should be equal } if (vType2.ValType == VType.ValTypeEnum.Null) { if (vType1.ValType == VType.ValTypeEnum.ReferenceValue || vType1.ValType == VType.ValTypeEnum.ConstantReference) return new VType(VType.ValTypeEnum.ReferenceValue, vType2.TypeSpec); else throw new ArgumentException(); // Both null should be equal } if (vType1.ValType == vType2.ValType) { convergedValType = vType1.ValType; if (convergedValType == VType.ValTypeEnum.ConstantValue) convergedValType = VType.ValTypeEnum.ValueValue; else if (convergedValType == VType.ValTypeEnum.ConstantReference) convergedValType = VType.ValTypeEnum.ReferenceValue; } else { // Different val types bool anyMatched = false; bool typeMustMatch = false; foreach (ValTypeConvergence convergence in ms_convergences) anyMatched = anyMatched || convergence.TryConverge(vType1.ValType, vType2.ValType, ref convergedValType, ref typeMustMatch); if (!anyMatched) throw new ArgumentException(); if (typeMustMatch && !vType1.TypeSpec.Equals(vType2.TypeSpec)) throw new ParseFailedException("CFG edge merge failed to merge managed ptrs"); } // Same value type? if (vType1.TypeSpec.Equals(vType2.TypeSpec)) return new VType(convergedValType, vType1.TypeSpec); // Different value types if (convergedValType == VType.ValTypeEnum.ValueValue) { // Both are value types, so these must converge return new VType(convergedValType, nodeCompiler.ArithConvergeValues(vType1.TypeSpec, vType2.TypeSpec)); } if (convergedValType == VType.ValTypeEnum.ReferenceValue) { // Both are reference types // The merge rules are (where vType1 is the existing type): // - If vType2 is assignable to vType1, use vType1 // - If vType1 is assignable to vType2, use vType2 // - Otherwise, use closest common supertype CppAssignabilityResolver resolver = new CppAssignabilityResolver(nodeCompiler.CppBuilder, nodeCompiler.CommonTypeLookupInst, m_builder.InClass, m_builder.InMethod); if (resolver.IsRefAssignable(vType2.TypeSpec, vType1.TypeSpec)) return new VType(convergedValType, vType1.TypeSpec); if (resolver.IsRefAssignable(vType1.TypeSpec, vType2.TypeSpec)) return new VType(convergedValType, vType2.TypeSpec); CLRTypeSpec commonBase = resolver.FindCommonBase(vType1.TypeSpec, vType2.TypeSpec); if (commonBase == null) throw new ParseFailedException("CFG edge merge failed"); return new VType(convergedValType, commonBase); } throw new ParseFailedException("CFG edge merge failed"); }
private static bool IsComparisonReference(VType vType1, VType vType2) { bool isRef = IsComparisonValueReference(vType1); if (isRef != IsComparisonValueReference(vType2)) throw new Exception("Couldn't resolve comparison reference status"); return isRef; }
public ValTypeConvergence(VType.ValTypeEnum source1, VType.ValTypeEnum source2, VType.ValTypeEnum converged, bool typeMustMatch) { m_source1 = source1; m_source2 = source2; m_converged = converged; m_typeMustMatch = typeMustMatch; }
private static bool IsComparisonValueReference(VType vType) { switch (vType.ValType) { case VType.ValTypeEnum.ReferenceValue: case VType.ValTypeEnum.ConstantReference: case VType.ValTypeEnum.Null: return true; case VType.ValTypeEnum.ValueValue: case VType.ValTypeEnum.ConstantValue: return false; default: throw new Exception("Invalid value type for comparison"); } }
public static double ApplyCR(double v, VType c, int channel) { if (c == VType.None) return v; if (c == VType.Channel) return v * Convert.ToDouble(channel); if (c == VType.Random) return v * UniformRND(); return v * Convert.ToDouble(channel) * UniformRND(); }
//Apparently having a constructor (not using; having!) that takes no arguments //is important for inheritance purposes. public VUser() { status = "notmade"; usertype = VType.notmade; }
public static Inline Num0(double v, VType c) { Span s = new Span(); if (v == 0D) s.Inlines.Add(""); else { if (v < 0D) s.Inlines.Add(" - "); else s.Inlines.Add(" + "); s.Inlines.Add(Math.Abs(v).ToString("G6")); Span sub = new Span(new Run(Utilities.ConvertFromVType(c))); sub.Typography.Variants = System.Windows.FontVariants.Subscript; s.Inlines.Add(sub); } return s; }
public VUser(string uname) { userName = uname; status = "notmade"; usertype = VType.notmade; }
public CfgOutboundEdgePrototype(VType[] outboundTypes, SsaRegister[] outboundRegs) { m_outboundRegs = outboundRegs; m_outboundTypes = outboundTypes; }
public VUser(string uname, string pswd, string fname, string mname, string lname, string stat) { stat = stat.ToLower(); userName = uname; password = pswd; fstName = fname; midName = mname; lstName = lname; status = stat; usertype = (stat == "admin") ? VType.admin : //if (stat == "faculty") ? VType.faculty : //elseif VType.student; //else because stat != "student" ever, see project spec }
public Script QueryScript(VType.Query query, Logger log) { if (query == null) { log.Error(StringsScripting.Query_empty); return null; } var list = allscripts.GetAll().ToList(); VType.Query.QueryReduceByTag(list, query, log); if (list == null || list.Count == 0) { log.Error(StringsScripting.Query_empty); return null; } // ToDo 6: Make not random. int r = random.Next(0, list.Count); return list[r].Value; }