src/BytecodeCompiler.cpp
changeset 193 970abfc9f077
parent 192 23a804fa1d3e
child 194 b029d63565a2
     1.1 --- a/src/BytecodeCompiler.cpp	Sun Sep 16 23:15:13 2012 -0700
     1.2 +++ b/src/BytecodeCompiler.cpp	Sun Sep 16 23:33:48 2012 -0700
     1.3 @@ -206,6 +206,21 @@
     1.4             (type->isArray() && type->isFixedLength());
     1.5  }
     1.6  
     1.7 +static inline Array *
     1.8 +StringLiteralToArray(Zone *zone, StringLiteral *node)
     1.9 +{
    1.10 +    Local<Type> type(zone, node->type());
    1.11 +    Local<ArrayMap> map(zone, ArrayMap::Attach(zone, type));
    1.12 +    if (!map)
    1.13 +        return NULL;
    1.14 +
    1.15 +    return Array::NewString(zone,
    1.16 +                            map,
    1.17 +                            node->string()->raw(),
    1.18 +                            node->string()->length(),
    1.19 +                            Heap::Tenure_Old);
    1.20 +}
    1.21 +
    1.22  void
    1.23  BytecodeCompiler::visit(Assignment *node)
    1.24  {
    1.25 @@ -271,7 +286,23 @@
    1.26      }
    1.27  
    1.28      if (node->token() == TOK_ASSIGN) {
    1.29 -        node->expression()->accept(this);
    1.30 +        // Special case: if the left-hand side is a string literal, we must
    1.31 +        // spawn a new copy (:TODO: something about const?)
    1.32 +        if (node->expression()->isStringLiteral() && !left->isFixedLength()) {
    1.33 +            Local<Array> string(zone_,
    1.34 +                    StringLiteralToArray(zone_, node->expression()->toStringLiteral()));
    1.35 +            if (!string)
    1.36 +                return;
    1.37 +
    1.38 +            Local<ArrayMap> arrayMap(zone_, ArrayMap::cast(string->map()));
    1.39 +            __ note_position(node->expression()->pos());
    1.40 +            __ int_(string->length());
    1.41 +            __ newarray(OP_NEWSIZED, arrayMap, Heap::Tenure_Default);
    1.42 +            __ object(string);
    1.43 +            __ copyarray();
    1.44 +        } else {
    1.45 +            node->expression()->accept(this);
    1.46 +        }
    1.47      } else {
    1.48          visitForALU(left, node->expression());
    1.49  
    1.50 @@ -739,21 +770,6 @@
    1.51      __ float_((float)node->value());
    1.52  }
    1.53  
    1.54 -static inline Array *
    1.55 -StringLiteralToArray(Zone *zone, StringLiteral *node)
    1.56 -{
    1.57 -    Local<Type> type(zone, node->type());
    1.58 -    Local<ArrayMap> map(zone, ArrayMap::Attach(zone, type));
    1.59 -    if (!map)
    1.60 -        return NULL;
    1.61 -
    1.62 -    return Array::NewString(zone,
    1.63 -                            map,
    1.64 -                            node->string()->raw(),
    1.65 -                            node->string()->length(),
    1.66 -                            Heap::Tenure_Old);
    1.67 -}
    1.68 -
    1.69  void
    1.70  BytecodeCompiler::visit(StringLiteral *node)
    1.71  {