1.1 --- a/jitcraft/BytecodeCompiler.cpp Sun Jul 01 16:36:39 2012 -0700
1.2 +++ b/jitcraft/BytecodeCompiler.cpp Sun Jul 01 18:21:15 2012 -0700
1.3 @@ -194,7 +194,7 @@
1.4 __ get(var);
1.5 }
1.6 }
1.7 - } else if (node->lvalue()->isIndexExpression()) {
1.8 + } else {
1.9 IndexExpression *index = node->lvalue()->toIndexExpression();
1.10
1.11 // Note: Eventually, watch out for a whole here. An expression like:
1.12 @@ -241,7 +241,7 @@
1.13 __ set(var);
1.14 } else {
1.15 IndexExpression *index = node->lvalue()->toIndexExpression();
1.16 - // :TODO: get rid of the BOUNDS instruction, embed it in setarray*?
1.17 + // :TODO: get rid of the BOUNDS instruction, embed it in g/setarray*?
1.18 // We can't emit it here because the stack is slightly out of position.
1.19 // __ bounds();
1.20 __ setarray(index->left()->type()->contained()->primitive());
1.21 @@ -249,6 +249,110 @@
1.22 }
1.23
1.24 void
1.25 +BytecodeCompiler::visit(IncDecExpression *node)
1.26 +{
1.27 + // In the postfix case, the logic looks like:
1.28 + // (1) Bind -> REF
1.29 + // (2) Dup -> REF REF
1.30 + // (3) Fetch -> REF VAL
1.31 + // (4) Swap -> VAL REF
1.32 + // (5) Pick -> VAL REF VAL
1.33 + // (6) Add -> VAL REF VAL+1
1.34 + // (7) Store -> VAL VAL+1
1.35 + // (8) Drop -> VAL
1.36 + //
1.37 + // In the prefix case, the logic looks like:
1.38 + // (1) Bind -> REF
1.39 + // (2) Dup -> REF REF
1.40 + // (3) Fetch -> REF VAL
1.41 + // --
1.42 + // --
1.43 + // (6) Add -> REF VAL+1
1.44 + // (7) Store -> VAL+1
1.45 + // --
1.46 + //
1.47 + // This is squirrely enough such that we don't bother sharing too much
1.48 + // with the above.
1.49 + //
1.50 + // Note: We simulate a "Pick" operation with a dup2+pop.
1.51 +
1.52 + // This is steps (1) to (5).
1.53 + Expression *expr = node->expression();
1.54 + if (expr->isNameProxy()) {
1.55 + NameProxy *proxy = expr->toNameProxy();
1.56 + Variable *var = proxy->binding()->toVariable();
1.57 +
1.58 + // Bind.
1.59 + if (var->type()->isReference() || var->type()->isArray())
1.60 + __ get(var);
1.61 +
1.62 + // Dup and fetch.
1.63 + if (var->type()->isReference()) {
1.64 + __ dup();
1.65 + __ getref(node->type()->primitive());
1.66 + if (node->postfix()) {
1.67 + __ swap();
1.68 + __ pick2();
1.69 + }
1.70 + } else {
1.71 + assert(!var->type()->isArray());
1.72 + __ get(var);
1.73 + if (node->postfix())
1.74 + __ dup();
1.75 + }
1.76 + } else {
1.77 + IndexExpression *index = expr->toIndexExpression();
1.78 + index->left()->accept(this);
1.79 + index->right()->accept(this);
1.80 +
1.81 + assert(!node->type()->isArray());
1.82 + __ bounds();
1.83 + __ dup2();
1.84 + __ getarray(node->type()->primitive());
1.85 +
1.86 + if (node->postfix()) {
1.87 + // The stack looks like this now:
1.88 + // ARRAY INDEX VALUE
1.89 + //
1.90 + // So we must use a PICK operation to rotate the stack into position.
1.91 + __ roll3(); // INDEX VALUE ARRAY
1.92 + __ roll3(); // VALUE ARRAY INDEX
1.93 + __ pick3(); // VALUE ARRAY INDEX VALUE
1.94 + }
1.95 + }
1.96 +
1.97 + // Perform step (6).
1.98 + if (node->type()->isFloat()) {
1.99 + __ float_(1.0);
1.100 + } else {
1.101 + assert(node->type()->isInt32());
1.102 + __ int_(1);
1.103 + }
1.104 +
1.105 + if (node->token() == TOK_INCREMENT)
1.106 + __ binary(OP_ADD);
1.107 + else
1.108 + __ binary(OP_SUB);
1.109 +
1.110 + // Perform step (7).
1.111 + if (expr->isNameProxy()) {
1.112 + NameProxy *proxy = expr->toNameProxy();
1.113 + Variable *var = proxy->binding()->toVariable();
1.114 +
1.115 + if (var->type()->isReference())
1.116 + __ setref(node->type()->primitive());
1.117 + else
1.118 + __ set(var);
1.119 + } else {
1.120 + __ setarray(node->type()->primitive());
1.121 + }
1.122 +
1.123 + // Perform step (8).
1.124 + if (node->postfix())
1.125 + __ pop();
1.126 +}
1.127 +
1.128 +void
1.129 BytecodeCompiler::visitForALU(Type *needed, Expression *node)
1.130 {
1.131 node->accept(this);