Example #1
0
        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));
            }
        }
Example #2
0
        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();
        }