[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.
This commit is contained in:
Tomas Lindquist Olsen 2008-07-13 20:49:10 +02:00
parent 3f37dbe005
commit dbd640a3dc
9 changed files with 91 additions and 60 deletions

View file

@ -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<LLValue*> ctorargs;
ctorargs.push_back(mem);
for (size_t i=0; i<arguments->dim; ++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

View file

@ -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()

View file

@ -157,7 +157,6 @@ struct DFuncValue : DValue
FuncDeclaration* func;
LLValue* val;
LLValue* vthis;
unsigned cc;
DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt = 0);

View file

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

View file

@ -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

61
gen/tocall.cpp Normal file
View file

@ -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<LLValue*> args;
if (thisOffset)
args.push_back(thismem);
for (size_t i=0; i<arguments->dim; ++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);
}

View file

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

View file

@ -361,6 +361,7 @@
<path>tests/dstress/extract__.c</path>
<path>tests/dstress/ifeq__.c</path>
<path>tests/dstress/return__.c</path>
<path>e2ir.c</path>
</blacklist>
<build>
<buildtool>make</buildtool>

View file

@ -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