From dbd640a3dc72174fb706de95c66a195ec2c4c0d6 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Sun, 13 Jul 2008 20:49:10 +0200 Subject: [PATCH] [svn r368] Fixed custom class allocators with arbitrary user arguments. Closes #25 Removed some dead code. Started on a more generalised approach to call misc. D functions. --- gen/classes.cpp | 65 ++++++++++------------------------------ gen/dvalue.cpp | 1 - gen/dvalue.h | 1 - gen/functions.cpp | 4 +-- gen/llvmhelpers.h | 11 +++++++ gen/tocall.cpp | 61 +++++++++++++++++++++++++++++++++++++ gen/toir.cpp | 6 ---- llvmdc.kdevelop | 1 + llvmdc.kdevelop.filelist | 1 + 9 files changed, 91 insertions(+), 60 deletions(-) create mode 100644 gen/tocall.cpp diff --git a/gen/classes.cpp b/gen/classes.cpp index 6608d1d6..a5dde05a 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -796,15 +796,18 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp) // custom allocator else if (newexp->allocator) { - DtoForceDeclareDsymbol(newexp->allocator); - assert(newexp->newargs); - assert(newexp->newargs->dim == 1); + DValue* res = DtoCallDFunc(newexp->allocator, newexp->newargs); + mem = DtoBitCast(res->getRVal(), DtoType(tc), "newclass_custom"); - llvm::Function* fn = newexp->allocator->ir.irFunc->func; - assert(fn); - DValue* arg = ((Expression*)newexp->newargs->data[0])->toElem(gIR); - mem = gIR->CreateCallOrInvoke(fn, arg->getRVal(), "newclass_custom_alloc")->get(); - mem = DtoBitCast(mem, DtoType(tc), "newclass_custom"); +// DtoForceDeclareDsymbol(newexp->allocator); +// assert(newexp->newargs); +// assert(newexp->newargs->dim == 1); +// +// llvm::Function* fn = newexp->allocator->ir.irFunc->func; +// assert(fn); +// DValue* arg = ((Expression*)newexp->newargs->data[0])->toElem(gIR); +// mem = gIR->CreateCallOrInvoke(fn, arg->getRVal(), "newclass_custom_alloc")->get(); +// mem = DtoBitCast(mem, DtoType(tc), "newclass_custom"); } // default allocator else @@ -834,13 +837,11 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp) { Logger::println("Resolving nested context"); LOG_SCOPE; - size_t idx = 2; - //idx += tc->sym->ir.irStruct->interfaces.size(); - LLValue* nest = gIR->func()->decl->ir.irFunc->nestedVar; + LLValue* nest = gIR->func()->nestedVar; if (!nest) - nest = gIR->func()->decl->ir.irFunc->thisVar; + nest = gIR->func()->thisVar; assert(nest); - LLValue* gep = DtoGEPi(mem,0,idx,"tmp"); + LLValue* gep = DtoGEPi(mem,0,2,"tmp"); nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); DtoStore(nest, gep); } @@ -849,7 +850,7 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp) if (newexp->member) { assert(newexp->arguments != NULL); - return DtoCallClassCtor(tc, newexp->member, newexp->arguments, mem); + return DtoCallDFunc(newexp->member, newexp->arguments, tc, mem); } // return default constructed class @@ -887,42 +888,6 @@ void DtoInitClass(TypeClass* tc, LLValue* dst) ////////////////////////////////////////////////////////////////////////////////////////// -DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* arguments, LLValue* mem) -{ - Logger::println("Calling constructor"); - LOG_SCOPE; - - assert(ctor); - DtoForceDeclareDsymbol(ctor); - llvm::Function* fn = ctor->ir.irFunc->func; - TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); - - llvm::PAListPtr palist; - - std::vector ctorargs; - ctorargs.push_back(mem); - for (size_t i=0; idim; ++i) - { - Expression* ex = (Expression*)arguments->data[i]; - Argument* fnarg = Argument::getNth(tf->parameters, i); - DValue* argval = DtoArgument(fnarg, ex); - LLValue* a = argval->getRVal(); - const LLType* aty = fn->getFunctionType()->getParamType(i+1); - if (a->getType() != aty) - a = DtoBitCast(a, aty); - ctorargs.push_back(a); - if (fnarg && fnarg->llvmByVal) - palist = palist.addAttr(i+2, llvm::ParamAttr::ByVal); // return,this is 2 - } - CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, ctorargs.begin(), ctorargs.end(), "tmp"); - call->setCallingConv(DtoCallingConv(LINKd)); - call->setParamAttrs(palist); - - return new DImValue(type, call->get(), false); -} - -////////////////////////////////////////////////////////////////////////////////////////// - void DtoFinalizeClass(LLValue* inst) { // get runtime function diff --git a/gen/dvalue.cpp b/gen/dvalue.cpp index 9cabb23d..d120a1fc 100644 --- a/gen/dvalue.cpp +++ b/gen/dvalue.cpp @@ -69,7 +69,6 @@ DFuncValue::DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt) type = func->type; val = v; vthis = vt; - cc = (unsigned)-1; } LLValue* DFuncValue::getRVal() diff --git a/gen/dvalue.h b/gen/dvalue.h index aa75ad99..9924185e 100644 --- a/gen/dvalue.h +++ b/gen/dvalue.h @@ -157,7 +157,6 @@ struct DFuncValue : DValue FuncDeclaration* func; LLValue* val; LLValue* vthis; - unsigned cc; DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt = 0); diff --git a/gen/functions.cpp b/gen/functions.cpp index b1de6adf..870fe6cb 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -827,8 +827,8 @@ void DtoVariadicArgument(Expression* argexp, LLValue* dst) { Logger::println("DtoVariadicArgument"); LOG_SCOPE; - DVarValue* vv = new DVarValue(argexp->type, dst, true); - DtoAssign(vv, argexp->toElem(gIR)); + DVarValue vv(argexp->type, dst, true); + DtoAssign(&vv, argexp->toElem(gIR)); } ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 15e41f40..282d665d 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -1,6 +1,7 @@ #ifndef LLVMDC_GEN_LLVMHELPERS_H #define LLVMDC_GEN_LLVMHELPERS_H +#include "gen/llvm.h" #include "statement.h" // dynamic memory helpers @@ -87,4 +88,14 @@ DValue* DtoBinRem(DValue* lhs, DValue* rhs); // target stuff void findDefaultTarget(); +/** + * Calls a D function (with D calling conv). + * @param fdecl The FuncDeclaration to call + * @param arguments The Array of ExpressionS to pass as arguments. + * @param type Optionally the TypeClass of the 'this' arguement. + * @param thismem Optionally the LLValue for the 'this' argument. + * @return The function call's return value. + */ +DValue* DtoCallDFunc(FuncDeclaration* fdecl, Array* arguments, TypeClass* type=0, LLValue* thismem=0); + #endif diff --git a/gen/tocall.cpp b/gen/tocall.cpp new file mode 100644 index 00000000..bb45d607 --- /dev/null +++ b/gen/tocall.cpp @@ -0,0 +1,61 @@ +#include "gen/llvm.h" + +#include "mtype.h" +#include "declaration.h" + +#include "gen/tollvm.h" +#include "gen/llvmhelpers.h" +#include "gen/irstate.h" +#include "gen/dvalue.h" +#include "gen/functions.h" + +#include "gen/logger.h" + +////////////////////////////////////////////////////////////////////////////////////////// + +DValue* DtoCallDFunc(FuncDeclaration* fdecl, Array* arguments, TypeClass* type, LLValue* thismem) +{ + Logger::println("Calling function: %s", fdecl->toPrettyChars()); + LOG_SCOPE; + + assert(fdecl); + DtoForceDeclareDsymbol(fdecl); + llvm::Function* fn = fdecl->ir.irFunc->func; + TypeFunction* tf = (TypeFunction*)DtoDType(fdecl->type); + + llvm::PAListPtr palist; + + int thisOffset = 0; + if (type || thismem) + { + assert(type && thismem); + thisOffset = 1; + } + + std::vector args; + if (thisOffset) + args.push_back(thismem); + for (size_t i=0; idim; ++i) + { + Expression* ex = (Expression*)arguments->data[i]; + Argument* fnarg = Argument::getNth(tf->parameters, i); + DValue* argval = DtoArgument(fnarg, ex); + LLValue* a = argval->getRVal(); + const LLType* aty = fn->getFunctionType()->getParamType(i+thisOffset); + if (a->getType() != aty) + { + Logger::cout() << "expected: " << *aty << '\n'; + Logger::cout() << "got: " << *a->getType() << '\n'; + a = DtoBitCast(a, aty); + } + args.push_back(a); + if (fnarg && fnarg->llvmByVal) + palist = palist.addAttr(i+thisOffset+1, llvm::ParamAttr::ByVal); // return,this,args... + } + + CallOrInvoke* call = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), "tmp"); + call->setCallingConv(DtoCallingConv(LINKd)); + call->setParamAttrs(palist); + + return new DImValue(type, call->get(), false); +} diff --git a/gen/toir.cpp b/gen/toir.cpp index e48d58ac..171f4962 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1233,12 +1233,6 @@ DValue* CallExp::toElem(IRState* p) call->setCallingConv(DtoCallingConv(dlink)); } } - /*else if (delegateCall) { - call->setCallingConv(DtoCallingConv(dlink)); - }*/ - else if (dfn && dfn->cc != (unsigned)-1) { - call->setCallingConv(dfn->cc); - } else { call->setCallingConv(DtoCallingConv(dlink)); } diff --git a/llvmdc.kdevelop b/llvmdc.kdevelop index 2fa81bd0..89f10c8d 100644 --- a/llvmdc.kdevelop +++ b/llvmdc.kdevelop @@ -361,6 +361,7 @@ tests/dstress/extract__.c tests/dstress/ifeq__.c tests/dstress/return__.c + e2ir.c make diff --git a/llvmdc.kdevelop.filelist b/llvmdc.kdevelop.filelist index 0250200b..105c9abe 100644 --- a/llvmdc.kdevelop.filelist +++ b/llvmdc.kdevelop.filelist @@ -124,6 +124,7 @@ gen/runtime.h gen/statements.cpp gen/structs.cpp gen/structs.h +gen/tocall.cpp gen/tocsym.cpp gen/todebug.cpp gen/todebug.h