mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-12 06:49:02 +02:00
[svn r219] Fixed: the tango/lib/gc/basic garbage collector now compiles and links into an executable (change in tango/lib/llvmdc-posix.mak), closes #5 .
Changed: removed the crappy realloc based dynamic memory runtime and started moving over to DMD style runtime support, part of moving to real GC. Fixed: dynamic arrays now use GC runtime for allocating memory. Fixed: new expression now use GC for allocating memory. Changed: revamped the dynamic array support routines related to dynamic memory. Fixed: assertions no longer create exsessive allocas. Changed: misc. minor cleanups.
This commit is contained in:
227
gen/arrays.cpp
227
gen/arrays.cpp
@@ -62,6 +62,9 @@ const llvm::ArrayType* DtoStaticArrayType(Type* t)
|
||||
|
||||
void DtoSetArrayToNull(llvm::Value* v)
|
||||
{
|
||||
Logger::println("DtoSetArrayToNull");
|
||||
LOG_SCOPE;
|
||||
|
||||
llvm::Value* len = DtoGEPi(v,0,0,"tmp",gIR->scopebb());
|
||||
llvm::Value* zerolen = llvm::ConstantInt::get(len->getType()->getContainedType(0), 0, false);
|
||||
new llvm::StoreInst(zerolen, len, gIR->scopebb());
|
||||
@@ -76,6 +79,9 @@ void DtoSetArrayToNull(llvm::Value* v)
|
||||
|
||||
void DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
|
||||
{
|
||||
Logger::println("DtoArrayAssign");
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(gIR);
|
||||
if (dst->getType() == src->getType())
|
||||
{
|
||||
@@ -114,6 +120,9 @@ void DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
|
||||
|
||||
void DtoArrayInit(llvm::Value* l, llvm::Value* r)
|
||||
{
|
||||
Logger::println("DtoArrayInit");
|
||||
LOG_SCOPE;
|
||||
|
||||
const llvm::PointerType* ptrty = isaPointer(l->getType());
|
||||
const llvm::Type* t = ptrty->getContainedType(0);
|
||||
const llvm::ArrayType* arrty = isaArray(t);
|
||||
@@ -151,6 +160,9 @@ static size_t checkRectArrayInit(const llvm::Type* pt, constLLVMTypeP& finalty)
|
||||
|
||||
void DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val)
|
||||
{
|
||||
Logger::println("DtoArrayInit");
|
||||
LOG_SCOPE;
|
||||
|
||||
Logger::cout() << "array: " << *ptr << " dim: " << *dim << " val: " << *val << '\n';
|
||||
const llvm::Type* pt = ptr->getType()->getContainedType(0);
|
||||
const llvm::Type* t = val->getType();
|
||||
@@ -244,16 +256,24 @@ void DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val)
|
||||
|
||||
void DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr)
|
||||
{
|
||||
Logger::cout() << "DtoSetArray(" << *arr << ", " << *dim << ", " << *ptr << ")\n";
|
||||
Logger::println("DtoSetArray");
|
||||
LOG_SCOPE;
|
||||
|
||||
Logger::cout() << "arr = " << *arr << '\n';
|
||||
Logger::cout() << "dim = " << *dim << '\n';
|
||||
Logger::cout() << "ptr = " << *ptr << '\n';
|
||||
|
||||
const llvm::StructType* st = isaStruct(arr->getType()->getContainedType(0));
|
||||
|
||||
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
||||
|
||||
llvm::Value* arrdim = DtoGEP(arr,zero,zero,"tmp",gIR->scopebb());
|
||||
Logger::cout() << "arrdim = " << *arrdim << '\n';
|
||||
new llvm::StoreInst(dim, arrdim, gIR->scopebb());
|
||||
|
||||
llvm::Value* arrptr = DtoGEP(arr,zero,one,"tmp",gIR->scopebb());
|
||||
Logger::cout() << "arrptr = " << *arrptr << '\n';
|
||||
new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
|
||||
}
|
||||
|
||||
@@ -484,60 +504,81 @@ llvm::Constant* DtoConstSlice(llvm::Constant* dim, llvm::Constant* ptr)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
llvm::Value* DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit)
|
||||
DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
|
||||
{
|
||||
const llvm::Type* ty = DtoType(dty);
|
||||
assert(ty != llvm::Type::VoidTy);
|
||||
size_t sz = getABITypeSize(ty);
|
||||
llvm::ConstantInt* n = llvm::ConstantInt::get(DtoSize_t(), sz, false);
|
||||
llvm::Value* bytesize = (sz == 1) ? dim : llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb());
|
||||
Logger::println("DtoNewDynArray : %s", arrayType->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
llvm::Value* nullptr = llvm::ConstantPointerNull::get(getPtrToType(ty));
|
||||
bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
|
||||
|
||||
llvm::Value* newptr = DtoRealloc(nullptr, bytesize);
|
||||
llvm::SmallVector<llvm::Value*,2> args;
|
||||
args.push_back(DtoTypeInfoOf(arrayType));
|
||||
assert(DtoType(dim->getType()) == DtoSize_t());
|
||||
args.push_back(dim->getRVal());
|
||||
|
||||
if (doinit) {
|
||||
llvm::Value* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem");
|
||||
const llvm::Type* dstType = DtoType(arrayType)->getContainedType(1);
|
||||
if (newptr->getType() != dstType)
|
||||
newptr = DtoBitCast(newptr, dstType, ".gc_mem");
|
||||
|
||||
Logger::cout() << "final ptr = " << *newptr << '\n';
|
||||
|
||||
#if 0
|
||||
if (defaultInit) {
|
||||
DValue* e = dty->defaultInit()->toElem(gIR);
|
||||
DtoArrayInit(newptr,dim,e->getRVal());
|
||||
}
|
||||
#endif
|
||||
|
||||
llvm::Value* lenptr = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
|
||||
new llvm::StoreInst(dim,lenptr,gIR->scopebb());
|
||||
llvm::Value* ptrptr = DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
|
||||
new llvm::StoreInst(newptr,ptrptr,gIR->scopebb());
|
||||
|
||||
return newptr;
|
||||
return new DSliceValue(arrayType, args[1], newptr);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
llvm::Value* DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz)
|
||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
|
||||
{
|
||||
llvm::Value* ptr = DtoGEPi(arr, 0, 1, "tmp", gIR->scopebb());
|
||||
llvm::Value* ptrld = new llvm::LoadInst(ptr,"tmp",gIR->scopebb());
|
||||
Logger::println("DtoResizeDynArray : %s", arrayType->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
size_t isz = getABITypeSize(ptrld->getType()->getContainedType(0));
|
||||
llvm::ConstantInt* n = llvm::ConstantInt::get(DtoSize_t(), isz, false);
|
||||
llvm::Value* bytesz = (isz == 1) ? sz : llvm::BinaryOperator::createMul(n,sz,"tmp",gIR->scopebb());
|
||||
assert(array);
|
||||
assert(newdim);
|
||||
assert(arrayType);
|
||||
assert(arrayType->toBasetype()->ty == Tarray);
|
||||
|
||||
llvm::Value* newptr = DtoRealloc(ptrld, bytesz);
|
||||
new llvm::StoreInst(newptr,ptr,gIR->scopebb());
|
||||
bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_arraysetlengthT" : "_d_arraysetlengthiT" );
|
||||
|
||||
llvm::Value* len = DtoGEPi(arr, 0, 0, "tmp", gIR->scopebb());
|
||||
new llvm::StoreInst(sz,len,gIR->scopebb());
|
||||
llvm::SmallVector<llvm::Value*,4> args;
|
||||
args.push_back(DtoTypeInfoOf(arrayType));
|
||||
args.push_back(newdim->getRVal());
|
||||
args.push_back(DtoArrayLen(array));
|
||||
llvm::Value* arrPtr = DtoArrayPtr(array);
|
||||
Logger::cout() << "arrPtr = " << *arrPtr << '\n';
|
||||
args.push_back(DtoBitCast(arrPtr, fn->getFunctionType()->getParamType(3), "tmp"));
|
||||
|
||||
return newptr;
|
||||
llvm::Value* newptr = gIR->ir->CreateCall(fn, args.begin(), args.end(), ".gc_mem");
|
||||
if (newptr->getType() != arrPtr->getType())
|
||||
newptr = DtoBitCast(newptr, arrPtr->getType(), ".gc_mem");
|
||||
|
||||
return new DSliceValue(arrayType, newdim->getRVal(), newptr);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void DtoCatAssignElement(llvm::Value* arr, Expression* exp)
|
||||
DSliceValue* DtoCatAssignElement(DValue* array, Expression* exp)
|
||||
{
|
||||
llvm::Value* ptr = DtoGEPi(arr, 0, 0, "tmp");
|
||||
llvm::Value* idx = DtoLoad(ptr);
|
||||
llvm::Value* one = llvm::ConstantInt::get(idx->getType(),1,false);
|
||||
llvm::Value* len = llvm::BinaryOperator::createAdd(idx, one, "tmp", gIR->scopebb());
|
||||
DtoResizeDynArray(arr,len);
|
||||
Logger::println("DtoCatAssignElement");
|
||||
LOG_SCOPE;
|
||||
|
||||
ptr = DtoLoad(DtoGEPi(arr, 0, 1, "tmp"));
|
||||
assert(array);
|
||||
|
||||
llvm::Value* idx = DtoArrayLen(array);
|
||||
llvm::Value* one = DtoConstSize_t(1);
|
||||
llvm::Value* len = gIR->ir->CreateAdd(idx,one,"tmp");
|
||||
|
||||
DValue* newdim = new DImValue(Type::tsize_t, len);
|
||||
DSliceValue* slice = DtoResizeDynArray(array->getType(), array, newdim);
|
||||
|
||||
llvm::Value* ptr = slice->ptr;
|
||||
ptr = new llvm::GetElementPtrInst(ptr, idx, "tmp", gIR->scopebb());
|
||||
|
||||
DValue* dptr = new DVarValue(exp->type, ptr, true);
|
||||
@@ -548,33 +589,47 @@ void DtoCatAssignElement(llvm::Value* arr, Expression* exp)
|
||||
|
||||
if (!e->inPlace())
|
||||
DtoAssign(dptr, e);
|
||||
|
||||
return slice;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void DtoCatAssignArray(llvm::Value* arr, Expression* exp)
|
||||
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp)
|
||||
{
|
||||
Logger::println("DtoCatAssignArray");
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* e = exp->toElem(gIR);
|
||||
|
||||
llvm::Value *len1, *len2, *src1, *src2, *res;
|
||||
|
||||
DValue* darr = new DVarValue(exp->type, arr, true);
|
||||
|
||||
len1 = DtoArrayLen(darr);
|
||||
len1 = DtoArrayLen(arr);
|
||||
len2 = DtoArrayLen(e);
|
||||
res = gIR->ir->CreateAdd(len1,len2,"tmp");
|
||||
|
||||
llvm::Value* mem = DtoResizeDynArray(arr,res);
|
||||
DValue* newdim = new DImValue(Type::tsize_t, res);
|
||||
DSliceValue* slice = DtoResizeDynArray(arr->getType(), arr, newdim);
|
||||
|
||||
src1 = DtoArrayPtr(darr);
|
||||
src1 = slice->ptr;
|
||||
src2 = DtoArrayPtr(e);
|
||||
|
||||
mem = gIR->ir->CreateGEP(mem,len1,"tmp");
|
||||
DtoMemCpy(mem,src2,len2);
|
||||
// advance ptr
|
||||
src1 = gIR->ir->CreateGEP(src1,len1,"tmp");
|
||||
|
||||
// memcpy
|
||||
llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src2->getType()->getContainedType(0)));
|
||||
llvm::Value* bytelen = gIR->ir->CreateMul(len2, elemSize, "tmp");
|
||||
DtoMemCpy(src1,src2,bytelen);
|
||||
|
||||
return slice;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void DtoCatArrays(llvm::Value* arr, Expression* exp1, Expression* exp2)
|
||||
DSliceValue* DtoCatArrays(Type* type, Expression* exp1, Expression* exp2)
|
||||
{
|
||||
Logger::println("DtoCatArrays");
|
||||
LOG_SCOPE;
|
||||
|
||||
Type* t1 = DtoDType(exp1->type);
|
||||
Type* t2 = DtoDType(exp2->type);
|
||||
|
||||
@@ -590,50 +645,86 @@ void DtoCatArrays(llvm::Value* arr, Expression* exp1, Expression* exp2)
|
||||
len2 = DtoArrayLen(e2);
|
||||
res = gIR->ir->CreateAdd(len1,len2,"tmp");
|
||||
|
||||
llvm::Value* mem = DtoNewDynArray(arr, res, DtoDType(t1->next), false);
|
||||
DValue* lenval = new DImValue(Type::tsize_t, res);
|
||||
DSliceValue* slice = DtoNewDynArray(type, lenval, false);
|
||||
llvm::Value* mem = slice->ptr;
|
||||
|
||||
src1 = DtoArrayPtr(e1);
|
||||
src2 = DtoArrayPtr(e2);
|
||||
|
||||
DtoMemCpy(mem,src1,len1);
|
||||
// first memcpy
|
||||
llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0)));
|
||||
llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp");
|
||||
DtoMemCpy(mem,src1,bytelen);
|
||||
|
||||
// second memcpy
|
||||
mem = gIR->ir->CreateGEP(mem,len1,"tmp");
|
||||
DtoMemCpy(mem,src2,len2);
|
||||
bytelen = gIR->ir->CreateMul(len2, elemSize, "tmp");
|
||||
DtoMemCpy(mem,src2,bytelen);
|
||||
|
||||
return slice;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
void DtoCatArrayElement(llvm::Value* arr, Expression* exp1, Expression* exp2)
|
||||
DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2)
|
||||
{
|
||||
Logger::println("DtoCatArrayElement");
|
||||
LOG_SCOPE;
|
||||
|
||||
Type* t1 = DtoDType(exp1->type);
|
||||
Type* t2 = DtoDType(exp2->type);
|
||||
|
||||
// handle reverse case
|
||||
if (t2->next && t1 == DtoDType(t2->next))
|
||||
{
|
||||
Type* tmp = t1;
|
||||
t1 = t2;
|
||||
t2 = tmp;
|
||||
Expression* e = exp1;
|
||||
exp1 = exp2;
|
||||
exp2 = e;
|
||||
}
|
||||
|
||||
DValue* e1 = exp1->toElem(gIR);
|
||||
DValue* e2 = exp2->toElem(gIR);
|
||||
|
||||
llvm::Value *len1, *src1, *res;
|
||||
|
||||
len1 = DtoArrayLen(e1);
|
||||
res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
|
||||
// handle prefix case, eg. int~int[]
|
||||
if (t2->next && t1 == DtoDType(t2->next))
|
||||
{
|
||||
len1 = DtoArrayLen(e2);
|
||||
res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
|
||||
|
||||
llvm::Value* mem = DtoNewDynArray(arr, res, DtoDType(t1->next), false);
|
||||
DValue* lenval = new DImValue(Type::tsize_t, res);
|
||||
DSliceValue* slice = DtoNewDynArray(type, lenval, false);
|
||||
llvm::Value* mem = slice->ptr;
|
||||
|
||||
src1 = DtoArrayPtr(e1);
|
||||
DVarValue* memval = new DVarValue(e1->getType(), mem, true);
|
||||
DtoAssign(memval, e1);
|
||||
|
||||
DtoMemCpy(mem,src1,len1);
|
||||
src1 = DtoArrayPtr(e2);
|
||||
|
||||
mem = gIR->ir->CreateGEP(mem,len1,"tmp");
|
||||
DVarValue* memval = new DVarValue(e2->getType(), mem, true);
|
||||
DtoAssign(memval, e2);
|
||||
mem = gIR->ir->CreateGEP(mem,DtoConstSize_t(1),"tmp");
|
||||
|
||||
llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0)));
|
||||
llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp");
|
||||
DtoMemCpy(mem,src1,bytelen);
|
||||
|
||||
|
||||
return slice;
|
||||
}
|
||||
// handle suffix case, eg. int[]~int
|
||||
else
|
||||
{
|
||||
len1 = DtoArrayLen(e1);
|
||||
res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
|
||||
|
||||
DValue* lenval = new DImValue(Type::tsize_t, res);
|
||||
DSliceValue* slice = DtoNewDynArray(type, lenval, false);
|
||||
llvm::Value* mem = slice->ptr;
|
||||
|
||||
src1 = DtoArrayPtr(e1);
|
||||
|
||||
llvm::Value* elemSize = DtoConstSize_t(getABITypeSize(src1->getType()->getContainedType(0)));
|
||||
llvm::Value* bytelen = gIR->ir->CreateMul(len1, elemSize, "tmp");
|
||||
DtoMemCpy(mem,src1,bytelen);
|
||||
|
||||
mem = gIR->ir->CreateGEP(mem,len1,"tmp");
|
||||
DVarValue* memval = new DVarValue(e2->getType(), mem, true);
|
||||
DtoAssign(memval, e2);
|
||||
|
||||
return slice;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -866,6 +957,7 @@ llvm::Value* DtoArrayLen(DValue* v)
|
||||
{
|
||||
Logger::println("DtoArrayLen");
|
||||
LOG_SCOPE;
|
||||
|
||||
Type* t = DtoDType(v->getType());
|
||||
if (t->ty == Tarray) {
|
||||
if (DSliceValue* s = v->isSlice()) {
|
||||
@@ -894,6 +986,9 @@ llvm::Value* DtoArrayLen(DValue* v)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
llvm::Value* DtoArrayPtr(DValue* v)
|
||||
{
|
||||
Logger::println("DtoArrayPtr");
|
||||
LOG_SCOPE;
|
||||
|
||||
Type* t = DtoDType(v->getType());
|
||||
if (t->ty == Tarray) {
|
||||
if (DSliceValue* s = v->isSlice()) {
|
||||
|
||||
12
gen/arrays.h
12
gen/arrays.h
@@ -19,13 +19,13 @@ void DtoArrayAssign(llvm::Value* l, llvm::Value* r);
|
||||
void DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr);
|
||||
void DtoSetArrayToNull(llvm::Value* v);
|
||||
|
||||
llvm::Value* DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit=true);
|
||||
llvm::Value* DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz);
|
||||
DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit=true);
|
||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
|
||||
|
||||
void DtoCatAssignElement(llvm::Value* arr, Expression* exp);
|
||||
void DtoCatAssignArray(llvm::Value* arr, Expression* exp);
|
||||
void DtoCatArrays(llvm::Value* arr, Expression* e1, Expression* e2);
|
||||
void DtoCatArrayElement(llvm::Value* arr, Expression* exp1, Expression* exp2);
|
||||
DSliceValue* DtoCatAssignElement(DValue* arr, Expression* exp);
|
||||
DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp);
|
||||
DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2);
|
||||
DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2);
|
||||
|
||||
void DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src);
|
||||
|
||||
|
||||
@@ -237,25 +237,41 @@ static void LLVM_D_BuildRuntimeModule()
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// realloc
|
||||
// void* _d_realloc(void* ptr, size_t n)
|
||||
// void* _d_allocmemoryT(TypeInfo ti)
|
||||
{
|
||||
std::string fname("_d_realloc");
|
||||
std::string fname("_d_allocmemoryT");
|
||||
std::vector<const llvm::Type*> types;
|
||||
types.push_back(voidPtrTy);
|
||||
types.push_back(sizeTy);
|
||||
types.push_back(typeInfoTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||
new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
}
|
||||
|
||||
// free
|
||||
// void _d_free(void* ptr)
|
||||
// void* _d_newarrayT(TypeInfo ti, size_t length)
|
||||
// void* _d_newarrayiT(TypeInfo ti, size_t length)
|
||||
{
|
||||
std::string fname("_d_free");
|
||||
std::string fname("_d_newarrayT");
|
||||
std::string fname2("_d_newarrayiT");
|
||||
std::vector<const llvm::Type*> types;
|
||||
types.push_back(voidPtrTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidTy, types, false);
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(sizeTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||
new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
|
||||
// void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
|
||||
// void* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
|
||||
{
|
||||
std::string fname("_d_arraysetlengthT");
|
||||
std::string fname2("_d_arraysetlengthiT");
|
||||
std::vector<const llvm::Type*> types;
|
||||
types.push_back(typeInfoTy);
|
||||
types.push_back(sizeTy);
|
||||
types.push_back(sizeTy);
|
||||
types.push_back(voidPtrTy);
|
||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||
new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||
new llvm::Function(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||
}
|
||||
|
||||
// Object _d_newclass(ClassInfo ci)
|
||||
|
||||
92
gen/toir.cpp
92
gen/toir.cpp
@@ -572,10 +572,15 @@ DValue* AssignExp::toElem(IRState* p)
|
||||
DImValue* im = r->isIm();
|
||||
if (!im || !im->inPlace()) {
|
||||
Logger::println("assignment not inplace");
|
||||
if (l->isArrayLen())
|
||||
DtoResizeDynArray(l->getLVal(), r->getRVal());
|
||||
if (DArrayLenValue* al = l->isArrayLen())
|
||||
{
|
||||
DSliceValue* slice = DtoResizeDynArray(l->getType(), l, r);
|
||||
DtoAssign(l, slice);
|
||||
}
|
||||
else
|
||||
{
|
||||
DtoAssign(l, r);
|
||||
}
|
||||
}
|
||||
|
||||
if (l->isSlice() || l->isComplex())
|
||||
@@ -1932,10 +1937,54 @@ DValue* NewExp::toElem(IRState* p)
|
||||
|
||||
Type* ntype = DtoDType(newtype);
|
||||
|
||||
// new class
|
||||
if (ntype->ty == Tclass) {
|
||||
Logger::println("new class");
|
||||
return DtoNewClass((TypeClass*)ntype, this);
|
||||
}
|
||||
// new dynamic array
|
||||
else if (ntype->ty == Tarray)
|
||||
{
|
||||
Logger::println("new dynamic array: %s", newtype->toChars());
|
||||
// get dim
|
||||
assert(arguments);
|
||||
assert(arguments->dim == 1);
|
||||
DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
|
||||
// allocate & init
|
||||
return DtoNewDynArray(newtype, sz, true);
|
||||
}
|
||||
// new static array
|
||||
else if (ntype->ty == Tsarray)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
// new struct
|
||||
else if (ntype->ty == Tstruct)
|
||||
{
|
||||
// allocate
|
||||
llvm::Value* mem = DtoNew(newtype);
|
||||
// init
|
||||
TypeStruct* ts = (TypeStruct*)ntype;
|
||||
if (ts->isZeroInit()) {
|
||||
DtoStructZeroInit(mem);
|
||||
}
|
||||
else {
|
||||
assert(ts->sym);
|
||||
DtoStructCopy(mem,ts->sym->ir.irStruct->init);
|
||||
}
|
||||
return new DImValue(type, mem, false);
|
||||
}
|
||||
// new basic type
|
||||
else
|
||||
{
|
||||
// allocate
|
||||
llvm::Value* mem = DtoNew(newtype);
|
||||
// BUG: default initialize
|
||||
// return
|
||||
return new DImValue(type, mem, false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
const llvm::Type* t = DtoType(ntype);
|
||||
|
||||
@@ -1969,8 +2018,17 @@ DValue* NewExp::toElem(IRState* p)
|
||||
assert(0 && "num args to 'new' != 1");
|
||||
}
|
||||
}
|
||||
// simple new of a single non-class, non-array value
|
||||
else {
|
||||
emem = new llvm::MallocInst(t,"tmp",p->scopebb());
|
||||
// get runtime function
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT");
|
||||
// get type info
|
||||
llvm::Constant* ti = DtoTypeInfoOf(newtype);
|
||||
assert(isaPointer(ti));
|
||||
// call runtime
|
||||
llvm::SmallVector<llvm::Value*,1> arg;
|
||||
arg.push_back(ti);
|
||||
emem = p->ir->CreateCall(fn, arg.begin(), arg.end(), ".gc_mem");
|
||||
}
|
||||
|
||||
if (ntype->ty == Tstruct) {
|
||||
@@ -1985,6 +2043,8 @@ DValue* NewExp::toElem(IRState* p)
|
||||
}
|
||||
|
||||
return new DImValue(type, emem, inplace);
|
||||
*/
|
||||
assert(0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -2053,10 +2113,11 @@ DValue* ArrayLengthExp::toElem(IRState* p)
|
||||
LOG_SCOPE;
|
||||
|
||||
DValue* u = e1->toElem(p);
|
||||
Logger::println("e1 = %s", e1->type->toChars());
|
||||
|
||||
if (p->topexp() && p->topexp()->e1 == this)
|
||||
{
|
||||
return new DArrayLenValue(type, u->getLVal());
|
||||
return new DArrayLenValue(e1->type, u->getLVal());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2488,6 +2549,19 @@ DValue* CatExp::toElem(IRState* p)
|
||||
|
||||
bool arrNarr = DtoDType(e1->type) == DtoDType(e2->type);
|
||||
|
||||
// array ~ array
|
||||
if (arrNarr)
|
||||
{
|
||||
return DtoCatArrays(type, e1, e2);
|
||||
}
|
||||
// array ~ element
|
||||
// element ~ array
|
||||
else
|
||||
{
|
||||
return DtoCatArrayElement(type, e1, e2);
|
||||
}
|
||||
|
||||
/*
|
||||
IRExp* ex = p->topexp();
|
||||
if (ex && ex->e2 == this) {
|
||||
assert(ex->v);
|
||||
@@ -2502,11 +2576,13 @@ DValue* CatExp::toElem(IRState* p)
|
||||
const llvm::Type* arrty = DtoType(t);
|
||||
llvm::Value* dst = new llvm::AllocaInst(arrty, "tmpmem", p->topallocapoint());
|
||||
if (arrNarr)
|
||||
DtoCatAr
|
||||
DtoCatArrays(dst,e1,e2);
|
||||
else
|
||||
DtoCatArrayElement(dst,e1,e2);
|
||||
return new DVarValue(type, dst, true);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -2523,15 +2599,17 @@ DValue* CatAssignExp::toElem(IRState* p)
|
||||
Type* e2type = DtoDType(e2->type);
|
||||
|
||||
if (e2type == elemtype) {
|
||||
DtoCatAssignElement(l->getLVal(),e2);
|
||||
DSliceValue* slice = DtoCatAssignElement(l,e2);
|
||||
DtoAssign(l, slice);
|
||||
}
|
||||
else if (e1type == e2type) {
|
||||
DtoCatAssignArray(l->getLVal(),e2);
|
||||
DSliceValue* slice = DtoCatAssignArray(l,e2);
|
||||
DtoAssign(l, slice);
|
||||
}
|
||||
else
|
||||
assert(0 && "only one element at a time right now");
|
||||
|
||||
return 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
110
gen/tollvm.cpp
110
gen/tollvm.cpp
@@ -655,41 +655,20 @@ llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::stri
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty)
|
||||
llvm::Value* DtoNew(Type* newtype)
|
||||
{
|
||||
/*size_t sz = gTargetData->getTypeSize(ty);
|
||||
llvm::ConstantInt* n = llvm::ConstantInt::get(DtoSize_t(), sz, false);
|
||||
if (ptr == 0) {
|
||||
llvm::PointerType* i8pty = getPtrToType(llvm::Type::Int8Ty);
|
||||
ptr = llvm::ConstantPointerNull::get(i8pty);
|
||||
}
|
||||
return DtoRealloc(ptr, n);*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* n)
|
||||
{
|
||||
assert(ptr);
|
||||
assert(n);
|
||||
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_realloc");
|
||||
assert(fn);
|
||||
|
||||
llvm::Value* newptr = ptr;
|
||||
|
||||
const llvm::PointerType* i8pty = getPtrToType(llvm::Type::Int8Ty);
|
||||
if (ptr->getType() != i8pty) {
|
||||
newptr = new llvm::BitCastInst(ptr,i8pty,"tmp",gIR->scopebb());
|
||||
}
|
||||
|
||||
std::vector<llvm::Value*> args;
|
||||
args.push_back(newptr);
|
||||
args.push_back(n);
|
||||
llvm::Value* ret = new llvm::CallInst(fn, args.begin(), args.end(), "tmprealloc", gIR->scopebb());
|
||||
|
||||
return ret->getType() == ptr->getType() ? ret : new llvm::BitCastInst(ret,ptr->getType(),"tmp",gIR->scopebb());
|
||||
// get runtime function
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_allocmemoryT");
|
||||
// get type info
|
||||
llvm::Constant* ti = DtoTypeInfoOf(newtype);
|
||||
assert(isaPointer(ti));
|
||||
// call runtime
|
||||
llvm::SmallVector<llvm::Value*,1> arg;
|
||||
arg.push_back(ti);
|
||||
// allocate
|
||||
llvm::Value* mem = gIR->ir->CreateCall(fn, arg.begin(), arg.end(), ".gc_mem");
|
||||
// cast
|
||||
return DtoBitCast(mem, getPtrToType(DtoType(newtype)), ".gc_mem");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -707,7 +686,12 @@ void DtoAssert(Loc* loc, DValue* msg)
|
||||
|
||||
// file param
|
||||
c = DtoConstString(loc->filename);
|
||||
llvm::AllocaInst* alloc = new llvm::AllocaInst(c->getType(), "srcfile", gIR->topallocapoint());
|
||||
llvm::AllocaInst* alloc = gIR->func()->srcfileArg;
|
||||
if (!alloc)
|
||||
{
|
||||
alloc = new llvm::AllocaInst(c->getType(), "srcfile", gIR->topallocapoint());
|
||||
gIR->func()->srcfileArg = alloc;
|
||||
}
|
||||
llvm::Value* ptr = DtoGEPi(alloc, 0,0, "tmp");
|
||||
DtoStore(c->getOperand(0), ptr);
|
||||
ptr = DtoGEPi(alloc, 0,1, "tmp");
|
||||
@@ -938,6 +922,7 @@ void DtoAssign(DValue* lhs, DValue* rhs)
|
||||
}
|
||||
// rhs is slice
|
||||
else if (DSliceValue* s = rhs->isSlice()) {
|
||||
assert(s->getType()->toBasetype() == lhs->getType()->toBasetype());
|
||||
DtoSetArray(lhs->getLVal(),s->len,s->ptr);
|
||||
}
|
||||
// null
|
||||
@@ -1282,15 +1267,6 @@ llvm::Constant* DtoConstStringPtr(const char* str, const char* section)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Constant* DtoConstNullPtr(const llvm::Type* t)
|
||||
{
|
||||
return llvm::ConstantPointerNull::get(
|
||||
getPtrToType(t)
|
||||
);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void DtoMemSetZero(llvm::Value* dst, llvm::Value* nbytes)
|
||||
{
|
||||
const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty);
|
||||
@@ -1319,20 +1295,19 @@ void DtoMemSetZero(llvm::Value* dst, llvm::Value* nbytes)
|
||||
|
||||
void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes)
|
||||
{
|
||||
assert(dst->getType() == src->getType());
|
||||
const llvm::Type* arrty = getVoidPtrType();
|
||||
|
||||
const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty);
|
||||
llvm::Value *dstarr, *srcarr;
|
||||
llvm::Value* dstarr;
|
||||
if (dst->getType() == arrty)
|
||||
{
|
||||
dstarr = dst;
|
||||
srcarr = src;
|
||||
}
|
||||
else
|
||||
{
|
||||
dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
|
||||
srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
|
||||
}
|
||||
dstarr = DtoBitCast(dst, arrty, "tmp");
|
||||
|
||||
llvm::Value* srcarr;
|
||||
if (src->getType() == arrty)
|
||||
srcarr = src;
|
||||
else
|
||||
srcarr = DtoBitCast(src, arrty, "tmp");
|
||||
|
||||
llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
|
||||
std::vector<llvm::Value*> llargs;
|
||||
@@ -1807,6 +1782,8 @@ void DtoAnnotation(const char* str)
|
||||
gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const llvm::StructType* DtoInterfaceInfoType()
|
||||
{
|
||||
if (gIR->interfaceInfoType)
|
||||
@@ -1831,3 +1808,28 @@ const llvm::StructType* DtoInterfaceInfoType()
|
||||
|
||||
return gIR->interfaceInfoType;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Constant* DtoTypeInfoOf(Type* type)
|
||||
{
|
||||
const llvm::Type* typeinfotype = DtoType(Type::typeinfo->type);
|
||||
TypeInfoDeclaration* tidecl = type->getTypeInfoDeclaration();
|
||||
DtoForceDeclareDsymbol(tidecl);
|
||||
assert(tidecl->ir.irGlobal != NULL);
|
||||
llvm::Constant* c = isaConstant(tidecl->ir.irGlobal->value);
|
||||
assert(c != NULL);
|
||||
return llvm::ConstantExpr::getBitCast(c, typeinfotype);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -39,6 +39,9 @@ llvm::Value* DtoBoolean(llvm::Value* val);
|
||||
const llvm::Type* DtoSize_t();
|
||||
const llvm::StructType* DtoInterfaceInfoType();
|
||||
|
||||
// getting typeinfo of type
|
||||
llvm::Constant* DtoTypeInfoOf(Type* ty);
|
||||
|
||||
// initializer helpers
|
||||
llvm::Constant* DtoConstInitializer(Type* type, Initializer* init);
|
||||
llvm::Constant* DtoConstFieldInitializer(Type* type, Initializer* init);
|
||||
@@ -57,8 +60,7 @@ llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, const std::string& var, llvm
|
||||
llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb=NULL);
|
||||
|
||||
// dynamic memory helpers
|
||||
llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty);
|
||||
llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len);
|
||||
llvm::Value* DtoNew(Type* newtype);
|
||||
|
||||
// assertion generator
|
||||
void DtoAssert(Loc* loc, DValue* msg);
|
||||
@@ -79,7 +81,6 @@ llvm::ConstantFP* DtoConstFP(Type* t, long double value);
|
||||
llvm::Constant* DtoConstString(const char*);
|
||||
llvm::Constant* DtoConstStringPtr(const char* str, const char* section = 0);
|
||||
llvm::Constant* DtoConstBool(bool);
|
||||
llvm::Constant* DtoConstNullPtr(const llvm::Type* t);
|
||||
|
||||
// is template instance check
|
||||
bool DtoIsTemplateInstance(Dsymbol* s);
|
||||
|
||||
@@ -24,6 +24,8 @@ IrFunction::IrFunction(FuncDeclaration* fd)
|
||||
_arguments = NULL;
|
||||
_argptr = NULL;
|
||||
dwarfSubProg = NULL;
|
||||
|
||||
srcfileArg = NULL;
|
||||
}
|
||||
|
||||
IrFunction::~IrFunction()
|
||||
|
||||
@@ -22,6 +22,8 @@ struct IrFunction : IrBase
|
||||
llvm::Value* _argptr;
|
||||
llvm::Constant* dwarfSubProg;
|
||||
|
||||
llvm::AllocaInst* srcfileArg;
|
||||
|
||||
IrFunction(FuncDeclaration* fd);
|
||||
virtual ~IrFunction();
|
||||
};
|
||||
|
||||
@@ -189,31 +189,30 @@ extern (C) void _d_delclass(Object* p)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
struct Array
|
||||
{
|
||||
size_t length;
|
||||
byte* data;
|
||||
void* data;
|
||||
}
|
||||
|
||||
+/
|
||||
|
||||
/**
|
||||
* Allocate a new array of length elements.
|
||||
* ti is the type of the resulting array, or pointer to element.
|
||||
* (For when the array is initialized to 0)
|
||||
*/
|
||||
extern (C) Array _d_newarrayT(TypeInfo ti, size_t length)
|
||||
extern (C) void* _d_newarrayT(TypeInfo ti, size_t length)
|
||||
{
|
||||
void* p;
|
||||
Array result;
|
||||
auto size = ti.next.tsize(); // array element size
|
||||
|
||||
debug(PRINTF) printf("_d_newarrayT(length = x%x, size = %d)\n", length, size);
|
||||
if (length == 0 || size == 0)
|
||||
return Array();
|
||||
return null;
|
||||
|
||||
version (D_InlineAsm_X86)
|
||||
{
|
||||
@@ -230,24 +229,25 @@ extern (C) Array _d_newarrayT(TypeInfo ti, size_t length)
|
||||
p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
|
||||
debug(PRINTF) printf(" p = %p\n", p);
|
||||
memset(p, 0, size);
|
||||
return Array(length, p);
|
||||
return p;
|
||||
|
||||
Loverflow:
|
||||
onOutOfMemoryError();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For when the array has a non-zero initializer.
|
||||
*/
|
||||
extern (C) Array _d_newarrayiT(TypeInfo ti, size_t length)
|
||||
extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length)
|
||||
{
|
||||
Array result;
|
||||
void* result;
|
||||
auto size = ti.next.tsize(); // array element size
|
||||
|
||||
debug(PRINTF) printf("_d_newarrayiT(length = %d, size = %d)\n", length, size);
|
||||
|
||||
if (length == 0 || size == 0)
|
||||
result = Array();
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
auto initializer = ti.next.init();
|
||||
@@ -285,15 +285,17 @@ extern (C) Array _d_newarrayiT(TypeInfo ti, size_t length)
|
||||
memcpy(p + u, q, isize);
|
||||
}
|
||||
}
|
||||
va_end(q);
|
||||
result = Array(length, p);
|
||||
result = p;
|
||||
}
|
||||
return result;
|
||||
|
||||
Loverflow:
|
||||
onOutOfMemoryError();
|
||||
return null;
|
||||
}
|
||||
|
||||
/+
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -400,8 +402,6 @@ extern (C) Array _d_newarraymiT(TypeInfo ti, int ndims, ...)
|
||||
return result;
|
||||
}
|
||||
|
||||
+/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -410,6 +410,16 @@ void* _d_allocmemory(size_t nbytes)
|
||||
return gc_malloc(nbytes);
|
||||
}
|
||||
|
||||
+/
|
||||
|
||||
/**
|
||||
* for allocating a single POD value
|
||||
*/
|
||||
extern (C) void* _d_allocmemoryT(TypeInfo ti)
|
||||
{
|
||||
return gc_malloc(ti.tsize(), (ti.flags() & 1) ? BlkAttr.NO_SCAN : 0);
|
||||
}
|
||||
|
||||
/+
|
||||
|
||||
/**
|
||||
@@ -496,16 +506,14 @@ extern (C) void rt_finalize(void* p, bool det = true)
|
||||
}
|
||||
}
|
||||
|
||||
/+
|
||||
|
||||
/**
|
||||
* Resize dynamic arrays with 0 initializers.
|
||||
*/
|
||||
extern (C) byte[] _d_arraysetlengthT(TypeInfo ti, size_t newlength, Array *p)
|
||||
extern (C) byte* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
|
||||
in
|
||||
{
|
||||
assert(ti);
|
||||
assert(!p.length || p.data);
|
||||
assert(!plength || pdata);
|
||||
}
|
||||
body
|
||||
{
|
||||
@@ -516,7 +524,7 @@ body
|
||||
{
|
||||
printf("_d_arraysetlengthT(p = %p, sizeelem = %d, newlength = %d)\n", p, sizeelem, newlength);
|
||||
if (p)
|
||||
printf("\tp.data = %p, p.length = %d\n", p.data, p.length);
|
||||
printf("\tp.data = %p, p.length = %d\n", pdata, plength);
|
||||
}
|
||||
|
||||
if (newlength)
|
||||
@@ -543,26 +551,26 @@ body
|
||||
|
||||
debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
|
||||
|
||||
if (p.data)
|
||||
if (pdata)
|
||||
{
|
||||
newdata = p.data;
|
||||
if (newlength > p.length)
|
||||
newdata = pdata;
|
||||
if (newlength > plength)
|
||||
{
|
||||
size_t size = p.length * sizeelem;
|
||||
auto info = gc_query(p.data);
|
||||
size_t size = plength * sizeelem;
|
||||
auto info = gc_query(pdata);
|
||||
|
||||
if (info.size <= newsize || info.base != p.data)
|
||||
if (info.size <= newsize || info.base != pdata)
|
||||
{
|
||||
if (info.size >= PAGESIZE && info.base == p.data)
|
||||
if (info.size >= PAGESIZE && info.base == pdata)
|
||||
{ // Try to extend in-place
|
||||
auto u = gc_extend(p.data, (newsize + 1) - info.size, (newsize + 1) - info.size);
|
||||
auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
|
||||
if (u)
|
||||
{
|
||||
goto L1;
|
||||
}
|
||||
}
|
||||
newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
|
||||
newdata[0 .. size] = p.data[0 .. size];
|
||||
newdata[0 .. size] = pdata[0 .. size];
|
||||
}
|
||||
L1:
|
||||
newdata[size .. newsize] = 0;
|
||||
@@ -575,15 +583,14 @@ body
|
||||
}
|
||||
else
|
||||
{
|
||||
newdata = p.data;
|
||||
newdata = pdata;
|
||||
}
|
||||
|
||||
p.data = newdata;
|
||||
p.length = newlength;
|
||||
return newdata[0 .. newlength];
|
||||
return newdata;
|
||||
|
||||
Loverflow:
|
||||
onOutOfMemoryError();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -595,10 +602,10 @@ Loverflow:
|
||||
* initsize size of initializer
|
||||
* ... initializer
|
||||
*/
|
||||
extern (C) byte[] _d_arraysetlengthiT(TypeInfo ti, size_t newlength, Array *p)
|
||||
extern (C) byte* _d_arraysetlengthiT(TypeInfo ti, size_t newlength, size_t plength, byte* pdata)
|
||||
in
|
||||
{
|
||||
assert(!p.length || p.data);
|
||||
assert(!plength || pdata);
|
||||
}
|
||||
body
|
||||
{
|
||||
@@ -616,7 +623,7 @@ body
|
||||
{
|
||||
printf("_d_arraysetlengthiT(p = %p, sizeelem = %d, newlength = %d, initsize = %d)\n", p, sizeelem, newlength, initsize);
|
||||
if (p)
|
||||
printf("\tp.data = %p, p.length = %d\n", p.data, p.length);
|
||||
printf("\tp.data = %p, p.length = %d\n", pdata, plength);
|
||||
}
|
||||
|
||||
if (newlength)
|
||||
@@ -642,27 +649,27 @@ body
|
||||
}
|
||||
debug(PRINTF) printf("newsize = %x, newlength = %x\n", newsize, newlength);
|
||||
|
||||
size_t size = p.length * sizeelem;
|
||||
size_t size = plength * sizeelem;
|
||||
|
||||
if (p.data)
|
||||
if (pdata)
|
||||
{
|
||||
newdata = p.data;
|
||||
if (newlength > p.length)
|
||||
newdata = pdata;
|
||||
if (newlength > plength)
|
||||
{
|
||||
auto info = gc_query(p.data);
|
||||
auto info = gc_query(pdata);
|
||||
|
||||
if (info.size <= newsize || info.base != p.data)
|
||||
if (info.size <= newsize || info.base != pdata)
|
||||
{
|
||||
if (info.size >= PAGESIZE && info.base == p.data)
|
||||
if (info.size >= PAGESIZE && info.base == pdata)
|
||||
{ // Try to extend in-place
|
||||
auto u = gc_extend(p.data, (newsize + 1) - info.size, (newsize + 1) - info.size);
|
||||
auto u = gc_extend(pdata, (newsize + 1) - info.size, (newsize + 1) - info.size);
|
||||
if (u)
|
||||
{
|
||||
goto L1;
|
||||
}
|
||||
}
|
||||
newdata = cast(byte *)gc_malloc(newsize + 1, info.attr);
|
||||
newdata[0 .. size] = p.data[0 .. size];
|
||||
newdata[0 .. size] = pdata[0 .. size];
|
||||
L1: ;
|
||||
}
|
||||
}
|
||||
@@ -692,17 +699,17 @@ body
|
||||
}
|
||||
else
|
||||
{
|
||||
newdata = p.data;
|
||||
newdata = pdata;
|
||||
}
|
||||
|
||||
p.data = newdata;
|
||||
p.length = newlength;
|
||||
return newdata[0 .. newlength];
|
||||
return newdata;
|
||||
|
||||
Loverflow:
|
||||
onOutOfMemoryError();
|
||||
return null;
|
||||
}
|
||||
|
||||
/+
|
||||
|
||||
/**
|
||||
* Append y[] to array x[].
|
||||
|
||||
@@ -83,7 +83,6 @@ OBJ_BASE= \
|
||||
eh.bc \
|
||||
genobj.bc \
|
||||
lifetime.bc \
|
||||
mem.bc \
|
||||
memory.bc \
|
||||
qsort2.bc \
|
||||
switch.bc \
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
extern(C):
|
||||
|
||||
void* realloc(void*,size_t);
|
||||
void free(void*);
|
||||
|
||||
void* _d_realloc(void* ptr, size_t n)
|
||||
{
|
||||
return realloc(ptr, n);
|
||||
}
|
||||
|
||||
void _d_free(void* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
@@ -2056,7 +2056,12 @@ struct Gcx
|
||||
// get put on the stack so they'll be scanned
|
||||
void *sp;
|
||||
size_t result;
|
||||
version (GNU)
|
||||
version(LLVMDC)
|
||||
{
|
||||
// TODO & BUG:
|
||||
// should make sure registers are on the stack, maybe some external asm ?
|
||||
}
|
||||
else version (GNU)
|
||||
{
|
||||
__builtin_unwind_init();
|
||||
sp = & sp;
|
||||
@@ -2070,7 +2075,11 @@ struct Gcx
|
||||
}
|
||||
}
|
||||
result = fullcollect(sp);
|
||||
version (GNU)
|
||||
version(LLVMDC)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
else version (GNU)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ LIB_MASK_C=libtango-base-c-llvmdc*.a
|
||||
|
||||
DIR_CC=./common/tango
|
||||
DIR_RT=./compiler/llvmdc
|
||||
#DIR_GC=./gc/basic
|
||||
DIR_GC=./gc/stub
|
||||
|
||||
CP=cp -f
|
||||
|
||||
63
tangotests/mem1.d
Normal file
63
tangotests/mem1.d
Normal file
@@ -0,0 +1,63 @@
|
||||
module tangotests.mem1;
|
||||
|
||||
import tango.stdc.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
printf("new int;\n");
|
||||
int* i = new int;
|
||||
assert(*i == 0);
|
||||
|
||||
printf("new int[3];\n");
|
||||
int[] ar = new int[3];
|
||||
ar[0] = 1;
|
||||
ar[1] = 56;
|
||||
assert(ar.length == 3);
|
||||
assert(ar[0] == 1);
|
||||
assert(ar[1] == 56);
|
||||
assert(ar[2] == 0);
|
||||
|
||||
printf("array ~= elem;\n");
|
||||
int[] ar2;
|
||||
ar2 ~= 22;
|
||||
assert(ar2.length == 1);
|
||||
assert(ar2[0] == 22);
|
||||
|
||||
printf("array ~= array;\n");
|
||||
ar2 ~= ar;
|
||||
assert(ar2.length == 4);
|
||||
assert(ar2[0] == 22);
|
||||
assert(ar2[1] == 1);
|
||||
printf("%d %d %d %d\n", ar2[0], ar2[1], ar2[2], ar2[3]);
|
||||
assert(ar2[2] == 56);
|
||||
assert(ar2[3] == 0);
|
||||
|
||||
printf("array ~ array;\n");
|
||||
int[] ar5 = ar ~ ar2;
|
||||
assert(ar5.length == 7);
|
||||
assert(ar5[0] == 1);
|
||||
assert(ar5[1] == 56);
|
||||
assert(ar5[2] == 0);
|
||||
assert(ar5[3] == 22);
|
||||
assert(ar5[4] == 1);
|
||||
assert(ar5[5] == 56);
|
||||
assert(ar5[6] == 0);
|
||||
|
||||
printf("array ~ elem;\n");
|
||||
int[] ar4 = ar2 ~ 123;
|
||||
assert(ar4.length == 5);
|
||||
assert(ar4[0] == 22);
|
||||
assert(ar4[1] == 1);
|
||||
assert(ar4[2] == 56);
|
||||
assert(ar4[3] == 0);
|
||||
assert(ar4[4] == 123);
|
||||
|
||||
printf("elem ~ array;\n");
|
||||
int[] ar3 = 123 ~ ar2;
|
||||
assert(ar3.length == 5);
|
||||
assert(ar3[0] == 123);
|
||||
assert(ar3[1] == 22);
|
||||
assert(ar3[2] == 1);
|
||||
assert(ar3[3] == 56);
|
||||
assert(ar3[4] == 0);
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
module arrays;
|
||||
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
void integer()
|
||||
|
||||
Reference in New Issue
Block a user