How to add and reference a new field within Generic Class<p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">Hi,</span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">I’m working with Phoenix for .Net Assembly Transformation and my question is how we can add a new field to a generic Class and then load it.</span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">Suppose for instance we have the following Generic Class :<br/></span></span></p> <pre lang="x-c#">public class Test&lt;T&gt; { private T value; public Test(T value) { this.value = value; } public T Value { get { return value; } set { this.value = value; } } }</pre> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style="font-size:10pt;line-height:115%;font-family:'Courier New'">And we need to transform this to <br/></span></p> <pre lang="x-c#">public class Test&lt;T&gt; { private T value; int newfield; public Test(T value) { this.value = value; } public T Value { get { return value; } set { this.value = value; } } public void MyMethod(int t) { newfield = t; } }</pre> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style=""><span style="font-size:small"><span style="font-family:Calibri">When I consider the field as a usual field, I’m able to generate the modified generic class. However the PEVerify tool complain with the following Error :</span></span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><em><span style=""><span style="font-size:small"><span style="font-family:Calibri">System.BadImageFormatException: Fields inside generic classes must be referenced using MemberRefs, even in the same module as the class.</span></span></span></em></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">After some try I noted that to reference a field within the generic class we have to load the field of the class instantiated with the type variable “!0” as follows :<br/></span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"> </p> <pre lang="x-c#">Phx.Collections.TypeList typeList = Phx.Collections.TypeList.New(Phx.GlobalData.GlobalLifetime); typeList.Append(testType.TypeVariableTypeList.Head.Data); Phx.Types.AggregateType insta = testType.Instantiate(typeList); </pre> <p class=MsoNormal style="margin:0cm 0cm 10pt"> </p> <span style="font-size:10pt;line-height:115%;font-family:'Courier New'"> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style=""><span style="font-size:small"><span style="font-family:Calibri">However this works only for an existing field because when we add a new field to the generic class, this field does not appear in the instantiated class. Even, if I try to add the field manually I get exception error. </span></span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style=""><span style="font-size:small"><span style="font-family:Calibri">Can somebody give me a guidance please?</span></span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style=""><span style="font-size:small;font-family:Calibri">Thank you!</span></span><span style="color:black"></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"> </p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><br/></p> </span>© 2009 Microsoft Corporation. All rights reserved.Sat, 04 Jul 2009 02:34:12 Zeaf5c602-e74a-43a0-a262-a5ce9b02cccdhttp://social.msdn.microsoft.com/Forums/en-US/phoenix/thread/eaf5c602-e74a-43a0-a262-a5ce9b02cccd#eaf5c602-e74a-43a0-a262-a5ce9b02cccdhttp://social.msdn.microsoft.com/Forums/en-US/phoenix/thread/eaf5c602-e74a-43a0-a262-a5ce9b02cccd#eaf5c602-e74a-43a0-a262-a5ce9b02cccdAAyoubhttp://social.msdn.microsoft.com/Profile/en-US/?user=AAyoubHow to add and reference a new field within Generic Class<p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">Hi,</span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">I’m working with Phoenix for .Net Assembly Transformation and my question is how we can add a new field to a generic Class and then load it.</span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">Suppose for instance we have the following Generic Class :<br/></span></span></p> <pre lang="x-c#">public class Test&lt;T&gt; { private T value; public Test(T value) { this.value = value; } public T Value { get { return value; } set { this.value = value; } } }</pre> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style="font-size:10pt;line-height:115%;font-family:'Courier New'">And we need to transform this to <br/></span></p> <pre lang="x-c#">public class Test&lt;T&gt; { private T value; int newfield; public Test(T value) { this.value = value; } public T Value { get { return value; } set { this.value = value; } } public void MyMethod(int t) { newfield = t; } }</pre> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style=""><span style="font-size:small"><span style="font-family:Calibri">When I consider the field as a usual field, I’m able to generate the modified generic class. However the PEVerify tool complain with the following Error :</span></span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><em><span style=""><span style="font-size:small"><span style="font-family:Calibri">System.BadImageFormatException: Fields inside generic classes must be referenced using MemberRefs, even in the same module as the class.</span></span></span></em></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">After some try I noted that to reference a field within the generic class we have to load the field of the class instantiated with the type variable “!0” as follows :<br/></span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"> </p> <pre lang="x-c#">Phx.Collections.TypeList typeList = Phx.Collections.TypeList.New(Phx.GlobalData.GlobalLifetime); typeList.Append(testType.TypeVariableTypeList.Head.Data); Phx.Types.AggregateType insta = testType.Instantiate(typeList); </pre> <p class=MsoNormal style="margin:0cm 0cm 10pt"> </p> <span style="font-size:10pt;line-height:115%;font-family:'Courier New'"> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style=""><span style="font-size:small"><span style="font-family:Calibri">However this works only for an existing field because when we add a new field to the generic class, this field does not appear in the instantiated class. Even, if I try to add the field manually I get exception error. </span></span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style=""><span style="font-size:small"><span style="font-family:Calibri">Can somebody give me a guidance please?</span></span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style=""><span style="font-size:small;font-family:Calibri">Thank you!</span></span><span style="color:black"></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"> </p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><br/></p> </span>Thu, 25 Jun 2009 21:35:34 Z2009-06-25T21:35:34Zhttp://social.msdn.microsoft.com/Forums/en-US/phoenix/thread/eaf5c602-e74a-43a0-a262-a5ce9b02cccd#e3dc4f54-5c2a-4b96-a703-8f105458270dhttp://social.msdn.microsoft.com/Forums/en-US/phoenix/thread/eaf5c602-e74a-43a0-a262-a5ce9b02cccd#e3dc4f54-5c2a-4b96-a703-8f105458270dAAyoubhttp://social.msdn.microsoft.com/Profile/en-US/?user=AAyoubHow to add and reference a new field within Generic Class<p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">Hi,</span></span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US><span style="font-size:small;font-family:Calibri">Here a workaround for the previous question. To load a field, I use the following Function: <br/><br/></span></span> <p> </p> </p> <pre lang="x-c#">public Phx.IR.ValueInstruction ldfld(Phx.Symbols.FieldSymbol fieldsymbol, bool append) { Phx.IR.ValueInstruction inst = Phx.IR.ValueInstruction.NewUnary(funit, Phx.Targets.Architectures.Msil.Opcode.ldfld, stackslot, Phx.IR.MemoryOperand.New(funit, fieldsymbol.Field, null, stackslot, 0, Phx.Alignment.NaturalAlignment(fieldsymbol.Type), funit.AliasInfo.AllHeapMemoryTag, funit.SafetyInfo.SafeTag)); funit.Legalize.Instruction(inst); if (fieldsymbol.EnclosingAggregateType.IsGeneric) { Phx.Collections.TypeList typeList = Phx.Collections.TypeList.New(Phx.GlobalData.GlobalLifetime); foreach (Phx.Types.TypeVariableType typeVar in fieldsymbol.EnclosingAggregateType.TypeVariableTypeList) { typeList.Append(typeVar); } Phx.Types.AggregateType instance = fieldsymbol.EnclosingAggregateType.Instantiate(typeList); Phx.Symbols.FieldSymbol thisfield = instance.FieldSymbolList; while (thisfield != null) { if (thisfield.UninstantiatedFieldSymbol == fieldsymbol) { thisfield.IsToolGenerated = false; thisfield.NeedsFixup = true; thisfield.MustBeEmittedInMetadata = true; inst.SourceOperand.ResetField(thisfield.Field); break; } thisfield = thisfield.NextFieldSymbol; } } if (append) appendInst.InsertBefore(inst); return inst; }</pre> <p class=MsoNormal style="margin:0cm 0cm 10pt"> </p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US>When the field is newly added, we have to create the memory operand before; elsewhere the field is not populated in the FieldSymbolList of the instantiated class. </span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span lang=EN-US>A better and more general solution for this problem will be appreciated.</span></p>Fri, 26 Jun 2009 16:46:03 Z2009-06-26T16:49:29Zhttp://social.msdn.microsoft.com/Forums/en-US/phoenix/thread/eaf5c602-e74a-43a0-a262-a5ce9b02cccd#31dc4a7a-d3a1-44a9-beb4-193277a1a492http://social.msdn.microsoft.com/Forums/en-US/phoenix/thread/eaf5c602-e74a-43a0-a262-a5ce9b02cccd#31dc4a7a-d3a1-44a9-beb4-193277a1a492AAyoubhttp://social.msdn.microsoft.com/Profile/en-US/?user=AAyoubHow to add and reference a new field within Generic Class<p class=MsoNormal style="margin:0cm 0cm 10pt"><span style="font-size:12pt;line-height:115%;font-family:'Times New Roman','serif'" lang=EN-US>Hi,</span></p> <p class=MsoNormal style="margin:0cm 0cm 10pt"><span style="font-size:12pt;color:black;line-height:115%;font-family:'Times New Roman','serif'" lang=EN-US>The following code shows how we can obtain a generic class function symbol newly created to do a call from another function of the same generic class. We have to create a function symbol with a visibility ClrTokenReference and append it to the instantiated class.</span><span style="font-size:12pt;line-height:115%;font-family:'Times New Roman','serif'" lang=EN-US></span></p> <pre lang="x-c#">public Phx.Symbols.FunctionSymbol ResetFunction(Phx.Symbols.FunctionSymbol funcsymbol) { if (funcsymbol.EnclosingAggregateType.IsGeneric) { Phx.Collections.TypeList typeList = Phx.Collections.TypeList.New(Phx.GlobalData.GlobalLifetime); foreach (Phx.Types.TypeVariableType typeVar in funcsymbol.EnclosingAggregateType.TypeVariableTypeList) { typeList.Append(typeVar); } Phx.Types.AggregateType instance = funcsymbol.EnclosingAggregateType.Instantiate(typeList); Phx.Symbols.FunctionSymbol thisfunction = Phx.Symbols.FunctionSymbol.New(moduleUnit.SymbolTable, 0, funcsymbol.Name, funcsymbol.FunctionType, Phx.Symbols.Visibility.ClrTokenReference); instance.AppendMethodSymbol(thisfunction); instance.TypeSymbol.InsertInLexicalScope(thisfunction, thisfunction.Name); thisfunction.MustBeEmittedInMetadata = true; thisfunction.UninstantiatedFunctionSymbol = funcsymbol; return thisfunction; } else return funcsymbol; }</pre>Sat, 04 Jul 2009 02:29:12 Z2009-07-04T02:33:13Z