diff -r a85a0303bcb8 -r 7926a7921fa3 src/Interpreter.cpp --- a/src/Interpreter.cpp Sun Aug 05 00:31:20 2012 -0700 +++ b/src/Interpreter.cpp Sun Aug 05 00:45:06 2012 -0700 @@ -81,19 +81,41 @@ return true; } +static bool CopyStruct(Zone *zone, Struct *left, Struct *right); + // Even though this function can fail, we immediately bail out, so it doesn't // matter if we've leaving things unrooted. static bool CopyArray(Zone *zone, Array *source, Array *dest) { - assert(source->type()->levels() == 1); - assert(dest->type()->levels() == 1); - assert(source->type()->contained()->primitive() == - dest->type()->contained()->primitive()); - assert(source->nelements() >= dest->nelements()); - assert(dest->elementSize() == source->elementSize()); + if (source->type()->contained()->isArray()) { + assert(dest->type()->contained()->isArray()); + assert(source->length() == dest->length()); + + for (unsigned i = 0; i < source->length(); i++) { + Array *left = Array::cast(source->readObject(i)); + Array *right = Array::cast(dest->readObject(i)); + if (!CopyArray(zone, left, right)) + return false; + } + } else if (source->type()->contained()->isStruct()) { + assert(dest->type()->contained() == source->type()->contained()); + assert(source->length() == dest->length()); - memcpy(source->vec(), dest->vec(), dest->nelements() * dest->elementSize()); + for (unsigned i = 0; i < source->length(); i++) { + Struct *left = Struct::cast(source->readObject(i)); + Struct *right = Struct::cast(dest->readObject(i)); + if (!CopyStruct(zone, left, right)) + return false; + } + } else { + assert(source->type()->pod() == dest->type()->pod()); + assert(source->type()->pod() == PrimitiveType_Char + ? source->length() >= dest->length() + : source->length() == dest->length()); + + memcpy(source->vec(), dest->vec(), dest->length() * dest->elementSize()); + } return true; } @@ -673,8 +695,8 @@ { Array *array = top.sp[-2].array; int index = top.sp[-1].i32; - if (index < 0 || unsigned(index) >= array->nelements()) { - zone->reportError(Message_ArrayIndexOutOfBounds, index, array->nelements()); + if (index < 0 || unsigned(index) >= array->length()) { + zone->reportError(Message_ArrayIndexOutOfBounds, index, array->length()); goto error; } break;