diff -r 4d0fff61d65e -r 0456a16c2a63 src/BytecodeCompiler.cpp --- a/src/BytecodeCompiler.cpp Sun Aug 05 21:24:41 2012 -0700 +++ b/src/BytecodeCompiler.cpp Mon Aug 06 02:03:36 2012 -0700 @@ -721,42 +721,23 @@ __ float_((float)node->value()); } -static inline ArrayMap * -BuildArrayMap(Zone *zone, Handle type) -{ - if (type->newMap()) - return ArrayMap::cast(type->newMap()); - - Local map(zone, ArrayMap::New(zone, type)); - if (!map) - return NULL; - - // Ensure the inner type has an array map if needed. - if (type->contained()->isArray()) { - Local contained(zone, type->contained()); - if (!BuildArrayMap(zone, contained)) - return NULL; - } - - type->setNewMap(map); - return map; -} - void BytecodeCompiler::visit(StringLiteral *node) { Local type(zone_, node->type()); - Local map(zone_, BuildArrayMap(zone_, type)); + Local map(zone_, ArrayMap::Attach(zone_, type)); if (!map) return; - Local array(zone_, Array::New(zone_, map, node->string()->length(), Heap::Tenure_Old)); + Local array(zone_, + Array::NewString(zone_, + map, + node->string()->raw(), + node->string()->length(), + Heap::Tenure_Old)); if (!array) return; - assert(array->length() >= node->string()->length()); - memcpy(array->chars(), node->string()->raw(), node->string()->length() * sizeof(char)); - __ note_position(node->pos()); __ object(array); } @@ -782,7 +763,7 @@ Local type(zone_, var->type()); if (type->isArray()) { - Local map(zone_, BuildArrayMap(zone_, type)); + Local map(zone_, ArrayMap::Attach(zone_, type)); __ note_position(node->pos()); if (var->scope()->kind() == Scope::GLOBAL) __ newarray(map, Heap::Tenure_Old); @@ -900,6 +881,8 @@ // If there are missing arguments, then we're not done and have to push // default parameters. Local box(zone_); + Local array(zone_); + Local map(zone_); for (size_t i = node->arguments()->length(); i < funType->parameters()->length(); i++) { box = Box::cast(funType->defaults()->at(i)); @@ -910,13 +893,29 @@ __ float_(box->toFloat()); else assert(false); + + if (funType->parameterAt(i)->isReference()) { + __ note_position(node->pos()); + __ slotref_lifo(); + } } else { - assert(false); - } + assert(box->type()->isArray()); - if (funType->parameterAt(i)->isReference()) { - __ note_position(node->pos()); - __ slotref_lifo(); + array = Array::cast(box->toObject()); + if (funType->parameterAt(i)->isConst()) { + __ object(array); + } else { + // We need to copy the array since it's mutable. Note that + // although COPYARRAY returns its left-hand side, this may + // change in the future, we do the same thing and dupe the + // newly allocated array. + map = ArrayMap::cast(array->map()); + __ newarray(map, Heap::Tenure_Stack); + __ dup(); + __ object(array); + __ copyarray(); + __ pop(); + } } argc++;