Пример #1
0
        /// <summary>
        /// Creates the "newobj" method for a type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The function.</returns>
        private ValueRef createNewobjMethod(TypeDefinition type)
        {
            string     name    = string.Format("newobj_{0}", type.FullName);
            BuilderRef builder = LLVM.CreateBuilderInContext(mCompiler.ModuleContext);

            // Create method type.
            TypeRef  funcType = LLVM.FunctionType(TypeHelper.GetTypeRefFromType(type), new TypeRef[0], false);
            ValueRef func     = LLVM.AddFunction(mCompiler.Module, name, funcType);

            LLVM.SetLinkage(func, Linkage.InternalLinkage);

            BasicBlockRef entry = LLVM.AppendBasicBlockInContext(mCompiler.ModuleContext, func, string.Empty);

            LLVM.PositionBuilderAtEnd(builder, entry);

            // Allocate space on the heap for this object.
            TypeRef  typeRef = mCompiler.Lookup.GetTypeRef(type);
            ValueRef objPtr  = LLVM.BuildMalloc(builder, typeRef, "newobj");

            // Initialize class VTables.
            Lookup lookup = mCompiler.Lookup;

            if (lookup.NeedsVirtualCall(type))
            {
                VTable vtable = lookup.GetVTable(type);
                KeyValuePair <TypeDefinition, Tuple <TypeRef, ValueRef> >[] others = vtable.GetAllClassEntries();
                foreach (KeyValuePair <TypeDefinition, Tuple <TypeRef, ValueRef> > pair in others)
                {
                    uint     index     = lookup.GetClassVTableIndex(pair.Key);
                    ValueRef vTableGep = LLVM.BuildInBoundsGEP(builder, objPtr, new ValueRef[] { LLVM.ConstInt(TypeHelper.Int32, 0, false), LLVM.ConstInt(TypeHelper.Int32, index, false) }, "vtabledst");
                    LLVM.BuildStore(builder, pair.Value.Item2, vTableGep);
                }
            }

            // Initialize interface indirection table.
            if (type.HasInterfaces)
            {
                ValueRef indirectionTable = mLookup.GetInterfaceIndirectionTable(type);
                ValueRef gep = LLVM.BuildInBoundsGEP(builder, objPtr, new ValueRef[] { LLVM.ConstInt(TypeHelper.Int32, 0, false), LLVM.ConstInt(TypeHelper.Int32, 0, false) }, "interfaceindirectiontablegep");
                LLVM.BuildStore(builder, LLVM.BuildPointerCast(builder, indirectionTable, TypeHelper.VoidPtr, string.Empty), gep);
            }

            // Return object pointer.
            LLVM.BuildRet(builder, objPtr);

            LLVM.DisposeBuilder(builder);

            return(func);
        }