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)) } } }); }
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); }
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); }
public FunctionType BuildSignature() { return(FunctionType.Create(ret, args.ToArray())); }
/// <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); } }