Performs memory layout of a type for compilation.
Beispiel #1
0
        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;
        }
Beispiel #3
0
        /// <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;
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #8
0
        /// <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);
        }
Beispiel #9
0
        /// <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();
        }
Beispiel #10
0
        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();
        }
Beispiel #11
0
        /// <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();
        }
Beispiel #12
0
        /// <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;
        }
Beispiel #15
0
 /// <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>
 /// 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>
 /// 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);
Beispiel #19
0
        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();
        }
Beispiel #20
0
        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);
Beispiel #25
0
        public void Load(TypeSystem typeSystem)
        {
            TypeSystem = typeSystem;

            TypeLayout = new MosaTypeLayout(typeSystem, CompilerOptions.Architecture.NativePointerSize, CompilerOptions.Architecture.NativeAlignment);

            CompilationScheduler = new CompilationScheduler();
        }
Beispiel #26
0
 /// <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;
     }
 }
Beispiel #27
0
        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();
        }