1.1 --- a/src/Interpreter.cpp Sat Dec 22 23:18:57 2012 -0800
1.2 +++ b/src/Interpreter.cpp Mon Dec 24 02:49:20 2012 -0800
1.3 @@ -82,69 +82,27 @@
1.4 return true;
1.5 }
1.6
1.7 -static bool CopyStruct(Zone *zone, Handle<Struct> left, Handle<Struct> right);
1.8 -
1.9 static bool
1.10 -ChangeArrayLength(Zone *zone, Handle<Array> source, Handle<Array> dest)
1.11 +DuplicateArray(Zone *zone, Handle<Array> src)
1.12 {
1.13 - return true;
1.14 -}
1.15 + Local<ArrayMap> map(zone, ArrayMap::cast(src->map()));
1.16 + Local<Array> dest(zone);
1.17
1.18 -// Even though this function can fail, we immediately bail out, so it doesn't
1.19 -// matter if we've leaving things unrooted.
1.20 -static bool
1.21 -CopyArray(Zone *zone, Handle<Array> dest, Handle<Array> source)
1.22 -{
1.23 - if (source->length() != dest->length()) {
1.24 - if (!ChangeArrayLength(zone, source, dest))
1.25 - return false;
1.26 + if (map->type()->isFixedLength()) {
1.27 + dest = Array::NewFixed(zone, map);
1.28 + } else {
1.29 + Type *type = map->type();
1.30 + int sizes[MAX_ARRAY_DEPTH];
1.31 + for (unsigned i = 0; i < map->type()->levels(); i++) {
1.32 + ArrayType *atype = ArrayType::cast(type);
1.33 + sizes[i] = atype->isFixedLength()
1.34 + ? atype->fixedLength()
1.35 + : 0;
1.36 + type = atype->contained();
1.37 + }
1.38 }
1.39
1.40 - Local<Type> contained(zone, source->type()->contained());
1.41 - if (contained->isArray() && ArrayType::cast(contained)->isFixedLength()) {
1.42 - assert(dest->type()->contained()->isArray());
1.43 - assert(source->length() == dest->length());
1.44 -
1.45 - Local<Array> left(zone);
1.46 - Local<Array> right(zone);
1.47 - for (unsigned i = 0; i < source->length(); i++) {
1.48 - left = Array::cast(dest->readObject(i));
1.49 - right = Array::cast(source->readObject(i));
1.50 - if (!CopyArray(zone, left, right))
1.51 - return false;
1.52 - }
1.53 - return true;
1.54 - }
1.55 -
1.56 - if (contained->isStruct()) {
1.57 - assert(dest->type()->contained() == contained);
1.58 - assert(source->length() == dest->length());
1.59 -
1.60 - Local<Struct> left(zone);
1.61 - Local<Struct> right(zone);
1.62 - for (unsigned i = 0; i < source->length(); i++) {
1.63 - left = Struct::cast(dest->readObject(i));
1.64 - right = Struct::cast(source->readObject(i));
1.65 - if (!CopyStruct(zone, left, right))
1.66 - return false;
1.67 - }
1.68 - return true;
1.69 - }
1.70 -
1.71 - if (contained->isTraceable()) {
1.72 - for (unsigned i = 0; i < source->length(); i++)
1.73 - dest->writeObject(zone, i, source->readObject(i));
1.74 - return true;
1.75 - }
1.76 -
1.77 - assert(contained->pod() == dest->type()->contained()->pod());
1.78 - assert(contained->pod() == PrimitiveType_Char
1.79 - ? source->length() <= dest->length()
1.80 - : source->length() == dest->length());
1.81 -
1.82 - assert(dest->length());
1.83 - memcpy(dest->bytes(), source->bytes(), source->length() * Array::SizeForElement(dest->type()));
1.84 - return true;
1.85 + Local<Array> dst(zone);
1.86 }
1.87
1.88 static void
1.89 @@ -269,49 +227,6 @@
1.90 StoreField(zone, obj, desc, v);
1.91 }
1.92
1.93 -// Even though this function can fail, we immediately bail out, so it doesn't
1.94 -// matter if we've leaving things unrooted.
1.95 -static bool
1.96 -CopyStruct(Zone *zone, Handle<Struct> left, Handle<Struct> right)
1.97 -{
1.98 - assert(left->map()->type() == right->map()->type());
1.99 -
1.100 - Local<StructType> type(zone, StructType::cast(left->map()->type()));
1.101 - Local<Struct> leftStruct(zone);
1.102 - Local<Struct> rightStruct(zone);
1.103 - Local<Array> leftArray(zone);
1.104 - Local<Array> rightArray(zone);
1.105 - for (unsigned i = 0; i < type->fields()->length(); i++) {
1.106 - Descriptor *desc = Descriptor::cast(type->fields()->at(i));
1.107 -
1.108 - LocalSlot rval;
1.109 - FetchField(right, desc, &rval);
1.110 -
1.111 - // If the field is a struct, we need to deep-copy.
1.112 - if (desc->type()->isStruct()) {
1.113 - LocalSlot lval;
1.114 -
1.115 - FetchField(left, desc, &lval);
1.116 - leftStruct = Struct::cast(lval.obj);
1.117 - rightStruct = Struct::cast(rval.obj);
1.118 - if (!CopyStruct(zone, leftStruct, rightStruct))
1.119 - return false;
1.120 - } else if (desc->type()->isArray()) {
1.121 - LocalSlot lval;
1.122 -
1.123 - FetchField(left, desc, &lval);
1.124 - leftArray = Array::cast(lval.obj);
1.125 - rightArray = Array::cast(rval.obj);
1.126 - if (!CopyArray(zone, leftArray, rightArray))
1.127 - return false;
1.128 - } else {
1.129 - StoreField(zone, left, desc, rval);
1.130 - }
1.131 - }
1.132 -
1.133 - return true;
1.134 -}
1.135 -
1.136 static bool
1.137 InvokeNative(Zone *zone, Handle<Native> native, void *identity, LocalSlot *args, unsigned argc,
1.138 int *result)
1.139 @@ -773,6 +688,15 @@
1.140 break;
1.141 }
1.142
1.143 +case OP_DUPARRAY:
1.144 +{
1.145 + Local<Array> src(zone, Array::cast(top.sp[-1].obj));
1.146 + top.sp[-1].obj = Array::DeepCopy(zone, src, Heap::Tenure_Default);
1.147 + if (!top.sp[-1].obj)
1.148 + goto error;
1.149 + break;
1.150 +}
1.151 +
1.152 case OP_NEWFIXED:
1.153 {
1.154 Heap::Tenure tenure = (Heap::Tenure)top.pc[1];
1.155 @@ -905,7 +829,7 @@
1.156 // right, since in this case the result of the expression could be different.
1.157 Local<Array> left(zone, Array::cast(top.sp[-2].array));
1.158 Local<Array> right(zone, Array::cast(top.sp[-1].array));
1.159 - if (!CopyArray(zone, left, right))
1.160 + if (!Array::ShallowCopy(zone, left, right))
1.161 goto error;
1.162 top.sp--;
1.163 break;
1.164 @@ -1016,7 +940,7 @@
1.165 {
1.166 Local<Struct> left(zone, Struct::cast(top.sp[-2].obj));
1.167 Local<Struct> right(zone, Struct::cast(top.sp[-1].obj));
1.168 - if (!CopyStruct(zone, left, right))
1.169 + if (!Struct::Copy(zone, left, right))
1.170 goto error;
1.171 top.sp[-2].obj = top.sp[-1].obj;
1.172 top.sp--;