private static String TypeSpecFromSpec(OpCodeKb kb) { var type = kb.Meta.GetOrDefault("Type", "i4"); if (kb.Tags.Contains("s")) { var bytes = int.Parse(type.Substring(1)); type = type.Substring(0, 1) + (bytes / 4); } return(type); }
private static Type TypeFromSpec(OpCodeKb kb) { return TypeFromTypeSpec(TypeSpecFromSpec(kb)); }
private static String TypeSpecFromSpec(OpCodeKb kb) { var type = kb.Meta.GetOrDefault("Type", "i4"); if (kb.Tags.Contains("s")) { var bytes = int.Parse(type.Substring(1)); type = type.Substring(0, 1) + (bytes / 4); } return type; }
private static void InferFromTag(OpCodeKb kb, String tag) { if (tag == "ovf") { var p = kb.EnsureProperty("FailsOnOverflow", typeof(bool)); p.Getter = "true"; } else if (tag == "un") { var p = kb.EnsureProperty("ExpectsUn", typeof(bool)); p.Getter = "true"; } else if (tag == "s") { // just ignore this } else if (tag == "virt") { var p = kb.EnsureProperty("IsVirtual", typeof(bool)); p.Getter = "true"; } else if (tag.StartsWith("expects.") || tag.StartsWith("yields.")) { var p = kb.EnsureProperty(CapitalizeAfterPeriods(tag), typeof(bool)); p.Getter = "true"; } else if (tag.StartsWith("predicate.")) { var p = kb.EnsureProperty("PredicateType", typeof(PredicateType?)); var predicate = PredicateFromPredicateSpec(tag); p.Getter = typeof(PredicateType).GetCSharpRef(ToCSharpOptions.ForCodegen) + "." + predicate; } else if (tag.StartsWith("operator.")) { var p = kb.EnsureProperty("OperatorType", typeof(OperatorType)); var @operator = OperatorFromOperatorSpec(tag); p.Getter = typeof(OperatorType).GetCSharpRef(ToCSharpOptions.ForCodegen) + "." + @operator; } else if (tag.StartsWith("instantiates.")) { var f_ctor = kb.Fields["_ctorToken"]; var f_type = kb.Fields["_typeToken"]; var what = tag.Substring("instantiates.".Length); if (what == "obj") { f_ctor.Initializer = "ReadMetadataToken(reader)"; } else if (what == "arr") { f_type.Initializer = "ReadMetadataToken(reader)"; } else { AssertionHelper.Fail(); } } else if (tag == "br" || tag == "leave") { // this will be processed elsewhere } else if (tag == String.Empty) { // empty string after dot in prefix ops kb.Tags.Remove(String.Empty); kb.Tags.Add("."); } else { // all this hassle is solely for Ldstr/Ldtoken instructions // since they need both type and const semantics var type = TypeFromTypeSpec(tag); var @const = ValueFromConstSpec(tag); if (type != null) { kb.Meta["Type"] = tag; kb.Props.ContainsKey("Type").AssertFalse(); var p = kb.EnsureProperty("Type", typeof(Type)); if (tag != "token") p.Getter = "typeof(" + type.GetCSharpRef(ToCSharpOptions.ForCodegen) + ")"; else p.Getter = "_constValue.GetType()"; } if (@const != null) { var f_constValue = kb.Fields["_constValue"]; var f_useConstValue = kb.Fields["_useConstValue"]; f_constValue.Initializer = @const.ToInvariantString(); f_useConstValue.Initializer = "true"; } if (@type == null && @const == null) { // so that we never miss an instruction with an unknown part AssertionHelper.Fail(); } } }
private static void InferFromOpcode(OpCodeKb kb) { if (kb.OpCode.FlowControl == FlowControl.Meta) { kb.Tags.Add("Prefix"); if (kb.Family == "unaligned") { (kb.OpCode.OperandType == OperandType.ShortInlineI).AssertTrue(); var p = kb.EnsureProperty("Alignment", typeof(Byte)); kb.Meta["ValueProp"] = p.Name; p.Getter = "_alignment"; var f = kb.EnsureField("_alignment", typeof(Byte)); f.Initializer = "ReadU1(reader)"; } else if (kb.Family == "constrained") { (kb.OpCode.OperandType == OperandType.InlineType).AssertTrue(); var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else { (kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); } } else if (kb.Family == "endfinally" || kb.Family == "endfilter") { (kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); // kb.Tags.Add("Ignore"); // todo. uncomment the line above and perform all necessary fixups } else if (kb.Family == "switch") { var f = kb.EnsureField("_targetOffsets", typeof(ReadOnlyCollection<Tuple<Int32, Int32>>)); var buffer1 = new StringBuilder(); buffer1.AppendLine(String.Format("(({0})(() => ", typeof(Func<ReadOnlyCollection<Tuple<Int32, Int32>>>).GetCSharpRef(ToCSharpOptions.ForCodegen))); buffer1.AppendLine("{"); buffer1.AppendLine("var n = ReadI4(reader);".Indent()); buffer1.AppendLine(String.Format("var pivot = ({0})reader.BaseStream.Position + sizeof({0}) * n;", typeof(Int32).GetCSharpRef(ToCSharpOptions.ForCodegen)).Indent()); buffer1.AppendLine(); buffer1.Append(String.Format("return {0}.ToReadOnly(", typeof(EnumerableExtensions).GetCSharpRef(ToCSharpOptions.ForCodegen)).Indent()); buffer1.AppendLine(String.Format("{0}.Select(", typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen))); buffer1.AppendLine(String.Format("{0}.Range(1, n), _ => ", typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen)).Indent().Indent()); buffer1.AppendLine("{".Indent().Indent()); buffer1.AppendLine("var relative = ReadI4(reader);".Indent().Indent().Indent()); buffer1.AppendLine("var absolute = pivot + relative;".Indent().Indent().Indent()); buffer1.AppendLine(String.Format("return {0}.Create(relative, absolute);", typeof(Tuple).GetCSharpRef(ToCSharpOptions.ForCodegen)).Indent().Indent().Indent()); buffer1.AppendLine("}));".Indent().Indent()); buffer1.Append("}))()"); f.Initializer = buffer1.ToString(); var p_RelativeTargetOffsets = kb.EnsureProperty("RelativeTargetOffsets", typeof(ReadOnlyCollection<Int32>)); p_RelativeTargetOffsets.Getter = String.Format( "{0}.ToReadOnly({1}.Select(_targetOffsets, t => t.Item2))", typeof(EnumerableExtensions).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen)); var p_AbsoluteTargetOffsets = kb.EnsureProperty("AbsoluteTargetOffsets", typeof(ReadOnlyCollection<Int32>)); p_AbsoluteTargetOffsets.Getter = String.Format( "{0}.ToReadOnly({1}.Select(_targetOffsets, t => t.Item2))", typeof(EnumerableExtensions).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen)); var p_Targets = kb.EnsureProperty("Targets", typeof(ReadOnlyCollection<ILOp>)); var buffer2 = new StringBuilder(); buffer2.Append(String.Format("var resolved = {0}.Select(", typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen))); buffer2.AppendLine("AbsoluteTargetOffsets, offset => ResolveReference(offset));"); buffer2.Append(String.Format("return {0}.ToReadOnly(resolved);", typeof(EnumerableExtensions).GetCSharpRef(ToCSharpOptions.ForCodegen))); p_Targets.Getter = buffer2.ToString(); } else if (kb.OpCode.FlowControl == FlowControl.Branch || kb.OpCode.FlowControl == FlowControl.Cond_Branch) { (kb.OpCode.OperandType == OperandType.InlineBrTarget || kb.OpCode.OperandType == OperandType.ShortInlineBrTarget).AssertTrue(); var p_target = kb.EnsureProperty("Target", typeof(IILOp)); p_target.Getter = "ResolveReference(_absoluteTargetOffset)"; var p_rto = kb.EnsureProperty("RelativeTargetOffset", typeof(Int32)); p_rto.Getter = "_relativeTargetOffset"; var p_ato = kb.EnsureProperty("AbsoluteTargetOffset", typeof(Int32)); p_ato.Getter = "_absoluteTargetOffset"; // relative offset === operand of the opcode var f_rto = kb.EnsureField("_relativeTargetOffset", typeof(Int32)); f_rto.SetLazyInitializer(_ => String.Format( "Read" + TypeSpecFromSpec(kb).Capitalize() + "(reader)", typeof(Int32).GetCSharpRef(ToCSharpOptions.ForCodegen))); // absolute offset === exact offset that can be resolved into target var f_ato = kb.EnsureField("_absoluteTargetOffset", typeof(Int32)); f_ato.SetLazyInitializer(_ => String.Format( "({0})origPos + sizeof({1}) + _relativeTargetOffset", typeof(Int32).GetCSharpRef(ToCSharpOptions.ForCodegen), TypeFromSpec(kb).AssertNotNull().GetCSharpRef(ToCSharpOptions.ForCodegen))); } else if (kb.Family == "ldarg" || kb.Family == "ldarga" || kb.Family == "starg") { (kb.OpCode.OperandType == OperandType.InlineVar || kb.OpCode.OperandType == OperandType.ShortInlineVar || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); var p_Index = kb.EnsureProperty("Index", typeof(int)); p_Index.Getter = "_value"; var p_Arg = kb.EnsureProperty("Arg", typeof(ParameterInfo)); p_Arg.Getter = "if (Source.Method == null || Source.Args == null)" + Environment.NewLine + "{" + Environment.NewLine + " return null;" + Environment.NewLine + "}" + Environment.NewLine + "else" + Environment.NewLine + "{" + Environment.NewLine + " if (Source.Method.IsStatic)" + Environment.NewLine + " {" + Environment.NewLine + " return Source.Args[_value];" + Environment.NewLine + " }" + Environment.NewLine + " else" + Environment.NewLine + " {" + Environment.NewLine + " return _value == 0 ? null : Source.Args[_value - 1];" + Environment.NewLine + " }" + Environment.NewLine + "}"; var f_value = kb.EnsureField("_value", typeof(Int32)); var f_useConstValue = kb.EnsureField("_useConstValue", typeof(bool)); var f_constValue = kb.EnsureField("_constValue", typeof(Int32?)); f_value.SetLazyInitializer(_ => f_useConstValue.Name + " ? " + f_constValue.Name + ".Value : Read" + TypeSpecFromSpec(kb).Capitalize() + "(reader)"); } else if (kb.Family == "ldloc" || kb.Family == "ldloca" || kb.Family == "stloc") { (kb.OpCode.OperandType == OperandType.InlineVar || kb.OpCode.OperandType == OperandType.ShortInlineVar || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); var p_Index = kb.EnsureProperty("Index", typeof(int)); p_Index.Getter = "_value"; var p_Loc = kb.EnsureProperty("Loc", typeof(ILocalVar)); p_Loc.Getter = "if (Source.Method == null || Source.Locals == null)" + Environment.NewLine + "{" + Environment.NewLine + " return null;" + Environment.NewLine + "}" + Environment.NewLine + "else" + Environment.NewLine + "{" + Environment.NewLine + " return Source.Locals[_value];" + Environment.NewLine + "}"; var f_value = kb.EnsureField("_value", typeof(Int32)); var f_useConstValue = kb.EnsureField("_useConstValue", typeof(bool)); var f_constValue = kb.EnsureField("_constValue", typeof(Int32?)); f_value.SetLazyInitializer(_ => f_useConstValue.Name + " ? " + f_constValue.Name + ".Value : Read" + TypeSpecFromSpec(kb).Capitalize() + "(reader)"); } else if (kb.Family == "ldc") { (kb.OpCode.OperandType == OperandType.InlineI || kb.OpCode.OperandType == OperandType.InlineI8 || kb.OpCode.OperandType == OperandType.InlineR || kb.OpCode.OperandType == OperandType.ShortInlineI || kb.OpCode.OperandType == OperandType.ShortInlineR || kb.OpCode.OperandType == OperandType.InlineString || kb.OpCode.OperandType == OperandType.InlineTok || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); var p = kb.EnsureProperty("Value", typeof(Object)); p.Getter = "_value"; var f_value = kb.EnsureField("_value", typeof(Object)); var f_useConstValue = kb.EnsureField("_useConstValue", typeof(bool)); var f_constValue = kb.EnsureField("_constValue", typeof(Object)); var cast = kb.OpCode.Name == "ldc.i4.s" ? String.Format("({0})", typeof(int).GetCSharpRef(ToCSharpOptions.Informative)) : String.Empty; f_value.SetLazyInitializer(_ => f_useConstValue.Name + " ? " + f_constValue.Name + " : " + cast + "Read" + TypeSpecFromSpec(kb).Capitalize() + "(reader)"); } else if (kb.Family == "isinst" || kb.Family == "sizeof" || kb.Family == "initobj" || kb.Family == "stobj" || kb.Family == "ldobj" || kb.Family == "cpobj" || kb.Family == "mkrefany" || kb.Family == "refanyval") { (kb.OpCode.OperandType == OperandType.InlineType).AssertTrue(); var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else if (kb.Family == "ldelem" || kb.Family == "ldelema" || kb.Family == "stelem") { (kb.OpCode.OperandType == OperandType.InlineType || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); if (kb.OpCode.OperandType == OperandType.InlineType) { var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else { // InferFromTag will take care of XXXelemYYY.TYPE (see below) } } else if (kb.Family == "ldind" || kb.Family == "stind") { (kb.OpCode.OperandType == OperandType.InlineType || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); if (kb.OpCode.OperandType == OperandType.InlineType) { var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else { // InferFromTag will take care of XXXind.TYPE (see below) } kb.EnsurePrefix("IsVolatile", typeof(bool), "volatile"); kb.EnsurePrefix("IsUnaligned", typeof(bool), "unaligned"); var p_IsAligned = kb.EnsureProperty("IsAligned", typeof(bool)); p_IsAligned.Getter = "!IsUnaligned"; var p_Alignment = kb.EnsureProperty("Alignment", typeof(byte)); var buf = new StringBuilder(); buf.AppendLine(String.Format( "var unaligned = {0}.SingleOrDefault({0}.OfType<{1}>(Prefixes));", typeof(Enumerable), "Unaligned")); buf.AppendLine(String.Format( "var defaultAlignment = (({0})(() => {{ throw new {1}(); }}))();", typeof(Func<byte>).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(NotImplementedException).GetCSharpRef(ToCSharpOptions.ForCodegen))); buf.Append("return unaligned != null ? unaligned.Alignment : defaultAlignment"); p_Alignment.Getter = buf.ToString(); } else if (kb.Family == "cast") { (kb.OpCode.OperandType == OperandType.InlineType || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); if (kb.OpCode.OperandType == OperandType.InlineType) { var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = kb.OpCode.Name == "box" ? String.Format("typeof({0})", typeof(Object).GetCSharpRef(ToCSharpOptions.ForCodegen)) : "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } } else if (kb.Family == "new") { (kb.OpCode.OperandType == OperandType.InlineType || kb.OpCode.OperandType == OperandType.InlineMethod).AssertTrue(); var f_ctorToken = kb.EnsureField("_ctorToken", typeof(Int32?)); var p_ctorToken = kb.EnsureProperty("CtorToken", typeof(Int32?)); p_ctorToken.Getter = "_ctorToken;"; var f_typeToken = kb.EnsureField("_typeToken", typeof(Int32?)); var p_typeToken = kb.EnsureProperty("TypeToken", typeof(Int32?)); p_typeToken.Getter = "_typeToken;"; var p_ctor = kb.EnsureProperty("Ctor", typeof(ConstructorInfo)); if (kb.OpCode == OpCodes.Newobj) p_ctor.Getter = String.Format("CtorFromToken({0}.AssertValue({1}))", typeof(AssertionHelper).GetCSharpRef(ToCSharpOptions.ForCodegen), f_ctorToken.Name); else if (kb.OpCode == OpCodes.Newarr) p_ctor.Getter = String.Format("Type != null ? {0}.AssertSingle(Type.GetConstructors()) : null", typeof(AssertionHelper).GetCSharpRef(ToCSharpOptions.ForCodegen)); else throw AssertionHelper.Fail(); var p_type = kb.EnsureProperty("Type", typeof(Type)); if (kb.OpCode == OpCodes.Newobj) p_type.Getter = "Ctor != null ? Ctor.DeclaringType : null"; else if (kb.OpCode == OpCodes.Newarr) p_type.Getter = String.Format("var elementType = TypeFromToken({0}.AssertValue({1}));", typeof(AssertionHelper).GetCSharpRef(ToCSharpOptions.ForCodegen), f_typeToken.Name) + Environment.NewLine + "return elementType != null ? elementType.MakeArrayType() : null;"; else throw AssertionHelper.Fail(); } else if (kb.Family == "ldftn" || kb.Family == "jmp") { (kb.OpCode.OperandType == OperandType.InlineMethod).AssertTrue(); var p_Token = kb.EnsureProperty("MethodToken", typeof(Int32)); p_Token.Getter = "_methodToken;"; var p_Method = kb.EnsureProperty("Method", typeof(MethodBase)); p_Method.Getter = "MethodBaseFromToken(_methodToken);"; var f = kb.EnsureField("_methodToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else if (kb.Family == "call") { (kb.OpCode.OperandType == OperandType.InlineMethod || kb.OpCode.OperandType == OperandType.InlineSig).AssertTrue(); var p_Method = kb.EnsureProperty("Method", typeof(MethodBase)); if (kb.OpCode.OperandType == OperandType.InlineMethod) p_Method.Getter = "MethodBaseFromToken(_methodToken);"; else if (kb.OpCode.OperandType == OperandType.InlineSig) p_Method.Getter = "MethodBaseFromSignature(SignatureFromToken(_signatureToken));"; else throw AssertionHelper.Fail(); var p_MethodToken = kb.EnsureProperty("MethodToken", typeof(Int32)); if (kb.OpCode.OperandType == OperandType.InlineMethod) p_MethodToken.Getter = "_methodToken;"; else if (kb.OpCode.OperandType == OperandType.InlineSig) p_MethodToken.Getter = null; else throw AssertionHelper.Fail(); var f_MethodToken = kb.EnsureField("_methodToken", typeof(Int32)); if (kb.OpCode.OperandType == OperandType.InlineMethod) f_MethodToken.Initializer = "ReadMetadataToken(reader)"; else if (kb.OpCode.OperandType == OperandType.InlineSig) f_MethodToken.Initializer = null; else throw AssertionHelper.Fail(); var p_Signature = kb.EnsureProperty("Signature", typeof(byte[])); if (kb.OpCode.OperandType == OperandType.InlineMethod) p_Signature.Getter = null; else if (kb.OpCode.OperandType == OperandType.InlineSig) p_Signature.Getter = "SignatureFromToken(_signatureToken);"; else throw AssertionHelper.Fail(); var p_SignatureToken = kb.EnsureProperty("SignatureToken", typeof(Int32)); if (kb.OpCode.OperandType == OperandType.InlineMethod) p_SignatureToken.Getter = null; else if (kb.OpCode.OperandType == OperandType.InlineSig) p_SignatureToken.Getter = "_signatureToken;"; else throw AssertionHelper.Fail(); var f_SignatureToken = kb.EnsureField("_signatureToken", typeof(Int32)); if (kb.OpCode.OperandType == OperandType.InlineMethod) f_SignatureToken.Initializer = null; else if (kb.OpCode.OperandType == OperandType.InlineSig) f_SignatureToken.Initializer = "ReadMetadataToken(reader)"; else throw AssertionHelper.Fail(); var pfx_constrained = kb.EnsurePrefix("Constraint", typeof(Type), "constrained"); pfx_constrained.Getter = "Type"; kb.EnsurePrefix("IsTail", typeof(bool), "tail"); } else if (kb.Family == "ldfld" || kb.Family == "ldflda" || kb.Family == "stfld") { (kb.OpCode.OperandType == OperandType.InlineField).AssertTrue(); var p_Token = kb.EnsureProperty("FieldToken", typeof(Int32)); p_Token.Getter = "_fieldToken;"; var p_Fld = kb.EnsureProperty("Field", typeof(FieldInfo)); p_Fld.Getter = "FieldFromToken(_fieldToken);"; var f = kb.EnsureField("_fieldToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; kb.EnsurePrefix("IsVolatile", typeof(bool), "volatile"); var pfx_Unaligned = kb.EnsurePrefix("IsUnaligned", typeof(bool), "unaligned"); if (kb.Family == "ldfld") pfx_Unaligned.Filter = "OpSpec.OpCode.Value != 0x7e /* ldsfld */"; if (kb.Family == "stfld") pfx_Unaligned.Filter = "OpSpec.OpCode.Value != 0x80 /* stsfld */"; var p_IsAligned = kb.EnsureProperty("IsAligned", typeof(bool)); p_IsAligned.Getter = "!IsUnaligned"; var p_Alignment = kb.EnsureProperty("Alignment", typeof(byte)); var buf = new StringBuilder(); buf.AppendLine(String.Format( "var unaligned = {0}.SingleOrDefault({0}.OfType<{1}>(Prefixes));", typeof(Enumerable), "Unaligned")); buf.AppendLine(String.Format( "var defaultAlignment = (({0})(() => {{ throw new {1}(); }}))();", typeof(Func<byte>).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(NotImplementedException).GetCSharpRef(ToCSharpOptions.ForCodegen))); buf.Append("return unaligned != null ? unaligned.Alignment : defaultAlignment"); p_Alignment.Getter = buf.ToString(); } else if (kb.Family == "initblk" || kb.Family == "cpblk") { kb.EnsurePrefix("IsVolatile", typeof(bool), "volatile"); kb.EnsurePrefix("IsUnaligned", typeof(bool), "unaligned"); var p_IsAligned = kb.EnsureProperty("IsAligned", typeof(bool)); p_IsAligned.Getter = "!IsUnaligned"; var p_Alignment = kb.EnsureProperty("Alignment", typeof(byte)); var buf = new StringBuilder(); buf.AppendLine(String.Format( "var unaligned = {0}.SingleOrDefault({0}.OfType<{1}>(Prefixes));", typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen), "Unaligned")); buf.AppendLine(String.Format( "var defaultAlignment = ({0}){1}.SizeOf(typeof({2}));", typeof(byte).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(Marshal).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(IntPtr).GetCSharpRef(ToCSharpOptions.ForCodegen))); buf.Append("return unaligned != null ? unaligned.Alignment : defaultAlignment"); p_Alignment.Getter = buf.ToString(); p_Alignment.IsUnsafe = true; } else { // so that we never miss any other instructions with arguments (kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); } }
private static Type TypeFromSpec(OpCodeKb kb) { return(TypeFromTypeSpec(TypeSpecFromSpec(kb))); }
private static void InferFromTag(OpCodeKb kb, String tag) { if (tag == "ovf") { var p = kb.EnsureProperty("FailsOnOverflow", typeof(bool)); p.Getter = "true"; } else if (tag == "un") { var p = kb.EnsureProperty("ExpectsUn", typeof(bool)); p.Getter = "true"; } else if (tag == "s") { // just ignore this } else if (tag == "virt") { var p = kb.EnsureProperty("IsVirtual", typeof(bool)); p.Getter = "true"; } else if (tag.StartsWith("expects.") || tag.StartsWith("yields.")) { var p = kb.EnsureProperty(CapitalizeAfterPeriods(tag), typeof(bool)); p.Getter = "true"; } else if (tag.StartsWith("predicate.")) { var p = kb.EnsureProperty("PredicateType", typeof(PredicateType?)); var predicate = PredicateFromPredicateSpec(tag); p.Getter = typeof(PredicateType).GetCSharpRef(ToCSharpOptions.ForCodegen) + "." + predicate; } else if (tag.StartsWith("operator.")) { var p = kb.EnsureProperty("OperatorType", typeof(OperatorType)); var @operator = OperatorFromOperatorSpec(tag); p.Getter = typeof(OperatorType).GetCSharpRef(ToCSharpOptions.ForCodegen) + "." + @operator; } else if (tag.StartsWith("instantiates.")) { var f_ctor = kb.Fields["_ctorToken"]; var f_type = kb.Fields["_typeToken"]; var what = tag.Substring("instantiates.".Length); if (what == "obj") { f_ctor.Initializer = "ReadMetadataToken(reader)"; } else if (what == "arr") { f_type.Initializer = "ReadMetadataToken(reader)"; } else { AssertionHelper.Fail(); } } else if (tag == "br" || tag == "leave") { // this will be processed elsewhere } else if (tag == String.Empty) { // empty string after dot in prefix ops kb.Tags.Remove(String.Empty); kb.Tags.Add("."); } else { // all this hassle is solely for Ldstr/Ldtoken instructions // since they need both type and const semantics var type = TypeFromTypeSpec(tag); var @const = ValueFromConstSpec(tag); if (type != null) { kb.Meta["Type"] = tag; kb.Props.ContainsKey("Type").AssertFalse(); var p = kb.EnsureProperty("Type", typeof(Type)); if (tag != "token") { p.Getter = "typeof(" + type.GetCSharpRef(ToCSharpOptions.ForCodegen) + ")"; } else { p.Getter = "_constValue.GetType()"; } } if (@const != null) { var f_constValue = kb.Fields["_constValue"]; var f_useConstValue = kb.Fields["_useConstValue"]; f_constValue.Initializer = @const.ToInvariantString(); f_useConstValue.Initializer = "true"; } if (@type == null && @const == null) { // so that we never miss an instruction with an unknown part AssertionHelper.Fail(); } } }
private static void InferFromOpcode(OpCodeKb kb) { if (kb.OpCode.FlowControl == FlowControl.Meta) { kb.Tags.Add("Prefix"); if (kb.Family == "unaligned") { (kb.OpCode.OperandType == OperandType.ShortInlineI).AssertTrue(); var p = kb.EnsureProperty("Alignment", typeof(Byte)); kb.Meta["ValueProp"] = p.Name; p.Getter = "_alignment"; var f = kb.EnsureField("_alignment", typeof(Byte)); f.Initializer = "ReadU1(reader)"; } else if (kb.Family == "constrained") { (kb.OpCode.OperandType == OperandType.InlineType).AssertTrue(); var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else { (kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); } } else if (kb.Family == "endfinally" || kb.Family == "endfilter") { (kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); // kb.Tags.Add("Ignore"); // todo. uncomment the line above and perform all necessary fixups } else if (kb.Family == "switch") { var f = kb.EnsureField("_targetOffsets", typeof(ReadOnlyCollection <Tuple <Int32, Int32> >)); var buffer1 = new StringBuilder(); buffer1.AppendLine(String.Format("(({0})(() => ", typeof(Func <ReadOnlyCollection <Tuple <Int32, Int32> > >).GetCSharpRef(ToCSharpOptions.ForCodegen))); buffer1.AppendLine("{"); buffer1.AppendLine("var n = ReadI4(reader);".Indent()); buffer1.AppendLine(String.Format("var pivot = ({0})reader.BaseStream.Position + sizeof({0}) * n;", typeof(Int32).GetCSharpRef(ToCSharpOptions.ForCodegen)).Indent()); buffer1.AppendLine(); buffer1.Append(String.Format("return {0}.ToReadOnly(", typeof(EnumerableExtensions).GetCSharpRef(ToCSharpOptions.ForCodegen)).Indent()); buffer1.AppendLine(String.Format("{0}.Select(", typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen))); buffer1.AppendLine(String.Format("{0}.Range(1, n), _ => ", typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen)).Indent().Indent()); buffer1.AppendLine("{".Indent().Indent()); buffer1.AppendLine("var relative = ReadI4(reader);".Indent().Indent().Indent()); buffer1.AppendLine("var absolute = pivot + relative;".Indent().Indent().Indent()); buffer1.AppendLine(String.Format("return {0}.Create(relative, absolute);", typeof(Tuple).GetCSharpRef(ToCSharpOptions.ForCodegen)).Indent().Indent().Indent()); buffer1.AppendLine("}));".Indent().Indent()); buffer1.Append("}))()"); f.Initializer = buffer1.ToString(); var p_RelativeTargetOffsets = kb.EnsureProperty("RelativeTargetOffsets", typeof(ReadOnlyCollection <Int32>)); p_RelativeTargetOffsets.Getter = String.Format( "{0}.ToReadOnly({1}.Select(_targetOffsets, t => t.Item2))", typeof(EnumerableExtensions).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen)); var p_AbsoluteTargetOffsets = kb.EnsureProperty("AbsoluteTargetOffsets", typeof(ReadOnlyCollection <Int32>)); p_AbsoluteTargetOffsets.Getter = String.Format( "{0}.ToReadOnly({1}.Select(_targetOffsets, t => t.Item2))", typeof(EnumerableExtensions).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen)); var p_Targets = kb.EnsureProperty("Targets", typeof(ReadOnlyCollection <ILOp>)); var buffer2 = new StringBuilder(); buffer2.Append(String.Format("var resolved = {0}.Select(", typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen))); buffer2.AppendLine("AbsoluteTargetOffsets, offset => ResolveReference(offset));"); buffer2.Append(String.Format("return {0}.ToReadOnly(resolved);", typeof(EnumerableExtensions).GetCSharpRef(ToCSharpOptions.ForCodegen))); p_Targets.Getter = buffer2.ToString(); } else if (kb.OpCode.FlowControl == FlowControl.Branch || kb.OpCode.FlowControl == FlowControl.Cond_Branch) { (kb.OpCode.OperandType == OperandType.InlineBrTarget || kb.OpCode.OperandType == OperandType.ShortInlineBrTarget).AssertTrue(); var p_target = kb.EnsureProperty("Target", typeof(IILOp)); p_target.Getter = "ResolveReference(_absoluteTargetOffset)"; var p_rto = kb.EnsureProperty("RelativeTargetOffset", typeof(Int32)); p_rto.Getter = "_relativeTargetOffset"; var p_ato = kb.EnsureProperty("AbsoluteTargetOffset", typeof(Int32)); p_ato.Getter = "_absoluteTargetOffset"; // relative offset === operand of the opcode var f_rto = kb.EnsureField("_relativeTargetOffset", typeof(Int32)); f_rto.SetLazyInitializer(_ => String.Format( "Read" + TypeSpecFromSpec(kb).Capitalize() + "(reader)", typeof(Int32).GetCSharpRef(ToCSharpOptions.ForCodegen))); // absolute offset === exact offset that can be resolved into target var f_ato = kb.EnsureField("_absoluteTargetOffset", typeof(Int32)); f_ato.SetLazyInitializer(_ => String.Format( "({0})origPos + sizeof({1}) + _relativeTargetOffset", typeof(Int32).GetCSharpRef(ToCSharpOptions.ForCodegen), TypeFromSpec(kb).AssertNotNull().GetCSharpRef(ToCSharpOptions.ForCodegen))); } else if (kb.Family == "ldarg" || kb.Family == "ldarga" || kb.Family == "starg") { (kb.OpCode.OperandType == OperandType.InlineVar || kb.OpCode.OperandType == OperandType.ShortInlineVar || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); var p_Index = kb.EnsureProperty("Index", typeof(int)); p_Index.Getter = "_value"; var p_Arg = kb.EnsureProperty("Arg", typeof(ParameterInfo)); p_Arg.Getter = "if (Source.Method == null || Source.Args == null)" + Environment.NewLine + "{" + Environment.NewLine + " return null;" + Environment.NewLine + "}" + Environment.NewLine + "else" + Environment.NewLine + "{" + Environment.NewLine + " if (Source.Method.IsStatic)" + Environment.NewLine + " {" + Environment.NewLine + " return Source.Args[_value];" + Environment.NewLine + " }" + Environment.NewLine + " else" + Environment.NewLine + " {" + Environment.NewLine + " return _value == 0 ? null : Source.Args[_value - 1];" + Environment.NewLine + " }" + Environment.NewLine + "}"; var f_value = kb.EnsureField("_value", typeof(Int32)); var f_useConstValue = kb.EnsureField("_useConstValue", typeof(bool)); var f_constValue = kb.EnsureField("_constValue", typeof(Int32?)); f_value.SetLazyInitializer(_ => f_useConstValue.Name + " ? " + f_constValue.Name + ".Value : Read" + TypeSpecFromSpec(kb).Capitalize() + "(reader)"); } else if (kb.Family == "ldloc" || kb.Family == "ldloca" || kb.Family == "stloc") { (kb.OpCode.OperandType == OperandType.InlineVar || kb.OpCode.OperandType == OperandType.ShortInlineVar || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); var p_Index = kb.EnsureProperty("Index", typeof(int)); p_Index.Getter = "_value"; var p_Loc = kb.EnsureProperty("Loc", typeof(ILocalVar)); p_Loc.Getter = "if (Source.Method == null || Source.Locals == null)" + Environment.NewLine + "{" + Environment.NewLine + " return null;" + Environment.NewLine + "}" + Environment.NewLine + "else" + Environment.NewLine + "{" + Environment.NewLine + " return Source.Locals[_value];" + Environment.NewLine + "}"; var f_value = kb.EnsureField("_value", typeof(Int32)); var f_useConstValue = kb.EnsureField("_useConstValue", typeof(bool)); var f_constValue = kb.EnsureField("_constValue", typeof(Int32?)); f_value.SetLazyInitializer(_ => f_useConstValue.Name + " ? " + f_constValue.Name + ".Value : Read" + TypeSpecFromSpec(kb).Capitalize() + "(reader)"); } else if (kb.Family == "ldc") { (kb.OpCode.OperandType == OperandType.InlineI || kb.OpCode.OperandType == OperandType.InlineI8 || kb.OpCode.OperandType == OperandType.InlineR || kb.OpCode.OperandType == OperandType.ShortInlineI || kb.OpCode.OperandType == OperandType.ShortInlineR || kb.OpCode.OperandType == OperandType.InlineString || kb.OpCode.OperandType == OperandType.InlineTok || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); var p = kb.EnsureProperty("Value", typeof(Object)); p.Getter = "_value"; var f_value = kb.EnsureField("_value", typeof(Object)); var f_useConstValue = kb.EnsureField("_useConstValue", typeof(bool)); var f_constValue = kb.EnsureField("_constValue", typeof(Object)); var cast = kb.OpCode.Name == "ldc.i4.s" ? String.Format("({0})", typeof(int).GetCSharpRef(ToCSharpOptions.Informative)) : String.Empty; f_value.SetLazyInitializer(_ => f_useConstValue.Name + " ? " + f_constValue.Name + " : " + cast + "Read" + TypeSpecFromSpec(kb).Capitalize() + "(reader)"); } else if (kb.Family == "isinst" || kb.Family == "sizeof" || kb.Family == "initobj" || kb.Family == "stobj" || kb.Family == "ldobj" || kb.Family == "cpobj" || kb.Family == "mkrefany" || kb.Family == "refanyval") { (kb.OpCode.OperandType == OperandType.InlineType).AssertTrue(); var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else if (kb.Family == "ldelem" || kb.Family == "ldelema" || kb.Family == "stelem") { (kb.OpCode.OperandType == OperandType.InlineType || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); if (kb.OpCode.OperandType == OperandType.InlineType) { var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else { // InferFromTag will take care of XXXelemYYY.TYPE (see below) } } else if (kb.Family == "ldind" || kb.Family == "stind") { (kb.OpCode.OperandType == OperandType.InlineType || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); if (kb.OpCode.OperandType == OperandType.InlineType) { var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else { // InferFromTag will take care of XXXind.TYPE (see below) } kb.EnsurePrefix("IsVolatile", typeof(bool), "volatile"); kb.EnsurePrefix("IsUnaligned", typeof(bool), "unaligned"); var p_IsAligned = kb.EnsureProperty("IsAligned", typeof(bool)); p_IsAligned.Getter = "!IsUnaligned"; var p_Alignment = kb.EnsureProperty("Alignment", typeof(byte)); var buf = new StringBuilder(); buf.AppendLine(String.Format( "var unaligned = {0}.SingleOrDefault({0}.OfType<{1}>(Prefixes));", typeof(Enumerable), "Unaligned")); buf.AppendLine(String.Format( "var defaultAlignment = (({0})(() => {{ throw new {1}(); }}))();", typeof(Func <byte>).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(NotImplementedException).GetCSharpRef(ToCSharpOptions.ForCodegen))); buf.Append("return unaligned != null ? unaligned.Alignment : defaultAlignment"); p_Alignment.Getter = buf.ToString(); } else if (kb.Family == "cast") { (kb.OpCode.OperandType == OperandType.InlineType || kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); if (kb.OpCode.OperandType == OperandType.InlineType) { var p_Token = kb.EnsureProperty("TypeToken", typeof(Int32)); p_Token.Getter = "_typeToken;"; var p_Type = kb.EnsureProperty("Type", typeof(Type)); p_Type.Getter = kb.OpCode.Name == "box" ? String.Format("typeof({0})", typeof(Object).GetCSharpRef(ToCSharpOptions.ForCodegen)) : "TypeFromToken(_typeToken);"; var f = kb.EnsureField("_typeToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } } else if (kb.Family == "new") { (kb.OpCode.OperandType == OperandType.InlineType || kb.OpCode.OperandType == OperandType.InlineMethod).AssertTrue(); var f_ctorToken = kb.EnsureField("_ctorToken", typeof(Int32?)); var p_ctorToken = kb.EnsureProperty("CtorToken", typeof(Int32?)); p_ctorToken.Getter = "_ctorToken;"; var f_typeToken = kb.EnsureField("_typeToken", typeof(Int32?)); var p_typeToken = kb.EnsureProperty("TypeToken", typeof(Int32?)); p_typeToken.Getter = "_typeToken;"; var p_ctor = kb.EnsureProperty("Ctor", typeof(ConstructorInfo)); if (kb.OpCode == OpCodes.Newobj) { p_ctor.Getter = String.Format("CtorFromToken({0}.AssertValue({1}))", typeof(AssertionHelper).GetCSharpRef(ToCSharpOptions.ForCodegen), f_ctorToken.Name); } else if (kb.OpCode == OpCodes.Newarr) { p_ctor.Getter = String.Format("Type != null ? {0}.AssertSingle(Type.GetConstructors()) : null", typeof(AssertionHelper).GetCSharpRef(ToCSharpOptions.ForCodegen)); } else { throw AssertionHelper.Fail(); } var p_type = kb.EnsureProperty("Type", typeof(Type)); if (kb.OpCode == OpCodes.Newobj) { p_type.Getter = "Ctor != null ? Ctor.DeclaringType : null"; } else if (kb.OpCode == OpCodes.Newarr) { p_type.Getter = String.Format("var elementType = TypeFromToken({0}.AssertValue({1}));", typeof(AssertionHelper).GetCSharpRef(ToCSharpOptions.ForCodegen), f_typeToken.Name) + Environment.NewLine + "return elementType != null ? elementType.MakeArrayType() : null;"; } else { throw AssertionHelper.Fail(); } } else if (kb.Family == "ldftn" || kb.Family == "jmp") { (kb.OpCode.OperandType == OperandType.InlineMethod).AssertTrue(); var p_Token = kb.EnsureProperty("MethodToken", typeof(Int32)); p_Token.Getter = "_methodToken;"; var p_Method = kb.EnsureProperty("Method", typeof(MethodBase)); p_Method.Getter = "MethodBaseFromToken(_methodToken);"; var f = kb.EnsureField("_methodToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; } else if (kb.Family == "call") { (kb.OpCode.OperandType == OperandType.InlineMethod || kb.OpCode.OperandType == OperandType.InlineSig).AssertTrue(); var p_Method = kb.EnsureProperty("Method", typeof(MethodBase)); if (kb.OpCode.OperandType == OperandType.InlineMethod) { p_Method.Getter = "MethodBaseFromToken(_methodToken);"; } else if (kb.OpCode.OperandType == OperandType.InlineSig) { p_Method.Getter = "MethodBaseFromSignature(SignatureFromToken(_signatureToken));"; } else { throw AssertionHelper.Fail(); } var p_MethodToken = kb.EnsureProperty("MethodToken", typeof(Int32)); if (kb.OpCode.OperandType == OperandType.InlineMethod) { p_MethodToken.Getter = "_methodToken;"; } else if (kb.OpCode.OperandType == OperandType.InlineSig) { p_MethodToken.Getter = null; } else { throw AssertionHelper.Fail(); } var f_MethodToken = kb.EnsureField("_methodToken", typeof(Int32)); if (kb.OpCode.OperandType == OperandType.InlineMethod) { f_MethodToken.Initializer = "ReadMetadataToken(reader)"; } else if (kb.OpCode.OperandType == OperandType.InlineSig) { f_MethodToken.Initializer = null; } else { throw AssertionHelper.Fail(); } var p_Signature = kb.EnsureProperty("Signature", typeof(byte[])); if (kb.OpCode.OperandType == OperandType.InlineMethod) { p_Signature.Getter = null; } else if (kb.OpCode.OperandType == OperandType.InlineSig) { p_Signature.Getter = "SignatureFromToken(_signatureToken);"; } else { throw AssertionHelper.Fail(); } var p_SignatureToken = kb.EnsureProperty("SignatureToken", typeof(Int32)); if (kb.OpCode.OperandType == OperandType.InlineMethod) { p_SignatureToken.Getter = null; } else if (kb.OpCode.OperandType == OperandType.InlineSig) { p_SignatureToken.Getter = "_signatureToken;"; } else { throw AssertionHelper.Fail(); } var f_SignatureToken = kb.EnsureField("_signatureToken", typeof(Int32)); if (kb.OpCode.OperandType == OperandType.InlineMethod) { f_SignatureToken.Initializer = null; } else if (kb.OpCode.OperandType == OperandType.InlineSig) { f_SignatureToken.Initializer = "ReadMetadataToken(reader)"; } else { throw AssertionHelper.Fail(); } var pfx_constrained = kb.EnsurePrefix("Constraint", typeof(Type), "constrained"); pfx_constrained.Getter = "Type"; kb.EnsurePrefix("IsTail", typeof(bool), "tail"); } else if (kb.Family == "ldfld" || kb.Family == "ldflda" || kb.Family == "stfld") { (kb.OpCode.OperandType == OperandType.InlineField).AssertTrue(); var p_Token = kb.EnsureProperty("FieldToken", typeof(Int32)); p_Token.Getter = "_fieldToken;"; var p_Fld = kb.EnsureProperty("Field", typeof(FieldInfo)); p_Fld.Getter = "FieldFromToken(_fieldToken);"; var f = kb.EnsureField("_fieldToken", typeof(Int32)); f.Initializer = "ReadMetadataToken(reader)"; kb.EnsurePrefix("IsVolatile", typeof(bool), "volatile"); var pfx_Unaligned = kb.EnsurePrefix("IsUnaligned", typeof(bool), "unaligned"); if (kb.Family == "ldfld") { pfx_Unaligned.Filter = "OpSpec.OpCode.Value != 0x7e /* ldsfld */"; } if (kb.Family == "stfld") { pfx_Unaligned.Filter = "OpSpec.OpCode.Value != 0x80 /* stsfld */"; } var p_IsAligned = kb.EnsureProperty("IsAligned", typeof(bool)); p_IsAligned.Getter = "!IsUnaligned"; var p_Alignment = kb.EnsureProperty("Alignment", typeof(byte)); var buf = new StringBuilder(); buf.AppendLine(String.Format( "var unaligned = {0}.SingleOrDefault({0}.OfType<{1}>(Prefixes));", typeof(Enumerable), "Unaligned")); buf.AppendLine(String.Format( "var defaultAlignment = (({0})(() => {{ throw new {1}(); }}))();", typeof(Func <byte>).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(NotImplementedException).GetCSharpRef(ToCSharpOptions.ForCodegen))); buf.Append("return unaligned != null ? unaligned.Alignment : defaultAlignment"); p_Alignment.Getter = buf.ToString(); } else if (kb.Family == "initblk" || kb.Family == "cpblk") { kb.EnsurePrefix("IsVolatile", typeof(bool), "volatile"); kb.EnsurePrefix("IsUnaligned", typeof(bool), "unaligned"); var p_IsAligned = kb.EnsureProperty("IsAligned", typeof(bool)); p_IsAligned.Getter = "!IsUnaligned"; var p_Alignment = kb.EnsureProperty("Alignment", typeof(byte)); var buf = new StringBuilder(); buf.AppendLine(String.Format( "var unaligned = {0}.SingleOrDefault({0}.OfType<{1}>(Prefixes));", typeof(Enumerable).GetCSharpRef(ToCSharpOptions.ForCodegen), "Unaligned")); buf.AppendLine(String.Format( "var defaultAlignment = ({0}){1}.SizeOf(typeof({2}));", typeof(byte).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(Marshal).GetCSharpRef(ToCSharpOptions.ForCodegen), typeof(IntPtr).GetCSharpRef(ToCSharpOptions.ForCodegen))); buf.Append("return unaligned != null ? unaligned.Alignment : defaultAlignment"); p_Alignment.Getter = buf.ToString(); p_Alignment.IsUnsafe = true; } else { // so that we never miss any other instructions with arguments (kb.OpCode.OperandType == OperandType.InlineNone).AssertTrue(); } }