public static void Compile(CompilerOptions compilerOptions, List<FileInfo> inputFiles, CompilerTrace compilerTrace) { var moduleLoader = new MosaModuleLoader(); moduleLoader.AddPrivatePath(GetInputFileNames(inputFiles)); foreach (string file in GetInputFileNames(inputFiles)) { moduleLoader.LoadModuleFromFile(file); } var typeSystem = TypeSystem.Load(moduleLoader.CreateMetadata()); MosaTypeLayout typeLayout = new MosaTypeLayout(typeSystem, compilerOptions.Architecture.NativePointerSize, compilerOptions.Architecture.NativeAlignment); AotCompiler aot = new AotCompiler(compilerOptions.Architecture, typeSystem, typeLayout, compilerTrace, compilerOptions); var bootStage = compilerOptions.BootStageFactory != null ? compilerOptions.BootStageFactory() : null; aot.Pipeline.Add(new ICompilerStage[] { bootStage, compilerOptions.MethodPipelineExportDirectory != null ? new MethodPipelineExportStage(): null, new PlugStage(), new MethodCompilerSchedulerStage(), new TypeInitializerSchedulerStage(), bootStage, new MethodLookupTableStage(), new MethodExceptionLookupTableStage(), new MetadataStage(), new LinkerFinalizationStage(), compilerOptions.MapFile != null ? new MapFileGenerationStage() : null }); aot.Run(); }
/// <summary> /// Calculates the stack size for parameters. /// </summary> /// <param name="typeLayout">The type layouts.</param> /// <param name="operands">The operands.</param> /// <param name="method">The method.</param> /// <returns></returns> protected static int CalculateStackSizeForParameters(MosaTypeLayout typeLayout, BaseArchitecture architecture, List<Operand> operands, MosaMethod method) { Debug.Assert((method.Signature.Parameters.Count + (method.HasThis ? 1 : 0) == operands.Count) || (method.DeclaringType.IsDelegate && method.Signature.Parameters.Count == operands.Count), method.FullName); int offset = method.Signature.Parameters.Count - operands.Count; int result = 0; for (int index = operands.Count - 1; index >= 0; index--) { Operand operand = operands[index]; int size, alignment; architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment); var param = (index + offset >= 0) ? method.Signature.Parameters[index + offset] : null; if (param != null && operand.IsR8 && param.ParameterType.IsR4) { // adjust for parameter size on stack when method parameter is R4 while the calling variable is R8 architecture.GetTypeRequirements(typeLayout, param.ParameterType, out size, out alignment); } result = (int)Alignment.AlignUp(result, (uint)alignment) + size; } return result; }
/// <summary> /// Compiles the specified type system. /// </summary> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="compilerTrace">The compiler trace.</param> /// <param name="compilerOptions">The compiler options.</param> /// <param name="architecture">The architecture.</param> /// <param name="simAdapter">The sim adapter.</param> /// <param name="linker">The linker.</param> /// <returns></returns> public static SimCompiler Compile(TypeSystem typeSystem, MosaTypeLayout typeLayout, CompilerTrace compilerTrace, CompilerOptions compilerOptions, BaseArchitecture architecture, ISimAdapter simAdapter, BaseLinker linker) { var compiler = new SimCompiler(architecture, typeSystem, typeLayout, linker, compilerOptions, compilerTrace, simAdapter); compiler.Compile(); return compiler; }
public override void GetStackRequirements(MosaTypeLayout typeLayout, Operand stackOperand, out int size, out int alignment) { // Special treatment for some stack types // FIXME: Handle the size and alignment requirements of value types architecture.GetTypeRequirements(typeLayout, stackOperand.Type, out size, out alignment); if (size < alignment) size = alignment; }
/// <summary> /// Compiles the specified type system. /// </summary> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="internalTrace">The internal trace.</param> /// <param name="enabledSSA">if set to <c>true</c> [enabled ssa].</param> /// <param name="architecture">The architecture.</param> /// <param name="simAdapter">The sim adapter.</param> /// <param name="linker">The linker.</param> /// <returns></returns> public static SimCompiler Compile(TypeSystem typeSystem, MosaTypeLayout typeLayout, IInternalTrace internalTrace, bool enabledSSA, BaseArchitecture architecture, ISimAdapter simAdapter, ILinker linker) { CompilerOptions compilerOptions = new CompilerOptions(); compilerOptions.EnableSSA = enabledSSA; compilerOptions.EnableSSAOptimizations = enabledSSA; SimCompiler compiler = new SimCompiler(architecture, typeSystem, typeLayout, linker, compilerOptions, internalTrace, simAdapter); compiler.Compile(); return compiler; }
/// <summary> /// Compiles the specified type system. /// </summary> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="compilerTrace">The compiler trace.</param> /// <param name="platform">The platform.</param> /// <param name="enabledSSA">if set to <c>true</c> [enabled ssa].</param> /// <param name="enableOptimizations">if set to <c>true</c> [enable ssa optimizations].</param> /// <param name="emitBinary">if set to <c>true</c> [emit binary].</param> public static void Compile(TypeSystem typeSystem, MosaTypeLayout typeLayout, CompilerTrace compilerTrace, string platform, CompilerOptions compilerOptions, bool emitBinary) { BaseArchitecture architecture; switch (platform.ToLower()) { case "x86": architecture = Mosa.Platform.x86.Architecture.CreateArchitecture(Mosa.Platform.x86.ArchitectureFeatureFlags.AutoDetect); break; case "armv6": architecture = Mosa.Platform.ARMv6.Architecture.CreateArchitecture(Mosa.Platform.ARMv6.ArchitectureFeatureFlags.AutoDetect); break; //case "avr32": architecture = Mosa.Platform.AVR32.Architecture.CreateArchitecture(Mosa.Platform.AVR32.ArchitectureFeatureFlags.AutoDetect); break; default: architecture = Mosa.Platform.x86.Architecture.CreateArchitecture(Mosa.Platform.x86.ArchitectureFeatureFlags.AutoDetect); break; } var compiler = new ExplorerCompiler(architecture, typeSystem, typeLayout, compilerTrace, compilerOptions, emitBinary); compiler.Compile(); }
/// <summary> /// Prevents a default instance of the <see cref="ExplorerCompiler" /> class from being created. /// </summary> /// <param name="architecture">The compiler target architecture.</param> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="compilerTrace">The internal trace.</param> /// <param name="compilerOptions">The compiler options.</param> public ExplorerCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, CompilerTrace compilerTrace, CompilerOptions compilerOptions, bool emitBinary) : base(architecture, typeSystem, typeLayout, new CompilationScheduler(typeSystem, true), compilerTrace, new ExplorerLinker(), compilerOptions) { this.emitBinary = emitBinary; // Build the assembly compiler pipeline Pipeline.Add(new ICompilerStage[] { new PlugStage(), new MethodCompilerSchedulerStage(), new TypeInitializerSchedulerStage(), new MethodLookupTableStage(), new MethodExceptionLookupTableStage(), new MetadataStage(), }); architecture.ExtendCompilerPipeline(Pipeline); }
/// <summary> /// Prevents a default instance of the <see cref="SimCompiler" /> class from being created. /// </summary> /// <param name="architecture">The compiler target architecture.</param> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="linker">The linker.</param> /// <param name="compilerOptions">The compiler options.</param> /// <param name="internalTrace">The internal trace.</param> /// <param name="simAdapter">The sim adapter.</param> public SimCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, ILinker linker, CompilerOptions compilerOptions, IInternalTrace internalTrace, ISimAdapter simAdapter) : base(architecture, typeSystem, typeLayout, new CompilationScheduler(typeSystem, true), internalTrace, linker, compilerOptions) { this.simAdapter = simAdapter; // Build the assembly compiler pipeline Pipeline.Add(new ICompilerStage[] { new PlugStage(), new MethodCompilerSchedulerStage(), new TypeInitializerSchedulerStage(), new SimPowerUpStage(), new TypeLayoutStage(), new MetadataStage(), new LinkerFinalizationStage(), }); architecture.ExtendCompilerPipeline(Pipeline); }
/// <summary> /// Initializes a new compiler instance. /// </summary> /// <param name="architecture">The compiler target architecture.</param> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="compilationScheduler">The compilation scheduler.</param> /// <param name="compilerTrace">The compiler trace.</param> /// <param name="linker">The linker.</param> /// <param name="compilerOptions">The compiler options.</param> /// <exception cref="System.ArgumentNullException">@Architecture</exception> protected BaseCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, ICompilationScheduler compilationScheduler, CompilerTrace compilerTrace, BaseLinker linker, CompilerOptions compilerOptions) { if (architecture == null) throw new ArgumentNullException(@"Architecture"); Pipeline = new CompilerPipeline(); Architecture = architecture; TypeSystem = typeSystem; TypeLayout = typeLayout; CompilerTrace = compilerTrace; CompilerOptions = compilerOptions; Counters = new Counters(); CompilationScheduler = compilationScheduler; PlugSystem = new PlugSystem(); Linker = linker; if (Linker == null) { Linker = compilerOptions.LinkerFactory(); Linker.Initialize(compilerOptions.BaseAddress, architecture.Endianness, architecture.ElfMachineType); } // Create new dictionary IntrinsicTypes = new Dictionary<string, Type>(); // Get all the classes that implement the IIntrinsicInternalMethod interface IEnumerable<Type> types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => typeof(IIntrinsicInternalMethod).IsAssignableFrom(p) && p.IsClass); // Iterate through all the found types foreach (var t in types) { // Now get all the ReplacementTarget attributes var attributes = (ReplacementTargetAttribute[])t.GetCustomAttributes(typeof(ReplacementTargetAttribute), true); for (int i = 0; i < attributes.Length; i++) { // Finally add the dictionary entry mapping the target string and the type IntrinsicTypes.Add(attributes[i].Target, t); } } PlatformInternalRuntimeType = GetPlatformInternalRuntimeType(); }
public static void Compile(CompilerOptions compilerOptions, List<FileInfo> inputFiles) { var moduleLoader = new MosaModuleLoader(); moduleLoader.AddPrivatePath(GetInputFileNames(inputFiles)); foreach (string file in GetInputFileNames(inputFiles)) { moduleLoader.LoadModuleFromFile(file); } var typeSystem = TypeSystem.Load(moduleLoader.CreateMetadata()); MosaTypeLayout typeLayout = new MosaTypeLayout(typeSystem, compilerOptions.Architecture.NativePointerSize, compilerOptions.Architecture.NativeAlignment); ConfigurableTraceFilter filter = new ConfigurableTraceFilter(); filter.MethodMatch = MatchType.None; filter.Method = string.Empty; filter.StageMatch = MatchType.Any; filter.TypeMatch = MatchType.Any; filter.ExcludeInternalMethods = false; IInternalTrace internalTrace = new BasicInternalTrace(); internalTrace.TraceFilter = filter; AotCompiler aot = new AotCompiler(compilerOptions.Architecture, typeSystem, typeLayout, internalTrace, compilerOptions); var bootStage = compilerOptions.BootStageFactory != null ? compilerOptions.BootStageFactory() : null; aot.Pipeline.Add(new ICompilerStage[] { bootStage, compilerOptions.MethodPipelineExportDirectory != null ? new MethodPipelineExportStage(): null, new PlugStage(), new MethodCompilerSchedulerStage(), new TypeInitializerSchedulerStage(), bootStage, new TypeLayoutStage(), new MetadataStage(), new ObjectFileLayoutStage(), new LinkerFinalizationStage(), compilerOptions.MapFile != null ? new MapFileGenerationStage() : null }); aot.Run(); }
/// <summary> /// Compiles the specified type system. /// </summary> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="internalTrace">The internal trace.</param> /// <param name="platform">The platform.</param> /// <param name="enabledSSA">if set to <c>true</c> [enabled ssa].</param> /// <param name="emitBinary">if set to <c>true</c> [emit binary].</param> public static void Compile(TypeSystem typeSystem, MosaTypeLayout typeLayout, IInternalTrace internalTrace, string platform, bool enabledSSA, bool emitBinary) { BaseArchitecture architecture; switch (platform.ToLower()) { case "x86": architecture = Mosa.Platform.x86.Architecture.CreateArchitecture(Mosa.Platform.x86.ArchitectureFeatureFlags.AutoDetect); break; case "armv6": architecture = Mosa.Platform.ARMv6.Architecture.CreateArchitecture(Mosa.Platform.ARMv6.ArchitectureFeatureFlags.AutoDetect); break; //case "avr32": architecture = Mosa.Platform.AVR32.Architecture.CreateArchitecture(Mosa.Platform.AVR32.ArchitectureFeatureFlags.AutoDetect); break; default: architecture = Mosa.Platform.x86.Architecture.CreateArchitecture(Mosa.Platform.x86.ArchitectureFeatureFlags.AutoDetect); break; } CompilerOptions compilerOptions = new CompilerOptions(); compilerOptions.EnableSSA = enabledSSA; compilerOptions.EnableSSAOptimizations = enabledSSA && enabledSSA; ExplorerCompiler compiler = new ExplorerCompiler(architecture, typeSystem, typeLayout, internalTrace, compilerOptions, emitBinary); compiler.Compile(); }
/// <summary> /// Initializes a new compiler instance. /// </summary> /// <param name="architecture">The compiler target architecture.</param> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="compilationScheduler">The compilation scheduler.</param> /// <param name="internalTrace">The internal trace.</param> /// <param name="compilerOptions">The compiler options.</param> protected BaseCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, ICompilationScheduler compilationScheduler, IInternalTrace internalTrace, ILinker linker, CompilerOptions compilerOptions) { if (architecture == null) throw new ArgumentNullException(@"Architecture"); Pipeline = new CompilerPipeline(); Architecture = architecture; TypeSystem = typeSystem; TypeLayout = typeLayout; InternalTrace = internalTrace; CompilerOptions = compilerOptions; Counters = new Counters(); CompilationScheduler = compilationScheduler; PlugSystem = new PlugSystem(); Linker = linker; if (Linker == null) { Linker = compilerOptions.LinkerFactory(); Linker.Initialize(compilerOptions.OutputFile, architecture.Endianness, architecture.ElfMachineType); } }
/// <summary> /// Gets the type memory requirements. /// </summary> /// <param name="typeLayout">The type layouts.</param> /// <param name="type">The type.</param> /// <param name="size">Receives the memory size of the type.</param> /// <param name="alignment">Receives alignment requirements of the type.</param> public abstract void GetTypeRequirements(MosaTypeLayout typeLayout, MosaType type, out int size, out int alignment);
/// <summary> /// Gets the type memory requirements. /// </summary> /// <param name="typeLayout">The type layouts.</param> /// <param name="type">The type.</param> /// <param name="size">Receives the memory size of the type.</param> /// <param name="alignment">Receives alignment requirements of the type.</param> public override void GetTypeRequirements(MosaTypeLayout typeLayout, MosaType type, out int size, out int alignment) { alignment = type.IsR8 ? 8 : 4; size = type.IsValueType ? typeLayout.GetTypeSize(type) : 4; }
/// <summary> /// Initializes a new instance of the <see cref="AotCompiler" /> class. /// </summary> /// <param name="architecture">The architecture.</param> /// <param name="typeSystem">The type system.</param> /// <param name="typeLayout">The type layout.</param> /// <param name="internalTrace">The internal trace.</param> /// <param name="compilerOptions">The compiler options.</param> public AotCompiler(BaseArchitecture architecture, TypeSystem typeSystem, MosaTypeLayout typeLayout, IInternalTrace internalTrace, CompilerOptions compilerOptions) : base(architecture, typeSystem, typeLayout, new CompilationScheduler(typeSystem, true), internalTrace, null, compilerOptions) { }
protected static int CalculateStackSizeForParameters(MosaTypeLayout typeLayout, BaseArchitecture architecture, List<Operand> operands) { // first operand is the call location int result = 0; foreach (var operand in operands) { int size, alignment; architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment); result = Alignment.AlignUp(result, alignment) + size; } return result; }
/// <summary> /// Requests the calling convention to create an appropriate move instruction to populate the return /// value of a method. /// </summary> /// <param name="typeLayout">The type layouts.</param> /// <param name="context">The context.</param> /// <param name="operand">The operand, that's holding the return value.</param> public abstract void SetReturnValue(MosaTypeLayout typeLayout, Context context, Operand operand);
public static void UpdateTree(TreeView treeView, TypeSystem typeSystem, MosaTypeLayout typeLayout, bool showSizes) { treeView.BeginUpdate(); treeView.Nodes.Clear(); foreach (var module in typeSystem.Modules) { TreeNode moduleNode = new TreeNode(module.Name); treeView.Nodes.Add(moduleNode); foreach (MosaType type in module.Types.Values) { TreeNode typeNode = new TreeNode(type.FullName); moduleNode.Nodes.Add(typeNode); if (type.BaseType != null) { TreeNode baseTypeNode = new TreeNode("Base Type: " + type.BaseType.FullName); typeNode.Nodes.Add(baseTypeNode); } if (type.DeclaringType != null) { TreeNode baseTypeNode = new TreeNode("Enclosing Type: " + type.DeclaringType.FullName); typeNode.Nodes.Add(baseTypeNode); } if (type.Interfaces.Count != 0) { TreeNode interfacesNodes = new TreeNode("Interfaces"); typeNode.Nodes.Add(interfacesNodes); foreach (MosaType interfaceType in type.Interfaces) { TreeNode interfaceNode = new TreeNode(interfaceType.FullName); interfacesNodes.Nodes.Add(interfaceNode); } } if (type.Fields.Count != 0) { TreeNode fieldsNode = new TreeNode("Fields"); if (showSizes) fieldsNode.Text = fieldsNode.Text + " (Count: " + type.Fields.Count.ToString() + " - Size: " + typeLayout.GetTypeSize(type).ToString() + ")"; typeNode.Nodes.Add(fieldsNode); foreach (MosaField field in type.Fields) { TreeNode fieldNode = new TreeNode(field.ShortName); fieldsNode.Nodes.Add(fieldNode); if (field.IsStatic) fieldNode.Text = fieldNode.Text + " [Static]"; if (showSizes) { fieldNode.Text = fieldNode.Text + " (Size: " + typeLayout.GetFieldSize(field).ToString(); if (!field.IsStatic) fieldNode.Text = fieldNode.Text + " - Offset: " + typeLayout.GetFieldOffset(field).ToString(); fieldNode.Text = fieldNode.Text + ")"; } } } if (type.Methods.Count != 0) { TreeNode methodsNode = new TreeNode("Methods"); typeNode.Nodes.Add(methodsNode); foreach (MosaMethod method in type.Methods) { TreeNode methodNode = new ViewNode<MosaMethod>(method, method.ShortName); methodsNode.Nodes.Add(methodNode); if (method.IsStatic) methodNode.Text = methodNode.Text + " [Static]"; if (method.IsAbstract) methodNode.Text = methodNode.Text + " [Abstract]"; if (method.IsNewSlot) methodNode.Text = methodNode.Text + " [NewSlot]"; if (method.IsVirtual) methodNode.Text = methodNode.Text + " [Virtual]"; if (method.IsFinal) methodNode.Text = methodNode.Text + " [Final]"; if (method.IsSpecialName) methodNode.Text = methodNode.Text + " [SpecialName]"; if (method.IsRTSpecialName) methodNode.Text = methodNode.Text + " [RTSpecialName]"; if (method.GenericArguments.Count != 0) { TreeNode genericParameterNodes = new TreeNode("Generic Arguments Types"); methodNode.Nodes.Add(genericParameterNodes); foreach (var genericParameter in method.GenericArguments) { TreeNode GenericParameterNode = new TreeNode(genericParameter.Name); genericParameterNodes.Nodes.Add(GenericParameterNode); } } } } if (typeLayout.GetMethodTable(type) != null) { TreeNode methodTableNode = new TreeNode("Method Table"); typeNode.Nodes.Add(methodTableNode); foreach (MosaMethod method in typeLayout.GetMethodTable(type)) { TreeNode methodNode = new ViewNode<MosaMethod>(method, method.ShortName); methodTableNode.Nodes.Add(methodNode); } } } } treeView.EndUpdate(); }
private static void PatchInvoke(MethodCompiler methodCompiler) { // check if instance is null (if so, it's a static call to the methodPointer) var loadInstruction = methodCompiler.Architecture.Is32BitPlatform ? (BaseInstruction)IRInstruction.Load32 : IRInstruction.Load64; var compareInstruction = methodCompiler.Architecture.Is32BitPlatform ? (BaseInstruction)IRInstruction.Compare32x32 : IRInstruction.Compare64x64; var branchInstruction = methodCompiler.Architecture.Is32BitPlatform ? (BaseInstruction)IRInstruction.Branch32 : IRInstruction.Branch64; var nativeIntegerType = methodCompiler.Architecture.Is32BitPlatform ? methodCompiler.TypeSystem.BuiltIn.U4 : methodCompiler.TypeSystem.BuiltIn.U8; var methodPointerField = GetField(methodCompiler.Method.DeclaringType, "methodPointer"); int methodPointerOffset = methodCompiler.TypeLayout.GetFieldOffset(methodPointerField); var methodPointerOffsetOperand = methodCompiler.CreateConstant(methodPointerOffset); var instanceField = GetField(methodCompiler.Method.DeclaringType, "instance"); int instanceOffset = methodCompiler.TypeLayout.GetFieldOffset(instanceField); var instanceOffsetOperand = methodCompiler.CreateConstant(instanceOffset); var size = methodCompiler.Architecture.NativeInstructionSize; bool withReturn = (methodCompiler.Method.Signature.ReturnType == null) ? false : !methodCompiler.Method.Signature.ReturnType.IsVoid; var b0 = new Context(CreateMethodStructure(methodCompiler)); var b1 = new Context(methodCompiler.BasicBlocks.CreateBlock()); var b2 = new Context(methodCompiler.BasicBlocks.CreateBlock()); var b3 = new Context(methodCompiler.BasicBlocks.CreateBlock()); var vrs = new Operand[methodCompiler.Parameters.Length]; for (int i = 0; i < methodCompiler.Parameters.Length; i++) { var type = methodCompiler.Parameters[i].Type; if (!MosaTypeLayout.CanFitInRegister(type)) { b0.AppendInstruction(IRInstruction.LoadParamCompound, vrs[i], methodCompiler.Parameters[i]); b0.MosaType = type; } else { vrs[i] = methodCompiler.VirtualRegisters.Allocate(methodCompiler.Parameters[i].Type); var paramLoadInstruction = BaseMethodCompilerStage.GetLoadParameterInstruction(vrs[i].Type, methodCompiler.Architecture.Is32BitPlatform); b0.AppendInstruction(paramLoadInstruction, vrs[i], methodCompiler.Parameters[i]); b0.MosaType = type; } } var thisOperand = vrs[0]; var opMethod = methodCompiler.VirtualRegisters.Allocate(nativeIntegerType); var opInstance = methodCompiler.VirtualRegisters.Allocate(thisOperand.Type); var opCompare = methodCompiler.VirtualRegisters.Allocate(nativeIntegerType); var opReturn = withReturn ? methodCompiler.AllocateVirtualRegisterOrStackSlot(methodCompiler.Method.Signature.ReturnType) : null; b0.AppendInstruction(loadInstruction, opMethod, thisOperand, methodPointerOffsetOperand); b0.AppendInstruction(loadInstruction, opInstance, thisOperand, instanceOffsetOperand); b0.AppendInstruction(compareInstruction, ConditionCode.Equal, opCompare, opInstance, methodCompiler.ConstantZero); b0.AppendInstruction(branchInstruction, ConditionCode.Equal, null, opCompare, methodCompiler.ConstantZero, b2.Block); //b0.AddBranchTarget(b2.Block); b0.AppendInstruction(IRInstruction.Jmp, b1.Block); var operands = new List <Operand>(methodCompiler.Parameters.Length + 1); for (int i = 1; i < methodCompiler.Parameters.Length; i++) { operands.Add(vrs[i]); } var result = withReturn ? opReturn : null; // no instance b1.AppendInstruction(IRInstruction.CallDynamic, result, opMethod, operands); b1.InvokeMethod = methodCompiler.Method; b1.AppendInstruction(IRInstruction.Jmp, b3.Block); // instance b2.AppendInstruction(IRInstruction.CallDynamic, result, opMethod, opInstance, operands); b2.InvokeMethod = methodCompiler.Method; b2.AppendInstruction(IRInstruction.Jmp, b3.Block); // return if (opReturn != null) { var setReturn = BaseMethodCompilerStage.GetSetReturnInstruction(opReturn.Type, methodCompiler.Architecture.Is32BitPlatform); b3.AppendInstruction(setReturn, null, opReturn); } b3.AppendInstruction(IRInstruction.Jmp, methodCompiler.BasicBlocks.EpilogueBlock); }
/// <summary> /// Calculates the stack size for parameters. /// </summary> /// <param name="typeLayout">The type layouts.</param> /// <param name="operands">The operands.</param> /// <param name="method">The method.</param> /// <returns></returns> protected static int CalculateStackSizeForParameters(MosaTypeLayout typeLayout, BaseArchitecture architecture, List<Operand> operands, MosaMethod method) { Debug.Assert((method.Signature.Parameters.Count + (method.HasThis ? 1 : 0) == operands.Count) || (method.DeclaringType.IsDelegate && method.Signature.Parameters.Count == operands.Count)); int offset = method.Signature.Parameters.Count - operands.Count; int result = 0; for (int index = operands.Count - 1; index >= 0; index--) { Operand operand = operands[index]; int size, alignment; architecture.GetTypeRequirements(typeLayout, operand.Type, out size, out alignment); var param = (index + offset >= 0) ? method.Signature.Parameters[index + offset] : null; if (param != null && operand.IsR8 && param.Type.IsR4) architecture.GetTypeRequirements(typeLayout, param.Type, out size, out alignment); if (size < alignment) size = alignment; result += size; } return result; }
public static void UpdateTree(TreeView treeView, TypeSystem typeSystem, MosaTypeLayout typeLayout, bool showSizes) { treeView.BeginUpdate(); treeView.Nodes.Clear(); foreach (var module in typeSystem.Modules) { List<TreeNode> namespaces = new List<TreeNode>(); TreeNode moduleNode = new TreeNode(module.Name); treeView.Nodes.Add(moduleNode); List<MosaType> typeList = (new List<MosaType>(module.Types.Values)).OrderBy(o => o.FullName).ToList(); foreach (MosaType type in typeList) { TreeNode namespaceNode = null; string @namespace = (string.IsNullOrWhiteSpace(type.Namespace)) ? "[No Namespace]" : type.Namespace; foreach (TreeNode node in namespaces) { if (node.Text.Equals(@namespace)) { namespaceNode = node; break; } } if (namespaceNode == null) { namespaceNode = new TreeNode(@namespace); moduleNode.Nodes.Add(namespaceNode); namespaces.Add(namespaceNode); } TreeNode typeNode = new TreeNode(type.FullName); namespaceNode.Nodes.Add(typeNode); if (type.BaseType != null) { TreeNode baseTypeNode = new TreeNode("Base Type: " + type.BaseType.FullName); typeNode.Nodes.Add(baseTypeNode); } if (type.DeclaringType != null) { TreeNode declaringTypeNode = new TreeNode("Declaring Type: " + type.DeclaringType.FullName); typeNode.Nodes.Add(declaringTypeNode); } if (type.ElementType != null) { TreeNode elementTypeNode = new TreeNode("Element Type: " + type.ElementType.FullName); typeNode.Nodes.Add(elementTypeNode); } if (type.Interfaces.Count != 0) { TreeNode interfacesNodes = new TreeNode("Interfaces"); typeNode.Nodes.Add(interfacesNodes); foreach (MosaType interfaceType in type.Interfaces) { TreeNode interfaceNode = new TreeNode(interfaceType.FullName); interfacesNodes.Nodes.Add(interfaceNode); } } if (type.Fields.Count != 0) { TreeNode fieldsNode = new TreeNode("Fields"); if (showSizes) fieldsNode.Text = fieldsNode.Text + " (Count: " + type.Fields.Count.ToString() + " - Size: " + typeLayout.GetTypeSize(type).ToString() + ")"; typeNode.Nodes.Add(fieldsNode); foreach (MosaField field in type.Fields) { TreeNode fieldNode = new TreeNode(field.ShortName); fieldsNode.Nodes.Add(fieldNode); if (field.IsStatic) fieldNode.Text = fieldNode.Text + " [Static]"; if (showSizes) { fieldNode.Text = fieldNode.Text + " (Size: " + typeLayout.GetFieldSize(field).ToString(); if (!field.IsStatic) fieldNode.Text = fieldNode.Text + " - Offset: " + typeLayout.GetFieldOffset(field).ToString(); fieldNode.Text = fieldNode.Text + ")"; } } } if (type.Properties.Count != 0) { TreeNode propertiesNode = new TreeNode("Properties"); if (showSizes) propertiesNode.Text = propertiesNode.Text + " (Count: " + type.Properties.Count.ToString() + ")"; typeNode.Nodes.Add(propertiesNode); foreach (MosaProperty property in type.Properties) { TreeNode propertyNode = new ViewNode<MosaProperty>(property, property.ShortName); propertiesNode.Nodes.Add(propertyNode); if (property.GetterMethod != null) { TreeNode getterNode = new ViewNode<MosaMethod>(property.GetterMethod, property.GetterMethod.ShortName); propertyNode.Nodes.Add(getterNode); if (property.GetterMethod.IsStatic) getterNode.Text = getterNode.Text + " [Static]"; if (property.GetterMethod.IsAbstract) getterNode.Text = getterNode.Text + " [Abstract]"; if (property.GetterMethod.IsNewSlot) getterNode.Text = getterNode.Text + " [NewSlot]"; if (property.GetterMethod.IsVirtual) getterNode.Text = getterNode.Text + " [Virtual]"; if (property.GetterMethod.IsFinal) getterNode.Text = getterNode.Text + " [Final]"; if (property.GetterMethod.IsSpecialName) getterNode.Text = getterNode.Text + " [SpecialName]"; if (property.GetterMethod.IsRTSpecialName) getterNode.Text = getterNode.Text + " [RTSpecialName]"; if (property.GetterMethod.GenericArguments.Count != 0) { TreeNode genericParameterNodes = new TreeNode("Generic Arguments Types"); getterNode.Nodes.Add(genericParameterNodes); foreach (var genericParameter in property.GetterMethod.GenericArguments) { TreeNode GenericParameterNode = new TreeNode(genericParameter.Name); genericParameterNodes.Nodes.Add(GenericParameterNode); } } } if (property.SetterMethod != null) { TreeNode setterNode = new ViewNode<MosaMethod>(property.SetterMethod, property.SetterMethod.ShortName); propertyNode.Nodes.Add(setterNode); if (property.SetterMethod.IsStatic) setterNode.Text = setterNode.Text + " [Static]"; if (property.SetterMethod.IsAbstract) setterNode.Text = setterNode.Text + " [Abstract]"; if (property.SetterMethod.IsNewSlot) setterNode.Text = setterNode.Text + " [NewSlot]"; if (property.SetterMethod.IsVirtual) setterNode.Text = setterNode.Text + " [Virtual]"; if (property.SetterMethod.IsFinal) setterNode.Text = setterNode.Text + " [Final]"; if (property.SetterMethod.IsSpecialName) setterNode.Text = setterNode.Text + " [SpecialName]"; if (property.SetterMethod.IsRTSpecialName) setterNode.Text = setterNode.Text + " [RTSpecialName]"; if (property.SetterMethod.GenericArguments.Count != 0) { TreeNode genericParameterNodes = new TreeNode("Generic Arguments Types"); setterNode.Nodes.Add(genericParameterNodes); foreach (var genericParameter in property.SetterMethod.GenericArguments) { TreeNode GenericParameterNode = new TreeNode(genericParameter.Name); genericParameterNodes.Nodes.Add(GenericParameterNode); } } } } } if (type.Methods.Count != 0) { TreeNode methodsNode = new TreeNode("Methods"); typeNode.Nodes.Add(methodsNode); foreach (MosaMethod method in type.Methods) { if (method.ShortName.StartsWith("set_") || method.ShortName.StartsWith("get_")) continue; TreeNode methodNode = new ViewNode<MosaMethod>(method, method.ShortName); methodsNode.Nodes.Add(methodNode); if (method.IsStatic) methodNode.Text = methodNode.Text + " [Static]"; if (method.IsAbstract) methodNode.Text = methodNode.Text + " [Abstract]"; if (method.IsNewSlot) methodNode.Text = methodNode.Text + " [NewSlot]"; if (method.IsVirtual) methodNode.Text = methodNode.Text + " [Virtual]"; if (method.IsFinal) methodNode.Text = methodNode.Text + " [Final]"; if (method.IsSpecialName) methodNode.Text = methodNode.Text + " [SpecialName]"; if (method.IsRTSpecialName) methodNode.Text = methodNode.Text + " [RTSpecialName]"; if (method.GenericArguments.Count != 0) { TreeNode genericParameterNodes = new TreeNode("Generic Arguments Types"); methodNode.Nodes.Add(genericParameterNodes); foreach (var genericParameter in method.GenericArguments) { TreeNode GenericParameterNode = new TreeNode(genericParameter.Name); genericParameterNodes.Nodes.Add(GenericParameterNode); } } } } if (typeLayout.GetMethodTable(type) != null) { TreeNode methodTableNode = new TreeNode("Method Table"); typeNode.Nodes.Add(methodTableNode); foreach (MosaMethod method in typeLayout.GetMethodTable(type)) { TreeNode methodNode = new ViewNode<MosaMethod>(method, method.ShortName); methodTableNode.Nodes.Add(methodNode); } } } } treeView.EndUpdate(); }
/// <summary> /// Retrieves the stack requirements of a stack operand. /// </summary> /// <param name="typeLayout">The type layouts.</param> /// <param name="stackOperand">The operand to calculate the stack requirements for.</param> /// <param name="size">Receives the size of the operand in bytes.</param> /// <param name="alignment">Receives the alignment requirements of the operand in bytes.</param> /// <remarks> /// A stack operand is a parameter or a local variable. This function is used to properly build stack /// frame offsets for either type of stack operand. /// </remarks> public abstract void GetStackRequirements(MosaTypeLayout typeLayout, Operand stackOperand, out int size, out int alignment);
/// <summary> /// Expands method call instruction represented by the context to perform the method call. /// </summary> /// <param name="typeLayout">The type layouts.</param> /// <param name="context">The context.</param> public abstract void MakeCall(MosaTypeLayout typeLayout, Context context);
public void Load(TypeSystem typeSystem) { TypeSystem = typeSystem; TypeLayout = new MosaTypeLayout(typeSystem, CompilerOptions.Architecture.NativePointerSize, CompilerOptions.Architecture.NativeAlignment); CompilationScheduler = new CompilationScheduler(); }
/// <summary> /// Gets the type memory requirements. /// </summary> /// <param name="typeLayout">The type layouts.</param> /// <param name="type">The signature type.</param> /// <param name="size">Receives the memory size of the type.</param> /// <param name="alignment">Receives alignment requirements of the type.</param> public override void GetTypeRequirements(MosaTypeLayout typeLayout, MosaType type, out int size, out int alignment) { if (type.IsUI8 || type.IsR8 || !type.IsValueType || type.IsPointer) { size = 8; alignment = 8; } else if (typeLayout.IsCompoundType(type)) { size = typeLayout.GetTypeSize(type); alignment = 8; } else { size = 4; alignment = 4; } }
public void LoadAssembly(string filename) { MosaModuleLoader moduleLoader = new MosaModuleLoader(); moduleLoader.AddPrivatePath(System.IO.Path.GetDirectoryName(filename)); moduleLoader.LoadModuleFromFile(filename); TypeSystem = TypeSystem.Load(moduleLoader.CreateMetadata()); TypeLayout = new MosaTypeLayout(TypeSystem, 4, 4); assembliesView.UpdateTree(); }