[svn r307] Fixed: multidimensional new expressions now work. Eg.:

auto ma = new int[][] (3,9);
This commit is contained in:
Tomas Lindquist Olsen
2008-06-21 04:47:14 +02:00
parent 5647598da9
commit 67dd564222
7 changed files with 127 additions and 34 deletions

View File

@@ -477,6 +477,48 @@ DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit)
return new DSliceValue(arrayType, arrayLen, newptr);
}
//////////////////////////////////////////////////////////////////////////////////////////
DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit)
{
Logger::println("DtoNewMulDimDynArray : %s", arrayType->toChars());
LOG_SCOPE;
// typeinfo arg
LLValue* arrayTypeInfo = DtoTypeInfoOf(arrayType);
// get runtime function
bool zeroInit = arrayType->toBasetype()->nextOf()->isZeroInit();
LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, zeroInit ? "_d_newarraymT" : "_d_newarraymiT" );
// build dims
LLValue* dimsArg = new llvm::AllocaInst(DtoSize_t(), DtoConstUint(ndims), ".newdims", gIR->topallocapoint());
for (size_t i=0; i<ndims; ++i)
{
LLValue* dim = dims[i]->getRVal();
DtoStore(dim, DtoGEPi1(dimsArg, i));
}
// call allocator
LLConstant* arrayLen = DtoConstSize_t(ndims);
LLValue* newptr = gIR->ir->CreateCall3(fn, arrayTypeInfo, arrayLen, dimsArg, ".gc_mem");
// cast to wanted type
const LLType* 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
return new DSliceValue(arrayType, arrayLen, newptr);
}
//////////////////////////////////////////////////////////////////////////////////////////
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim)
{

View File

@@ -21,6 +21,7 @@ void DtoSetArray(LLValue* arr, LLValue* dim, LLValue* ptr);
void DtoSetArrayToNull(LLValue* v);
DSliceValue* DtoNewDynArray(Type* arrayType, DValue* dim, bool defaultInit=true);
DSliceValue* DtoNewMulDimDynArray(Type* arrayType, DValue** dims, size_t ndims, bool defaultInit=true);
DSliceValue* DtoResizeDynArray(Type* arrayType, DValue* array, DValue* newdim);
DSliceValue* DtoCatAssignElement(DValue* arr, Expression* exp);

View File

@@ -266,6 +266,20 @@ static void LLVM_D_BuildRuntimeModule()
llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M);
}
// void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims)
// void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims)
{
std::string fname("_d_newarraymT");
std::string fname2("_d_newarraymiT");
std::vector<const LLType*> types;
types.push_back(typeInfoTy);
types.push_back(sizeTy);
types.push_back(rt_ptr(sizeTy));
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, 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)
{

View File

@@ -1899,10 +1899,21 @@ DValue* NewExp::toElem(IRState* p)
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);
assert(arguments->dim >= 1);
if (arguments->dim == 1)
{
DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
// allocate & init
return DtoNewDynArray(newtype, sz, true);
}
else
{
size_t ndims = arguments->dim;
std::vector<DValue*> dims(ndims);
for (size_t i=0; i<ndims; ++i)
dims[i] = ((Expression*)arguments->data[i])->toElem(p);
return DtoNewMulDimDynArray(newtype, &dims[0], ndims, true);
}
}
// new static array
else if (ntype->ty == Tsarray)

View File

@@ -293,23 +293,19 @@ Loverflow:
return null;
}
/+
/**
*
*/
extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
extern (C) void* _d_newarraymT(TypeInfo ti, int ndims, size_t* dims)
{
Array result;
void* result;
debug(PRINTF) printf("_d_newarraymT(ndims = %d)\n", ndims);
if (ndims == 0)
result = Array();
result = null;
else
{ va_list q;
va_start!(int)(q, ndims);
void[] foo(TypeInfo ti, size_t* pdim, int ndims)
{
static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
{
size_t dim = *pdim;
void[] p;
@@ -317,7 +313,8 @@ extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
debug(PRINTF) printf("foo(ti = %p, ti.next = %p, dim = %d, ndims = %d\n", ti, ti.next, dim, ndims);
if (ndims == 1)
{
return _d_newarrayT(ti, dim);
auto r = _d_newarrayT(ti, dim);
return r[0 .. dim];
}
else
{
@@ -330,19 +327,16 @@ extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
return p;
}
size_t* pdim = cast(size_t *)q;
void[] arr = foo(ti, pdim, ndims);
result = Arra
debug(PRINTF) printf("result = %llx\n", result);
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, va_arg!(int)(q));
printf("index %d: %d\n", i, *dims++);
}
}
va_end(q);
}
return result;
}
@@ -351,19 +345,16 @@ extern (C) Array _d_newarraymT(TypeInfo ti, int ndims, ...)
/**
*
*/
extern (C) Array _d_newarraymiT(TypeInfo ti, int ndims, ...)
extern (C) void* _d_newarraymiT(TypeInfo ti, int ndims, size_t* dims)
{
Array result;
void* result;
debug(PRINTF) printf("_d_newarraymiT(ndims = %d)\n", ndims);
if (ndims == 0)
result = 0;
result = null;
else
{
va_list q;
va_start!(int)(q, ndims);
void[] foo(TypeInfo ti, size_t* pdim, int ndims)
static void[] foo(TypeInfo ti, size_t* pdim, int ndims)
{
size_t dim = *pdim;
void[] p;
@@ -371,7 +362,7 @@ extern (C) Array _d_newarraymiT(TypeInfo ti, int ndims, ...)
if (ndims == 1)
{
auto r = _d_newarrayiT(ti, dim);
p = *cast(void[]*)(&r);
p = r[0 .. dim];
}
else
{
@@ -384,23 +375,23 @@ extern (C) Array _d_newarraymiT(TypeInfo ti, int ndims, ...)
return p;
}
size_t* pdim = cast(size_t *)q;
result = cast(ulong)foo(ti, pdim, ndims);
debug(PRINTF) printf("result = %llx\n", result);
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, va_arg!(int)(q));
printf("init = %d\n", va_arg!(int)(q));
printf("index %d: %d\n", i, *dims++);
printf("init = %d\n", *dims++);
}
}
va_end(q);
}
return result;
}
/+
/**
*
*/

19
tangotests/marray1.d Normal file
View File

@@ -0,0 +1,19 @@
module tangotest.marray1;
void main()
{
int[][] arr;
int[] a = [1,2];
int[] b = [6,7,8,9];
arr ~= a;
arr ~= b;
assert(a.length == 2);
assert(b.length == 4);
assert(arr.length == 2);
assert(arr[0][0] == 1);
assert(arr[0][1] == 2);
assert(arr[1][0] == 6);
assert(arr[1][1] == 7);
assert(arr[1][2] == 8);
assert(arr[1][3] == 9);
}

15
tangotests/marray2.d Normal file
View File

@@ -0,0 +1,15 @@
module tangotests.marray2;
void main()
{
int[][] ma = new int[][](2,4);
assert(ma.length == 2);
assert(ma[0].length == 4);
assert(ma[1].length == 4);
ma[0][3] = 32;
ma[1][2] = 123;
ma[0][0] = 55;
assert(ma[0][3] == 32);
assert(ma[1][2] == 123);
assert(ma[0][0] == 55);
}