/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (pipeline == null) { throw new ObjectDisposedException(@"MethodCompilerBase"); } foreach (IMethodCompilerStage mcs in pipeline) { IDisposable d = mcs as IDisposable; if (null != d) { d.Dispose(); } } pipeline.Clear(); pipeline = null; architecture = null; linker = null; method = null; type = null; instructionSet = null; basicBlocks = null; }
public TestCaseMethodCompiler(IAssemblyLinker linker, IArchitecture architecture, IMetadataModule module, RuntimeType type, RuntimeMethod method) : base(linker, architecture, module, type, method) { // Populate the pipeline this.Pipeline.AddRange(new IMethodCompilerStage[] { new DecodingStage(), new BasicBlockBuilderStage(), new OperandDeterminationStage(), new InstructionLogger(), //new ConstantFoldingStage(), new CILTransformationStage(), //new InstructionLogger(), //InstructionStatisticsStage.Instance, //new DominanceCalculationStage(), //new EnterSSA(), //new ConstantPropagationStage(), //new ConstantFoldingStage(), //new LeaveSSA(), new StackLayoutStage(), new PlatformStubStage(), new InstructionLogger(), //new BlockReductionStage(), new LoopAwareBlockOrderStage(), //new SimpleTraceBlockOrderStage(), //new ReverseBlockOrderStage(), // reverse all the basic blocks and see if it breaks anything //new BasicBlockOrderStage() new CodeGenerationStage(), //new InstructionLogger(), }); }
/// <summary> /// Special resolution for internal calls. /// </summary> /// <param name="method">The internal call method to resolve.</param> /// <returns>The virtualAddress</returns> protected unsafe override long ResolveInternalCall(RuntimeMethod method) { Delegate methodDelegate = null; if (false == this.resolvedInternals.TryGetValue(method, out methodDelegate)) { ITypeSystem ts = RuntimeBase.Instance.TypeLoader; RuntimeMethod internalImpl = ts.GetImplementationForInternalCall(method); if (null != internalImpl) { // Find the .NET counterpart for this method (we're not really compiling or using trampolines just yet.) string typeName = String.Format(@"{0}.{1}, {2}", internalImpl.DeclaringType.Namespace, internalImpl.DeclaringType.Name, internalImpl.Module.Name); Type type = Type.GetType(typeName); MethodInfo mi = type.GetMethod(internalImpl.Name); methodDelegate = BuildDelegateForMethodInfo(mi); this.resolvedInternals.Add(method, methodDelegate); } } if (null == methodDelegate) { throw new NotImplementedException(@"InternalCall implementation not loaded."); } return(Marshal.GetFunctionPointerForDelegate(methodDelegate).ToInt64()); }
/// <summary> /// Creates a symbol name. /// </summary> /// <param name="symbol">The symbol name.</param> /// <returns>A string, which represents the symbol name.</returns> private string CreateSymbolName(RuntimeMethod symbol) { if (symbol == null) { throw new ArgumentNullException("symbol"); } // TODO: If it is a generic method instance, then the symbol name needs to be carefully constructed. ~BMarkham,2/18/09 if (symbol.IsGeneric) { throw new NotImplementedException(); } StringBuilder sb = new StringBuilder(); sb.Append(CreateSymbolName(symbol.DeclaringType)); sb.Append('.'); sb.Append(symbol.Name); sb.Append('('); bool hasEmittedSignaturePart = false; foreach (SigType parameterSignatureType in symbol.Signature.Parameters) { if (hasEmittedSignaturePart) { sb.Append(','); } sb.Append(parameterSignatureType.ToSymbolPart()); // FIXME : This obviously doesn't work! We need to emit class names. hasEmittedSignaturePart = true; } sb.Append(')'); return(sb.ToString()); }
/// <summary> /// Creates the attribute. /// </summary> /// <param name="attributeCtor">The attribute constructor to invoke.</param> /// <param name="args">The arguments to pass to the constructor.</param> /// <returns>The newly constructed attribute.</returns> private static object CreateAttribute(RuntimeMethod attributeCtor, object[] args) { RuntimeType rt = attributeCtor.DeclaringType; Type attributeType = Type.GetType(String.Format("{0}.{1}", rt.Namespace, rt.Name)); return(Activator.CreateInstance(attributeType, args, null)); }
/// <summary> /// Runs a test case. /// </summary> /// <typeparam name="TDelegate">The delegate used to run the test case.</typeparam> /// <param name="ns">The namespace of the test.</param> /// <param name="type">The type, which contains the test.</param> /// <param name="method">The name of the method of the test.</param> /// <param name="parameters">The parameters to pass to the test.</param> /// <returns>The result of the test.</returns> public object Run <TDelegate>(string ns, string type, string method, params object[] parameters) { // Do we need to compile the code? if (this.needCompile == true) { if (module != null) { RuntimeBase.Instance.AssemblyLoader.Unload(module); } this.assembly = this.CompileTestCode <TDelegate>(ns, type, method); Console.WriteLine("Executing MOSA compiler..."); module = RunMosaCompiler(this.assembly); this.needCompile = false; } // Find the test method to execute RuntimeMethod runtimeMethod = FindMethod( ns, type, method ); // Create a delegate for the test method Delegate fn = Marshal.GetDelegateForFunctionPointer( runtimeMethod.Address, typeof(TDelegate) ); // Execute the test method return(fn.DynamicInvoke(parameters)); }
internal object Invoke(RuntimeMethod method, object instance, object[] parameters) { if (parameters == null) { parameters = Array <object> .Empty; } RuntimeInterpreter interpreter = null; lock (interpreters) { if (interpreters.Count > 0) { interpreter = interpreters.Pop(); } } if (interpreter == null) { interpreter = new RuntimeInterpreter(this); } try { return(interpreter.Invoke(method, instance, parameters)); } finally { lock (interpreters) { interpreters.Push(interpreter); } } }
void IJitService.SetupJit(RuntimeMethod method) { // Check preconditions if (null == method) throw new ArgumentNullException(@"method"); Debug.Assert(MethodImplAttributes.IL == (method.ImplAttributes & MethodImplAttributes.IL), @"Non-IL method passed to IJitService.SetupJit"); if (MethodImplAttributes.IL != (method.ImplAttributes & MethodImplAttributes.IL)) throw new ArgumentException(@"Non-IL method passed to IJitService.SetupJit.", @"method"); // Code the appropriate trampoline /* if (method.DeclaringType.IsGeneric) { FIXME: method.DeclaringType is always null right now * the loader doesn't initialize these properly. } */ if (method.IsGeneric) { // Emit a generic call trampoline method.Address = EmitGenericMethodTrampoline(); } else { // A normal call trampoline method.Address = EmitStandardTrampoline(method); } }
void IJitService.SetupJit(RuntimeMethod method) { // Check preconditions if (null == method) { throw new ArgumentNullException(@"method"); } Debug.Assert(MethodImplAttributes.IL == (method.ImplAttributes & MethodImplAttributes.IL), @"Non-IL method passed to IJitService.SetupJit"); if (MethodImplAttributes.IL != (method.ImplAttributes & MethodImplAttributes.IL)) { throw new ArgumentException(@"Non-IL method passed to IJitService.SetupJit.", @"method"); } // Code the appropriate trampoline /* * if (method.DeclaringType.IsGeneric) { * FIXME: method.DeclaringType is always null right now * the loader doesn't initialize these properly. * } */ if (method.IsGeneric) { // Emit a generic call trampoline method.Address = EmitGenericMethodTrampoline(); } else { // A normal call trampoline method.Address = EmitStandardTrampoline(method); } }
private SymbolOperand GetInternalAllocateStringCallTarget(ITypeSystem typeSystem) { RuntimeType runtimeType = typeSystem.GetType(@"Mosa.Internal.Runtime"); RuntimeMethod callTarget = runtimeType.FindMethod(@"AllocateString"); return(SymbolOperand.FromMethod(callTarget)); }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (_pipeline == null) { throw new ObjectDisposedException("MethodCompilerBase"); } foreach (IMethodCompilerStage mcs in _pipeline) { IDisposable d = mcs as IDisposable; if (null != d) { d.Dispose(); } } _pipeline.Clear(); _pipeline = null; _architecture = null; _linker = null; _method = null; _module = null; _type = null; _instructionSet = null; _basicBlocks = null; }
public T Run <T>(TestCompilerSettings settings, string ns, string type, string method, params object[] parameters) { CompileTestCode(settings); // Find the test method to execute RuntimeMethod runtimeMethod = FindMethod( ns, type, method ); Debug.Assert(runtimeMethod != null, runtimeMethod.ToString()); //Debug.Assert(runtimeMethod.Address != null, runtimeMethod.ToString()); //Debug.Assert(runtimeMethod.Address != IntPtr.Zero, runtimeMethod.ToString()); // Get delegate name string delegateName; if (default(T) is System.ValueType) { delegateName = "Mosa.Test.Prebuilt.Delegates+" + DelegateUtility.GetDelegteName(default(T), parameters); } else { delegateName = "Mosa.Test.Prebuilt.Delegates+" + DelegateUtility.GetDelegteName(null, parameters); } // Get the prebuilt delegate type Type delegateType = Prebuilt.GetType(delegateName); Debug.Assert(delegateType != null, delegateName); IntPtr address = linker.GetSymbol(runtimeMethod.ToString()).VirtualAddress; // Create a delegate for the test method Delegate fn = Marshal.GetDelegateForFunctionPointer( address, delegateType ); // Execute the test method object tempResult = fn.DynamicInvoke(parameters); try { if (default(T) is System.ValueType) { return((T)tempResult); } else { return(default(T)); } } catch (InvalidCastException e) { Assert.Fail(@"Failed to convert result {0} of type {1} to type {2}.", tempResult, tempResult.GetType(), typeof(T)); throw e; } }
public override MethodCompilerBase CreateMethodCompiler(RuntimeType type, RuntimeMethod method) { IArchitecture arch = this.Architecture; MethodCompilerBase mc = new TestCaseMethodCompiler(this.Pipeline.Find<IAssemblyLinker>(), this.Architecture, this.Assembly, type, method); arch.ExtendMethodCompilerPipeline(mc.Pipeline); return mc; }
/// <summary> /// Initializes a new instance of the <see cref="MemberOperand"/> class. /// </summary> /// <param name="method">The method to reference.</param> /// <exception cref="System.ArgumentNullException"><paramref name="method"/> is null.</exception> public MemberOperand(RuntimeMethod method) : base(new SigType(CilElementType.I), null, IntPtr.Zero) { if (method == null) throw new ArgumentNullException(@"method"); this.member = method; }
private void CompilePendingMethods() { while (methodQueue.Count > 0) { RuntimeMethod method = methodQueue.Dequeue(); CompileMethod(method); } }
public SimpleJitMethodCompiler(AssemblyCompiler compiler, ICompilationSchedulerStage compilationScheduler, RuntimeType type, RuntimeMethod method, Stream codeStream, ITypeSystem typeSystem) : base(compiler.Pipeline.FindFirst<IAssemblyLinker>(), compiler.Architecture, compilationScheduler, type, method, typeSystem, compiler.Pipeline.FindFirst<ITypeLayout>()) { if (codeStream == null) throw new ArgumentNullException(@"codeStream"); this.codeStream = codeStream; }
public MethodCompiler(IAssemblyLinker linker, IArchitecture architecture, IMetadataModule module, RuntimeType type, RuntimeMethod method, Stream codeStream) : base(linker, architecture, module, type, method) { if (null == codeStream) throw new ArgumentNullException(@"codeStream"); _codeStream = codeStream; }
public override MethodCompilerBase CreateMethodCompiler(RuntimeType type, RuntimeMethod method) { IArchitecture arch = this.Architecture; MethodCompilerBase mc = new TestCaseMethodCompiler(this.Pipeline.Find <IAssemblyLinker>(), this.Architecture, this.Assembly, type, method); arch.ExtendMethodCompilerPipeline(mc.Pipeline); return(mc); }
protected string FormatRuntimeMember(RuntimeMethod method) { if (!showTokenValues.Checked) { return(method.Name); } return("[" + TokenToString(method.Token) + "] " + method.ToString()); }
/// <summary> /// Parses the specified attribute blob and instantiates the attribute. /// </summary> /// <param name="module">The metadata module, which contains the attribute blob.</param> /// <param name="attributeBlob">The attribute blob token.</param> /// <param name="attributeCtor">The constructor of the attribute.</param> /// <returns>The fully instantiated and initialized attribute.</returns> /// <exception cref="System.ArgumentException"><paramref name="attributeBlob"/> is invalid.</exception> /// <exception cref="System.ArgumentNullException"><paramref name="module"/> is null or <paramref name="attributeCtor"/> is null.</exception> public static object Parse(IMetadataModule module, TokenTypes attributeBlob, RuntimeMethod attributeCtor) { // Return value object result; // The blob data byte[] blob = null; // Try to load the blob From the module module.Metadata.Read(attributeBlob, out blob); if (null != blob) { if (0 != blob.Length) { // Create a binary reader for the blob using (BinaryReader reader = new BinaryReader(new MemoryStream(blob), Encoding.UTF8)) { ushort prologue = reader.ReadUInt16(); Debug.Assert(ATTRIBUTE_BLOB_PROLOGUE == prologue, "Attribute prologue doesn't match."); if (prologue != ATTRIBUTE_BLOB_PROLOGUE) { throw new ArgumentException("Invalid custom attribute blob.", "attributeBlob"); } // Fixed argument list of the ctor SigType[] paramSig = attributeCtor.Signature.Parameters; IList <RuntimeParameter> parameters = attributeCtor.Parameters; object[] args = new object[parameters.Count]; for (int idx = 0; idx < parameters.Count; idx++) { args[idx] = ParseFixedArg(module, reader, paramSig[idx]); } // Create the attribute instance result = CreateAttribute(attributeCtor, args); // Are there any named args? ushort numNamed = reader.ReadUInt16(); for (ushort idx = 0; idx < numNamed; idx++) { // FIXME: Process the named arguments Trace.WriteLine("Skipping named argument of an attribute."); } } } else { result = CreateAttribute(attributeCtor, null); } } else { throw new ArgumentException("Invalid attribute blob token.", "attributeBlob"); } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="LinkerMethodCompiler"/> class. /// </summary> /// <param name="compiler">The assembly compiler executing this method compiler.</param> /// <param name="method">The metadata of the method to compile.</param> /// <param name="instructionSet">The instruction set.</param> /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="method"/> or <paramref name="instructionSet"/> is null.</exception> public LinkerMethodCompiler(AssemblyCompiler compiler, RuntimeMethod method, InstructionSet instructionSet) : base(compiler.Pipeline.Find <IAssemblyLinker>(), compiler.Architecture, compiler.Assembly, method.DeclaringType, method) { InstructionSet = instructionSet; this.Pipeline.AddRange(new IMethodCompilerStage[] { new BasicBlockBuilderStage(), new CodeGenerationStage(), }); compiler.Architecture.ExtendMethodCompilerPipeline(this.Pipeline); }
/// <summary> /// Creates a method compiler /// </summary> /// <param name="type">The type.</param> /// <param name="method">The method to compile.</param> /// <returns> /// An instance of a MethodCompilerBase for the given type/method pair. /// </returns> public override MethodCompilerBase CreateMethodCompiler(RuntimeType type, RuntimeMethod method) { MethodCompilerBase mc = new AotMethodCompiler( this, type, method ); this.Architecture.ExtendMethodCompilerPipeline(mc.Pipeline); return mc; }
/// <summary> /// Initializes a new instance of the <see cref="LinkerMethodCompiler"/> class. /// </summary> /// <param name="compiler">The assembly compiler executing this method compiler.</param> /// <param name="method">The metadata of the method to compile.</param> /// <param name="instructionSet">The instruction set.</param> /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="method"/> or <paramref name="instructionSet"/> is null.</exception> public LinkerMethodCompiler(AssemblyCompiler compiler, RuntimeMethod method, InstructionSet instructionSet) : base(compiler.Pipeline.Find<IAssemblyLinker>(), compiler.Architecture, compiler.Assembly, method.DeclaringType, method) { InstructionSet = instructionSet; this.Pipeline.AddRange(new IMethodCompilerStage[] { new BasicBlockBuilderStage(), new CodeGenerationStage(), }); compiler.Architecture.ExtendMethodCompilerPipeline(this.Pipeline); }
/// <summary> /// Initializes a new instance of the <see cref="MemberOperand"/> class. /// </summary> /// <param name="method">The method to reference.</param> /// <exception cref="System.ArgumentNullException"><paramref name="method"/> is null.</exception> public MemberOperand(RuntimeMethod method) : base(new SigType(CilElementType.I), null, IntPtr.Zero) { if (method == null) { throw new ArgumentNullException(@"method"); } this.member = method; }
public object Invoke(IContext context, params object[] args) { try { ContextHolder.CurrentContext.Value = context; return(RuntimeMethod.Invoke(null, args)); } catch (TargetInvocationException e) { throw e.InnerException ?? e; } finally { ContextHolder.CurrentContext.Value = null; } }
/// <summary> /// Calls the specified target. /// </summary> /// <param name="target">The target.</param> public void Call(RuntimeMethod target) { _linker.Link( LinkType.RelativeOffset | LinkType.I4, _compiler.Method, (int)(_codeStream.Position - _codeStreamBasePosition) - 4, (int)(_codeStream.Position - _codeStreamBasePosition), target, IntPtr.Zero ); }
/// <summary> /// Creates a method compiler /// </summary> /// <param name="type">The type.</param> /// <param name="method">The method to compile.</param> /// <returns> /// An instance of a MethodCompilerBase for the given type/method pair. /// </returns> public override IMethodCompiler CreateMethodCompiler(ICompilationSchedulerStage compilationScheduler, RuntimeType type, RuntimeMethod method) { IMethodCompiler mc = new AotMethodCompiler( this, compilationScheduler, type, method ); this.Architecture.ExtendMethodCompilerPipeline(mc.Pipeline); return mc; }
/// <summary> /// Special resolution for internal calls. /// </summary> /// <param name="method">The internal call method to resolve.</param> /// <returns>The virtualAddress </returns> protected virtual long ResolveInternalCall(RuntimeMethod method) { long address = 0; ITypeSystem ts = RuntimeBase.Instance.TypeLoader; RuntimeMethod internalImpl = ts.GetImplementationForInternalCall(method); if (null != internalImpl) { address = internalImpl.Address.ToInt64(); } return(address); }
/// <summary> /// Creates a method compiler /// </summary> /// <param name="type">The type.</param> /// <param name="method">The method to compile.</param> /// <returns> /// An instance of a MethodCompilerBase for the given type/method pair. /// </returns> public override MethodCompilerBase CreateMethodCompiler(RuntimeType type, RuntimeMethod method) { IArchitecture arch = this.Architecture; MethodCompilerBase mc = new AotMethodCompiler( this, type, method ); arch.ExtendMethodCompilerPipeline(mc.Pipeline); return(mc); }
/// <summary> /// Decodes the invocation target. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The IL decoder, which provides decoding functionality.</param> /// <param name="flags">Flags, which control the</param> /// <returns></returns> protected static Token DecodeInvocationTarget(Context ctx, IInstructionDecoder decoder, InvokeSupportFlags flags) { // Retrieve the immediate argument - it contains the token // of the methoddef, methodref, methodspec or callsite to call. Token callTarget = decoder.DecodeTokenType(); if (!IsCallTargetSupported(callTarget.Table, flags)) { throw new InvalidOperationException(@"Invalid IL call target specification."); } RuntimeMethod method = null; ITypeModule module = null; Mosa.Runtime.TypeSystem.Generic.CilGenericType genericType = decoder.Method.DeclaringType as Mosa.Runtime.TypeSystem.Generic.CilGenericType; if (genericType != null) { module = (decoder.Method.DeclaringType as Mosa.Runtime.TypeSystem.Generic.CilGenericType).BaseGenericType.Module; } else { module = decoder.Method.Module; } switch (callTarget.Table) { case TableType.MethodDef: method = module.GetMethod(callTarget); break; case TableType.MemberRef: method = module.GetMethod(callTarget, decoder.Method.DeclaringType); if (method.DeclaringType.IsGeneric) { decoder.Compiler.Scheduler.ScheduleTypeForCompilation(method.DeclaringType); } break; case TableType.MethodSpec: method = module.GetMethod(callTarget); decoder.Compiler.Scheduler.ScheduleTypeForCompilation(method.DeclaringType); break; default: Debug.Assert(false, @"Should never reach this!"); break; } SetInvokeTarget(ctx, decoder.Compiler, method); return(callTarget); }
public void ScheduleMethodForCompilation(RuntimeMethod method) { if (method == null) throw new ArgumentNullException(@"method"); if (method.IsGeneric == false) { Console.WriteLine(@"Scheduling method {1}.{0} for compilation.", method.Name, method.DeclaringType.FullName); Debug.WriteLine(String.Format(@"Scheduling method {1}.{0} for compilation.", method.Name, method.DeclaringType.FullName)); this.methodQueue.Enqueue(method); } }
/// <summary> /// Determines if the given runtime member can be resolved immediately. /// </summary> /// <param name="member">The runtime member to determine resolution of.</param> /// <param name="virtualAddress">Receives the determined virtualAddress of the runtime member.</param> /// <returns> /// The method returns true, when it was successfully resolved. /// </returns> protected bool IsResolved(RuntimeMember member, out long virtualAddress) { // Is this a method? RuntimeMethod method = member as RuntimeMethod; if (null != method && method.ImplAttributes == MethodImplAttributes.InternalCall) { virtualAddress = ResolveInternalCall(method); return(0 != virtualAddress); } return(IsResolved(CreateSymbolName(member), out virtualAddress)); }
/// <summary> /// Initializes a new instance of the <see cref="LinkerMethodCompiler"/> class. /// </summary> /// <param name="compiler">The assembly compiler executing this method compiler.</param> /// <param name="method">The metadata of the method to compile.</param> /// <param name="instructionSet">The instruction set.</param> /// <exception cref="System.ArgumentNullException"><paramref name="compiler"/>, <paramref name="method"/> or <paramref name="instructionSet"/> is null.</exception> public LinkerMethodCompiler(AssemblyCompiler compiler, ICompilationSchedulerStage compilationScheduler, RuntimeMethod method, InstructionSet instructionSet) : base(compiler.Pipeline.FindFirst<IAssemblyLinker>(), compiler.Architecture, compilationScheduler, compiler.Assembly, method.DeclaringType, method) { this.InstructionSet = instructionSet; this.CreateBlock(-1, 0); this.Pipeline.AddRange(new IMethodCompilerStage[] { new SimpleTraceBlockOrderStage(), new PlatformStubStage(), new CodeGenerationStage(), }); compiler.Architecture.ExtendMethodCompilerPipeline(this.Pipeline); }
/// <summary> /// Parses the specified attribute blob and instantiates the attribute. /// </summary> /// <param name="module">The metadata module, which contains the attribute blob.</param> /// <param name="attributeBlob">The attribute blob token.</param> /// <param name="attributeCtor">The constructor of the attribute.</param> /// <returns>The fully instantiated and initialized attribute.</returns> /// <exception cref="System.ArgumentException"><paramref name="attributeBlob"/> is invalid.</exception> /// <exception cref="System.ArgumentNullException"><paramref name="module"/> is null or <paramref name="attributeCtor"/> is null.</exception> public static object Parse(IMetadataModule module, TokenTypes attributeBlob, RuntimeMethod attributeCtor) { // Return value object result; // Try to load the blob from the module byte[] blob = module.Metadata.ReadBlob(attributeBlob); if (null != blob) { if (0 != blob.Length) { // Create a binary reader for the blob using (BinaryReader reader = new BinaryReader(new MemoryStream(blob), Encoding.UTF8)) { ushort prologue = reader.ReadUInt16(); Debug.Assert(ATTRIBUTE_BLOB_PROLOGUE == prologue, @"Attribute prologue doesn't match."); if (prologue != ATTRIBUTE_BLOB_PROLOGUE) throw new ArgumentException(@"Invalid custom attribute blob.", "attributeBlob"); // Fixed argument list of the ctor SigType[] paramSig = attributeCtor.Signature.Parameters; IList<RuntimeParameter> parameters = attributeCtor.Parameters; object[] args = new object[parameters.Count]; for (int idx = 0; idx < parameters.Count; idx++) args[idx] = ParseFixedArg(module, reader, paramSig[idx]); // Create the attribute instance result = CreateAttribute(attributeCtor, args); // Are there any named args? ushort numNamed = reader.ReadUInt16(); for (ushort idx = 0; idx < numNamed; idx++) { // FIXME: Process the named arguments Trace.WriteLine(@"Skipping named argument of an attribute."); } } } else { result = CreateAttribute(attributeCtor, null); } } else { throw new ArgumentException(@"Invalid attribute blob token.", @"attributeBlob"); } return result; }
public void Run() { foreach (FakeEntry entry in fakeEntries) { RuntimeMethod method = this.GenerateMethod(entry.Namespace, entry.TypeName, entry.Method); this.GenerateInstructionSet(); this.Compile(method); } // Special case for Object.Equals, ValueType.Equals :( this.CompileObjectEquals(@"Object"); this.CompileObjectEquals(@"ValueType"); }
/// <summary> /// Determines if the given method is a method /// of a generic class that uses a generic parameter. /// </summary> /// <param name="method">The method to check</param> /// <returns>True if the method relies upon generic parameters</returns> public static bool HasGenericParameters(RuntimeMethod method) { // Check return type if (IsGenericParameter(method.Signature.ReturnType)) return true; // Check parameters foreach (SigType parameter in method.Signature.Parameters) { if (IsGenericParameter(parameter)) return true; } return false; }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> void IAssemblyCompilerStage.Run() { ITypeModule mainTypeModule = typeSystem.MainTypeModule; if (mainTypeModule.MetadataModule.EntryPoint.RID != 0) { RuntimeMethod entrypoint = mainTypeModule.GetMethod(mainTypeModule.MetadataModule.EntryPoint); Schedule(entrypoint); } ctx.AppendInstruction(IR.Instruction.EpilogueInstruction); ctx.Other = 0; method = LinkTimeCodeGenerator.Compile(compiler, @"AssemblyInit", instructionSet, typeSystem); }
/// <summary> /// Creates the ISR methods. /// </summary> private void CreateISRMethods() { // Get RuntimeMethod for the Mosa.Kernel.x86.IDT.InterruptHandler RuntimeType rt = typeSystem.GetType(@"Mosa.Kernel.x86.IDT"); if (rt == null) { return; } RuntimeMethod InterruptMethod = FindMethod(rt, "InterruptHandler"); if (InterruptMethod == null) { return; } SymbolOperand interruptMethod = SymbolOperand.FromMethod(InterruptMethod); SigType I1 = new SigType(CilElementType.I1); SigType I4 = new SigType(CilElementType.I4); RegisterOperand esp = new RegisterOperand(I4, GeneralPurposeRegister.ESP); for (int i = 0; i <= 255; i++) { InstructionSet set = new InstructionSet(100); Context ctx = new Context(set, -1); ctx.AppendInstruction(CPUx86.Instruction.CliInstruction); if (i <= 7 || i >= 16 | i == 9) // For IRQ 8, 10, 11, 12, 13, 14 the cpu automatically pushed the error code { ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I1, 0x0)); } ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I1, (byte)i)); ctx.AppendInstruction(CPUx86.Instruction.PushadInstruction); ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, null, interruptMethod); ctx.AppendInstruction(CPUx86.Instruction.PopadInstruction); ctx.AppendInstruction(CPUx86.Instruction.AddInstruction, esp, new ConstantOperand(I4, 0x08)); ctx.AppendInstruction(CPUx86.Instruction.StiInstruction); ctx.AppendInstruction(CPUx86.Instruction.IRetdInstruction); //LinkerGeneratedMethod method = LinkTimeCodeGenerator.Compile(this.compiler, @"InterruptISR" + i.ToString(), set, typeSystem); } }
protected void ScheduleMethodForCompilation(RuntimeMethod method) { if (method == null) { throw new ArgumentNullException(@"method"); } if (!method.IsGeneric) { Console.ForegroundColor = ConsoleColor.Blue; Console.Write(@"[Scheduling] "); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine("{1}.{0}", method.Name, method.DeclaringType.FullName); Debug.WriteLine(String.Format(@"Scheduling {1}.{0}", method.Name, method.DeclaringType.FullName)); methodQueue.Enqueue(method); } }
public object Invoke(RuntimeMethod method, object instance, object[] parameters) { try { var env = environment; var mObjects = stack.ManagedObjects; var esp = stack.StackBase; //push this if (method.HasThis) { StackObject.PushObject(esp, mObjects, instance); esp++; } //check parameters count if (method.ParametersCount != parameters.Length) { throw new ILInvokeException("invoke method {0} parameters count mismatch expected={1} actual={2}", method.Name, method.ParametersCount, parameters.Length); } //push parameters foreach (var parameter in parameters) { StackObject.PushObject(esp, mObjects, parameter); esp++; } bool unhandledException; esp = Execute(method, esp, out unhandledException); if (method.ReturnType == env.Void) { return(null); } return(StackObject.ToObject(esp, env, mObjects)); } finally { stack.Clear(); } }
/// <summary> /// Determines if the given method is a method /// of a generic class that uses a generic parameter. /// </summary> /// <param name="method">The method to check</param> /// <returns>True if the method relies upon generic parameters</returns> public static bool HasGenericParameters(RuntimeMethod method) { // Check return type if (IsGenericParameter(method.Signature.ReturnType)) { return(true); } // Check parameters foreach (SigType parameter in method.Signature.Parameters) { if (IsGenericParameter(parameter)) { return(true); } } return(false); }
/// <summary> /// Initializes a new instance of the <see cref="AotMethodCompiler"/> class. /// </summary> public AotMethodCompiler(AssemblyCompiler compiler, ICompilationSchedulerStage compilationScheduler, RuntimeType type, RuntimeMethod method) : base(compiler.Pipeline.FindFirst<IAssemblyLinker>(), compiler.Architecture, compilationScheduler, type, method, compiler.TypeSystem, compiler.Pipeline.FindFirst<ITypeLayout>()) { this.assemblyCompiler = compiler; this.Pipeline.AddRange( new IMethodCompilerStage[] { new DecodingStage(), //InstructionLogger.Instance, new BasicBlockBuilderStage(), //InstructionLogger.Instance, new OperandDeterminationStage(), InstructionLogger.Instance, StaticAllocationResolutionStageWrapper.Instance, //InstructionLogger.Instance, new CILTransformationStage(), InstructionLogger.Instance, //InstructionStatisticsStage.Instance, //new DominanceCalculationStage(), //InstructionLogger.Instance, //new EnterSSA(), //InstructionLogger.Instance, //new ConstantPropagationStage(), //InstructionLogger.Instance, //new ConstantFoldingStage(), //new StrengthReductionStage(), //InstructionLogger.Instance, //new LeaveSSA(), //InstructionLogger.Instance, new StackLayoutStage(), //InstructionLogger.Instance, new PlatformStubStage(), InstructionLogger.Instance, //new BlockReductionStage(), new LoopAwareBlockOrderStage(), //InstructionLogger.Instance, //new SimpleTraceBlockOrderStage(), //new ReverseBlockOrderStage(), //new LocalCSE(), new CodeGenerationStage(), }); }
/// <summary> /// Initializes a new instance of the <see cref="BaseMethodCompiler"/> class. /// </summary> /// <param name="linker">The _linker.</param> /// <param name="architecture">The target compilation Architecture.</param> /// <param name="type">The type, which owns the method to compile.</param> /// <param name="method">The method to compile by this instance.</param> protected BaseMethodCompiler( IAssemblyLinker linker, IArchitecture architecture, ICompilationSchedulerStage compilationScheduler, RuntimeType type, RuntimeMethod method, ITypeSystem typeSystem, ITypeLayout typeLayout) { if (architecture == null) { throw new ArgumentNullException(@"architecture"); } if (linker == null) { throw new ArgumentNullException(@"linker"); } if (compilationScheduler == null) { throw new ArgumentNullException(@"compilationScheduler"); } this.linker = linker; this.architecture = architecture; this.method = method; this.type = type; parameters = new List <Operand>(new Operand[method.Parameters.Count]); nextStackSlot = 0; basicBlocks = new List <BasicBlock>(); instructionSet = null; // this will be set later pipeline = new CompilerPipeline(); this.compilationScheduler = compilationScheduler; this.moduleTypeSystem = method.Module; this.typeSystem = typeSystem; this.typeLayout = typeLayout; }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> /// <param name="compiler">The compiler context to perform processing in.</param> public void Run(AssemblyCompiler compiler) { CheckImplementation(); // Set the default entry point in the linker, if no previous stage has replaced it. RuntimeMethod entryPoint = compiler.Assembly.EntryPoint; if (this.implementation.EntryPoint == null && entryPoint != null) { this.implementation.EntryPoint = GetSymbol(entryPoint); } // Run the real linker IAssemblyCompilerStage acs = this.implementation as IAssemblyCompilerStage; Debug.Assert(acs != null, @"Linker doesn't implement IAssemblyCompilerStage."); if (acs != null) { acs.Run(compiler); } }
/// <summary> /// Issues a linker request for the given runtime method. /// </summary> /// <param name="linkType">The type of link required.</param> /// <param name="method">The method the patched code belongs to.</param> /// <param name="methodOffset">The offset inside the method where the patch is placed.</param> /// <param name="methodRelativeBase">The base virtualAddress, if a relative link is required.</param> /// <param name="target">The method or static field to link against.</param> /// <param name="offset">An offset to apply to the link target.</param> public virtual long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, RuntimeMember target, IntPtr offset) { Debug.Assert(IsValid(target), "Invalid RuntimeMember passed to IAssemblyLinker.Link"); if (!IsValid(target)) { throw new ArgumentException("RuntimeMember is not a static field or method.", "member"); } long address; if (!IsResolved(target, out address)) { address = Link(linkType, method, methodOffset, methodRelativeBase, CreateSymbolName(target), offset); } else { address += offset.ToInt64(); } return(address); }
/// <summary> /// Initializes a new instance of the <see cref="AotMethodCompiler"/> class. /// </summary> /// <param name="compiler">The AOT assembly compiler.</param> /// <param name="type">The type.</param> /// <param name="method">The method.</param> public AotMethodCompiler(AotCompiler compiler, RuntimeType type, RuntimeMethod method) : base(compiler.Pipeline.Find<IAssemblyLinker>(), compiler.Architecture, compiler.Assembly, type, method) { aotCompiler = compiler; Pipeline.AddRange(new IMethodCompilerStage[] { new DecodingStage(), new InstructionLogger(typeof(DecodingStage)), new BasicBlockBuilderStage(), new InstructionLogger(typeof(BasicBlockBuilderStage)), new OperandDeterminationStage(), new InstructionLogger(typeof(OperandDeterminationStage)), new CILTransformationStage(), new InstructionLogger(typeof(CILTransformationStage)), //InstructionStatisticsStage.Instance, new DominanceCalculationStage(), new InstructionLogger(typeof(DominanceCalculationStage)), //new EnterSSA(), //new InstructionLogger(typeof(EnterSSA)), //new ConstantPropagationStage(), //InstructionLogger.Instance, //new ConstantFoldingStage(), //new StrengthReductionStage(), //InstructionLogger.Instance, //new LeaveSSA(), //InstructionLogger.Instance, //InstructionLogger.Instance, new StackLayoutStage(), new InstructionLogger(typeof(StackLayoutStage)), //InstructionLogger.Instance, //new BlockReductionStage(), new LoopAwareBlockOrderStage(), new InstructionLogger(typeof(LoopAwareBlockOrderStage)), //new SimpleTraceBlockOrderStage(), //new ReverseBlockOrderStage(), // InstructionStatisticsStage.Instance, //new LocalCSE(), new CodeGenerationStage(), }); }
public TestCaseMethodCompiler(TestCaseAssemblyCompiler compiler, IArchitecture architecture, ICompilationSchedulerStage compilationScheduler, RuntimeType type, RuntimeMethod method) : base(compiler.Pipeline.FindFirst<IAssemblyLinker>(), architecture, compilationScheduler, type, method, compiler.TypeSystem, compiler.Pipeline.FindFirst<ITypeLayout>()) { this.assemblyCompiler = compiler; // Populate the pipeline this.Pipeline.AddRange(new IMethodCompilerStage[] { new DecodingStage(), //new InstructionLogger(), new BasicBlockBuilderStage(), //new InstructionLogger(), new OperandDeterminationStage(), //new InstructionLogger(), new StaticAllocationResolutionStage(), //new InstructionLogger(), //new ConstantFoldingStage(), new CILTransformationStage(), //new InstructionLogger(), new CILLeakGuardStage() { MustThrowCompilationException = true }, //new InstructionLogger(), //InstructionStatisticsStage.Instance, //new DominanceCalculationStage(), //new EnterSSA(), //new ConstantPropagationStage(), //new ConstantFoldingStage(), //new LeaveSSA(), new StackLayoutStage(), new PlatformStubStage(), //new InstructionLogger(), //new BlockReductionStage(), new LoopAwareBlockOrderStage(), //new SimpleTraceBlockOrderStage(), //new ReverseBlockOrderStage(), // reverse all the basic blocks and see if it breaks anything //new BasicBlockOrderStage() new CodeGenerationStage(), //new InstructionLogger(), }); }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="target">The target.</param> public void AppendInstruction(IInstruction instruction, RuntimeMethod target) { AppendInstruction(instruction); InvokeTarget = target; }
/// <summary> /// Sets the instruction. /// </summary> /// <param name="instruction">The instruction.</param> /// <param name="target">The target.</param> public void SetInstruction(IInstruction instruction, RuntimeMethod target) { SetInstruction(instruction); InvokeTarget = target; }
public void AddMethod(RuntimeMethod method) { this.methods.Add(method); }
/// <summary> /// Creates the attribute. /// </summary> /// <param name="attributeCtor">The attribute constructor to invoke.</param> /// <param name="args">The arguments to pass to the constructor.</param> /// <returns>The newly constructed attribute.</returns> private static object CreateAttribute(RuntimeMethod attributeCtor, object[] args) { RuntimeType rt = attributeCtor.DeclaringType; Type attributeType = Type.GetType(String.Format("{0}.{1}", rt.Namespace, rt.Name)); return Activator.CreateInstance(attributeType, args, null); }
/// <summary> /// Issues a linker request for the given runtime method. /// </summary> /// <param name="method">The method the patched code belongs to.</param> /// <param name="methodOffset">The offset inside the method where the patch is placed.</param> /// <param name="linkType">The type of link required.</param> /// <param name="methodRelativeBase">The base address, if a relative link is required.</param> /// <param name="target">The method or static field to link against.</param> /// <returns> /// The return value is the preliminary address to place in the generated machine /// code. On 32-bit systems, only the lower 32 bits are valid. The above are not used. An implementation of /// IAssemblyLinker may not rely on 64-bits being stored in the memory defined by position. /// </returns> public virtual long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, RuntimeMember target) { return 0; }
/// <summary> /// Issues a linker request for the given runtime method. /// </summary> /// <param name="linkType">The type of link required.</param> /// <param name="method">The method the patched code belongs to.</param> /// <param name="methodOffset">The offset inside the method where the patch is placed.</param> /// <param name="methodRelativeBase">The base address, if a relative link is required.</param> /// <param name="symbol">The linker symbol to link against.</param> /// <returns> /// The return value is the preliminary address to place in the generated machine /// code. On 32-bit systems, only the lower 32 bits are valid. The above are not used. An implementation of /// IAssemblyLinker may not rely on 64-bits being stored in the memory defined by position. /// </returns> public virtual long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, string symbol) { return 0; }
/// <summary> /// Schedules the specified method for invocation in the main. /// </summary> /// <param name="method">The method.</param> public void Schedule(RuntimeMethod method) { _ctx.AppendInstruction(IR.Instruction.CallInstruction, method); }
/// <summary> /// Creates a method compiler /// </summary> /// <param name="type">The type.</param> /// <param name="method">The method to compile.</param> /// <returns>An instance of a MethodCompilerBase for the given type/method pair.</returns> public abstract MethodCompilerBase CreateMethodCompiler(ICompilationSchedulerStage schedulerStage, RuntimeType type, RuntimeMethod method);
private void Compile(RuntimeMethod method) { LinkerMethodCompiler methodCompiler = new LinkerMethodCompiler(this.compiler, this.compiler.Pipeline.FindFirst<ICompilationSchedulerStage>(), method, this.InstructionSet); methodCompiler.Compile(); }
/// <summary> /// Locates the attribute ctor method. /// </summary> private void LocateAttributeCtorMethod() { _ctorMethod = RuntimeBase.Instance.TypeLoader.GetMethod(DefaultSignatureContext.Instance, _module, _ctor); Debug.Assert(null != _ctorMethod); }
/// <summary> /// Issues a linker request for the given runtime method. /// </summary> /// <param name="linkType">The type of link required.</param> /// <param name="method">The method the patched code belongs to.</param> /// <param name="methodOffset">The offset inside the method where the patch is placed.</param> /// <param name="methodRelativeBase">The base virtualAddress, if a relative link is required.</param> /// <param name="target">The method or static field to link against.</param> /// <param name="offset">An offset to apply to the link target.</param> /// <returns></returns> public override long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, RuntimeMember target, IntPtr offset) { return base.Link(linkType, method, methodOffset, methodRelativeBase, target, offset); }
/// <summary> /// Issues a linker request for the given runtime method. /// </summary> /// <param name="linkType">The type of link required.</param> /// <param name="method">The method the patched code belongs to.</param> /// <param name="methodOffset">The offset inside the method where the patch is placed.</param> /// <param name="methodRelativeBase">The base virtualAddress, if a relative link is required.</param> /// <param name="targetSymbolName">The linker symbol to link against.</param> /// <param name="offset">The offset to apply to the symbol to link against.</param> /// <returns> /// The return value is the preliminary virtualAddress to place in the generated machine /// code. On 32-bit systems, only the lower 32 bits are valid. The above are not used. An implementation of /// IAssemblyLinker may not rely on 64-bits being stored in the memory defined by position. /// </returns> public virtual long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, string targetSymbolName, IntPtr offset) { Debug.Assert(null != targetSymbolName, @"Symbol can't be null."); if (null == targetSymbolName) throw new ArgumentNullException(@"symbol"); string symbolName = method.ToString(); return this.Link(linkType, symbolName, methodOffset, methodRelativeBase, targetSymbolName, offset); }
/// <summary> /// Issues a linker request for the given runtime method. /// </summary> /// <param name="linkType">The type of link required.</param> /// <param name="method">The method the patched code belongs to.</param> /// <param name="methodOffset">The offset inside the method where the patch is placed.</param> /// <param name="methodRelativeBase">The base virtualAddress, if a relative link is required.</param> /// <param name="symbol">The linker symbol to link against.</param> /// <param name="offset">The offset.</param> /// <returns> /// The return value is the preliminary virtualAddress to place in the generated machine /// code. On 32-bit systems, only the lower 32 bits are valid. The above are not used. An implementation of /// IAssemblyLinker may not rely on 64-bits being stored in the memory defined by position. /// </returns> public long Link(LinkType linkType, RuntimeMethod method, int methodOffset, int methodRelativeBase, string symbol, IntPtr offset) { CheckImplementation(); return this.implementation.Link(linkType, method, methodOffset, methodRelativeBase, symbol, offset); }