Ejemplo n.º 1
0
 protected VertexReaderDynarec(SafeILGenerator SafeILGenerator, VertexTypeStruct VertexType)
 {
     this.Offset = 0;
     this.SafeILGenerator = SafeILGenerator;
     this.VertexType = VertexType;
     this.VertexDataArgument = SafeILGenerator.DeclareArgument(typeof(void*), 0);
     this.VertexInfoArgument = SafeILGenerator.DeclareArgument(typeof(VertexInfo*), 0);
     this.IndexArgument = SafeILGenerator.DeclareArgument(typeof(int), 0);
     this.CountArgument = SafeILGenerator.DeclareArgument(typeof(int), 0);
     this.LocalColor = SafeILGenerator.DeclareLocal<uint>("LocalColor", false);
 }
Ejemplo n.º 2
0
        private Type DefineType(string Name, CType CType)
        {
            if (Name == null)
            {
                Name = String.Format("__anonymous_type_{0}", anonymous_type_index++);
            }

            var CUnionStructType = CType as CUnionStructType;

            if (CUnionStructType != null)
            {
                //var StructType = RootTypeBuilder.DefineNestedType(CSymbol.Name, TypeAttributes.NestedPublic | TypeAttributes.SequentialLayout | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, typeof(ValueType), (PackingSize)4);
                var StructTypeAttributes = TypeAttributes.Public | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit;
                StructTypeAttributes |= CUnionStructType.IsUnion ? TypeAttributes.ExplicitLayout : TypeAttributes.SequentialLayout;
                var StructType = ModuleBuilder.DefineType(Name, StructTypeAttributes, typeof(ValueType), (PackingSize)4);

                int          AvailableBits    = 0;
                int          BitOffset        = 0;
                FieldBuilder CurrentBitsField = null;

                //StructType.StructLayoutAttribute = new StructLayoutAttribute(LayoutKind.Sequential);
                {
                    foreach (var Item in CUnionStructType.Items)
                    {
                        var ItemType = ConvertCTypeToType(Item.CType);
                        if (Item.BitCount > 0)
                        {
                            if (CUnionStructType.IsUnion)
                            {
                                throw (new NotImplementedException());
                            }

                            if (AvailableBits <= 0)
                            {
                                CurrentBitsField = StructType.DefineField("_bits_" + UniqueId, ItemType, FieldAttributes.Private);
                                AvailableBits    = Marshal.SizeOf(ItemType) * 8;
                            }

                            var PropertyGetMethod = StructType.DefineMethod("get_" + Item.Name, MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, ItemType, new Type[] { });
                            var PropertySetMethod = StructType.DefineMethod("set_" + Item.Name, MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(void), new Type[] { ItemType });

                            int BitMask = (1 << Item.BitCount) - 1;

                            // Getter
                            {
                                var ILGenerator = new SafeILGenerator(PropertyGetMethod.GetILGenerator(), CheckTypes: false, DoDebug: false, DoLog: false);
                                var This        = ILGenerator.DeclareArgument(StructType, 0, "this");
                                ILGenerator.LoadArgument(This);
                                ILGenerator.LoadField(CurrentBitsField);
                                ILGenerator.Push(BitOffset);
                                ILGenerator.BinaryOperation(SafeBinaryOperator.ShiftRightUnsigned);
                                ILGenerator.Push(BitMask);
                                ILGenerator.BinaryOperation(SafeBinaryOperator.And);
                                ILGenerator.Return(ItemType);
                            }
                            // Setter
                            {
                                var ILGenerator = new SafeILGenerator(PropertySetMethod.GetILGenerator(), CheckTypes: false, DoDebug: false, DoLog: false);
                                var This        = ILGenerator.DeclareArgument(StructType, 0, "this");
                                var Value       = ILGenerator.DeclareArgument(ItemType, 1, "value");

                                ILGenerator.LoadArgument(This);
                                {
                                    // Loads the previous value with the bits to set cleared.
                                    ILGenerator.LoadArgument(This);
                                    ILGenerator.LoadField(CurrentBitsField);
                                    ILGenerator.Push(BitMask << BitOffset);
                                    ILGenerator.UnaryOperation(SafeUnaryOperator.Not);
                                    ILGenerator.BinaryOperation(SafeBinaryOperator.And);

                                    // Loads the argument displaced.
                                    ILGenerator.LoadArgument(Value);
                                    ILGenerator.Push(BitMask);
                                    ILGenerator.BinaryOperation(SafeBinaryOperator.And);
                                    ILGenerator.Push(BitOffset);
                                    ILGenerator.BinaryOperation(SafeBinaryOperator.ShiftLeft);

                                    // Ors the old value cleared with the displaced new value.
                                    ILGenerator.BinaryOperation(SafeBinaryOperator.Or);
                                }

                                ILGenerator.StoreField(CurrentBitsField);

                                ILGenerator.Return(typeof(void));
                            }

                            var Property = StructType.DefineProperty(Item.Name, PropertyAttributes.None, ItemType, new Type[0]);
                            Property.SetGetMethod(PropertyGetMethod);
                            Property.SetSetMethod(PropertySetMethod);

                            AvailableBits -= Item.BitCount;
                            BitOffset     += Item.BitCount;
                        }
                        else
                        {
                            var Field = StructType.DefineField(Item.Name, ItemType, FieldAttributes.Public);
                            if (CUnionStructType.IsUnion)
                            {
                                Field.SetCustomAttribute(new CustomAttributeBuilder(typeof(FieldOffsetAttribute).GetConstructor(new Type[] { typeof(int) }), new object[] { 0 }));
                            }
                        }
                    }
                    //Console.Error.WriteLine("Not implemented TypeDeclaration");
                }

                //PendingTypesToCreate.Add(StructType);
                StructType.CreateType();

                return(StructType);
            }
            else
            {
                return(ConvertCTypeToType(CType));
                //return null;
                //throw (new InvalidOperationException(String.Format("CStructType == null : {0}", CType)));
            }
        }
Ejemplo n.º 3
0
        public void FunctionDeclaration(CParser.FunctionDeclaration FunctionDeclaration)
        {
            PutDebugLine(FunctionDeclaration);

            var FunctionName      = FunctionDeclaration.CFunctionType.Name;
            var ReturnType        = ConvertCTypeToType(FunctionDeclaration.CFunctionType.Return);
            var ParameterTypes    = FunctionDeclaration.CFunctionType.Parameters.Select(Item => ConvertCTypeToType(Item.CType)).ToArray();
            var ParameterCSymbols = FunctionDeclaration.CFunctionType.Parameters;

            if (ParameterTypes.Length == 1 && ParameterTypes[0] == typeof(void))
            {
                ParameterTypes = new Type[0];
            }
            var FunctionReference = FunctionScope.Find(FunctionName);

            if (FunctionReference == null)
            {
                var CurrentMethodLazy = new Lazy <MethodInfo>(() =>
                {
                    var MethodBuilder = CurrentClass.DefineMethod(
                        FunctionName,
                        MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard,
                        ReturnType,
                        ParameterTypes
                        );

                    for (int n = 0; n < ParameterCSymbols.Length; n++)
                    {
                        MethodBuilder.DefineParameter(n, ParameterAttributes.None, ParameterCSymbols[n].Name);
                    }

                    return(MethodBuilder);
                });

                FunctionReference = new FunctionReference(this, FunctionName, CurrentMethodLazy, new SafeMethodTypeInfo()
                {
                    IsStatic   = true,
                    ReturnType = ReturnType,
                    Parameters = ParameterTypes,
                })
                {
                    BodyFinalized = false,
                };

                FunctionScope.Push(FunctionName, FunctionReference);
            }

            // Just declaration
            if (FunctionDeclaration.FunctionBody == null)
            {
            }
            // Has function body.
            else
            {
                var CurrentMethod = (FunctionReference.MethodInfo as MethodBuilder);

                if (FunctionName == "main")
                {
                    //HasEntryPoint = true;

                    var StartupMethod = CurrentClass.DefineMethod(
                        "__startup",
                        MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard,
                        typeof(int),
                        new Type[] { typeof(string[]) }
                        );

                    var StartupSafeILGenerator = new SafeILGenerator(StartupMethod.GetILGenerator(), CheckTypes: true, DoDebug: false, DoLog: false);
                    var ArgsArgument           = StartupSafeILGenerator.DeclareArgument(typeof(string[]), 0);

                    StartupSafeILGenerator.Push(CurrentClass);
                    StartupSafeILGenerator.Call((Func <RuntimeTypeHandle, Type>)Type.GetTypeFromHandle);
                    StartupSafeILGenerator.LoadArgument(ArgsArgument);
                    StartupSafeILGenerator.Call((Func <Type, string[], int>)CLibUtils.RunTypeMain);
                    //StartupSafeILGenerator.Call((Func<Type, string[], int>)CLibUtils.RunTypeMain);
                    StartupSafeILGenerator.Return(typeof(int));

                    EntryPoint = StartupMethod;
                    //EntryPoint = CurrentMethod;
                }

                var ILGenerator            = CurrentMethod.GetILGenerator();
                var CurrentSafeILGenerator = new SafeILGenerator(ILGenerator, CheckTypes: false, DoDebug: false, DoLog: true);

                AScope <VariableReference> .NewScope(ref this.VariableScope, () =>
                {
                    Scopable.RefScope(ref this.GotoContext, new LabelsContext(CurrentSafeILGenerator), () =>
                    {
                        Scopable.RefScope(ref this.CurrentMethod, CurrentMethod, () =>
                        {
                            Scopable.RefScope(ref this.SafeILGenerator, CurrentSafeILGenerator, () =>
                            {
                                // Set argument variables
                                ushort ArgumentIndex = 0;
                                foreach (var Parameter in FunctionDeclaration.CFunctionType.Parameters)
                                {
                                    var Argument = SafeILGenerator.DeclareArgument(ConvertCTypeToType(Parameter.CType), ArgumentIndex);
                                    this.VariableScope.Push(Parameter.Name, new VariableReference(Parameter.Name, Parameter.CType, Argument));
                                    ArgumentIndex++;
                                }

                                Traverse(FunctionDeclaration.FunctionBody);


                                if (FunctionDeclaration.FunctionBody.Statements.Length == 0 || !(FunctionDeclaration.FunctionBody.Statements.Last() is CParser.ReturnStatement))
                                //if (true)
                                {
                                    if (CurrentMethod.ReturnType != typeof(void))
                                    {
                                        SafeILGenerator.Push((int)0);
                                    }
                                    SafeILGenerator.Return(CurrentMethod.ReturnType);
                                }
                            });
#if SHOW_INSTRUCTIONS
                            Console.WriteLine("Code for '{0}':", FunctionName);
                            foreach (var Instruction in CurrentSafeILGenerator.GetEmittedInstructions())
                            {
                                Console.WriteLine("  {0}", Instruction);
                            }
#endif
                        });
                    });
                });

                FunctionReference.BodyFinalized = true;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ElementType"></param>
        /// <param name="ArrayFixedLength"></param>
        /// <returns></returns>
        protected override Type ConvertCTypeToType_GetFixedArrayType(CType ElementCType, Type ElementType, int ArrayFixedLength)
        {
            //var StructType = ModuleBuilder.DefineType(CSymbol.Name, TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, typeof(ValueType), (PackingSize)4);
            var TypeName = "FixedArrayType_" + ElementType.Name.Replace("*", "Pointer") + "_" + ArrayFixedLength;

            var ReusedType = ModuleBuilder.GetType(TypeName);

            if (ReusedType != null)
            {
                return(ReusedType);
            }

            int ElementSize = 4;

            if (ElementType is TypeBuilder)
            {
                Console.Error.WriteLine("!(ElementType is RuntimeType) :: {0}", ElementType.GetType());
                ElementSize = (ElementType as TypeBuilder).Size;

                if (ElementSize == 0)
                {
                    ElementSize = ElementCType.GetSize(this).Value;
                    if (ElementSize == 0)
                    {
                        throw (new NotImplementedException(String.Format("ElementSize = 0 : {0}", ElementSize)));
                    }
                }
            }
            else
            {
                // TODO: HACK! This way we get the size of the structue on the compiling platform, not the real platform. Pointers have distinct sizes.
                ElementSize = (ElementType != null) ? Marshal.SizeOf(ElementType) : 8;
            }

            // TODO: Fake to get the higher size a pointer would get on x64.
            if (ElementType.IsPointer)
            {
                ElementSize = 8;
            }

#if true
            var TempStruct = ModuleBuilder.DefineType(
                TypeName,
                TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit,
                typeof(ValueType),
                PackingSize.Unspecified,
                ArrayFixedLength * ElementSize
                );
#else
            var TempStruct = RootTypeBuilder.DefineNestedType(
                TypeName,
                TypeAttributes.NestedPublic | TypeAttributes.SequentialLayout | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit,
                typeof(ValueType),
                //PackingSize.Unspecified,
                ArrayFixedLength * ElementSize
                );
#endif

            var FirstElementField = TempStruct.DefineField("FirstElement", ElementType, FieldAttributes.Public);

#if false
            var Method_get_Item    = TempStruct.DefineMethod("get_Item", MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, CallingConventions.HasThis, ElementType, new Type[] { typeof(int) });
            var Method_set_Item    = TempStruct.DefineMethod("set_Item", MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, CallingConventions.HasThis, typeof(void), new Type[] { typeof(int), ElementType });
            var Method_get_Item_IL = new SafeILGenerator(Method_get_Item.GetILGenerator(), CheckTypes: true, DoDebug: false, DoLog: false);
            var Method_set_Item_IL = new SafeILGenerator(Method_set_Item.GetILGenerator(), CheckTypes: true, DoDebug: false, DoLog: false);
            {
                // TODO: Fix address.
                var ThisArgument  = Method_get_Item_IL.DeclareArgument(TempStruct.MakePointerType(), 0);
                var IndexArgument = Method_get_Item_IL.DeclareArgument(typeof(int), 1);
                Method_get_Item_IL.LoadArgument(ThisArgument);
                Method_get_Item_IL.LoadFieldAddress(FirstElementField);
                Method_get_Item_IL.LoadArgument(IndexArgument);
                Method_get_Item_IL.Sizeof(ElementType);
                Method_get_Item_IL.BinaryOperation(SafeBinaryOperator.MultiplySigned);
                Method_get_Item_IL.BinaryOperation(SafeBinaryOperator.AdditionSigned);
                Method_get_Item_IL.LoadIndirect(ElementType);
                Method_get_Item_IL.Return(ElementType);
            }
            {
                // TODO: Fix address.
                var ThisArgument  = Method_get_Item_IL.DeclareArgument(TempStruct.MakePointerType(), 0);
                var IndexArgument = Method_get_Item_IL.DeclareArgument(typeof(int), 1);
                var ValueArgument = Method_get_Item_IL.DeclareArgument(ElementType, 2);
                Method_set_Item_IL.LoadArgument(ThisArgument);
                Method_set_Item_IL.LoadFieldAddress(FirstElementField);
                Method_set_Item_IL.LoadArgument(IndexArgument);
                Method_set_Item_IL.Sizeof(ElementType);
                Method_set_Item_IL.BinaryOperation(SafeBinaryOperator.MultiplySigned);
                Method_set_Item_IL.BinaryOperation(SafeBinaryOperator.AdditionSigned);
                Method_set_Item_IL.LoadArgument(ValueArgument);
                Method_set_Item_IL.StoreIndirect(ElementType);
                Method_set_Item_IL.Return(typeof(void));
            }

            var PropartyItem = TempStruct.DefineProperty("Item", PropertyAttributes.SpecialName, CallingConventions.HasThis, ElementType, new Type[] { typeof(int) });
            PropartyItem.SetGetMethod(Method_get_Item);
            PropartyItem.SetSetMethod(Method_set_Item);
#endif

            //Method_get_Item_IL.NewObject();
            //Method_get_Item_IL.Throw();

            TempStruct.AddCustomAttribute <CFixedArrayAttribute>();

            TempStruct.CreateType();

            return(TempStruct);
        }