Exemplo n.º 1
0
        private void GenerateConstructors(GeneratedData toGenerate, CodeGenerationStore store)
        {
            foreach (var cls in toGenerate.Classes)
            {
                var type = cls.Key;
                var node = cls.Value;

                var fields = store.Fields[type].Select(x => (x, x.Name))
                             .ToDictionary(x => x.Name, x => x.x);

                foreach (IConstructorBuilder constructor in store.Constructors[type])
                {
                    var generator = constructor.GetILGenerator();

                    var parameters = toGenerate.Constructors[constructor].Parameters
                                     .Select((p, i) => (i, store.Types[p.Type], p.Name))
                                     .ToDictionary(x => x.Name, x => ((short)x.i, x.Item2));



                    var methodInfo = new CurrentMethodInfo(type, typeChecker !.VoidType, false,
                                                           parameters, fields);

                    var generation = new ILGeneration(generator, store, methodInfo, delegateConstructorTypes !, baseConstructorInfo !, typeChecker !);

                    GenerateMethod(generation, toGenerate.Constructors[constructor].Statements);
                }
            }
        }
Exemplo n.º 2
0
        private GeneratedData CreateTypesToGenerate(IReadOnlyList <ImmutableRootSyntaxNode> rootNodes, CodeGenerationStore store)
        {
            var toGenerate = new GeneratedData();

            foreach (var rootNode in rootNodes)
            {
                foreach (var node in rootNode.Delegates)
                {
                    var type = moduleBuilder.DefineType(node.Name, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AutoLayout, typeof(MulticastDelegate));

                    toGenerate.Delegates.Add(type, node);

                    store.Types.Add(node.Name, type);
                }

                foreach (var node in rootNode.Classes)
                {
                    var type = moduleBuilder.DefineType(node.Name, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AutoLayout);

                    store.Types.Add(node.Name, type);

                    toGenerate.Classes.Add(type, node);
                }
            }

            return(toGenerate);
        }
Exemplo n.º 3
0
        private void GenerateMethods(GeneratedData toGenerate, CodeGenerationStore store)
        {
            foreach (var cls in toGenerate.Classes)
            {
                var type = cls.Key;
                var node = cls.Value;

                var fields = store.Fields[type].Select(x => (x, x.Name))
                             .ToDictionary(x => x.Name, x => x.x);

                foreach (IMethodBuilder method in store.Methods[type])
                {
                    var generator = method.GetILGenerator();

                    int offset = method.IsStatic ? 0 : 1;

                    var parameters = toGenerate.Methods[method].Parameters
                                     .Select((p, i) => (i + offset, store.Types[p.Type], p.Name))
                                     .ToDictionary(x => x.Name, x => ((short)x.Item1, x.Item2));



                    var methodInfo = new CurrentMethodInfo(type, method.ReturnType, method.IsStatic,
                                                           parameters, fields);

                    var generation = new ILGeneration(generator, store, methodInfo, delegateConstructorTypes !, baseConstructorInfo !, typeChecker !);



                    GenerateMethod(generation, toGenerate.Methods[method].Statements);
                }
            }
        }
Exemplo n.º 4
0
        // Generate all of our delegates. Delegates are easy, since the code generated for them is fixed, and all implemented
        // by the runtime.
        private void GenerateDelegates(GeneratedData toGenerate, CodeGenerationStore store)
        {
            foreach (var delegateToGenerate in toGenerate.Delegates)
            {
                var type       = delegateToGenerate.Key;
                var syntaxNode = delegateToGenerate.Value;

                store.Fields.Add(type, Array.Empty <IFieldInfo>());

                // Generate our constructor
                var constructor = type.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, delegateConstructorTypes !);
                constructor.SetImplementationFlags(MethodImplAttributes.Runtime);

                store.Constructors.Add(type, new IConstructorInfo[] { constructor });

                store.ConstructorParameters.Add(constructor, delegateConstructorTypes !);

                var parameterTypes = new IType[syntaxNode.Parameters.Count];

                for (int i = 0; i < parameterTypes.Length; i++)
                {
                    var paramType = store.TypeDefLookup(syntaxNode.Parameters[i].Type);
                    if (syntaxNode.Parameters[i].IsRef)
                    {
                        throw new RefTypeException("Ref types are not supported");
                    }
                    typeChecker !.AssertTypeIsNotVoid(paramType);
                    parameterTypes[i] = paramType;
                }

                var returnType = store.TypeDefLookup(syntaxNode.ReturnType);

                // Generate the invoke method
                var method = type.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot, returnType, parameterTypes, false);
                method.SetImplementationFlags(MethodImplAttributes.Runtime);

                for (int i = 0; i < parameterTypes.Length; i++)
                {
                    method.DefineParameter(i + 1, ParameterAttributes.None, syntaxNode.Parameters[i].Name);
                }

                store.Methods.Add(type, new IMethodInfo[] { method });

                store.MethodParameters.Add(method, parameterTypes);

                store.Delegates.Add((method.ReturnType, parameterTypes, type, constructor));
            }
        }
Exemplo n.º 5
0
        private void GenerateClassPlaceholders(GeneratedData toGenerate, CodeGenerationStore store, ref IMethodInfo?entryPoint)
        {
            var patchedClasses = new Dictionary <ITypeBuilder, ImmutableClassSyntaxNode>();

            foreach (var classToGenerate in toGenerate.Classes)
            {
                var type = classToGenerate.Key;
                var node = classToGenerate.Value;
                var fieldsToInitialize = GenerateClassFields(classToGenerate.Key, node.Fields, store, node);

                var patchedConstructors = GenerateClassConstructors(type, node.Constructors, store, fieldsToInitialize, toGenerate.Constructors, node);
                patchedClasses.Add(type, node.MutateConstructors(patchedConstructors));

                GenerateClassMethods(type, node.Methods, store, toGenerate.Methods, ref entryPoint);
            }

            foreach (var patchedClass in patchedClasses)
            {
                toGenerate.Classes[patchedClass.Key] = patchedClass.Value;
            }
            ;
        }