Esempio n. 1
0
        public void ParamTypesRoundtrip()
        {
            var returnType     = LLVMTypeRef.Int8;
            var parameterTypes = new[] { LLVMTypeRef.Double };
            var functionType   = LLVMTypeRef.CreateFunction(returnType, parameterTypes);

            Assert.AreEqual(parameterTypes, functionType.ParamTypes);
        }
Esempio n. 2
0
        public void CreateDebugLocation()
        {
            string        fileName  = Path.GetFileName("DIBuilder.c");
            string        directory = Path.GetDirectoryName(".");
            LLVMModuleRef module    = LLVMModuleRef.CreateWithName("netscripten");

            module.Target = "asmjs-unknown-emscripten";
            var             dIBuilder    = module.CreateDIBuilder();
            var             builder      = module.Context.CreateBuilder();
            LLVMMetadataRef fileMetadata = dIBuilder.CreateFile(fileName, directory);

            LLVMMetadataRef compileUnitMetadata = dIBuilder.CreateCompileUnit(
                LLVMDWARFSourceLanguage.LLVMDWARFSourceLanguageC,
                fileMetadata, "ILC", 0 /* Optimized */, String.Empty, 1, String.Empty,
                LLVMDWARFEmissionKind.LLVMDWARFEmissionFull, 0, 0, 0);

            module.AddNamedMetadataOperand("llvm.dbg.cu", compileUnitMetadata);

            LLVMMetadataRef functionMetaType = dIBuilder.CreateSubroutineType(fileMetadata,
                                                                              ReadOnlySpan <LLVMMetadataRef> .Empty, LLVMDIFlags.LLVMDIFlagZero);

            uint lineNumber    = 1;
            var  debugFunction = dIBuilder.CreateFunction(fileMetadata, "CreateDebugLocation", "CreateDebugLocation",
                                                          fileMetadata,
                                                          lineNumber, functionMetaType, 1, 1, lineNumber, 0, 0);
            LLVMMetadataRef currentLine =
                module.Context.CreateDebugLocation(lineNumber, 0, debugFunction, default(LLVMMetadataRef));

            LLVMTypeRef[] FooParamTys = { LLVMTypeRef.Int64, LLVMTypeRef.Int64, };
            LLVMTypeRef   FooFuncTy   = LLVMTypeRef.CreateFunction(LLVMTypeRef.Int64, FooParamTys);
            LLVMValueRef  FooFunction = module.AddFunction("foo", FooFuncTy);

            var funcBlock = module.Context.AppendBasicBlock(FooFunction, "foo");

            builder.PositionAtEnd(funcBlock);
            builder.BuildRet(LLVMValueRef.CreateConstInt(LLVMTypeRef.Int64, 0));
            builder.CurrentDebugLocation = module.Context.MetadataAsValue(currentLine);
            var dwarfVersion = LLVMValueRef.CreateMDNode(new[]
            {
                LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 2), module.Context.GetMDString("Dwarf Version", 13),
                LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 4)
            });
            var dwarfSchemaVersion = LLVMValueRef.CreateMDNode(new[]
            {
                LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 2),
                module.Context.GetMDString("Debug Info Version", 18),
                LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 3)
            });

            module.AddNamedMetadataOperand("llvm.module.flags", dwarfVersion);
            module.AddNamedMetadataOperand("llvm.module.flags", dwarfSchemaVersion);
            dIBuilder.DIBuilderFinalize();

            module.TryVerify(LLVMVerifierFailureAction.LLVMPrintMessageAction, out string message);

            Assert.AreEqual("", message);
        }
Esempio n. 3
0
        private void EmitNativeMain(LLVMContextRef context)
        {
            LLVMValueRef shadowStackTop = Module.GetNamedGlobal("t_pShadowStackTop");

            LLVMBuilderRef builder        = context.CreateBuilder();
            var            mainSignature  = LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32, new LLVMTypeRef[] { LLVMTypeRef.Int32, LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0) }, false);
            var            mainFunc       = Module.AddFunction("__managed__Main", mainSignature);
            var            mainEntryBlock = mainFunc.AppendBasicBlock("entry");

            builder.PositionAtEnd(mainEntryBlock);
            LLVMValueRef managedMain = Module.GetNamedFunction("StartupCodeMain");

            if (managedMain.Handle == IntPtr.Zero)
            {
                throw new Exception("Main not found");
            }

            LLVMTypeRef  reversePInvokeFrameType = LLVMTypeRef.CreateStruct(new LLVMTypeRef[] { LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0) }, false);
            LLVMValueRef reversePinvokeFrame     = builder.BuildAlloca(reversePInvokeFrameType, "ReversePInvokeFrame");
            LLVMValueRef RhpReversePInvoke2      = Module.GetNamedFunction("RhpReversePInvoke2");

            if (RhpReversePInvoke2.Handle == IntPtr.Zero)
            {
                RhpReversePInvoke2 = Module.AddFunction("RhpReversePInvoke2", LLVMTypeRef.CreateFunction(LLVMTypeRef.Void, new LLVMTypeRef[] { LLVMTypeRef.CreatePointer(reversePInvokeFrameType, 0) }, false));
            }

            builder.BuildCall(RhpReversePInvoke2, new LLVMValueRef[] { reversePinvokeFrame }, "");

            var shadowStack     = builder.BuildMalloc(LLVMTypeRef.CreateArray(LLVMTypeRef.Int8, 1000000), String.Empty);
            var castShadowStack = builder.BuildPointerCast(shadowStack, LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), String.Empty);

            builder.BuildStore(castShadowStack, shadowStackTop);

            var shadowStackBottom = Module.AddGlobal(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), "t_pShadowStackBottom");

            shadowStackBottom.Linkage         = LLVMLinkage.LLVMExternalLinkage;
            shadowStackBottom.Initializer     = LLVMValueRef.CreateConstPointerNull(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0));
            shadowStackBottom.ThreadLocalMode = LLVMThreadLocalMode.LLVMLocalDynamicTLSModel;
            builder.BuildStore(castShadowStack, shadowStackBottom);

            // Pass on main arguments
            LLVMValueRef argc = mainFunc.GetParam(0);
            LLVMValueRef argv = mainFunc.GetParam(1);

            LLVMValueRef mainReturn = builder.BuildCall(managedMain, new LLVMValueRef[]
            {
                castShadowStack,
                argc,
                argv,
            },
                                                        "returnValue");

            builder.BuildRet(mainReturn);
            mainFunc.Linkage = LLVMLinkage.LLVMExternalLinkage;
        }
Esempio n. 4
0
        public static LLVMValueRef AddFunction(this LLVMModuleRef module, LLVMTypeRef returnType, string name, LLVMTypeRef[] parameterTypes, Action <LLVMValueRef, LLVMBuilderRef> action)
        {
            var type    = LLVMTypeRef.CreateFunction(returnType, parameterTypes);
            var func    = module.AddFunction(name, type);
            var block   = func.AppendBasicBlock(string.Empty);
            var builder = module.Context.CreateBuilder();

            builder.PositionAtEnd(block);
            action(func, builder);
            return(func);
        }
Esempio n. 5
0
        private static LLVMTypeRef CreateLlvmType(GlobalCompilationContext ctx)
        {
            var type = ctx.LlvmContext.CreateNamedStruct("__allocator_vtable");
            Span <LLVMTypeRef> members = stackalloc LLVMTypeRef[]
            {
                LLVMTypeRef.CreatePointer(LLVMTypeRef.CreateFunction(LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0), new[] { LLVMTypeRef.Int32 }), 0),
                LLVMTypeRef.CreatePointer(LLVMTypeRef.CreateFunction(LLVMTypeRef.Void, new[] { LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0) }), 0),
            };

            type.StructSetBody(members, false);
            return(type);
        }
        static void BuildFilterFunclet(LLVMModuleRef module, LLVMTypeRef[] funcletArgTypes)
        {
            LlvmFilterFunclet = module.AddFunction("LlvmFilterFunclet", LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32, funcletArgTypes, false));
            var            block          = LlvmFilterFunclet.AppendBasicBlock("Filter");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            LLVMValueRef filterResult = funcletBuilder.BuildCall(LlvmFilterFunclet.GetParam(0), new LLVMValueRef[] { LlvmFilterFunclet.GetParam(1) }, "callFilter");

            funcletBuilder.BuildRet(filterResult);
            funcletBuilder.Dispose();
        }
Esempio n. 7
0
        private void EmitReadyToRunHeaderCallback(LLVMContextRef context)
        {
            LLVMTypeRef intPtr    = LLVMTypeRef.CreatePointer(LLVMTypeRef.Int32, 0);
            LLVMTypeRef intPtrPtr = LLVMTypeRef.CreatePointer(intPtr, 0);
            var         callback  = Module.AddFunction("RtRHeaderWrapper", LLVMTypeRef.CreateFunction(intPtrPtr, new LLVMTypeRef[0], false));
            var         builder   = context.CreateBuilder();
            var         block     = callback.AppendBasicBlock("Block");

            builder.PositionAtEnd(block);

            LLVMValueRef rtrHeaderPtr     = GetSymbolValuePointer(Module, _nodeFactory.ReadyToRunHeader, _nodeFactory.NameMangler, false);
            LLVMValueRef castRtrHeaderPtr = builder.BuildPointerCast(rtrHeaderPtr, intPtrPtr, "castRtrHeaderPtr");

            builder.BuildRet(castRtrHeaderPtr);
        }
Esempio n. 8
0
        public override bool VisitTopLevelDelegate([NotNull] GamaParser.TopLevelDelegateContext context)
        {
            var name = context.Symbol().GetText();

            if (NamespaceContext.FindTypeRef(name) != null)
            {
                GlobalContext.AddError(new ErrorDuplicateType(context));
                return(false);
            }

            var retty = InstanceTypes.Void;

            var rettyfqtn = context.fqtn();

            if (rettyfqtn != null)
            {
                retty = NamespaceContext.FindTypeRefGlobal(rettyfqtn);
                if (retty == null)
                {
                    GlobalContext.AddError(new ErrorTypeNotFound(context.fqtn()));
                    return(false);
                }
            }

            var parms       = new GamaTypeRef[0];
            var parmsnative = new LLVMTypeRef[0];
            var parmsctx    = context.fqtnList();

            if (parmsctx != null)
            {
                var fqtns = parmsctx.fqtn();
                parms       = new GamaTypeRef[fqtns.Length];
                parmsnative = new LLVMTypeRef[fqtns.Length];
                for (int i = 0; i < fqtns.Length; i++)
                {
                    var ty = NamespaceContext.FindTypeRefGlobal(fqtns[i]);
                    if (ty == null)
                    {
                        GlobalContext.AddError(new ErrorTypeNotFound(fqtns[i]));
                        return(false);
                    }
                    parms[i]       = ty;
                    parmsnative[i] = ty.UnderlyingType;
                }
            }
            NamespaceContext.This.Types.Add(new GamaFunction(name, retty, parms, LLVMTypeRef.CreateFunction(retty.UnderlyingType, parmsnative)));
            return(true);
        }
Esempio n. 9
0
        public static LLVMTypeRef ToLLVMType(this Type type)
        {
            if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Vector128 <>))
            {
                var et = type.GetGenericArguments()[0];
                return(LLVMTypeRef.CreateVector(et.ToLLVMType(), 16U / (uint)Marshal.SizeOf(et)));
            }
            if (typeof(MulticastDelegate).IsAssignableFrom(type))
            {
                var mi = type.GetMethod("Invoke");
                return(LLVMTypeRef.CreateFunction(mi.ReturnType.ToLLVMType(),
                                                  mi.GetParameters().Select(x => x.ParameterType.ToLLVMType()).ToArray(), false));
            }
            if (type == typeof(void))
            {
                return(LLVMTypeRef.Void);
            }
            if (type.IsPointer)
            {
                return(LLVMTypeRef.Int64);
            }
            switch (Activator.CreateInstance(type))
            {
            case sbyte _:
            case byte _: return(LLVMTypeRef.Int8);

            case short _:
            case ushort _: return(LLVMTypeRef.Int16);

            case int _:
            case uint _: return(LLVMTypeRef.Int32);

            case long _:
            case ulong _: return(LLVMTypeRef.Int64);

            case Int128 _:
            case UInt128 _: return(LLVMTypeRef.CreateInt(128));

            case float _: return(LLVMTypeRef.Float);

            case double _: return(LLVMTypeRef.Double);

            case bool _: return(LLVMTypeRef.Int1);

            default: throw new NotSupportedException(type.Name);
            }
        }
Esempio n. 10
0
        public void TestMethod1()
        {
            LLVM.LinkInMCJIT();
            LLVM.InitializeX86TargetMC();
            LLVM.InitializeX86Target();
            LLVM.InitializeX86TargetInfo();
            LLVM.InitializeX86AsmParser();
            LLVM.InitializeX86AsmPrinter();
            var mod     = LLVMModuleRef.CreateWithName("Test1");
            var options = LLVMMCJITCompilerOptions.Create();

            options.NoFramePointerElim = 1;
            var engine = mod.CreateMCJITCompiler(ref options);

            LLVMTypeRef[] paramsType = { LLVMTypeRef.Int32 };
            var           funcType   = LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32, paramsType, false);
            var           acc        = mod.AddFunction("acc", funcType);
            var           gs         = mod.AddGlobal(LLVMTypeRef.Int32, "gs");
            var           entry      = acc.AppendBasicBlock("entry");
            var           builder    = mod.Context.CreateBuilder();

            builder.PositionAtEnd(entry);
            var tmp  = builder.BuildLoad(gs);
            var tmp2 = builder.BuildMul(tmp, acc.GetParam(0), "".AsSpan());

            builder.BuildStore(tmp2, gs);
            builder.BuildRet(tmp2);
            if (!mod.TryVerify(LLVMVerifierFailureAction.LLVMPrintMessageAction, out var error))
            {
                Trace.WriteLine(error);
            }
            builder.Dispose();
            object gsActual = 1;
            var    handle   = GCHandle.Alloc(gsActual, GCHandleType.Pinned);

            engine.AddGlobalMapping(gs, handle.AddrOfPinnedObject());
            var accMethod = engine.GetPointerToGlobal <Add>(acc);
            var gsAddr    = engine.GetPointerToGlobal(gs);

            Assert.AreEqual(2, accMethod(2));
            Assert.AreEqual(8, accMethod(4));
            Assert.AreEqual(8, gsActual);
            Trace.WriteLine(mod.PrintToString());
            engine.Dispose();
            handle.Free();
        }
Esempio n. 11
0
        private SNode Visit(SNode node)
        {
            LLVMTypeRef[] paramType = { };
            var           funcType  = LLVMTypeRef.CreateFunction(LLVMTypeRef.Void, paramType);

            func  = mod.AddFunction("main", funcType);
            entry = func.AppendBasicBlock("entry");
            var body = func.AppendBasicBlock("body");

            blockStack.Add(entry);
            blockStack.Add(body);
            symbolTables.Add(new LLVMSymbolTable(symbolTables.Last()));
            builder.PositionAtEnd(body);
            Visit(node.CompoundStatement);
            builder.BuildRetVoid();
            builder.PositionAtEnd(entry);
            builder.BuildBr(body);
            return(node);
        }
Esempio n. 12
0
        static void BuildCatchFunclet(LLVMModuleRef module, string funcletName, LLVMTypeRef[] funcletArgTypes, bool passGenericContext = false)
        {
            LlvmCatchFunclet = module.AddFunction(funcletName, LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32,
                                                                                          funcletArgTypes, false));
            var            block          = LlvmCatchFunclet.AppendBasicBlock("Catch");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            List <LLVMValueRef> llvmArgs = new List <LLVMValueRef>();

            llvmArgs.Add(LlvmCatchFunclet.GetParam(2));
            if (passGenericContext)
            {
                llvmArgs.Add(LlvmCatchFunclet.GetParam(3));
            }
            LLVMValueRef leaveToILOffset = funcletBuilder.BuildCall(LlvmCatchFunclet.GetParam(1), llvmArgs.ToArray(), string.Empty);

            funcletBuilder.BuildRet(leaveToILOffset);
            funcletBuilder.Dispose();
        }
Esempio n. 13
0
        static void BuildFilterFunclet(LLVMModuleRef module, string funcletName, LLVMTypeRef[] funcletArgTypes, bool passGenericContext = false)
        {
            LlvmFilterFunclet = module.AddFunction(funcletName, LLVMTypeRef.CreateFunction(LLVMTypeRef.Int32,
                                                                                           funcletArgTypes, false));
            var            block          = LlvmFilterFunclet.AppendBasicBlock("Filter");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            List <LLVMValueRef> llvmArgs = new List <LLVMValueRef>();

            llvmArgs.Add(LlvmFilterFunclet.GetParam(2)); //shadow stack
            llvmArgs.Add(LlvmFilterFunclet.GetParam(0)); // exception object
            if (passGenericContext)
            {
                llvmArgs.Add(LlvmFilterFunclet.GetParam(3));
            }
            LLVMValueRef filterResult = funcletBuilder.BuildCall(LlvmFilterFunclet.GetParam(1), llvmArgs.ToArray(), string.Empty);

            funcletBuilder.BuildRet(filterResult);
            funcletBuilder.Dispose();
        }
Esempio n. 14
0
        static void BuildFinallyFunclet(LLVMModuleRef module)
        {
            LlvmFinallyFunclet = module.AddFunction("LlvmFinallyFunclet", LLVMTypeRef.CreateFunction(LLVMTypeRef.Void,
                                                                                                     new LLVMTypeRef[]
            {
                LLVMTypeRef.CreatePointer(LLVMTypeRef.CreateFunction(LLVMTypeRef.Void, new LLVMTypeRef[] { LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0) }, false), 0), // finallyHandler
                LLVMTypeRef.CreatePointer(LLVMTypeRef.Int8, 0),                                                                                                          // shadow stack
            }, false));
            var            block          = LlvmFinallyFunclet.AppendBasicBlock("GenericFinally");
            LLVMBuilderRef funcletBuilder = Context.CreateBuilder();

            funcletBuilder.PositionAtEnd(block);

            var finallyFunclet  = LlvmFinallyFunclet.GetParam(0);
            var castShadowStack = LlvmFinallyFunclet.GetParam(1);

            List <LLVMValueRef> llvmArgs = new List <LLVMValueRef>();

            llvmArgs.Add(castShadowStack);

            funcletBuilder.BuildCall(finallyFunclet, llvmArgs.ToArray(), string.Empty);
            funcletBuilder.BuildRetVoid();
            funcletBuilder.Dispose();
        }
Esempio n. 15
0
        public override bool VisitTopLevelExternDef([NotNull] GamaParser.TopLevelExternDefContext context)
        {
            var name = context.Symbol().GetText();
            var list = NamespaceContext.FindFunctionRefGlobal(name);

            if (list == null)
            {
                list = new GamaFunctionList(name);
                NamespaceContext.This.Functions.Add(list);
            }

            var retty = InstanceTypes.Void;

            var rettyfqtn = context.typeName();

            if (rettyfqtn != null)
            {
                retty = NamespaceContext.FindTypeRefGlobal(rettyfqtn);
                if (retty == null)
                {
                    GlobalContext.AddError(new ErrorTypeNotFound(context.typeName()));
                    return(false);
                }
            }

            var ellipsis       = context.ellipsis() != null;
            var parmslist      = new GamaParamList();
            var argtypes       = new GamaTypeRef[0];
            var argtypesnative = new LLVMTypeRef[0];
            var fqtnlist       = context.typeList();

            if (fqtnlist != null)
            {
                var types = fqtnlist.typeName();
                argtypesnative = new LLVMTypeRef[types.Length];
                argtypes       = new GamaTypeRef[types.Length];
                for (int i = 0; i < types.Length; i++)
                {
                    var ty = NamespaceContext.FindTypeRefGlobal(types[i]);
                    if (ty == null)
                    {
                        GlobalContext.AddError(new ErrorTypeNotFound(types[i]));
                        return(false);
                    }
                    parmslist.Add(i.ToString(), ty); // Adding parameter with a numeric name, doesn't matter since this is a extern.
                    argtypes[i]       = ty;
                    argtypesnative[i] = ty.UnderlyingType;
                }
            }

            if (list.FindFunction(parmslist) != null)
            {
                GlobalContext.AddError(new ErrorDuplicateFunction(context));
                return(false);
            }

            var fnty  = new GamaFunction(retty, argtypes, LLVMTypeRef.CreateFunction(retty.UnderlyingType, argtypesnative, ellipsis), ellipsis);
            var modfn = GlobalContext.Module.AddFunction(name, fnty.UnderlyingType);

            var fnref = new GamaFunctionRef(retty, parmslist, fnty, modfn, false);

            list.AddFunction(fnref);

            return(true);
        }
Esempio n. 16
0
        public override bool VisitTopLevelFuncDef([NotNull] GamaParser.TopLevelFuncDefContext context)
        {
            var name   = context.Symbol().GetText();
            var fnlist = NamespaceContext.FindFunctionRef(name);
            var attrs  = context.funcAttr();

            // New function
            if (fnlist == null)
            {
                fnlist = new GamaFunctionList(name);
                var stplist         = context.symbolTypePairList();
                var parms           = new GamaParamList();
                var parmTypes       = new GamaTypeRef[0];
                var parmTypesNative = new LLVMTypeRef[0];

                if (stplist != null)
                {
                    var list = stplist.symbolTypePair();

                    parmTypes       = new GamaTypeRef[list.Length];
                    parmTypesNative = new LLVMTypeRef[list.Length];

                    for (int i = 0; i < list.Length; i++)
                    {
                        var stp  = list[i];
                        var sym  = stp.Symbol();
                        var type = NamespaceContext.FindTypeRefGlobal(stp.typeName());
                        if (type == null)
                        {
                            GlobalContext.AddError(new ErrorTypeNotFound(stp.typeName()));
                            return(false);
                        }
                        /* Since functions are not first-class types, we need to wrap them around with a pointer */
                        if (type is GamaFunction)
                        {
                            type = new GamaPointer(type);
                        }
                        if (!parms.Add(sym.GetText(), type))
                        {
                            GlobalContext.AddError(new ErrorDuplicateParameter(stp));
                            return(false); // TODO: fix error library.
                        }
                        parmTypesNative[i] = type.UnderlyingType;
                        parmTypes[i]       = type;
                    }
                }

                /* Determine type */
                var rettypefqtn = context.typeName();
                var retty       = InstanceTypes.Void;

                // If function has a non-void type
                if (rettypefqtn != null)
                {
                    // Find it
                    retty = NamespaceContext.FindTypeRefGlobal(rettypefqtn);
                    if (retty == null)
                    {
                        GlobalContext.AddError(new ErrorTypeNotFound(rettypefqtn));
                        return(false);
                    }
                }

                /* LLVM */
                var modty = new GamaFunction(retty, parmTypes, LLVMTypeRef.CreateFunction(retty.UnderlyingType, parmTypesNative));
                var modfn = NamespaceContext.This.Context.Module.AddFunction(name, modty.UnderlyingType);

                var fn   = new GamaFunctionRef(retty, parms, modty, modfn, false);
                var unit = new GamaFunctionCompiler(NamespaceContext, fn);

                /* Parameters are added to top frame of the target function, but they are not treated as conventional variables */
                foreach (var p in parms.Parameters)
                {
                    unit.Top.AddValue(p.Name, new GamaValueRef(p.Type, modfn.GetParam(p.Index), false));
                }

                unit.Visit(context.block());
                if (unit.Finish() == 0)
                {
                    // First add ident, if it fails you fail too.
                    if (attrs != null)
                    {
                        var attributes = new GamaAttributeCompiler(this).Visit(attrs);
                        if (attributes != null)
                        {
                            fn.Attributes = attributes;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    fnlist.AddFunction(fn);
                    NamespaceContext.This.Functions.Add(fnlist);
                }
                else
                {
                    ; // ?gnihtemos oD :ODOT (TODO:)
                }
                return(true);
            }
            // An override function
            else
            {
                var stplist = context.symbolTypePairList();
                var parms   = new GamaParamList();
                if (stplist != null)
                {
                    var list = stplist.symbolTypePair();
                    for (int i = 0; i < list.Length; i++)
                    {
                        var stp  = list[i];
                        var sym  = stp.Symbol();
                        var type = NamespaceContext.FindTypeRefGlobal(stp.typeName());
                        if (type == null)
                        {
                            GlobalContext.AddError(new ErrorTypeNotFound(stp.typeName()));
                            return(false);
                        }
                        if (type is GamaFunction)
                        {
                            if (!parms.Add(sym.GetText(), new GamaPointer(type)))
                            {
                                GlobalContext.AddError(new ErrorDuplicateParameter(stp));
                                return(false); // TODO: fix error library.
                            }
                            continue;
                        }
                        if (!parms.Add(sym.GetText(), type))
                        {
                            GlobalContext.AddError(new ErrorDuplicateParameter(stp));
                            return(false);
                        }
                    }
                }

                // Duplicate function if two functions have same type of parameters
                if (fnlist.FindFunction(parms) != null)
                {
                    GlobalContext.AddError(new ErrorDuplicateFunction(context));
                    return(false);
                }

                /* Determine type */
                var rettypefqtn = context.typeName();
                var retty       = InstanceTypes.Void;

                // If function has a non-void type
                if (rettypefqtn != null)
                {
                    // Find it
                    retty = NamespaceContext.FindTypeRefGlobal(rettypefqtn);
                    if (retty == null)
                    {
                        GlobalContext.AddError(new ErrorTypeNotFound(rettypefqtn));
                        return(false);
                    }
                }

                var modty = new GamaFunction(retty, parms.Parameters.Select(p => p.Type).ToArray(), LLVMTypeRef.CreateFunction(retty.UnderlyingType, parms.Parameters.Select(p => p.Type.UnderlyingType).ToArray()));
                var modfn = GlobalContext.Module.AddFunction(name, modty.UnderlyingType);

                var fn   = new GamaFunctionRef(retty, parms, modty, modfn, false);
                var unit = new GamaFunctionCompiler(NamespaceContext, fn);
                unit.Visit(context.block());
                if (unit.Finish() == 0)
                {
                    if (attrs != null)
                    {
                        var attributes = new GamaAttributeCompiler(this).Visit(attrs);
                        if (attributes != null)
                        {
                            fn.Attributes = attributes;
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    fnlist.AddFunction(fn);
                }
                else
                {
                    ; // TODO:
                }
                return(true);
            }
        }
Esempio n. 17
0
        public override bool VisitStructLevelMethod([NotNull] GamaParser.StructLevelMethodContext context)
        {
            var fndef = context.topLevelFuncDef();
            var name  = fndef.Symbol().GetText();
            GamaFunctionList fnlist = null;

            if (name == "new")
            {
                fnlist = StructType.Meta.Constructors;
            }
            else
            {
                fnlist = StructType.Meta.GetMethod(name);
            }

            if (fnlist == null)
            {
                fnlist = new GamaFunctionList(name);
                StructType.Meta.Methods.Add(fnlist);
            }

            var retty  = InstanceTypes.Void;
            var tyname = fndef.typeName();

            if (tyname != null)
            {
                retty = Parent.NamespaceContext.FindTypeRefGlobal(tyname);
                if (retty == null)
                {
                    Parent.GlobalContext.AddError(new ErrorTypeNotFound(tyname));
                    return(false);
                }
            }

            var stplist   = fndef.symbolTypePairList();
            var paramlist = new GamaParamList();

            paramlist.Add("this", new GamaPointer(StructType)); // add self as a pointer since this is a method

            if (stplist != null)
            {
                var pairs = stplist.symbolTypePair();
                foreach (var p in pairs)
                {
                    var ty = Parent.NamespaceContext.FindTypeRefGlobal(p.typeName());
                    if (ty == null)
                    {
                        Parent.GlobalContext.AddError(new ErrorTypeNotFound(p.typeName()));
                        return(false);
                    }
                    if (!paramlist.Add(p.Symbol().GetText(), ty))
                    {
                        Parent.GlobalContext.AddError(new ErrorDuplicateParameter(p));
                        return(false);
                    }
                }
            }

            if (fnlist.FindFunction(paramlist) != null)
            {
                Parent.GlobalContext.AddError(new ErrorDuplicateMethod(fndef));
                return(false);
            }

            var modty = new GamaFunction(retty, paramlist.Parameters.Select(p => p.Type).ToArray(), LLVMTypeRef.CreateFunction(retty.UnderlyingType, paramlist.Parameters.Select(p => p.Type.UnderlyingType).ToArray()));
            var modfn = Parent.GlobalContext.Module.AddFunction($"{ StructType.Name }.{ name }", modty.UnderlyingType);

            var fn = new GamaFunctionRef(retty, paramlist, modty, modfn, true);

            /* Parameters are added to top frame of the target function, but they are not treated as conventional variables */

            var unit = new GamaFunctionCompiler(Parent.NamespaceContext, fn);

            foreach (var p in paramlist.Parameters)
            {
                unit.Top.AddValue(p.Name, new GamaValueRef(p.Type, modfn.GetParam(p.Index), false));
            }

            unit.Visit(fndef.block());
            if (unit.Finish() == 0)
            {
                // TODO: handle type method attributes
                fnlist.AddFunction(fn);
            }
            else
            {
                ;
            }

            return(true);
        }
Esempio n. 18
0
 public Type FunctionType(Type returnType, Type[] paramTypes, bool isVarArg) =>
 LLVMTypeRef.CreateFunction(returnType, Array.ConvertAll(paramTypes, tp => (LLVMTypeRef)tp), isVarArg);