mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-01 15:40:55 +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
|
// custom allocator
|
||||||
else if (newexp->allocator)
|
else if (newexp->allocator)
|
||||||
{
|
{
|
||||||
DtoForceDeclareDsymbol(newexp->allocator);
|
DValue* res = DtoCallDFunc(newexp->allocator, newexp->newargs);
|
||||||
assert(newexp->newargs);
|
mem = DtoBitCast(res->getRVal(), DtoType(tc), "newclass_custom");
|
||||||
assert(newexp->newargs->dim == 1);
|
|
||||||
|
|
||||||
llvm::Function* fn = newexp->allocator->ir.irFunc->func;
|
// DtoForceDeclareDsymbol(newexp->allocator);
|
||||||
assert(fn);
|
// assert(newexp->newargs);
|
||||||
DValue* arg = ((Expression*)newexp->newargs->data[0])->toElem(gIR);
|
// assert(newexp->newargs->dim == 1);
|
||||||
mem = gIR->CreateCallOrInvoke(fn, arg->getRVal(), "newclass_custom_alloc")->get();
|
//
|
||||||
mem = DtoBitCast(mem, 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");
|
||||||
}
|
}
|
||||||
// default allocator
|
// default allocator
|
||||||
else
|
else
|
||||||
|
@ -834,13 +837,11 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp)
|
||||||
{
|
{
|
||||||
Logger::println("Resolving nested context");
|
Logger::println("Resolving nested context");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
size_t idx = 2;
|
LLValue* nest = gIR->func()->nestedVar;
|
||||||
//idx += tc->sym->ir.irStruct->interfaces.size();
|
|
||||||
LLValue* nest = gIR->func()->decl->ir.irFunc->nestedVar;
|
|
||||||
if (!nest)
|
if (!nest)
|
||||||
nest = gIR->func()->decl->ir.irFunc->thisVar;
|
nest = gIR->func()->thisVar;
|
||||||
assert(nest);
|
assert(nest);
|
||||||
LLValue* gep = DtoGEPi(mem,0,idx,"tmp");
|
LLValue* gep = DtoGEPi(mem,0,2,"tmp");
|
||||||
nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
|
nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
|
||||||
DtoStore(nest, gep);
|
DtoStore(nest, gep);
|
||||||
}
|
}
|
||||||
|
@ -849,7 +850,7 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp)
|
||||||
if (newexp->member)
|
if (newexp->member)
|
||||||
{
|
{
|
||||||
assert(newexp->arguments != NULL);
|
assert(newexp->arguments != NULL);
|
||||||
return DtoCallClassCtor(tc, newexp->member, newexp->arguments, mem);
|
return DtoCallDFunc(newexp->member, newexp->arguments, tc, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return default constructed class
|
// 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)
|
void DtoFinalizeClass(LLValue* inst)
|
||||||
{
|
{
|
||||||
// get runtime function
|
// get runtime function
|
||||||
|
|
|
@ -69,7 +69,6 @@ DFuncValue::DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt)
|
||||||
type = func->type;
|
type = func->type;
|
||||||
val = v;
|
val = v;
|
||||||
vthis = vt;
|
vthis = vt;
|
||||||
cc = (unsigned)-1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LLValue* DFuncValue::getRVal()
|
LLValue* DFuncValue::getRVal()
|
||||||
|
|
|
@ -157,7 +157,6 @@ struct DFuncValue : DValue
|
||||||
FuncDeclaration* func;
|
FuncDeclaration* func;
|
||||||
LLValue* val;
|
LLValue* val;
|
||||||
LLValue* vthis;
|
LLValue* vthis;
|
||||||
unsigned cc;
|
|
||||||
|
|
||||||
DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt = 0);
|
DFuncValue(FuncDeclaration* fd, LLValue* v, LLValue* vt = 0);
|
||||||
|
|
||||||
|
|
|
@ -827,8 +827,8 @@ void DtoVariadicArgument(Expression* argexp, LLValue* dst)
|
||||||
{
|
{
|
||||||
Logger::println("DtoVariadicArgument");
|
Logger::println("DtoVariadicArgument");
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
DVarValue* vv = new DVarValue(argexp->type, dst, true);
|
DVarValue vv(argexp->type, dst, true);
|
||||||
DtoAssign(vv, argexp->toElem(gIR));
|
DtoAssign(&vv, argexp->toElem(gIR));
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef LLVMDC_GEN_LLVMHELPERS_H
|
#ifndef LLVMDC_GEN_LLVMHELPERS_H
|
||||||
#define LLVMDC_GEN_LLVMHELPERS_H
|
#define LLVMDC_GEN_LLVMHELPERS_H
|
||||||
|
|
||||||
|
#include "gen/llvm.h"
|
||||||
#include "statement.h"
|
#include "statement.h"
|
||||||
|
|
||||||
// dynamic memory helpers
|
// dynamic memory helpers
|
||||||
|
@ -87,4 +88,14 @@ DValue* DtoBinRem(DValue* lhs, DValue* rhs);
|
||||||
// target stuff
|
// target stuff
|
||||||
void findDefaultTarget();
|
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
|
#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));
|
call->setCallingConv(DtoCallingConv(dlink));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*else if (delegateCall) {
|
|
||||||
call->setCallingConv(DtoCallingConv(dlink));
|
|
||||||
}*/
|
|
||||||
else if (dfn && dfn->cc != (unsigned)-1) {
|
|
||||||
call->setCallingConv(dfn->cc);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
call->setCallingConv(DtoCallingConv(dlink));
|
call->setCallingConv(DtoCallingConv(dlink));
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,6 +361,7 @@
|
||||||
<path>tests/dstress/extract__.c</path>
|
<path>tests/dstress/extract__.c</path>
|
||||||
<path>tests/dstress/ifeq__.c</path>
|
<path>tests/dstress/ifeq__.c</path>
|
||||||
<path>tests/dstress/return__.c</path>
|
<path>tests/dstress/return__.c</path>
|
||||||
|
<path>e2ir.c</path>
|
||||||
</blacklist>
|
</blacklist>
|
||||||
<build>
|
<build>
|
||||||
<buildtool>make</buildtool>
|
<buildtool>make</buildtool>
|
||||||
|
|
|
@ -124,6 +124,7 @@ gen/runtime.h
|
||||||
gen/statements.cpp
|
gen/statements.cpp
|
||||||
gen/structs.cpp
|
gen/structs.cpp
|
||||||
gen/structs.h
|
gen/structs.h
|
||||||
|
gen/tocall.cpp
|
||||||
gen/tocsym.cpp
|
gen/tocsym.cpp
|
||||||
gen/todebug.cpp
|
gen/todebug.cpp
|
||||||
gen/todebug.h
|
gen/todebug.h
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue