Example #1
0
        private static IReadOnlyDictionary <string, TypeMember> CreateMembers(GlobalCompilationContext ctx)
        {
            var global = ctx.GlobalNamespace;

            return(new Dictionary <string, TypeMember>(2)
            {
                {
                    "allocate_fn",
                    new TypeMember
                    {
                        Index = 0,
                        Name = "allocate_fn",
                        Type = PointerType.Create(FunctionType.Create(global.Types["void*"], new[] { global.Types["u32"] }, false, ctx)),
                    }
                },

                {
                    "free_fn",
                    new TypeMember
                    {
                        Index = 1,
                        Name = "free_fn",
                        Type = PointerType.Create(FunctionType.Create(global.Types["void"], new [] { global.Types["void*"] }, false, ctx))
                    }
                }
            });
        }
Example #2
0
        public static Function AddFunction(this Module module, Type returnType, string name, Type[] parameterTypes, Action <Function, IRBuilder> action)
        {
            var type    = FunctionType.Create(returnType, parameterTypes);
            var func    = module.AddFunction(name, type);
            var block   = func.AppendBasicBlock(string.Empty);
            var builder = IRBuilder.Create(module.Context);

            builder.PositionBuilderAtEnd(block);
            action(func, builder);
            return(func);
        }
Example #3
0
        private void CreateDefaultConstructor(StructDefinition node)
        {
            // Get the structure.
            Structure building = node.GetStructure();

            // Check for an user defined constructor.
            if (building.GetConstructor() != null)
            {
                return;
            }

            // Instance the building.
            GenericPrototype contGenProto = building.GetGenericPrototype();
            int       templateArgs        = contGenProto.GetPlaceHolderCount();
            Structure buildingInstance    = building;

            if (templateArgs != 0)
            {
                IChelaType[] thisArgs = new IChelaType[templateArgs];
                for (int i = 0; i < templateArgs; ++i)
                {
                    thisArgs[i] = contGenProto.GetPlaceHolder(i);
                }
                buildingInstance = (Structure)building.InstanceGeneric(
                    new GenericInstance(contGenProto, thisArgs), currentModule);
            }

            // Create the default constructor function type.
            List <IChelaType> arguments = new List <IChelaType> ();

            arguments.Add(ReferenceType.Create(buildingInstance));
            FunctionType ctorType = FunctionType.Create(ChelaType.GetVoidType(), arguments);

            // Create the constructor method.
            MemberFlags flags       = MemberFlags.Public | MemberFlags.Constructor;
            Method      constructor = new Method(building.GetName(), flags, building);

            constructor.SetFunctionType(ctorType);

            // Store it.
            building.AddFunction("<ctor>", constructor);
            node.SetDefaultConstructor(constructor);
        }
Example #4
0
 public FunctionType BuildSignature()
 {
     return(FunctionType.Create(ret, args.ToArray()));
 }
Example #5
0
        /// <summary>
        /// Deserializes the signature <paramref name="ss"/>. Any instantiated
        /// registers or stack variables are introduced into the Frame.
        /// </summary>
        /// <param name="ss"></param>
        /// <param name="frame"></param>
        /// <returns></returns>
        public FunctionType?Deserialize(SerializedSignature?ss, Frame frame)
        {
            if (ss == null)
            {
                return(null);
            }
            // If there is no explict return address size,
            // use the architecture's default return address size.

            var retAddrSize = ss.ReturnAddressOnStack != 0
                ? ss.ReturnAddressOnStack
                : this.Architecture.ReturnAddressOnStack;

            if (!ss.ParametersValid)
            {
                return(new FunctionType
                {
                    StackDelta = ss.StackDelta,
                    ReturnAddressOnStack = retAddrSize,
                });
            }

            var parameters = new List <Identifier>();

            Identifier?ret = null;

            if (UseUserSpecifiedStorages(ss))
            {
                this.argDeser = new ArgumentDeserializer(
                    this,
                    Architecture,
                    frame,
                    retAddrSize,
                    Architecture.WordWidth.Size);

                int fpuDelta = FpuStackOffset;
                FpuStackOffset = 0;
                if (ss.ReturnValue != null)
                {
                    ret       = DeserializeArgument(ss.ReturnValue, "");
                    fpuDelta += FpuStackOffset;
                }

                FpuStackOffset = 0;
                if (ss.Arguments != null)
                {
                    for (int iArg = 0; iArg < ss.Arguments.Length; ++iArg)
                    {
                        var sArg = ss.Arguments[iArg];
                        var arg  = DeserializeArgument(sArg, ss.Convention);
                        if (arg != null)
                        {
                            parameters.Add(arg);
                        }
                    }
                }
                fpuDelta      -= FpuStackOffset;
                FpuStackOffset = fpuDelta;
                var sig = FunctionType.Create(ret, parameters.ToArray());
                sig.IsVariadic      = this.IsVariadic;
                sig.IsInstanceMetod = ss.IsInstanceMethod;
                ApplyConvention(ss, sig);
                return(sig);
            }
            else
            {
                var dtRet = ss.ReturnValue != null && ss.ReturnValue.Type != null
                    ? ss.ReturnValue.Type.Accept(TypeLoader)
                    : null;

                var dtThis = ss.EnclosingType != null
                    ? new Pointer(ss.EnclosingType.Accept(TypeLoader), Architecture.PointerType.BitSize)
                    : null;
                var dtParameters = ss.Arguments != null
                    ? ss.Arguments
                                   .TakeWhile(p => p.Name != "...")
                                   .Select(p => p.Type !.Accept(TypeLoader))
                                   .ToList()
                    : new List <DataType>();

                // A calling convention governs the storage of a the
                // parameters

                var cc = platform.GetCallingConvention(ss.Convention);
                if (cc == null)
                {
                    // It was impossible to determine a calling convention,
                    // so we don't know how to decode this signature accurately.
                    return(new FunctionType
                    {
                        StackDelta = ss.StackDelta,
                        ReturnAddressOnStack = retAddrSize,
                    });
                }
                var res = new CallingConventionEmitter();
                cc.Generate(res, dtRet, dtThis, dtParameters);
                if (res.Return != null)
                {
                    ret = new Identifier(
                        res.Return is RegisterStorage retReg ? retReg.Name : "",
                        dtRet ?? VoidType.Instance,
                        res.Return);
                }
                if (res.ImplicitThis != null)
                {
                    var param = new Identifier("this", dtThis !, res.ImplicitThis);
                    parameters.Add(param);
                }
                bool isVariadic = false;
                if (ss.Arguments != null)
                {
                    for (int i = 0; i < ss.Arguments.Length; ++i)
                    {
                        if (ss.Arguments[i].Name == "...")
                        {
                            isVariadic = true;
                        }
                        else
                        {
                            var name  = GenerateParameterName(ss.Arguments[i].Name, dtParameters[i], res.Parameters[i]);
                            var param = new Identifier(name, dtParameters[i], res.Parameters[i]);
                            parameters.Add(param);
                        }
                    }
                }
                var ft = FunctionType.Create(ret, parameters.ToArray());
                ft.IsInstanceMetod = ss.IsInstanceMethod;
                ft.StackDelta      = ss.StackDelta != 0
                        ? ss.StackDelta
                        : res.StackDelta;
                ft.FpuStackDelta        = res.FpuStackDelta;
                ft.ReturnAddressOnStack = retAddrSize;
                ft.IsVariadic           = isVariadic;
                return(ft);
            }
        }