/// <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); }