mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-08 20:06:03 +03:00
Add _d_newarrayvT and _d_newarraymvT to create arrays without initialization.
Adjust DtoNewDynArray to use DtoArrayInit for initialization of new arrays. Make Type::tvoid->defaultInit() not error.
This commit is contained in:
parent
e0635f1707
commit
30c9af1945
6 changed files with 118 additions and 22 deletions
|
@ -1375,6 +1375,9 @@ Expression *TypeBasic::defaultInit(Loc loc)
|
||||||
#endif
|
#endif
|
||||||
switch (ty)
|
switch (ty)
|
||||||
{
|
{
|
||||||
|
case Tvoid:
|
||||||
|
return new IntegerExp(loc, value, Type::tbool);
|
||||||
|
|
||||||
case Tchar:
|
case Tchar:
|
||||||
value = 0xFF;
|
value = 0xFF;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -399,7 +399,7 @@ LLConstant* DtoConstSlice(LLConstant* dim, LLConstant* ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
|
DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit)
|
||||||
{
|
{
|
||||||
Logger::println("DtoNewDynArray : %s", arrayType->toChars());
|
Logger::println("DtoNewDynArray : %s", arrayType->toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
@ -412,8 +412,7 @@ DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
|
||||||
LLValue* arrayLen = dim->getRVal();
|
LLValue* arrayLen = dim->getRVal();
|
||||||
|
|
||||||
// get runtime function
|
// get runtime function
|
||||||
bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
|
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newarrayvT");
|
||||||
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarrayT" : "_d_newarrayiT" );
|
|
||||||
|
|
||||||
// call allocator
|
// call allocator
|
||||||
LLValue* newptr = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem")->get();
|
LLValue* newptr = gIR->CreateCallOrInvoke2(fn, arrayTypeInfo, arrayLen, ".gc_mem")->get();
|
||||||
|
@ -425,18 +424,18 @@ DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
|
||||||
|
|
||||||
Logger::cout() << "final ptr = " << *newptr << '\n';
|
Logger::cout() << "final ptr = " << *newptr << '\n';
|
||||||
|
|
||||||
#if 0
|
DSliceValue* ret = new DSliceValue(arrayType, arrayLen, newptr);
|
||||||
if (defaultInit) {
|
|
||||||
DValue* e = dty->defaultInit()->toElem(gIR);
|
|
||||||
DtoArrayInit(newptr,dim,e->getRVal());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return new DSliceValue(arrayType, arrayLen, newptr);
|
if (defaultInit) {
|
||||||
|
DValue* e = arrayType->nextOf()->defaultInit()->toElem(gIR);
|
||||||
|
DtoArrayInit(loc, ret, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit)
|
DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit)
|
||||||
{
|
{
|
||||||
Logger::println("DtoNewMulDimDynArray : %s", arrayType->toChars());
|
Logger::println("DtoNewMulDimDynArray : %s", arrayType->toChars());
|
||||||
LOG_SCOPE;
|
LOG_SCOPE;
|
||||||
|
@ -474,6 +473,7 @@ DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims,
|
||||||
Logger::cout() << "final ptr = " << *newptr << '\n';
|
Logger::cout() << "final ptr = " << *newptr << '\n';
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
// using this would reinit all arrays beyond the first level to []
|
||||||
if (defaultInit) {
|
if (defaultInit) {
|
||||||
DValue* e = dty->defaultInit()->toElem(gIR);
|
DValue* e = dty->defaultInit()->toElem(gIR);
|
||||||
DtoArrayInit(newptr,dim,e->getRVal());
|
DtoArrayInit(newptr,dim,e->getRVal());
|
||||||
|
@ -597,7 +597,7 @@ DSliceValue* DtoCatArrays(Type* type, Expression* exp1, Expression* exp2)
|
||||||
res = gIR->ir->CreateAdd(len1,len2,"tmp");
|
res = gIR->ir->CreateAdd(len1,len2,"tmp");
|
||||||
|
|
||||||
DValue* lenval = new DImValue(Type::tsize_t, res);
|
DValue* lenval = new DImValue(Type::tsize_t, res);
|
||||||
DSliceValue* slice = DtoNewDynArray(type, lenval, false);
|
DSliceValue* slice = DtoNewDynArray(exp1->loc, type, lenval, false);
|
||||||
LLValue* mem = slice->ptr;
|
LLValue* mem = slice->ptr;
|
||||||
|
|
||||||
src1 = DtoArrayPtr(e1);
|
src1 = DtoArrayPtr(e1);
|
||||||
|
@ -637,7 +637,7 @@ DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2)
|
||||||
res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
|
res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
|
||||||
|
|
||||||
DValue* lenval = new DImValue(Type::tsize_t, res);
|
DValue* lenval = new DImValue(Type::tsize_t, res);
|
||||||
DSliceValue* slice = DtoNewDynArray(type, lenval, false);
|
DSliceValue* slice = DtoNewDynArray(exp1->loc, type, lenval, false);
|
||||||
LLValue* mem = slice->ptr;
|
LLValue* mem = slice->ptr;
|
||||||
|
|
||||||
DVarValue* memval = new DVarValue(e1->getType(), mem);
|
DVarValue* memval = new DVarValue(e1->getType(), mem);
|
||||||
|
@ -661,7 +661,7 @@ DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2)
|
||||||
res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
|
res = gIR->ir->CreateAdd(len1,DtoConstSize_t(1),"tmp");
|
||||||
|
|
||||||
DValue* lenval = new DImValue(Type::tsize_t, res);
|
DValue* lenval = new DImValue(Type::tsize_t, res);
|
||||||
DSliceValue* slice = DtoNewDynArray(type, lenval, false);
|
DSliceValue* slice = DtoNewDynArray(exp1->loc, type, lenval, false);
|
||||||
LLValue* mem = slice->ptr;
|
LLValue* mem = slice->ptr;
|
||||||
|
|
||||||
src1 = DtoArrayPtr(e1);
|
src1 = DtoArrayPtr(e1);
|
||||||
|
|
|
@ -19,8 +19,8 @@ void DtoArrayAssign(LLValue* l, LLValue* r);
|
||||||
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr);
|
void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr);
|
||||||
void DtoSetArrayToNull(LLValue* v);
|
void DtoSetArrayToNull(LLValue* v);
|
||||||
|
|
||||||
DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit=true);
|
DSliceValue* DtoNewDynArray(Loc& loc, Type* arrayType, DValue* dim, bool defaultInit=true);
|
||||||
DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
|
DSliceValue* DtoNewMulDimDynArray(Loc& loc, Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
|
||||||
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
|
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
|
||||||
|
|
||||||
DSliceValue* DtoCatAssignElement(DValue* arr, Expression* exp);
|
DSliceValue* DtoCatAssignElement(DValue* arr, Expression* exp);
|
||||||
|
|
|
@ -237,22 +237,27 @@ static void LLVM_D_BuildRuntimeModule()
|
||||||
|
|
||||||
// void* _d_newarrayT(TypeInfo ti, size_t length)
|
// void* _d_newarrayT(TypeInfo ti, size_t length)
|
||||||
// void* _d_newarrayiT(TypeInfo ti, size_t length)
|
// void* _d_newarrayiT(TypeInfo ti, size_t length)
|
||||||
|
// void* _d_newarrayvT(TypeInfo ti, size_t length)
|
||||||
{
|
{
|
||||||
std::string fname("_d_newarrayT");
|
std::string fname("_d_newarrayT");
|
||||||
std::string fname2("_d_newarrayiT");
|
std::string fname2("_d_newarrayiT");
|
||||||
|
std::string fname3("_d_newarrayvT");
|
||||||
std::vector<const LLType*> types;
|
std::vector<const LLType*> types;
|
||||||
types.push_back(typeInfoTy);
|
types.push_back(typeInfoTy);
|
||||||
types.push_back(sizeTy);
|
types.push_back(sizeTy);
|
||||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||||
|
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims)
|
// void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims)
|
||||||
// void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims)
|
// void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims)
|
||||||
|
// void* _d_newarraymvT(TypeInfo ti, size_t length, size_t* dims)
|
||||||
{
|
{
|
||||||
std::string fname("_d_newarraymT");
|
std::string fname("_d_newarraymT");
|
||||||
std::string fname2("_d_newarraymiT");
|
std::string fname2("_d_newarraymiT");
|
||||||
|
std::string fname3("_d_newarraymvT");
|
||||||
std::vector<const LLType*> types;
|
std::vector<const LLType*> types;
|
||||||
types.push_back(typeInfoTy);
|
types.push_back(typeInfoTy);
|
||||||
types.push_back(sizeTy);
|
types.push_back(sizeTy);
|
||||||
|
@ -260,6 +265,7 @@ static void LLVM_D_BuildRuntimeModule()
|
||||||
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false);
|
||||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M);
|
||||||
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
|
||||||
|
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
|
// void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata)
|
||||||
|
|
|
@ -1452,7 +1452,7 @@ DValue* NewExp::toElem(IRState* p)
|
||||||
{
|
{
|
||||||
DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
|
DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
|
||||||
// allocate & init
|
// allocate & init
|
||||||
return DtoNewDynArray(newtype, sz, true);
|
return DtoNewDynArray(loc, newtype, sz, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1460,7 +1460,7 @@ DValue* NewExp::toElem(IRState* p)
|
||||||
std::vector<DValue*> dims(ndims);
|
std::vector<DValue*> dims(ndims);
|
||||||
for (size_t i=0; i<ndims; ++i)
|
for (size_t i=0; i<ndims; ++i)
|
||||||
dims[i] = ((Expression*)arguments->data[i])->toElem(p);
|
dims[i] = ((Expression*)arguments->data[i])->toElem(p);
|
||||||
return DtoNewMulDimDynArray(newtype, &dims[0], ndims, true);
|
return DtoNewMulDimDynArray(loc, newtype, &dims[0], ndims, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// new static array
|
// new static array
|
||||||
|
|
|
@ -202,7 +202,7 @@ struct Array
|
||||||
/**
|
/**
|
||||||
* Allocate a new array of length elements.
|
* Allocate a new array of length elements.
|
||||||
* ti is the type of the resulting array, or pointer to element.
|
* ti is the type of the resulting array, or pointer to element.
|
||||||
* (For when the array is initialized to 0)
|
* The resulting array is initialized to 0
|
||||||
*/
|
*/
|
||||||
extern (C) void* _d_newarrayT(TypeInfo ti, size_t length)
|
extern (C) void* _d_newarrayT(TypeInfo ti, size_t length)
|
||||||
{
|
{
|
||||||
|
@ -236,7 +236,8 @@ Loverflow:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For when the array has a non-zero initializer.
|
* As _d_newarrayT, but
|
||||||
|
* for when the array has a non-zero initializer.
|
||||||
*/
|
*/
|
||||||
extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length)
|
extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length)
|
||||||
{
|
{
|
||||||
|
@ -294,7 +295,44 @@ Loverflow:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* As _d_newarrayT, but without initialization
|
||||||
|
*/
|
||||||
|
extern (C) void* _d_newarrayvT(TypeInfo ti, size_t length)
|
||||||
|
{
|
||||||
|
void* p;
|
||||||
|
auto size = ti.next.tsize(); // array element size
|
||||||
|
|
||||||
|
debug(PRINTF) printf("_d_newarrayvT(length = %u, size = %d)\n", length, size);
|
||||||
|
if (length == 0 || size == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
version (D_InlineAsm_X86)
|
||||||
|
{
|
||||||
|
asm
|
||||||
|
{
|
||||||
|
mov EAX,size ;
|
||||||
|
mul EAX,length ;
|
||||||
|
mov size,EAX ;
|
||||||
|
jc Loverflow ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
size *= length;
|
||||||
|
p = gc_malloc(size + 1, !(ti.next.flags() & 1) ? BlkAttr.NO_SCAN : 0);
|
||||||
|
debug(PRINTF) printf(" p = %p\n", p);
|
||||||
|
return p;
|
||||||
|
|
||||||
|
Loverflow:
|
||||||
|
onOutOfMemoryError();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a new array of arrays of arrays of arrays ...
|
||||||
|
* ti is the type of the resulting array.
|
||||||
|
* ndims is the number of nested arrays.
|
||||||
|
* dims it the array of dimensions, its size is ndims.
|
||||||
|
* The resulting array is initialized to 0
|
||||||
*/
|
*/
|
||||||
extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
|
extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
|
||||||
{
|
{
|
||||||
|
@ -343,7 +381,8 @@ extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* As _d_newarraymT, but
|
||||||
|
* for when the array has a non-zero initializer.
|
||||||
*/
|
*/
|
||||||
extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
|
extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
|
||||||
{
|
{
|
||||||
|
@ -390,6 +429,54 @@ extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As _d_newarraymT, but without initialization
|
||||||
|
*/
|
||||||
|
extern (C) void* _d_newarraymvT(TypeInfo ti, int ndims, size_t* dims)
|
||||||
|
{
|
||||||
|
void* result;
|
||||||
|
|
||||||
|
debug(PRINTF) printf("_d_newarraymvT(ndims = %d)\n", ndims);
|
||||||
|
if (ndims == 0)
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
|
||||||
|
{
|
||||||
|
size_t dim = *pdim;
|
||||||
|
void[] p;
|
||||||
|
|
||||||
|
debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
|
||||||
|
if (ndims == 1)
|
||||||
|
{
|
||||||
|
auto r = _d_newarrayvT(ti, dim);
|
||||||
|
return r[0 .. dim];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = gc_malloc(dim * (void[]).sizeof + 1)[0 .. dim];
|
||||||
|
for (int i = 0; i < dim; i++)
|
||||||
|
{
|
||||||
|
(cast(void[]*)p.ptr)[i] = foo(ti.next, pdim + 1, ndims - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = foo(ti, dims, ndims).ptr;
|
||||||
|
debug(PRINTF) printf("result = %p\n", result);
|
||||||
|
|
||||||
|
version (none)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ndims; i++)
|
||||||
|
{
|
||||||
|
printf("index %d: %d\n", i, *dims++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/+
|
/+
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue