src/BytecodeCompiler.cpp
changeset 169 0456a16c2a63
parent 168 4d0fff61d65e
child 172 48cffae8c9e0
     1.1 --- a/src/BytecodeCompiler.cpp	Sun Aug 05 21:24:41 2012 -0700
     1.2 +++ b/src/BytecodeCompiler.cpp	Mon Aug 06 02:03:36 2012 -0700
     1.3 @@ -721,42 +721,23 @@
     1.4      __ float_((float)node->value());
     1.5  }
     1.6  
     1.7 -static inline ArrayMap *
     1.8 -BuildArrayMap(Zone *zone, Handle<Type> type)
     1.9 -{
    1.10 -    if (type->newMap())
    1.11 -        return ArrayMap::cast(type->newMap());
    1.12 -
    1.13 -    Local<ArrayMap> map(zone, ArrayMap::New(zone, type));
    1.14 -    if (!map)
    1.15 -        return NULL;
    1.16 -
    1.17 -    // Ensure the inner type has an array map if needed.
    1.18 -    if (type->contained()->isArray()) {
    1.19 -        Local<Type> contained(zone, type->contained());
    1.20 -        if (!BuildArrayMap(zone, contained))
    1.21 -            return NULL;
    1.22 -    }
    1.23 -
    1.24 -    type->setNewMap(map);
    1.25 -    return map;
    1.26 -}
    1.27 -
    1.28  void
    1.29  BytecodeCompiler::visit(StringLiteral *node)
    1.30  {
    1.31      Local<Type> type(zone_, node->type());
    1.32 -    Local<ArrayMap> map(zone_, BuildArrayMap(zone_, type));
    1.33 +    Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, type));
    1.34      if (!map)
    1.35          return;
    1.36  
    1.37 -    Local<Array> array(zone_, Array::New(zone_, map, node->string()->length(), Heap::Tenure_Old));
    1.38 +    Local<Array> array(zone_,
    1.39 +        Array::NewString(zone_,
    1.40 +                         map,
    1.41 +                         node->string()->raw(),
    1.42 +                         node->string()->length(),
    1.43 +                         Heap::Tenure_Old));
    1.44      if (!array)
    1.45          return;
    1.46  
    1.47 -    assert(array->length() >= node->string()->length());
    1.48 -    memcpy(array->chars(), node->string()->raw(), node->string()->length() * sizeof(char));
    1.49 -
    1.50      __ note_position(node->pos());
    1.51      __ object(array);
    1.52  }
    1.53 @@ -782,7 +763,7 @@
    1.54      
    1.55      Local<Type> type(zone_, var->type());
    1.56      if (type->isArray()) {
    1.57 -        Local<ArrayMap> map(zone_, BuildArrayMap(zone_, type));
    1.58 +        Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, type));
    1.59          __ note_position(node->pos());
    1.60          if (var->scope()->kind() == Scope::GLOBAL)
    1.61              __ newarray(map, Heap::Tenure_Old);
    1.62 @@ -900,6 +881,8 @@
    1.63      // If there are missing arguments, then we're not done and have to push
    1.64      // default parameters.
    1.65      Local<Box> box(zone_);
    1.66 +    Local<Array> array(zone_);
    1.67 +    Local<ArrayMap> map(zone_);
    1.68      for (size_t i = node->arguments()->length(); i < funType->parameters()->length(); i++) {
    1.69          box = Box::cast(funType->defaults()->at(i));
    1.70  
    1.71 @@ -910,13 +893,29 @@
    1.72                  __ float_(box->toFloat());
    1.73              else
    1.74                  assert(false);
    1.75 +
    1.76 +            if (funType->parameterAt(i)->isReference()) {
    1.77 +                __ note_position(node->pos());
    1.78 +                __ slotref_lifo();
    1.79 +            }
    1.80          } else {
    1.81 -            assert(false);
    1.82 -        }
    1.83 +            assert(box->type()->isArray());
    1.84  
    1.85 -        if (funType->parameterAt(i)->isReference()) {
    1.86 -            __ note_position(node->pos());
    1.87 -            __ slotref_lifo();
    1.88 +            array = Array::cast(box->toObject());
    1.89 +            if (funType->parameterAt(i)->isConst()) {
    1.90 +                __ object(array);
    1.91 +            } else {
    1.92 +                // We need to copy the array since it's mutable. Note that
    1.93 +                // although COPYARRAY returns its left-hand side, this may
    1.94 +                // change in the future, we do the same thing and dupe the
    1.95 +                // newly allocated array.
    1.96 +                map = ArrayMap::cast(array->map());
    1.97 +                __ newarray(map, Heap::Tenure_Stack);
    1.98 +                __ dup();
    1.99 +                __ object(array);
   1.100 +                __ copyarray();
   1.101 +                __ pop();
   1.102 +            }
   1.103          }
   1.104  
   1.105          argc++;