jitcraft/BytecodeCompiler.cpp
changeset 23 8a31742781c1
parent 22 765ab1b672a3
child 26 a48382113da6
     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);