Generi functions
- Hi,
I am trying to generate MSIL code for a simple generic function like this:
But I'm getting the following erros:class MyClass { public T foo<T>(T arg) { return arg; } }<br />
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 4) applyrgs [line 10] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 4) applyrgs [line 10] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 4) applyrgs [line 10] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\ir\ir.cpp, Line 7358
this->FunctionUnit->Architecture->CanEnregisterType(type)
in (Function number 4) applyrgs [line 10] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\ir\ir.cpp, Line 8675
functionUnit->Architecture->CanEnregisterType(type)
in (Function number 4) applyrgs [line 10] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 4) applyrgs [line 10] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 4) applyrgs [line 10] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\metadata\metadata.cpp, Line 10204
Unreached
in (Function number 4) applyrgs [line 10] during Stack Allocation
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Any ideas of what is causing this?
Thanks,
Guilherme
Todas las respuestas
Something is asking for the BitSize of a type, which means the type needs to have a known size. Can you provide a call stack?
Architect - Microsoft Phoenix Project- Hi Andy,
Here is the code I'm using to compile this generic function:
Phx.Name functionName = Phx.Name.New(ModuleUnit.Lifetime, "foo"); Phx.Symbols.FunctionSymbol functionSymbol = Phx.Symbols.FunctionSymbol.New(ModuleUnit.SymbolTable, 0, functionName, null, Phx.Symbols.Visibility.GlobalReference); Phx.Symbols.MsilTypeSymbol genericSymbol = Phx.Symbols.MsilTypeSymbol.New(ModuleUnit.SymbolTable, Phx.Name.New(functionSymbol.Lifetime, "T"), 0); Phx.Types.TypeVariableType genericType = functionSymbol.GenerateTypeVariable(ModuleUnit.TypeTable, genericSymbol, 0); Phx.Types.FunctionTypeBuilder functionBuilder = Phx.Types.FunctionTypeBuilder.New(ModuleUnit.TypeTable); functionBuilder.Begin(); // Set return type functionBuilder.AppendReturnParameter(genericType); // Set arguments types functionBuilder.AppendParameter(genericType, Phx.Types.ParameterKind.UserDefined); functionBuilder.CallingConventionKind = Phx.Types.CallingConventionKind.ClrCall; functionBuilder.GenericArity = 1; // Fix the type... functionSymbol.FunctionType = functionBuilder.GetFunctionType(); // Create a FunctionUnit object. Phx.FunctionUnit functionUnit = Phx.FunctionUnit.New(functionSymbol, Phx.CodeGenerationMode.IJW, ModuleUnit.TypeTable, ModuleUnit.MsilRuntime.Architecture, ModuleUnit.MsilRuntime, ModuleUnit, 0); // Associate the function unit with the provided // method symbol. functionSymbol.FunctionUnit = functionUnit; // Add the function unit to the module unit. ModuleUnit.AppendChildUnit(functionUnit); // Create a symbol table for the function. Phx.Symbols.Table functionSymbolTable = Phx.Symbols.Table.New(functionUnit, 64, false); // Make it accessible by symbol name. functionSymbolTable.AddMap(Phx.Symbols.NameMap.New(functionSymbolTable, 64)); // Generate a token map. Phx.Targets.Runtimes.Vccrt.Win.Msil.Runtime runtime = functionUnit.Runtime as Phx.Targets.Runtimes.Vccrt.Win.Msil.Runtime; runtime.TokenMap = Phx.Symbols.TokenMap.New(Phx.GlobalData.SymbolTable, 64); // Initialize the lifetime of the function unit. functionUnit.AllocateLifetime(); // Append and enter instruction after the start instruction. Phx.IR.LabelInstruction enterInstruction = Phx.IR.LabelInstruction.New( functionUnit, Phx.Common.Opcode.EnterFunction, functionSymbol); // Retrieve start and end instructions for the unit. Phx.IR.Instruction startInstruction = functionUnit.FirstInstruction; startInstruction.InsertAfter(enterInstruction); startInstruction.AppendLabelSource(Phx.IR.LabelOperandKind.Technical, Phx.IR.LabelOperand.New(functionUnit, enterInstruction)); Phx.Symbols.LocalVariableSymbol localVar = Phx.Symbols.LocalVariableSymbol.New(functionUnit.SymbolTable, externId++, Phx.Name.New(functionUnit.Lifetime, "arg"), genericType, Phx.Symbols.StorageClass.Parameter); Phx.IR.VariableOperand localvarOperand = Phx.IR.VariableOperand.New(functionUnit, genericType, localVar); functionUnit.FirstEnterInstruction.AppendDestination(localvarOperand); // Create a label target for the exit instruction. Phx.IR.LabelInstruction exitInstruction = Phx.IR.LabelInstruction.New(functionUnit, Phx.Common.Opcode.ExitFunction); // Insert it into the instruction stream. functionUnit.LastInstruction.InsertBefore(exitInstruction); // Generate a return instruction. Phx.IR.BranchInstruction returnInstruction = Phx.IR.BranchInstruction.NewReturn(functionUnit, Phx.Common.Opcode.Return, exitInstruction); returnInstruction.AppendSource(localvarOperand); // Insert it into the instruction stream. exitInstruction.InsertBefore(returnInstruction); // Allow the framework to finalize creation of the unit. functionUnit.FinishCreation(); // Now that we're done with IR for this unit, pop it off the context // stack (creating the unit pushed it on). functionUnit.Context.PopUnit();<br/> <br/> this.functionUnits.Add(functionUnit);
The stacktrace:
at Phx.PE.Writer.UpdateEncodedIR(FunctionUnit functionUnit) at Compiler.Framework.AbstractCodeGenerator.ExecutePhases(FunctionUnit functionUnit) in e:\Users\Guilherme\Documents\Visual Studio 2008\Projects\MyCompiler.NET\Compiladores.Framework\AbstractCodeGenerator.cs:line 791 at Compiler.Framework.AbstractCodeGenerator.ExecutePhases() in e:\Users\Guilherme\Documents\Visual Studio 2008\Projects\MyCompiler.NET\Compiladores.Framework\AbstractCodeGenerator.cs:line 178 at MyCompiler.Core.Parser.CoreMain.Main(String[] args) in e:\Users\Guilherme\Documents\Visual Studio 2008\Projects\MyCompiler.NET\MyCompiler.Core.Parser\CoreMain.cs:line 62 at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()
My ExecutePhases is this:
// Executes the phase list on the provided function unit. private void ExecutePhases(Phx.FunctionUnit functionUnit) { // Push the unit onto the current context. Phx.Threading.Context context = Phx.Threading.Context.GetCurrent(); context.PushUnit(functionUnit); // Run the phase list. phaseConfiguration.PhaseList.DoPhaseList(functionUnit); // Force creation of a new signature. Phx.Targets.Runtimes.Vccrt.Win.Msil.Frame frame = functionUnit.Frame as Phx.Targets.Runtimes.Vccrt.Win.Msil.Frame; frame.LocalVarSigTok = 0; // Assign byte offsets to local parameters. int i = 0; foreach (Phx.Symbols.Symbol localSymbol in functionUnit.SymbolTable.AllSymbols) { if (!localSymbol.IsLocalVariableSymbol) continue; if (!localSymbol.AsLocalVariableSymbol.IsAuto) continue; localSymbol.Location.AsFrameLocation.ByteOffset = i++; } // Finish encoding and release the function unit. Phx.PE.Writer.UpdateEncodedIR(functionUnit); Phx.Metadata.SignatureEmitter.EncodeLocalSignature(functionUnit); functionUnit.ReleaseLifetime(); }
Regards,
Guilherme Oliveira
- One more info: the exception thrown is a System.NullReferenceException.
- Any chance you could get line numbers for the Phoenix code? We ship the PDBs, so if you run this under the debugger and and point the debugger symbols at the right directory it should find them.
Another thing that might be interesting is to set PHX=-verbosetracepewriter in the environment when you run this...
Architect - Microsoft Phoenix Project - I was not able to get the line numbers. All I got was this at the VS2010:
> phxd.dll!Phx::PE::Writer::UpdateEncodedIR(Phx::FunctionUnit^ functionUnit = 0x072d98c4) Line 2841 + 0x3 bytes C++
I hope the trace helps:
Parsing... Code generation... Before Lower EH Main $L1: (references=0) #11:9-11:10 START Executable.Base.Program::Main(T) #11:9-11:10 Executable.Base.Program::Main: (references=1) #11:9-11:10 args = ENTERFUNCTION #11:9-11:10 br $L7 #11:9-11:10 $L7: (references=1) #11:9-11:10 ENTERBODY #11:9-11:10 nop #11:9-11:10 SR0 = call* &[mscorlib]System.Reflection.Assembly::GetExecutingAssembly, $L6(EH) #12:13-12:77 SR0 = ldstr Constant-"$Program" #12:13-12:77 SR0 = callvirt* &[mscorlib]System.Reflection.Assembly::GetType, SR0, SR0, $L6(EH) #12:13-12:77 type = stloc SR0 #12:13-12:77 SR0 = ldloc type #14:13-14:77 SR0 = ldc false(0x00000000) #14:13-14:77 SR0 = newarray* [mscorlib]System.Type, SR0, $L6(EH) #14:13-14:77 SR0 = callvirt* &[mscorlib]System.Type::GetConstructor, SR0, SR0, $L6(EH) #14:13-14:77 SR0 = ldnull nullptr(0x00000000) #14:13-14:77 SR0 = callvirt* &[mscorlib]System.Reflection.ConstructorInfo::Invoke, SR0, SR0, $L6(EH) #14:13-14:77 compiler = stloc SR0 #14:13-14:77 SR0 = ldloc type #16:13-16:65 SR0 = ldstr Constant-"$Main" #16:13-16:65 SR0 = callvirt* &[mscorlib]System.Type::GetMethod, SR0, SR0, $L6(EH) #16:13-16:65 mainMethodInfo = stloc SR0 #16:13-16:65 SR0 = ldloc mainMethodInfo #18:13-18:51 SR0 = ldloc compiler #18:13-18:51 SR0 = ldnull nullptr(0x00000000) #18:13-18:51 SR0 = callvirt* &[mscorlib]System.Reflection.MethodBase::Invoke, SR0, SR0, SR0, $L6(EH) #18:13-18:51 pop SR0 #18:13-18:51 SR0 = ldc false(0x00000000) #20:13-20:22 CS$1$0000 = stloc SR0 #20:13-20:22 br $L5 #20:13-20:22 $L5: (references=1) Offset: 73(0x0049) #21:9-21:10 SR0 = ldloc CS$1$0000 #21:9-21:10 br $L8 #21:9-21:10 $L8: (references=1) Offset: 74(0x004a) #21:9-21:10 EXITBODY #21:9-21:10 ret Executable.Base.Program::Main(T) #21:9-21:10 Executable.Base.Program::Main: (references=1) Offset: 75(0x004b) #21:9-21:10 EXITFUNCTION #21:9-21:10 $L6: (references=7) #21:9-21:10 UNWIND #21:9-21:10 $L2: (references=0) Offset: 75(0x004b) #21:9-21:10 END #21:9-21:10 ==> Before LayoutBlocks $L1: (references=0) #11:9-11:10 START Executable.Base.Program::Main(T) #11:9-11:10 Executable.Base.Program::Main: (references=1) #11:9-11:10 args = ENTERFUNCTION #11:9-11:10 br $L7 #11:9-11:10 $L7: (references=1) #11:9-11:10 ENTERBODY #11:9-11:10 nop #11:9-11:10 SR0 = call* &[mscorlib]System.Reflection.Assembly::GetExecutingAssembly, $L6(EH) #12:13-12:77 SR0 = ldstr Constant-"$Program" #12:13-12:77 SR0 = callvirt* &[mscorlib]System.Reflection.Assembly::GetType, SR0, SR0, $L6(EH) #12:13-12:77 type = stloc SR0 #12:13-12:77 SR0 = ldloc type #14:13-14:77 SR0 = ldc false(0x00000000) #14:13-14:77 SR0 = newarray* [mscorlib]System.Type, SR0, $L6(EH) #14:13-14:77 SR0 = callvirt* &[mscorlib]System.Type::GetConstructor, SR0, SR0, $L6(EH) #14:13-14:77 SR0 = ldnull nullptr(0x00000000) #14:13-14:77 SR0 = callvirt* &[mscorlib]System.Reflection.ConstructorInfo::Invoke, SR0, SR0, $L6(EH) #14:13-14:77 compiler = stloc SR0 #14:13-14:77 SR0 = ldloc type #16:13-16:65 SR0 = ldstr Constant-"$Main" #16:13-16:65 SR0 = callvirt* &[mscorlib]System.Type::GetMethod, SR0, SR0, $L6(EH) #16:13-16:65 mainMethodInfo = stloc SR0 #16:13-16:65 SR0 = ldloc mainMethodInfo #18:13-18:51 SR0 = ldloc compiler #18:13-18:51 SR0 = ldnull nullptr(0x00000000) #18:13-18:51 SR0 = callvirt* &[mscorlib]System.Reflection.MethodBase::Invoke, SR0, SR0, SR0, $L6(EH) #18:13-18:51 pop SR0 #18:13-18:51 SR0 = ldc false(0x00000000) #20:13-20:22 CS$1$0000 = stloc SR0 #20:13-20:22 br $L5 #20:13-20:22 $L5: (references=1) Offset: 73(0x0049) #21:9-21:10 SR0 = ldloc CS$1$0000 #21:9-21:10 br $L8 #21:9-21:10 $L8: (references=1) Offset: 74(0x004a) #21:9-21:10 EXITBODY #21:9-21:10 ret Executable.Base.Program::Main(T) #21:9-21:10 Executable.Base.Program::Main: (references=1) Offset: 75(0x004b) #21:9-21:10 EXITFUNCTION #21:9-21:10 $L6: (references=7) #21:9-21:10 UNWIND #21:9-21:10 $L2: (references=0) Offset: 75(0x004b) #21:9-21:10 END #21:9-21:10 ==> Before OptimizeFlow $L1: (references=0) #11:9-11:10 START Executable.Base.Program::Main(T) #11:9-11:10 Executable.Base.Program::Main: (references=1) #11:9-11:10 args = ENTERFUNCTION #11:9-11:10 br $L7 #11:9-11:10 $L7: (references=1) #11:9-11:10 ENTERBODY #11:9-11:10 nop #11:9-11:10 SR0 = call* &[mscorlib]System.Reflection.Assembly::GetExecutingAssembly, $L6(EH) #12:13-12:77 SR0 = ldstr Constant-"$Program" #12:13-12:77 SR0 = callvirt* &[mscorlib]System.Reflection.Assembly::GetType, SR0, SR0, $L6(EH) #12:13-12:77 type = stloc SR0 #12:13-12:77 SR0 = ldloc type #14:13-14:77 SR0 = ldc false(0x00000000) #14:13-14:77 SR0 = newarray* [mscorlib]System.Type, SR0, $L6(EH) #14:13-14:77 SR0 = callvirt* &[mscorlib]System.Type::GetConstructor, SR0, SR0, $L6(EH) #14:13-14:77 SR0 = ldnull nullptr(0x00000000) #14:13-14:77 SR0 = callvirt* &[mscorlib]System.Reflection.ConstructorInfo::Invoke, SR0, SR0, $L6(EH) #14:13-14:77 compiler = stloc SR0 #14:13-14:77 SR0 = ldloc type #16:13-16:65 SR0 = ldstr Constant-"$Main" #16:13-16:65 SR0 = callvirt* &[mscorlib]System.Type::GetMethod, SR0, SR0, $L6(EH) #16:13-16:65 mainMethodInfo = stloc SR0 #16:13-16:65 SR0 = ldloc mainMethodInfo #18:13-18:51 SR0 = ldloc compiler #18:13-18:51 SR0 = ldnull nullptr(0x00000000) #18:13-18:51 SR0 = callvirt* &[mscorlib]System.Reflection.MethodBase::Invoke, SR0, SR0, SR0, $L6(EH) #18:13-18:51 pop SR0 #18:13-18:51 SR0 = ldc false(0x00000000) #20:13-20:22 CS$1$0000 = stloc SR0 #20:13-20:22 br $L5 #20:13-20:22 $L5: (references=1) Offset: 73(0x0049) #21:9-21:10 SR0 = ldloc CS$1$0000 #21:9-21:10 br $L8 #21:9-21:10 $L8: (references=1) Offset: 74(0x004a) #21:9-21:10 EXITBODY #21:9-21:10 ret Executable.Base.Program::Main(T) #21:9-21:10 Executable.Base.Program::Main: (references=1) Offset: 75(0x004b) #21:9-21:10 EXITFUNCTION #21:9-21:10 $L6: (references=7) #21:9-21:10 UNWIND #21:9-21:10 $L2: (references=0) Offset: 75(0x004b) #21:9-21:10 END #21:9-21:10 ==> Before FinalizeIR $L1: (references=0) #11:9-11:10 START Executable.Base.Program::Main(T) #11:9-11:10 Executable.Base.Program::Main: (references=1) #11:9-11:10 args = ENTERFUNCTION #11:9-11:10 $L7: (references=0) #11:9-11:10 ENTERBODY #11:9-11:10 nop #11:9-11:10 SR0 = call* &[mscorlib]System.Reflection.Assembly::GetExecutingAssembly, $L6(EH) #12:13-12:77 SR0 = ldstr Constant-"$Program" #12:13-12:77 SR0 = callvirt* &[mscorlib]System.Reflection.Assembly::GetType, SR0, SR0, $L6(EH) #12:13-12:77 type = stloc SR0 #12:13-12:77 SR0 = ldloc type #14:13-14:77 SR0 = ldc false(0x00000000) #14:13-14:77 SR0 = newarray* [mscorlib]System.Type, SR0, $L6(EH) #14:13-14:77 SR0 = callvirt* &[mscorlib]System.Type::GetConstructor, SR0, SR0, $L6(EH) #14:13-14:77 SR0 = ldnull nullptr(0x00000000) #14:13-14:77 SR0 = callvirt* &[mscorlib]System.Reflection.ConstructorInfo::Invoke, SR0, SR0, $L6(EH) #14:13-14:77 compiler = stloc SR0 #14:13-14:77 SR0 = ldloc type #16:13-16:65 SR0 = ldstr Constant-"$Main" #16:13-16:65 SR0 = callvirt* &[mscorlib]System.Type::GetMethod, SR0, SR0, $L6(EH) #16:13-16:65 mainMethodInfo = stloc SR0 #16:13-16:65 SR0 = ldloc mainMethodInfo #18:13-18:51 SR0 = ldloc compiler #18:13-18:51 SR0 = ldnull nullptr(0x00000000) #18:13-18:51 SR0 = callvirt* &[mscorlib]System.Reflection.MethodBase::Invoke, SR0, SR0, SR0, $L6(EH) #18:13-18:51 pop SR0 #18:13-18:51 SR0 = ldc false(0x00000000) #20:13-20:22 CS$1$0000 = stloc SR0 #20:13-20:22 SR0 = ldloc CS$1$0000 #21:9-21:10 $L8: (references=0) Offset: 74(0x004a) #21:9-21:10 EXITBODY #21:9-21:10 ret Executable.Base.Program::Main(T) #21:9-21:10 Executable.Base.Program::Main: (references=1) Offset: 75(0x004b) #21:9-21:10 EXITFUNCTION #21:9-21:10 $L6: (references=7) #21:9-21:10 UNWIND #21:9-21:10 $L2: (references=0) Offset: 75(0x004b) #21:9-21:10 END #21:9-21:10 ==> Encoded method: ----- Encoded IR for Executable.Base.Program::Main at 00002050 Executable.Base.Program::Main: 13 30 03 00 3D 00 00 00 00 00 00 00 00 28 00 00 .0..=........(.. 00 00 72 00 00 00 00 6F 00 00 00 00 0A 06 16 8D ..r....o........ 00 00 00 00 6F 00 00 00 00 14 6F 00 00 00 00 0B ....o.....o..... 06 72 00 00 00 00 6F 00 00 00 00 0C 08 07 14 6F .r....o........o 00 00 00 00 26 16 0D 09 2A ....&...* ^26 0040 Invoke DataArrayIsOwned Before Lower EH .ctor $L1: (references=0) #0 START Executable.Base.Program::.ctor(T) #0 Executable.Base.Program::.ctor: (references=1) #0 this = ENTERFUNCTION #0 br $L6 #0 $L6: (references=1) #0 ENTERBODY #0 SR0 = ldarg this #0 call* &[mscorlib]System.Object::.ctor, SR0, $L5(EH) #0 br $L7 #0 $L7: (references=1) Offset: 7(0x0007) #0 EXITBODY #0 ret Executable.Base.Program::.ctor(T) #0 Executable.Base.Program::.ctor: (references=1) Offset: 8(0x0008) #0 EXITFUNCTION #0 $L5: (references=1) #0 UNWIND #0 $L2: (references=0) Offset: 8(0x0008) #0 END #0 ==> Before LayoutBlocks $L1: (references=0) #0 START Executable.Base.Program::.ctor(T) #0 Executable.Base.Program::.ctor: (references=1) #0 this = ENTERFUNCTION #0 br $L6 #0 $L6: (references=1) #0 ENTERBODY #0 SR0 = ldarg this #0 call* &[mscorlib]System.Object::.ctor, SR0, $L5(EH) #0 br $L7 #0 $L7: (references=1) Offset: 7(0x0007) #0 EXITBODY #0 ret Executable.Base.Program::.ctor(T) #0 Executable.Base.Program::.ctor: (references=1) Offset: 8(0x0008) #0 EXITFUNCTION #0 $L5: (references=1) #0 UNWIND #0 $L2: (references=0) Offset: 8(0x0008) #0 END #0 ==> Before OptimizeFlow $L1: (references=0) #0 START Executable.Base.Program::.ctor(T) #0 Executable.Base.Program::.ctor: (references=1) #0 this = ENTERFUNCTION #0 br $L6 #0 $L6: (references=1) #0 ENTERBODY #0 SR0 = ldarg this #0 call* &[mscorlib]System.Object::.ctor, SR0, $L5(EH) #0 br $L7 #0 $L7: (references=1) Offset: 7(0x0007) #0 EXITBODY #0 ret Executable.Base.Program::.ctor(T) #0 Executable.Base.Program::.ctor: (references=1) Offset: 8(0x0008) #0 EXITFUNCTION #0 $L5: (references=1) #0 UNWIND #0 $L2: (references=0) Offset: 8(0x0008) #0 END #0 ==> Before FinalizeIR $L1: (references=0) #0 START Executable.Base.Program::.ctor(T) #0 Executable.Base.Program::.ctor: (references=1) #0 this = ENTERFUNCTION #0 $L6: (references=0) #0 ENTERBODY #0 SR0 = ldarg this #0 call* &[mscorlib]System.Object::.ctor, SR0, $L5(EH) #0 $L7: (references=0) Offset: 7(0x0007) #0 EXITBODY #0 ret Executable.Base.Program::.ctor(T) #0 Executable.Base.Program::.ctor: (references=1) Offset: 8(0x0008) #0 EXITFUNCTION #0 $L5: (references=1) #0 UNWIND #0 $L2: (references=0) Offset: 8(0x0008) #0 END #0 ==> Encoded method: ----- Encoded IR for Executable.Base.Program::.ctor at 0000209b Executable.Base.Program::.ctor: 13 30 01 00 07 00 00 00 00 00 00 00 02 28 00 00 .0...........(.. ^26 000e .ctor 00 00 2A ..* DataArrayIsOwned Before Lower EH UnmanagedEntryPoint $L1: (references=0) #0 START UnmanagedEntryPoint(T) #0 UnmanagedEntryPoint: (references=1) #0 ENTERFUNCTION #0 jmp _CorExeMain* #0 UnmanagedEntryPoint: (references=0) Offset: 6(0x0006) #0 EXITFUNCTION #0 $L2: (references=0) #0 END #0 ==> Before LayoutBlocks $L1: (references=0) #0 START UnmanagedEntryPoint(T) #0 UnmanagedEntryPoint: (references=1) #0 ENTERFUNCTION #0 jmp _CorExeMain* #0 UnmanagedEntryPoint: (references=0) Offset: 6(0x0006) #0 EXITFUNCTION #0 $L2: (references=0) #0 END #0 ==> Before FinalizeIR $L1: (references=0) #0 START UnmanagedEntryPoint(T) #0 UnmanagedEntryPoint: (references=1) #0 ENTERFUNCTION #0 jmp _CorExeMain* #0 UnmanagedEntryPoint: (references=0) Offset: 6(0x0006) #0 EXITFUNCTION #0 $L2: (references=0) #0 END #0 ==> Encoded method: ----- Encoded IR for UnmanagedEntryPoint at 000027fe UnmanagedEntryPoint: FF 25 00 00 00 00 .%.... ^17 0002 _CorExeMain DataArrayIsOwned includes 1 instructions ==> Before FinalizeIR $L1: (references=0) #0 START [Executable.Base]$Program::.ctor(T) #0 [Executable.Base]$Program::.ctor: (references=1) #0 $this = ENTERFUNCTION #0 br $L5 #0 $L5: (references=1) #0 ENTERBODY #0 t277(SR0) = ld $this #0 _CALLVIRT &[mscorlib]System.Object::.ctor, t277(SR1) #0 br $L4 #0 $L4: (references=1) #0 br $L7 #0 $L7: (references=1) #0 EXITBODY #0 ret $L6(T) #0 $L6: (references=1) #0 EXITFUNCTION #0 $L2: (references=0) #0 END #0 ==> Encoded method: ----- Encoded IR for [Executable.Base]$Program::.ctor at 00000000 [Executable.Base]$Program::.ctor: 03 30 01 00 16 00 00 00 00 00 00 00 38 00 00 00 .0..........8... 00 02 6F 00 00 00 00 38 00 00 00 00 38 00 00 00 ..o....8....8... ^26 0013 .ctor 00 2A .* DataArrayIsOwned includes 6 instructions Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\ir\ir.cpp, Line 7358 this->FunctionUnit->Architecture->CanEnregisterType(type) in (Function number 0) foo during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\ir\ir.cpp, Line 8675 functionUnit->Architecture->CanEnregisterType(type) in (Function number 0) foo during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\metadata\metadata.cpp, Line 10204 Unreached in (Function number 0) foo during Stack Allocation in (PEModule) Executable.Base.exe in (Program) <unnamed unit> ==> Before FinalizeIR $L1: (references=0) START foo(T) foo: (references=1) arg = ENTERFUNCTION br $L5 $L5: (references=1) ENTERBODY t278(SR0) = ld arg $t277 = st t278(SR0) br $L4 $L4: (references=1) br $L7 $L7: (references=1) EXITBODY ret $L6(T) $L6: (references=1) EXITFUNCTION $L2: (references=0) END - Hi, I fixed the NullReferenceException (I forgot to set the methodSymbol.AllocationBaseSectionSymbol and the DebugInfo). Now my code does not generate exceptions, only these Assertion Failures:
----- Encoded IR for [Executable.Base]$Program::.ctor at 00000000 [Executable.Base]$Program::.ctor: 03 30 01 00 16 00 00 00 00 00 00 00 38 00 00 00 .0..........8... 00 02 6F 00 00 00 00 38 00 00 00 00 38 00 00 00 ..o....8....8... ^26 0013 .ctor 00 2A .* DataArrayIsOwned includes 6 instructions Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo [line 12] during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo [line 12] during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo [line 12] during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\ir\ir.cpp, Line 7358 this->FunctionUnit->Architecture->CanEnregisterType(type) in (Function number 0) foo [line 12] during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\ir\ir.cpp, Line 8675 functionUnit->Architecture->CanEnregisterType(type) in (Function number 0) foo [line 12] during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo [line 12] during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746 this->IsConstant in (Function number 0) foo [line 12] during Lower in (PEModule) Executable.Base.exe in (Program) <unnamed unit> Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\metadata\metadata.cpp, Line 10204 Unreached in (Function number 0) foo [line 12] during Stack Allocation in (PEModule) Executable.Base.exe in (Program) <unnamed unit> ==> Before FinalizeIR $L1: (references=0) #12:323-12:323 START [Executable.Base]Maina::foo(T) #12:323-12:323 [Executable.Base]Maina::foo: (references=1) #12:323-12:323 arg = ENTERFUNCTION #12:323-12:323 br $L5 #12:323-12:323 $L5: (references=1) #12:323-12:323 ENTERBODY #12:323-12:323 t278(SR0) = ld arg #12:323-12:323 $t277 = st t278(SR0) #12:323-12:323 br $L4 #12:323-12:323 $L4: (references=1) #12:323-12:323 br $L7 #12:323-12:323 $L7: (references=1) #12:323-12:323 EXITBODY #12:323-12:323 ret $L6(T) #12:323-12:323 $L6: (references=1) #12:323-12:323 EXITFUNCTION #12:323-12:323 $L2: (references=0) #12:323-12:323 END #12:323-12:323 ==> Encoded method: ----- Encoded IR for [Executable.Base]Maina::foo at 00000000 [Executable.Base]Maina::foo: 13 30 01 00 12 00 00 00 00 00 00 00 38 00 00 00 .0..........8... 00 02 0A 38 00 00 00 00 38 00 00 00 00 2A ...8....8....* DataArrayIsOwned includes 6 instructions Emiting Data UnitAt the end the executable is create, but the method is not there. What am I missing now?
Regards,
Guilherme Oliveira Here is the code with the recent changes I made:
Phx.Name functionName = Phx.Name.New(ModuleUnit.Lifetime, "foo");
Phx.Symbols.
FunctionSymbol functionSymbol = Phx.Symbols.FunctionSymbol.New(ModuleUnit.SymbolTable, 0, functionName, null, Phx.Symbols.Visibility.GlobalReference);
Phx.Symbols.
MsilTypeSymbol genericSymbol = Phx.Symbols.MsilTypeSymbol.New(ModuleUnit.SymbolTable, Phx.Name.New(functionSymbol.Lifetime, "T"), 0);
Phx.Types.
TypeVariableType genericType = functionSymbol.GenerateTypeVariable(ModuleUnit.TypeTable, genericSymbol, 0);
Phx.Types.
FunctionTypeBuilder functionBuilder = Phx.Types.FunctionTypeBuilder.New(ModuleUnit.TypeTable);
functionBuilder.Begin();
// Set return type
functionBuilder.AppendReturnParameter(genericType);
// Set arguments types
functionBuilder.AppendParameter(genericType, Phx.Types.
ParameterKind.UserDefined);
functionBuilder.CallingConventionKind = Phx.Types.
CallingConventionKind.ClrCall;
functionBuilder.GenericArity = 1;
// Fix the type...
functionSymbol.FunctionType = functionBuilder.GetFunctionType();
// Create a FunctionUnit object.
Phx.
FunctionUnit functionUnit = Phx.FunctionUnit.New(functionSymbol,
Phx.
CodeGenerationMode.IJW, ModuleUnit.TypeTable,
ModuleUnit.MsilRuntime.Architecture, ModuleUnit.MsilRuntime,
ModuleUnit, 0);
// Associate the function unit with the provided
// method symbol.
functionSymbol.FunctionUnit = functionUnit;
// Add the symbol as a method of the enclosing type.
_currentModule.ClassType.AppendMethodSymbol(functionSymbol);
_currentModule.ClassType.TypeSymbol.InsertInLexicalScope(functionSymbol, functionName);
AllocateMethodSymbol(ModuleUnit, functionSymbol);
functionSymbol.MethodSpecifier = Phx.Symbols.
MethodSpecifier.Static;
functionSymbol.Access = Phx.Symbols.
Access.Public;
// Add the function unit to the module unit.
ModuleUnit.AppendChildUnit(functionUnit);
// Create a symbol table for the function.
Phx.Symbols.
Table functionSymbolTable = Phx.Symbols.Table.New(functionUnit, 64, false);
// Make it accessible by symbol name.
functionSymbolTable.AddMap(Phx.Symbols.
NameMap.New(functionSymbolTable, 64));
// Generate a token map.
Phx.Targets.Runtimes.Vccrt.Win.Msil.
Runtime runtime = functionUnit.Runtime as Phx.Targets.Runtimes.Vccrt.Win.Msil.Runtime;
runtime.TokenMap = Phx.Symbols.
TokenMap.New(Phx.GlobalData.SymbolTable, 64);
// Initialize the lifetime of the function unit.
functionUnit.AllocateLifetime();
// Generate debug information.
Phx.Debug.
Info.New(functionUnit.Lifetime, functionUnit);
int
line = 12, column = 323;
functionUnit.CurrentDebugTag =
functionUnit.DebugInfo.CreateTag(Phx.
Name.New(functionUnit.Lifetime, "temp"), (uint)line, (ushort)column);
functionUnit.FirstInstruction.DebugTag = functionUnit.CurrentDebugTag;
functionUnit.LastInstruction.DebugTag = functionUnit.CurrentDebugTag;
// Append and enter instruction after the start instruction.
Phx.IR.
LabelInstruction enterInstruction = Phx.IR.LabelInstruction.New(
functionUnit, Phx.Common.
Opcode.EnterFunction, functionSymbol);
enterInstruction.DebugTag = functionUnit.CurrentDebugTag;
// Retrieve start and end instructions for the unit.
Phx.IR.
Instruction startInstruction = functionUnit.FirstInstruction;
startInstruction.DebugTag = functionUnit.CurrentDebugTag;
startInstruction.InsertAfter(enterInstruction);
startInstruction.AppendLabelSource(Phx.IR.
LabelOperandKind.Technical,
Phx.IR.
LabelOperand.New(functionUnit, enterInstruction));
Phx.Symbols.
LocalVariableSymbol localVar = Phx.Symbols.LocalVariableSymbol.New(functionUnit.SymbolTable, externId++,
Phx.
Name.New(functionUnit.Lifetime, "arg"), genericType, Phx.Symbols.StorageClass.Parameter);
Phx.IR.
VariableOperand localvarOperand = Phx.IR.VariableOperand.New(functionUnit, genericType, localVar);
functionUnit.FirstEnterInstruction.AppendDestination(localvarOperand);
// Create a label target for the exit instruction.
Phx.IR.
LabelInstruction exitInstruction = Phx.IR.LabelInstruction.New(functionUnit, Phx.Common.Opcode.ExitFunction);
exitInstruction.DebugTag = functionUnit.CurrentDebugTag;
// Insert it into the instruction stream.
functionUnit.LastInstruction.InsertBefore(exitInstruction);
// Generate a return instruction.
Phx.IR.
BranchInstruction returnInstruction = Phx.IR.BranchInstruction.NewReturn(functionUnit, Phx.Common.Opcode.Return, exitInstruction);
returnInstruction.DebugTag = functionUnit.CurrentDebugTag;
returnInstruction.AppendSource(localvarOperand);
// Insert it into the instruction stream.
exitInstruction.InsertBefore(returnInstruction);
// Allow the framework to finalize creation of the unit.
functionUnit.FinishCreation();
// Now that we're done with IR for this unit, pop it off the context
// stack (creating the unit pushed it on).
functionUnit.Context.PopUnit();
this
.functionUnits.Add(functionUnit);
- Andy, please help.
- Can you rerun your last example with the -dumptypes -dumpallphases:#foo options turned on? (eg, in your cmd.exe type: set PHX=-dumptypes -dumpallphases:#foo and then run your program).
Architect - Microsoft Phoenix Project Here is the output:
IR after MIR Lower (control MirLower)Function Unit #0
$L1: (references=0) #12:323-12:323
START [Executable.Base]Maina::foo(T) #12:323-12:323
[Executable.Base]Maina::foo: (references=1) #12:323-12:323
arg.T(!!0).a8 = ENTERFUNCTION #12:323-12:323
RETURN arg.T(!!0).a8, $L4(T) #12:323-12:323
$L4: (references=1) #12:323-12:323
EXITFUNCTION #12:323-12:323
$L2: (references=0) #12:323-12:323
END #12:323-12:323IR after Canonicalize (control Canonicalize)
Function Unit #0
$L1: (references=0) #12:323-12:323
START [Executable.Base]Maina::foo(T) #12:323-12:323
[Executable.Base]Maina::foo: (references=1) #12:323-12:323
arg.T(!!0).a8 = ENTERFUNCTION #12:323-12:323
RETURN arg.T(!!0).a8, $L4(T) #12:323-12:323
$L4: (references=1) #12:323-12:323
EXITFUNCTION #12:323-12:323
$L2: (references=0) #12:323-12:323
END #12:323-12:323
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 0) foo [line 12] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 0) foo [line 12] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 0) foo [line 12] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\ir\ir.cpp, Line 7358
this->FunctionUnit->Architecture->CanEnregisterType(type)
in (Function number 0) foo [line 12] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\ir\ir.cpp, Line 8675
functionUnit->Architecture->CanEnregisterType(type)
in (Function number 0) foo [line 12] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 0) foo [line 12] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\types\type.inl, Line 746
this->IsConstant
in (Function number 0) foo [line 12] during Lower
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>IR after Lower (control Lower)
Function Unit #0
$L1: (references=0) #12:323-12:323
START [Executable.Base]Maina::foo(T) #12:323-12:323
[Executable.Base]Maina::foo: (references=1) #12:323-12:323
arg.T(!!0).a8 = ENTERFUNCTION #12:323-12:323
br $L5 #12:323-12:323
$L5: (references=1) #12:323-12:323
ENTERBODY #12:323-12:323
t278(SR0).T(!!0) = ld arg.T(!!0).a8 #12:323-12:323
$t277.T(!!0).a8 = st t278(SR0).T(!!0) #12:323-12:323
br $L4 #12:323-12:323
$L4: (references=1) #12:323-12:323
EXITBODY #12:323-12:323
br $L6 #12:323-12:323
$L6: (references=1) #12:323-12:323
EXITFUNCTION #12:323-12:323
$L2: (references=0) #12:323-12:323
END #12:323-12:323IR after Switch Lower (control SwitchLower)
Function Unit #0
$L1: (references=0) #12:323-12:323
START [Executable.Base]Maina::foo(T) #12:323-12:323
[Executable.Base]Maina::foo: (references=1) #12:323-12:323
arg.T(!!0).a8 = ENTERFUNCTION #12:323-12:323
br $L5 #12:323-12:323
$L5: (references=1) #12:323-12:323
ENTERBODY #12:323-12:323
t278(SR0).T(!!0) = ld arg.T(!!0).a8 #12:323-12:323
$t277.T(!!0).a8 = st t278(SR0).T(!!0) #12:323-12:323
br $L4 #12:323-12:323
$L4: (references=1) #12:323-12:323
EXITBODY #12:323-12:323
br $L6 #12:323-12:323
$L6: (references=1) #12:323-12:323
EXITFUNCTION #12:323-12:323
$L2: (references=0) #12:323-12:323
END #12:323-12:323IR after StackOptimization (control MSILStackify)
Function Unit #0
$L1: (references=0) #12:323-12:323
START [Executable.Base]Maina::foo(T) #12:323-12:323
[Executable.Base]Maina::foo: (references=1) #12:323-12:323
arg.T(!!0).a8 = ENTERFUNCTION #12:323-12:323
br $L5 #12:323-12:323
$L5: (references=1) #12:323-12:323
ENTERBODY #12:323-12:323
t278(SR0).T(!!0) = ld arg.T(!!0).a8 #12:323-12:323
$t277.T(!!0).a8 = st t278(SR0).T(!!0) #12:323-12:323
br $L4 #12:323-12:323
$L4: (references=1) #12:323-12:323
br $L7 #12:323-12:323
$L7: (references=1) #12:323-12:323
EXITBODY #12:323-12:323
br $L6 #12:323-12:323
$L6: (references=1) #12:323-12:323
EXITFUNCTION #12:323-12:323
$L2: (references=0) #12:323-12:323
END #12:323-12:323
Phoenix Assertion Failure: d:\enlistments\sdk_june08\src\phx\metadata\metadata.cpp, Line 10204
Unreached
in (Function number 0) foo [line 12] during Stack Allocation
in (PEModule) Executable.Base.exe
in (Program) <unnamed unit>IR after Stack Allocation (control StackAllocate)
Function Unit #0
$L1: (references=0) #12:323-12:323
START [Executable.Base]Maina::foo(T) #12:323-12:323
[Executable.Base]Maina::foo: (references=1) #12:323-12:323
arg.T(!!0).a8 = ENTERFUNCTION #12:323-12:323
br $L5 #12:323-12:323
$L5: (references=1) #12:323-12:323
ENTERBODY #12:323-12:323
t278(SR0).T(!!0) = ld arg.T(!!0).a8 #12:323-12:323
$t277.T(!!0).a8 = st t278(SR0).T(!!0) #12:323-12:323
br $L4 #12:323-12:323
$L4: (references=1) #12:323-12:323
br $L7 #12:323-12:323
$L7: (references=1) #12:323-12:323
EXITBODY #12:323-12:323
br $L6 #12:323-12:323
$L6: (references=1) #12:323-12:323
EXITFUNCTION #12:323-12:323
$L2: (references=0) #12:323-12:323
END #12:323-12:323IR after Frame Generation (control Frame)
Function Unit #0
$L1: (references=0) #12:323-12:323
START [Executable.Base]Maina::foo(T) #12:323-12:323
[Executable.Base]Maina::foo: (references=1) #12:323-12:323
arg.T(!!0).a8 = ENTERFUNCTION #12:323-12:323
br $L5 #12:323-12:323
$L5: (references=1) #12:323-12:323
ENTERBODY #12:323-12:323
t278(SR0).T(!!0) = ld arg.T(!!0).a8 #12:323-12:323
$t277.T(!!0).a8 = st t278(SR0).T(!!0) #12:323-12:323
br $L4 #12:323-12:323
$L4: (references=1) #12:323-12:323
br $L7 #12:323-12:323
$L7: (references=1) #12:323-12:323
EXITBODY #12:323-12:323
ret $L6(T) #12:323-12:323
$L6: (references=1) #12:323-12:323
EXITFUNCTION #12:323-12:323
$L2: (references=0) #12:323-12:323
END #12:323-12:323IR after Block Layout (control BlockLayout)
Function Unit #0
$L1: (references=0) #12:323-12:323
START [Executable.Base]Maina::foo(T) #12:323-12:323
[Executable.Base]Maina::foo: (references=1) #12:323-12:323
arg.T(!!0).a8 = ENTERFUNCTION #12:323-12:323
br $L5 #12:323-12:323
$L5: (references=1) #12:323-12:323
ENTERBODY #12:323-12:323
t278(SR0).T(!!0) = ld arg.T(!!0).a8 #12:323-12:323
$t277.T(!!0).a8 = st t278(SR0).T(!!0) #12:323-12:323
br $L4 #12:323-12:323
$L4: (references=1) #12:323-12:323
br $L7 #12:323-12:323
$L7: (references=1) #12:323-12:323
EXITBODY #12:323-12:323
ret $L6(T) #12:323-12:323
$L6: (references=1) #12:323-12:323
EXITFUNCTION #12:323-12:323
$L2: (references=0) #12:323-12:323
END #12:323-12:323Andy please help-me.

