public ILabel AllocateStruct(Function.Function function, StructType structType, ILocation target, ILabel after) { if (structType.Fields.Count == 0) { return(after); } var allocateFunctionName = NameMangler.GetMangledName("allocate", new List <AST.DataType>() { IntType.Instance }, null); var allocateFunc = new Function.Function( null, allocateFunctionName, new List <AST.VariableDeclaration>() { new AST.VariableDeclaration(null, IntType.Instance, "size", null) }, isEntryPoint: false, isForeign: true); var sizeRegister = new VirtualRegister(); var call = this.callGenerator.GenerateCall(target, new List <VirtualRegister>() { sizeRegister }, after, callerFunction: function, function: allocateFunc); var writeSize = new RegisterWrite(sizeRegister, new IntegerImmediateValue(structType.Fields.Count * 8)); var startLabel = this.labelFactory.GetLabel(new Tree(writeSize, new UnconditionalJump(call))); return(startLabel); }
private Computation ConvertNode(AST.FunctionCall node, ILabel after) { var resultLocation = node.Declaration.ReturnType.IsHeapType() ? (ILocation)this.function.ReserveStackFrameLocation(node.Declaration.ReturnType) : new VirtualRegister(); var argumentRegisters = Enumerable .Range(0, node.Arguments.Count) .Select(i => new VirtualRegister()) .ToList(); var callArguments = argumentRegisters.ToList(); callArguments.Reverse(); var tempQualifier = node.Declaration.Function; var callLabel = this.callGenerator.GenerateCall( resultLocation, callArguments, after, this.function, tempQualifier); var argumentsLabel = node.Arguments .Reverse() .Zip(argumentRegisters, (argument, register) => new { Argument = argument, Register = register }) .Aggregate( callLabel, (next, x) => { var result = this.labelFactory.WithLabel( writeLabel => { var argValue = this.GenerateExpression(x.Argument, writeLabel); Node write = new RegisterWrite(x.Register, argValue.Result); return(new Tree(write, new UnconditionalJump(next)), argValue); });