mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-14 20:03:14 +01:00
Fixes for closures
This commit is contained in:
@@ -772,6 +772,9 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||
}
|
||||
#endif
|
||||
|
||||
FuncGen fg;
|
||||
irfunction->gen = &fg;
|
||||
|
||||
DtoCreateNestedContext(fd);
|
||||
|
||||
#if DMDV2
|
||||
@@ -801,12 +804,8 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||
}
|
||||
|
||||
// output function body
|
||||
{
|
||||
FuncGen fg;
|
||||
irfunction->gen = &fg;
|
||||
fd->fbody->toIR(gIR);
|
||||
irfunction->gen = 0;
|
||||
}
|
||||
fd->fbody->toIR(gIR);
|
||||
irfunction->gen = 0;
|
||||
|
||||
// TODO: clean up this mess
|
||||
|
||||
|
||||
@@ -130,6 +130,17 @@ llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const
|
||||
return ai;
|
||||
}
|
||||
|
||||
LLValue* DtoGcMalloc(const llvm::Type* lltype, const char* name)
|
||||
{
|
||||
// get runtime function
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemory");
|
||||
// parameters
|
||||
LLValue *size = DtoConstSize_t(getTypeAllocSize(lltype));
|
||||
// call runtime allocator
|
||||
LLValue* mem = gIR->CreateCallOrInvoke(fn, size, name).getInstruction();
|
||||
// cast
|
||||
return DtoBitCast(mem, getPtrToType(lltype), name);
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -45,6 +45,7 @@ void DtoDeleteArray(DValue* arr);
|
||||
llvm::AllocaInst* DtoAlloca(Type* type, const char* name = "");
|
||||
llvm::AllocaInst* DtoArrayAlloca(Type* type, unsigned arraysize, const char* name = "");
|
||||
llvm::AllocaInst* DtoRawAlloca(const llvm::Type* lltype, size_t alignment, const char* name = "");
|
||||
LLValue* DtoGcMalloc(const llvm::Type* lltype, const char* name = "");
|
||||
|
||||
// assertion generator
|
||||
void DtoAssert(Module* M, Loc loc, DValue* msg);
|
||||
|
||||
@@ -68,6 +68,24 @@ static FuncDeclaration* getParentFunc(Dsymbol* sym, bool stopOnStatic) {
|
||||
return (parent ? parent->isFuncDeclaration() : NULL);
|
||||
}
|
||||
|
||||
static void storeVariable(VarDeclaration *vd, LLValue *dst)
|
||||
{
|
||||
LLValue *value = vd->ir.irLocal->value;
|
||||
#if DMDV2
|
||||
int ty = vd->type->ty;
|
||||
FuncDeclaration *fd = getParentFunc(vd, true);
|
||||
assert(fd && "No parent function for nested variable?");
|
||||
if (fd->needsClosure() && !vd->isRef() && (ty == Tstruct || ty == Tsarray) && isaPointer(value->getType())) {
|
||||
// Copy structs and static arrays
|
||||
LLValue *mem = DtoGcMalloc(DtoType(vd->type), ".gc_mem");
|
||||
DtoAggrCopy(mem, value);
|
||||
DtoAlignedStore(mem, dst);
|
||||
} else
|
||||
#endif
|
||||
// Store the address into the frame
|
||||
DtoAlignedStore(value, dst);
|
||||
}
|
||||
|
||||
static void DtoCreateNestedContextType(FuncDeclaration* fd);
|
||||
|
||||
DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd, bool byref)
|
||||
@@ -206,7 +224,7 @@ void DtoNestedInit(VarDeclaration* vd)
|
||||
val = DtoAlignedLoad(val, (std::string(".frame.") + parentfunc->toChars()).c_str());
|
||||
}
|
||||
val = DtoGEPi(val, 0, vd->ir.irLocal->nestedIndex, vd->toChars());
|
||||
DtoAlignedStore(vd->ir.irLocal->value, val);
|
||||
storeVariable(vd, val);
|
||||
} else {
|
||||
// Already initialized in DtoCreateNestedContext
|
||||
}
|
||||
@@ -534,11 +552,15 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
||||
unsigned depth = irfunction->depth;
|
||||
const llvm::StructType *frameType = irfunction->frameType;
|
||||
// Create frame for current function and append to frames list
|
||||
// FIXME: For D2, this should be a gc_malloc (or similar) call, not alloca
|
||||
// (Note that it'd also require more aggressive copying of
|
||||
// by-value parameters instead of just alloca'd ones)
|
||||
// FIXME: alignment ?
|
||||
LLValue* frame = DtoRawAlloca(frameType, 0, ".frame");
|
||||
LLValue* frame = 0;
|
||||
#if DMDV2
|
||||
if (fd->needsClosure())
|
||||
frame = DtoGcMalloc(frameType, ".frame");
|
||||
else
|
||||
#endif
|
||||
frame = DtoRawAlloca(frameType, 0, ".frame");
|
||||
|
||||
|
||||
// copy parent frames into beginning
|
||||
if (depth != 0) {
|
||||
@@ -602,7 +624,7 @@ void DtoCreateNestedContext(FuncDeclaration* fd) {
|
||||
// passed-in pointer (for 'ref' or 'out' parameters) or
|
||||
// a pointer arg with byval attribute.
|
||||
// Store the address into the frame and set the byref flag.
|
||||
DtoAlignedStore(vd->ir.irLocal->value, gep);
|
||||
storeVariable(vd, gep);
|
||||
vd->ir.irLocal->byref = true;
|
||||
}
|
||||
} else if (vd->isRef() || vd->isOut()) {
|
||||
|
||||
@@ -264,6 +264,17 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// void* _d_allocmemory(size_t sz)
|
||||
{
|
||||
llvm::StringRef fname("_d_allocmemory");
|
||||
std::vector<const LLType*> types;
|
||||
types.push_back(sizeTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M)
|
||||
->setAttributes(Attr_NoAlias);
|
||||
}
|
||||
|
||||
// void* _d_allocmemoryT(TypeInfo ti)
|
||||
{
|
||||
llvm::StringRef fname("_d_allocmemoryT");
|
||||
|
||||
@@ -778,6 +778,11 @@ size_t getTypePaddedSize(const LLType* t)
|
||||
return sz;
|
||||
}
|
||||
|
||||
size_t getTypeAllocSize(const LLType* t)
|
||||
{
|
||||
return gTargetData->getTypeAllocSize(t);
|
||||
}
|
||||
|
||||
unsigned char getABITypeAlign(const LLType* t)
|
||||
{
|
||||
return gTargetData->getABITypeAlignment(t);
|
||||
|
||||
@@ -95,6 +95,7 @@ LLConstant* getNullValue(const LLType* t);
|
||||
size_t getTypeBitSize(const LLType* t);
|
||||
size_t getTypeStoreSize(const LLType* t);
|
||||
size_t getTypePaddedSize(const LLType* t);
|
||||
size_t getTypeAllocSize(const LLType* t);
|
||||
|
||||
// type alignments
|
||||
unsigned char getABITypeAlign(const LLType* t);
|
||||
|
||||
Reference in New Issue
Block a user