diff -r 23a804fa1d3e -r 970abfc9f077 src/BytecodeCompiler.cpp --- a/src/BytecodeCompiler.cpp Sun Sep 16 23:15:13 2012 -0700 +++ b/src/BytecodeCompiler.cpp Sun Sep 16 23:33:48 2012 -0700 @@ -206,6 +206,21 @@ (type->isArray() && type->isFixedLength()); } +static inline Array * +StringLiteralToArray(Zone *zone, StringLiteral *node) +{ + Local type(zone, node->type()); + Local map(zone, ArrayMap::Attach(zone, type)); + if (!map) + return NULL; + + return Array::NewString(zone, + map, + node->string()->raw(), + node->string()->length(), + Heap::Tenure_Old); +} + void BytecodeCompiler::visit(Assignment *node) { @@ -271,7 +286,23 @@ } if (node->token() == TOK_ASSIGN) { - node->expression()->accept(this); + // Special case: if the left-hand side is a string literal, we must + // spawn a new copy (:TODO: something about const?) + if (node->expression()->isStringLiteral() && !left->isFixedLength()) { + Local string(zone_, + StringLiteralToArray(zone_, node->expression()->toStringLiteral())); + if (!string) + return; + + Local arrayMap(zone_, ArrayMap::cast(string->map())); + __ note_position(node->expression()->pos()); + __ int_(string->length()); + __ newarray(OP_NEWSIZED, arrayMap, Heap::Tenure_Default); + __ object(string); + __ copyarray(); + } else { + node->expression()->accept(this); + } } else { visitForALU(left, node->expression()); @@ -739,21 +770,6 @@ __ float_((float)node->value()); } -static inline Array * -StringLiteralToArray(Zone *zone, StringLiteral *node) -{ - Local type(zone, node->type()); - Local map(zone, ArrayMap::Attach(zone, type)); - if (!map) - return NULL; - - return Array::NewString(zone, - map, - node->string()->raw(), - node->string()->length(), - Heap::Tenure_Old); -} - void BytecodeCompiler::visit(StringLiteral *node) {