1.1 --- a/src/BytecodeCompiler.cpp Sat Aug 04 21:47:30 2012 -0700
1.2 +++ b/src/BytecodeCompiler.cpp Sat Aug 04 23:26:49 2012 -0700
1.3 @@ -201,6 +201,8 @@
1.4 void
1.5 BytecodeCompiler::visit(Assignment *node)
1.6 {
1.7 + Local<Type> type(zone_, node->expression()->type());
1.8 +
1.9 // The first step is three sub-steps:
1.10 //
1.11 // (1) Bind the left-hand side.
1.12 @@ -213,8 +215,12 @@
1.13 Variable *var = proxy->binding()->toVariable();
1.14
1.15 // Bind.
1.16 - if (var->type()->isReference() || var->type()->isArray())
1.17 + if (var->type()->isReference() ||
1.18 + var->type()->isArray() ||
1.19 + var->type()->isStruct())
1.20 + {
1.21 __ get(var);
1.22 + }
1.23
1.24 // Get the value if needed.
1.25 if (node->token() != TOK_ASSIGN) {
1.26 @@ -234,15 +240,16 @@
1.27
1.28 expr->left()->accept(this);
1.29
1.30 - if (node->token() != TOK_ASSIGN) {
1.31 + if (node->token() != TOK_ASSIGN)
1.32 __ dup();
1.33 +
1.34 + if (node->token() != TOK_ASSIGN || (type->isStruct() || type->isArray()))
1.35 __ getfield(expr->fieldIndex(), expr->type());
1.36 - }
1.37 } else {
1.38 IndexExpression *index = node->lvalue()->toIndexExpression();
1.39 __ note_position(index->pos());
1.40
1.41 - // Note: Eventually, watch out for a whole here. An expression like:
1.42 + // Note: Eventually, watch out for a hole here. An expression like:
1.43 //
1.44 // (a[4] = (5, a = []))
1.45 //
1.46 @@ -252,13 +259,12 @@
1.47 index->left()->accept(this);
1.48 index->right()->accept(this);
1.49
1.50 - if (node->token() != TOK_ASSIGN) {
1.51 + if (node->token() != TOK_ASSIGN)
1.52 __ dup2();
1.53 +
1.54 + if (node->token() != TOK_ASSIGN || (type->isStruct() || type->isArray())) {
1.55 __ bounds();
1.56 - if (node->type()->isArray())
1.57 - __ getarray_o();
1.58 - else
1.59 - __ getarray(node->type());
1.60 + __ getarray(index->type());
1.61 }
1.62 }
1.63
1.64 @@ -273,11 +279,16 @@
1.65 }
1.66
1.67 // Emit the store.
1.68 - if (node->expression()->type()->isArray()) {
1.69 + if (type->isArray()) {
1.70 // Unlike references, which can only be computed from a NamePRoxy,
1.71 // arrays can be computed from multiple lvalue types.
1.72 __ note_position(node->pos());
1.73 - __ arraycopy();
1.74 + __ copyarray();
1.75 + } else if (type->isStruct()) {
1.76 + // Structs have value semantics, so emit a full copy. We don't break
1.77 + // this down into u-ops, to avoid unnecessary bytecode explosion.
1.78 + __ note_position(node->pos());
1.79 + __ copystruct();
1.80 } else if (node->lvalue()->isNameProxy()) {
1.81 NameProxy *proxy = node->lvalue()->toNameProxy();
1.82 Variable *var = proxy->binding()->toVariable();
1.83 @@ -793,7 +804,7 @@
1.84 if (node->initialization()) {
1.85 node->initialization()->accept(this);
1.86 __ note_position(node->pos());
1.87 - __ arraycopy();
1.88 + __ copyarray();
1.89 }
1.90 } else if (type->isStruct()) {
1.91 Local<Map> map(zone_, type->newMap());