1.1 --- a/src/Array.cpp Sat Sep 15 19:33:24 2012 -0700
1.2 +++ b/src/Array.cpp Sun Sep 16 19:02:23 2012 -0700
1.3 @@ -72,58 +72,121 @@
1.4 }
1.5
1.6 Array *
1.7 -Array::New(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure)
1.8 +Array::NewRaw(Zone *zone, Handle<ArrayMap> map, unsigned nelements, Heap::Tenure tenure)
1.9 {
1.10 - assert(map->type()->isFixedLength());
1.11 + if (nelements > (INT_MAX / SizeFor(map->type(), 1))) {
1.12 + zone->reportError(Message_ArraySizeTooBig);
1.13 + return NULL;
1.14 + }
1.15
1.16 - return Array::New(zone, map, map->type()->fixedLength(), tenure);
1.17 -}
1.18 -
1.19 -Array *
1.20 -Array::New(Zone *zone, Handle<ArrayMap> map, uint32 elements, Heap::Tenure tenure)
1.21 -{
1.22 - size_t elementBytes = SizeFor(map->type(), elements);
1.23 + size_t elementBytes = SizeFor(map->type(), nelements);
1.24 size_t bytes = sizeof(Array) + elementBytes;
1.25 Local<Array> array(zone, Array::cast(zone->allocate(map, bytes, tenure)));
1.26 if (!array)
1.27 return NULL;
1.28
1.29 - array->nelements_ = elements;
1.30 + array->nelements_ = nelements;
1.31 array->elements_ = (Array *)array + 1;
1.32 + memset(array->vec(), 0, elementBytes);
1.33
1.34 - if (map->type()->contained()->isArray()) {
1.35 - Local<ArrayMap> childMap(zone, ArrayMap::cast(map->type()->contained()->newMap()));
1.36 - Local<Array> child(zone);
1.37 - for (unsigned i = 0; i < elements; i++) {
1.38 - unsigned length = map->type()->contained()->isFixedLength()
1.39 - ? map->type()->contained()->fixedLength()
1.40 - : 0;
1.41 - child = Array::New(zone, childMap, length, tenure);
1.42 - if (!child)
1.43 - return NULL;
1.44 -
1.45 - array->writeObject(zone, i, child);
1.46 - }
1.47 - } else if (map->type()->contained()->isStruct()) {
1.48 + if (map->type()->contained()->isStruct()) {
1.49 Local<StructMap> childMap(zone, StructMap::cast(map->type()->contained()->newMap()));
1.50 Local<Struct> child(zone);
1.51 - for (unsigned i = 0; i < elements; i++) {
1.52 + for (unsigned i = 0; i < nelements; i++) {
1.53 child = Struct::New(zone, childMap, tenure);
1.54 if (!child)
1.55 return NULL;
1.56
1.57 array->writeObject(zone, i, child);
1.58 }
1.59 - } else {
1.60 - memset(array->elements_, 0, elementBytes);
1.61 + }
1.62 +
1.63 + return array;
1.64 +}
1.65 +
1.66 +static Array *
1.67 +ConstructSizedArray(Zone *zone, Handle<ArrayMap> map, int dims[MAX_ARRAY_DEPTH],
1.68 + unsigned level, Heap::Tenure tenure)
1.69 +{
1.70 + Local<Array> array(zone, Array::NewRaw(zone, map, dims[level], tenure));
1.71 + if (!array)
1.72 + return NULL;
1.73 +
1.74 + if (map->type()->contained()->isArray()) {
1.75 + Local<ArrayMap> childMap(zone, ArrayMap::cast(map->type()->contained()->newMap()));
1.76 + Local<Array> child(zone);
1.77 +
1.78 + for (unsigned i = 0; i < unsigned(dims[level]); i++) {
1.79 + child = ConstructSizedArray(zone, childMap, dims, level + 1, tenure);
1.80 + if (!child)
1.81 + return NULL;
1.82 +
1.83 + array->writeObject(zone, i, child);
1.84 + }
1.85 + }
1.86 +
1.87 + return array;
1.88 +}
1.89 +
1.90 +Array *
1.91 +Array::NewSized(Zone *zone, Handle<ArrayMap> map, int dims[MAX_ARRAY_DEPTH], Heap::Tenure tenure)
1.92 +{
1.93 + for (size_t i = 0; i < map->type()->levels(); i++) {
1.94 + if (dims[i] < 0) {
1.95 + zone->reportError(Message_InvalidDimensionSize, dims[i], i);
1.96 + return NULL;
1.97 + }
1.98 }
1.99 +
1.100 + return ConstructSizedArray(zone, map, dims, 0, tenure);
1.101 +}
1.102 +
1.103 +static Array *
1.104 +ConstructFixedArray(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure)
1.105 +{
1.106 + unsigned length = map->type()->fixedLength();
1.107 + Local<Array> array(zone, Array::NewRaw(zone, map, length, tenure));
1.108 + if (!array)
1.109 + return NULL;
1.110 +
1.111 + if (map->type()->contained()->isArray()) {
1.112 + Local<ArrayMap> childMap(zone, ArrayMap::cast(map->type()->contained()->newMap()));
1.113 + Local<Array> child(zone);
1.114 +
1.115 + if (childMap->type()->isFixedLength()) {
1.116 + for (unsigned i = 0; i < length; i++) {
1.117 + child = ConstructFixedArray(zone, childMap, tenure);
1.118 + if (!child)
1.119 + return NULL;
1.120 +
1.121 + array->writeObject(zone, i, child);
1.122 + }
1.123 + } else {
1.124 + for (unsigned i = 0; i < length; i++) {
1.125 + child = Array::NewRaw(zone, childMap, 0, tenure);
1.126 + if (!child)
1.127 + return NULL;
1.128 +
1.129 + array->writeObject(zone, i, child);
1.130 + }
1.131 + }
1.132 + }
1.133 +
1.134 return array;
1.135 }
1.136
1.137 Array *
1.138 +Array::NewFixed(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure)
1.139 +{
1.140 + return ConstructFixedArray(zone, map, tenure);
1.141 +}
1.142 +
1.143 +Array *
1.144 Array::NewString(Zone *zone, Handle<ArrayMap> map, Address buffer, size_t length, Heap::Tenure tenure)
1.145 {
1.146 - Local<Array> array(zone, Array::New(zone, map, length, tenure));
1.147 + assert(map->type()->isCharArray());
1.148 +
1.149 + Local<Array> array(zone, Array::New1D(zone, map, length, tenure));
1.150 if (!array)
1.151 return NULL;
1.152
1.153 @@ -133,6 +196,21 @@
1.154 }
1.155
1.156 Array *
1.157 +Array::New1D(Zone *zone, Handle<ArrayMap> map, uint32 elements, Heap::Tenure tenure)
1.158 +{
1.159 + assert(map->type()->levels());
1.160 + return Array::NewRaw(zone, map, elements, tenure);
1.161 +}
1.162 +
1.163 +Array *
1.164 +Array::NewEmpty(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure)
1.165 +{
1.166 + assert(!map->type()->isFixedLength());
1.167 +
1.168 + return Array::NewRaw(zone, map, 0, tenure);
1.169 +}
1.170 +
1.171 +Array *
1.172 Array::NewExternal(Zone *zone, Handle<ArrayMap> map, uint32 nelements, void *buffer,
1.173 Heap::Tenure tenure)
1.174 {