public ICodeBlock EmitUnary(ICodeBlock Value, Operator Op) { var valBlock = (CodeBlock)Value; var valType = valBlock.Type; if (Op.Equals(Operator.Not)) { return(new UnaryBlock(this, valBlock, valType, BuildNot, ConstNot)); } else if (Op.Equals(Operator.Subtract)) { if (valType.GetIsFloatingPoint()) { return(new UnaryBlock(this, valBlock, valType, BuildFNeg, ConstFNeg)); } else { return(new UnaryBlock(this, valBlock, valType, BuildNeg, ConstNeg)); } } else if (Op.Equals(Operator.Box)) { // To box a value x, we create a struct `{ typeof(x).vtable, x }` // and store it in the heap. // So we basically want to do this: // // var ptr = gcalloc(sizeof({ byte*, typeof(x) })); // ptr->vtable = (byte*)T.vtable; // ptr->value = x; // ptr // var constructedType = valType.MakePointerType(PointerKind.BoxPointer); var tmp = new SSAVariable("box_tmp", constructedType); var expr = new InitializedExpression( new BlockStatement(new IStatement[] { tmp.CreateSetStatement( Allocate( ToExpression(new SizeOfBlock(this, constructedType, false)), constructedType)), new StoreAtAddressStatement( GetVTablePtrExpr(tmp.CreateGetExpression()), ToExpression(new TypeVTableBlock(this, (LLVMType)valType))), new StoreAtAddressStatement( CreateUnboxExpr(tmp.CreateGetExpression(), valType), ToExpression(valBlock)) }), tmp.CreateGetExpression()); return(expr.Emit(this)); } else { throw new NotImplementedException( string.Format( "Unsupported unary op: {0} {1}", Op.Name, valType.FullName)); } }
public ICodeBlock EmitNewObject(IMethod Constructor, IEnumerable <ICodeBlock> Arguments) { var constructedType = Constructor.DeclaringType; if (constructedType.GetIsValueType()) { throw new InvalidOperationException( "cannot create a new 'struct' object; " + "'struct' object creation must be lowered to " + "method invocation before codegen"); } else if (constructedType.GetIsReferenceType()) { var tmp = new SSAVariable("class_tmp", constructedType); // Write the following code: // // var ptr = gcalloc(sizeof(T)); // ptr->vtable = (byte*)T.vtable; // ptr->ctor(args...); // static if (!#builtin_has_attribute(T.Finalize, NopAttribute)) // register_finalizer(ptr, T.Finalize); // ptr // var statements = new List <IStatement>(); statements.Add( tmp.CreateSetStatement( Allocate( ToExpression(new SizeOfBlock(this, constructedType, false)), constructedType))); statements.Add( new StoreAtAddressStatement( GetVTablePtrExpr(tmp.CreateGetExpression()), ToExpression(new TypeVTableBlock(this, (LLVMType)constructedType)))); statements.Add( new ExpressionStatement( new InvocationExpression( Constructor, tmp.CreateGetExpression(), Arguments.Cast <CodeBlock>() .Select <CodeBlock, IExpression>(ToExpression) .ToArray <IExpression>()))); var expr = new InitializedExpression( new BlockStatement(statements), tmp.CreateGetExpression()); return(expr.Emit(this)); } throw new NotImplementedException(); }