mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-01 07:30:43 +03:00
[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:
parent
3f37dbe005
commit
dbd640a3dc
9 changed files with 91 additions and 60 deletions
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -157,7 +157,6 @@ struct DFuncValue : DValue
|
|||
FuncDeclaration* func;
|
||||
LLValue* val;
|
||||
LLValue* vthis;
|
||||
unsigned cc;
|
||||
|
||||
DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt = 0);
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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
61
gen/tocall.cpp
Normal 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);
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue