src/Interpreter.cpp
changeset 234 26e3035cdffc
parent 230 fb3cd08bc7fb
child 236 072f1114ea5d
     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--;