예제 #1
0
        public override BlockCodegen Emit(BasicBlockBuilder BasicBlock)
        {
            var delegateAndBlock = Delegate.Emit(BasicBlock);

            BasicBlock = delegateAndBlock.BasicBlock;

            var methodTypeAllocBlock = (CodeBlock)codeGen.Allocate(
                new StaticCastExpression(
                    LLVMCodeGenerator.ToExpression(
                        new ConstantBlock(codeGen, PrimitiveTypes.UInt64, SizeOf(DelegateBlock.MethodTypeLayout))),
                    PrimitiveTypes.UInt64),
                Type).Emit(codeGen);

            var methodTypeAllocCodegen = methodTypeAllocBlock.Emit(BasicBlock);

            BasicBlock = methodTypeAllocCodegen.BasicBlock;

            BuildStore(
                BasicBlock.Builder,
                AtAddressEmitVariable.BuildConstantLoad(
                    BasicBlock.Builder,
                    BuildBitCast(
                        BasicBlock.Builder,
                        delegateAndBlock.Value,
                        PointerType(DelegateBlock.MethodTypeLayout, 0),
                        "delegate_ptr"),
                    "delegate_data"),
                methodTypeAllocCodegen.Value);

            BuildStore(
                BasicBlock.Builder,
                TypeVTableBlock.BuildTypeVTable(BasicBlock, Type),
                BuildStructGEP(BasicBlock.Builder, methodTypeAllocCodegen.Value, 0, "vtable_ptr_ptr"));

            return(new BlockCodegen(BasicBlock, methodTypeAllocCodegen.Value));
        }
예제 #2
0
        public override BlockCodegen Emit(BasicBlockBuilder BasicBlock)
        {
            var targetAndBlock = InvocationBlock.EmitTarget(BasicBlock, Target);

            BasicBlock = targetAndBlock.BasicBlock;

            var calleeAndBlock = InvocationBlock.EmitCallee(BasicBlock, targetAndBlock.Value, Callee, Op);

            BasicBlock = calleeAndBlock.BasicBlock;

            var methodTypeAllocBlock = (CodeBlock)codeGen.Allocate(
                new StaticCastExpression(
                    LLVMCodeGenerator.ToExpression(
                        new ConstantBlock(codeGen, PrimitiveTypes.UInt64, SizeOf(MethodTypeLayout))),
                    PrimitiveTypes.UInt64),
                Type).Emit(codeGen);

            var methodTypeAllocCodegen = methodTypeAllocBlock.Emit(BasicBlock);

            BasicBlock = methodTypeAllocCodegen.BasicBlock;

            BuildStore(
                BasicBlock.Builder,
                TypeVTableBlock.BuildTypeVTable(BasicBlock, Type),
                BuildStructGEP(BasicBlock.Builder, methodTypeAllocCodegen.Value, 0, "vtable_ptr_ptr"));

            bool hasContext = targetAndBlock.Value.Pointer != IntPtr.Zero;

            if (hasContext)
            {
                BuildStore(
                    BasicBlock.Builder,
                    BuildBitCast(
                        BasicBlock.Builder,
                        targetAndBlock.Value,
                        PointerType(Int8Type(), 0),
                        "context_obj"),
                    BuildStructGEP(
                        BasicBlock.Builder,
                        methodTypeAllocCodegen.Value,
                        1,
                        "context_obj_ptr"));
            }

            BuildStore(
                BasicBlock.Builder,
                BuildBitCast(
                    BasicBlock.Builder,
                    calleeAndBlock.Value,
                    PointerType(Int8Type(), 0),
                    "opaque_func_ptr"),
                BuildStructGEP(
                    BasicBlock.Builder,
                    methodTypeAllocCodegen.Value,
                    2,
                    "func_ptr_ptr"));

            BuildStore(
                BasicBlock.Builder,
                ConstInt(Int1Type(), hasContext ? 1ul : 0ul, false),
                BuildStructGEP(BasicBlock.Builder, methodTypeAllocCodegen.Value, 3, "has_context_ptr"));

            return(new BlockCodegen(BasicBlock, methodTypeAllocCodegen.Value));
        }