예제 #1
0
파일: Ldloc.cs 프로젝트: zrbruce/FlingOS
        public override void PerformStackOperations(ILPreprocessState conversionState, ILOp theOp)
        {
            bool loadAddr = (ILOp.OpCodes)theOp.opCode.Value == OpCodes.Ldloca ||
                            (ILOp.OpCodes)theOp.opCode.Value == OpCodes.Ldloca_S;
            UInt16 localIndex = 0;

            switch ((ILOp.OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Ldloc:
            case OpCodes.Ldloca:
                localIndex = (UInt16)Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Ldloc_0:
                localIndex = 0;
                break;

            case OpCodes.Ldloc_1:
                localIndex = 1;
                break;

            case OpCodes.Ldloc_2:
                localIndex = 2;
                break;

            case OpCodes.Ldloc_3:
                localIndex = 3;
                break;

            case OpCodes.Ldloc_S:
            case OpCodes.Ldloca_S:
                localIndex = (UInt16)theOp.ValueBytes[0];
                break;
            }

            Types.VariableInfo theLoc = conversionState.Input.TheMethodInfo.LocalInfos.ElementAt(localIndex);

            if (loadAddr)
            {
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false,
                    isValue            = false
                });
            }
            else
            {
                int pushedLocalSizeVal = theLoc.TheTypeInfo.SizeOnStackInBytes;

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = Utilities.IsFloat(theLoc.UnderlyingType),
                    sizeOnStackInBytes = pushedLocalSizeVal,
                    isGCManaged        = theLoc.TheTypeInfo.IsGCManaged,
                    isValue            = theLoc.TheTypeInfo.IsValueType
                });
            }
        }
예제 #2
0
파일: Starg.cs 프로젝트: zrbruce/FlingOS
        /// <summary>
        /// See base class documentation.
        /// <para>To Do's:</para>
        /// <list type="bullet">
        /// <item>
        /// <term>To do</term>
        /// <description>Implement storing of float arguments.</description>
        /// </item>
        /// </list>
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotImplementedException">
        /// Thrown when storing a float argument is required as it currently hasn't been
        /// implemented.
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// Thrown when an invalid number of bytes is specified for the argument to store.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Get the index of the argument to load
            Int16 index = 0;

            switch ((OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Starg:
                index = Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Starg_S:
                index = (Int16)theOp.ValueBytes[0];
                break;
            }

            Types.VariableInfo argInfo = conversionState.Input.TheMethodInfo.ArgumentInfos[index];
            //Used to store the number of bytes to add to EBP to get to the arg
            int BytesOffsetFromEBP = argInfo.Offset;

            //Pop the argument value from the stack
            int bytesForArg = argInfo.TheTypeInfo.SizeOnStackInBytes;

            for (int i = 0; i < bytesForArg; i += 4)
            {
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Dword, Dest = "[EBP+" + (BytesOffsetFromEBP + i) + "]"
                });
            }

            //Pop the arg value from our stack
            conversionState.CurrentStackFrame.Stack.Pop();
        }
예제 #3
0
파일: Stloc.cs 프로젝트: zrbruce/FlingOS
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if the value to store is floating point.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            UInt16 localIndex = 0;

            switch ((ILOp.OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Stloc:
                localIndex = (UInt16)Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Stloc_0:
                localIndex = 0;
                break;

            case OpCodes.Stloc_1:
                localIndex = 1;
                break;

            case OpCodes.Stloc_2:
                localIndex = 2;
                break;

            case OpCodes.Stloc_3:
                localIndex = 3;
                break;

            case OpCodes.Stloc_S:
                localIndex = (UInt16)theOp.ValueBytes[0];
                break;
            }

            Types.VariableInfo localInfo = conversionState.Input.TheMethodInfo.LocalInfos[localIndex];

            StackItem theItem = conversionState.CurrentStackFrame.Stack.Pop();

            if (theItem.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Float locals not supported yet!");
            }

            int locSize = localInfo.TheTypeInfo.SizeOnStackInBytes;

            if (locSize == 0)
            {
                conversionState.Append(new ASMOps.Comment("0 pop size (?!)"));
            }
            else
            {
                for (int i = 0; i < locSize; i += 4)
                {
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "[EBP-" + Math.Abs(localInfo.Offset + i).ToString() + "]"
                    });
                }
            }
        }
예제 #4
0
파일: Ldloc.cs 프로젝트: zrbruce/FlingOS
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when loading a float local is required as it currently hasn't been
        /// implemented.
        /// Also thrown if arguments are not of size 4 or 8 bytes.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load local

            bool loadAddr = (ILOp.OpCodes)theOp.opCode.Value == OpCodes.Ldloca ||
                            (ILOp.OpCodes)theOp.opCode.Value == OpCodes.Ldloca_S;
            UInt16 localIndex = 0;

            switch ((ILOp.OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Ldloc:
            case OpCodes.Ldloca:
                localIndex = (UInt16)Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Ldloc_0:
                localIndex = 0;
                break;

            case OpCodes.Ldloc_1:
                localIndex = 1;
                break;

            case OpCodes.Ldloc_2:
                localIndex = 2;
                break;

            case OpCodes.Ldloc_3:
                localIndex = 3;
                break;

            case OpCodes.Ldloc_S:
            case OpCodes.Ldloca_S:
                localIndex = (UInt16)theOp.ValueBytes[0];
                break;
            }

            Types.VariableInfo theLoc = conversionState.Input.TheMethodInfo.LocalInfos[localIndex];
            if (Utilities.IsFloat(theLoc.UnderlyingType))
            {
                //SUPPORT - floats
                throw new NotSupportedException("Float locals not supported yet!");
            }

            if (loadAddr)
            {
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EBP", Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Sub()
                {
                    Src = (-theLoc.Offset).ToString(), Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false,
                    isValue            = false
                });
            }
            else
            {
                int localSizeOnStack = theLoc.TheTypeInfo.SizeOnStackInBytes;

                if ((localSizeOnStack % 4) != 0)
                {
                    throw new NotSupportedException("Invalid local bytes size!");
                }
                else
                {
                    for (int i = theLoc.Offset + (localSizeOnStack - 4); i >= theLoc.Offset; i -= 4)
                    {
                        conversionState.Append(new ASMOps.Push()
                        {
                            Size = ASMOps.OperandSize.Dword, Src = "[EBP-" + Math.Abs(i).ToString() + "]"
                        });
                    }
                }

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = Utilities.IsFloat(theLoc.UnderlyingType),
                    sizeOnStackInBytes = localSizeOnStack,
                    isGCManaged        = theLoc.TheTypeInfo.IsGCManaged,
                    isValue            = theLoc.TheTypeInfo.IsValueType
                });
            }
        }
예제 #5
0
        /// <summary>
        /// Preprocesses the specified method.
        /// </summary>
        /// <param name="TheLibrary">The library being compiled.</param>
        /// <param name="theMethodInfo">The method to preprocess.</param>
        private static void PreprocessMethodInfo(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo)
        {
            if (theMethodInfo.Preprocessed)
            {
                return;
            }
            theMethodInfo.Preprocessed = true;

            string sig = theMethodInfo.Signature;
            bool SetMethodID = true;
            if (!theMethodInfo.IsConstructor)
            {
                System.Reflection.MethodInfo methodInf = (System.Reflection.MethodInfo)theMethodInfo.UnderlyingInfo;
                if (methodInf.GetBaseDefinition() != methodInf)
                {
                    Types.MethodInfo baseMethodInfo = TheLibrary.GetMethodInfo(methodInf.GetBaseDefinition());
                    PreprocessMethodInfo(TheLibrary, baseMethodInfo);
                    theMethodInfo.IDValue = baseMethodInfo.IDValue;
                    SetMethodID = false;
                }
            }
            if (SetMethodID)
            {
                Types.TypeInfo declarerTypeInfo = TheLibrary.GetTypeInfo(theMethodInfo.UnderlyingInfo.DeclaringType);
                int ID = GetMethodIDGenerator(TheLibrary, declarerTypeInfo);
                theMethodInfo.IDValue = ID + 1;
                declarerTypeInfo.MethodIDGenerator++;
            }

            int totalLocalsOffset = 0;
            foreach (Types.VariableInfo aVarInfo in theMethodInfo.LocalInfos)
            {
                //Causes processing of the type - in case it hasn't already been processed
                Types.TypeInfo aTypeInfo = TheLibrary.GetTypeInfo(aVarInfo.UnderlyingType);
                aVarInfo.TheTypeInfo = aTypeInfo;
                aVarInfo.Offset = totalLocalsOffset;
                totalLocalsOffset += aTypeInfo.SizeOnStackInBytes;
            }

            int totalArgsSize = 0;
            if (!theMethodInfo.IsStatic)
            {
                Types.VariableInfo newVarInfo = new Types.VariableInfo()
                {
                    UnderlyingType = theMethodInfo.UnderlyingInfo.DeclaringType,
                    Position = 0,
                    TheTypeInfo = TheLibrary.GetTypeInfo(theMethodInfo.UnderlyingInfo.DeclaringType)
                };

                theMethodInfo.ArgumentInfos.Add(newVarInfo);

                totalArgsSize += newVarInfo.TheTypeInfo.SizeOnStackInBytes;
            }
            System.Reflection.ParameterInfo[] args = theMethodInfo.UnderlyingInfo.GetParameters();
            foreach (System.Reflection.ParameterInfo argItem in args)
            {
                Types.VariableInfo newVarInfo = new Types.VariableInfo()
                {
                    UnderlyingType = argItem.ParameterType,
                    Position = theMethodInfo.ArgumentInfos.Count,
                    TheTypeInfo = TheLibrary.GetTypeInfo(argItem.ParameterType)
                };

                theMethodInfo.ArgumentInfos.Add(newVarInfo);
                totalArgsSize += newVarInfo.TheTypeInfo.SizeOnStackInBytes;
            }

            //System.Reflection.ParameterInfo returnArgItem = (theMethodInfo.IsConstructor ? null : ((System.Reflection.MethodInfo)theMethodInfo.UnderlyingInfo).ReturnParameter);
            //if (returnArgItem != null)
            //{
            //    Types.VariableInfo newVarInfo = new Types.VariableInfo()
            //    {
            //        UnderlyingType = returnArgItem.ParameterType,
            //        Position = theMethodInfo.ArgumentInfos.Count,
            //        TheTypeInfo = TheLibrary.GetTypeInfo(returnArgItem.ParameterType)
            //    };

            //    theMethodInfo.ArgumentInfos.Add(newVarInfo);
            //    totalArgsSize += newVarInfo.TheTypeInfo.SizeOnStackInBytes;
            //}

            int offset = totalArgsSize;
            for (int i = 0; i < theMethodInfo.ArgumentInfos.Count; i++)
            {
                offset -= theMethodInfo.ArgumentInfos[i].TheTypeInfo.SizeOnStackInBytes;
                theMethodInfo.ArgumentInfos[i].Offset = offset;
            }
        }
예제 #6
0
파일: Ldloc.cs 프로젝트: zrbruce/FlingOS
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when loading a float local is required as it currently hasn't been
        /// implemented.
        /// Also thrown if arguments are not of size 4 or 8 bytes.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load local

            bool loadAddr = (ILOp.OpCodes)theOp.opCode.Value == OpCodes.Ldloca ||
                            (ILOp.OpCodes)theOp.opCode.Value == OpCodes.Ldloca_S;
            UInt16 localIndex = 0;

            switch ((ILOp.OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Ldloc:
            case OpCodes.Ldloca:
                localIndex = (UInt16)Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Ldloc_0:
                localIndex = 0;
                break;

            case OpCodes.Ldloc_1:
                localIndex = 1;
                break;

            case OpCodes.Ldloc_2:
                localIndex = 2;
                break;

            case OpCodes.Ldloc_3:
                localIndex = 3;
                break;

            case OpCodes.Ldloc_S:
            case OpCodes.Ldloca_S:
                localIndex = (UInt16)theOp.ValueBytes[0];
                break;
            }

            int bytesOffset = 0;

            for (int i = 0; i < conversionState.Input.TheMethodInfo.LocalInfos.Count && i <= localIndex; i++)
            {
                bytesOffset += conversionState.Input.TheMethodInfo.LocalInfos[i].TheTypeInfo.SizeOnStackInBytes;
            }

            Types.VariableInfo theLoc = conversionState.Input.TheMethodInfo.LocalInfos[localIndex];
            if (Utilities.IsFloat(theLoc.UnderlyingType))
            {
                //SUPPORT - floats
                throw new NotSupportedException("Float locals not supported yet!");
            }

            if (loadAddr)
            {
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$fp", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.RegToReg
                });
                conversionState.Append(new ASMOps.Sub()
                {
                    Src1 = "$t0", Src2 = bytesOffset.ToString(), Dest = "$t0"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t0"
                });

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false,
                    isValue            = false
                });
            }
            else
            {
                int pushedLocalSizeVal = theLoc.TheTypeInfo.SizeOnStackInBytes;

                if ((pushedLocalSizeVal % 4) != 0)
                {
                    throw new NotSupportedException("Invalid local bytes size!");
                }
                else
                {
                    for (int i = bytesOffset - (pushedLocalSizeVal - 4); i <= bytesOffset; i += 4)
                    {
                        conversionState.Append(new ASMOps.Mov()
                        {
                            Size = ASMOps.OperandSize.Word, Src = "-" + i.ToString() + "($fp)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg
                        });
                        conversionState.Append(new ASMOps.Push()
                        {
                            Size = ASMOps.OperandSize.Word, Src = "$t0"
                        });
                    }
                }

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = Utilities.IsFloat(theLoc.UnderlyingType),
                    sizeOnStackInBytes = pushedLocalSizeVal,
                    isGCManaged        = theLoc.TheTypeInfo.IsGCManaged,
                    isValue            = theLoc.TheTypeInfo.IsValueType
                });
            }
        }
예제 #7
0
        /// <summary>
        /// See base class documentation.
        /// <para>To Do's:</para>
        /// <list type="bullet">
        /// <item>
        /// <term>To do</term>
        /// <description>Implement loading of float arguments.</description>
        /// </item>
        /// </list>
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when loading a float argument is required as it currently hasn't been
        /// implemented.
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// Thrown when an invalid number of bytes is specified for the argument to load.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Get the index of the argument to load
            Int16 index = 0;

            switch ((OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Ldarg:
                index = Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Ldarg_0:
                index = 0;
                break;

            case OpCodes.Ldarg_1:
                index = 1;
                break;

            case OpCodes.Ldarg_2:
                index = 2;
                break;

            case OpCodes.Ldarg_3:
                index = 3;
                break;

            case OpCodes.Ldarg_S:
                index = (Int16)theOp.ValueBytes[0];
                break;

            case OpCodes.Ldarga:
                index = Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Ldarga_S:
                index = (Int16)theOp.ValueBytes[0];
                break;
            }

            Types.VariableInfo argInfo = conversionState.Input.TheMethodInfo.ArgumentInfos[index];
            if (Utilities.IsFloat(argInfo.TheTypeInfo.UnderlyingType))
            {
                //SUPPORT - floats
                throw new NotSupportedException("Float arguments not supported yet!");
            }

            //Used to store the number of bytes to add to EBP to get to the arg
            int BytesOffsetFromEBP = argInfo.Offset;

            if ((OpCodes)theOp.opCode.Value == OpCodes.Ldarga ||
                (OpCodes)theOp.opCode.Value == OpCodes.Ldarga_S)
            {
                //Push the address of the argument onto the stack

                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$fp", Dest = "$t2", MoveType = ASMOps.Mov.MoveTypes.RegToReg
                });
                conversionState.Append(new ASMOps.Add()
                {
                    Src1 = "$t2", Src2 = BytesOffsetFromEBP.ToString(), Dest = "$t2"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t2"
                });

                //Push the address onto our stack
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    sizeOnStackInBytes = 4,
                    isFloat            = false,
                    isGCManaged        = false,
                    isValue            = false
                });
            }
            else
            {
                //Push the argument onto the stack
                Types.TypeInfo paramTypeInfo = argInfo.TheTypeInfo;
                int            bytesForArg   = paramTypeInfo.SizeOnStackInBytes;

                if (bytesForArg % 4 != 0)
                {
                    throw new ArgumentException("Cannot load arg! Don't understand byte size of the arg! Size:" + bytesForArg);
                }

                while (bytesForArg > 0)
                {
                    bytesForArg -= 4;

                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Word, Src = (BytesOffsetFromEBP + bytesForArg).ToString() + "($fp)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg
                    });
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Word, Src = "$t0"
                    });
                }

                //Push the arg onto our stack
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    sizeOnStackInBytes = paramTypeInfo.SizeOnStackInBytes,
                    isFloat            = false,
                    isGCManaged        = paramTypeInfo.IsGCManaged,
                    isValue            = paramTypeInfo.IsValueType
                });
            }
        }
예제 #8
0
파일: Ldarg.cs 프로젝트: zrbruce/FlingOS
        public override void PerformStackOperations(ILPreprocessState conversionState, ILOp theOp)
        {
            Int16 index = 0;

            switch ((OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Ldarg:
                index = Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Ldarg_0:
                index = 0;
                break;

            case OpCodes.Ldarg_1:
                index = 1;
                break;

            case OpCodes.Ldarg_2:
                index = 2;
                break;

            case OpCodes.Ldarg_3:
                index = 3;
                break;

            case OpCodes.Ldarg_S:
                index = (Int16)theOp.ValueBytes[0];
                break;

            case OpCodes.Ldarga:
                index = Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Ldarga_S:
                index = (Int16)theOp.ValueBytes[0];
                break;
            }

            if ((OpCodes)theOp.opCode.Value == OpCodes.Ldarga ||
                (OpCodes)theOp.opCode.Value == OpCodes.Ldarga_S)
            {
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    sizeOnStackInBytes = 4,
                    isFloat            = false,
                    isGCManaged        = false,
                    isValue            = false
                });
            }
            else
            {
                Types.VariableInfo argInfo       = conversionState.Input.TheMethodInfo.ArgumentInfos[index];
                Types.TypeInfo     paramTypeInfo = argInfo.TheTypeInfo;
                int bytesForArg = paramTypeInfo.SizeOnStackInBytes;
                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    sizeOnStackInBytes = bytesForArg,
                    isFloat            = false,
                    isGCManaged        = paramTypeInfo.IsGCManaged,
                    isValue            = paramTypeInfo.IsValueType
                });
            }
        }