src/compiler/HIR.cpp
changeset 215 b8f650a441a5
parent 212 443d24cfdf2d
child 217 c22e983b3b6e
     1.1 --- a/src/compiler/HIR.cpp	Sun Nov 18 15:00:08 2012 -0800
     1.2 +++ b/src/compiler/HIR.cpp	Sun Nov 18 15:24:30 2012 -0800
     1.3 @@ -89,6 +89,11 @@
     1.4  }
     1.5  
     1.6  void
     1.7 +HGlobal::hold(BytecodeEmitter &emitter_)
     1.8 +{
     1.9 +}
    1.10 +
    1.11 +void
    1.12  HGlobal::store(BytecodeEmitter &emitter_)
    1.13  {
    1.14      __ setglobal(sym_);
    1.15 @@ -108,6 +113,13 @@
    1.16  }
    1.17  
    1.18  void
    1.19 +HLocal::hold(BytecodeEmitter &emitter_)
    1.20 +{
    1.21 +    if (sym_->type()->isReference())
    1.22 +        __ dup();
    1.23 +}
    1.24 +
    1.25 +void
    1.26  HLocal::store(BytecodeEmitter &emitter_)
    1.27  {
    1.28      if (sym_->type()->isReference())
    1.29 @@ -133,6 +145,12 @@
    1.30  }
    1.31  
    1.32  void
    1.33 +HIndex::hold(BytecodeEmitter &emitter_)
    1.34 +{
    1.35 +    __ dup2();
    1.36 +}
    1.37 +
    1.38 +void
    1.39  HIndex::store(BytecodeEmitter &emitter_)
    1.40  {
    1.41      __ setelem(type());
    1.42 @@ -164,37 +182,39 @@
    1.43      __ getglobal(global->sym());
    1.44  }
    1.45  
    1.46 -void
    1.47 -HIRTranslator::visitStore(HStore *store)
    1.48 -{
    1.49 -    store->lval()->bind(this, emitter_);
    1.50 -    store->rval()->accept(this);
    1.51 -    store->lval()->store(emitter_);
    1.52 -}
    1.53 -
    1.54  static inline Opcode
    1.55  TokenToOpcode(TokenKind kind)
    1.56  {
    1.57      switch (kind) {
    1.58        case TOK_PLUS:
    1.59 +      case TOK_ASSIGN_ADD:
    1.60          return OP_ADD;
    1.61        case TOK_MINUS:
    1.62 +      case TOK_ASSIGN_SUB:
    1.63          return OP_SUB;
    1.64        case TOK_STAR:
    1.65 +      case TOK_ASSIGN_MUL:
    1.66          return OP_MUL;
    1.67        case TOK_SLASH:
    1.68 +      case TOK_ASSIGN_DIV:
    1.69          return OP_DIV;
    1.70        case TOK_PERCENT:
    1.71 +      case TOK_ASSIGN_MOD:
    1.72          return OP_MOD;
    1.73        case TOK_SHR:
    1.74 +      case TOK_ASSIGN_SHR:
    1.75          return OP_SHR;
    1.76        case TOK_USHR:
    1.77 +      case TOK_ASSIGN_USHR:
    1.78          return OP_USHR;
    1.79        case TOK_SHL:
    1.80 +      case TOK_ASSIGN_SHL:
    1.81          return OP_SHL;
    1.82        case TOK_BITAND:
    1.83 +      case TOK_ASSIGN_BITAND:
    1.84          return OP_BITAND;
    1.85        case TOK_BITOR:
    1.86 +      case TOK_ASSIGN_BITOR:
    1.87          return OP_BITOR;
    1.88        case TOK_GT:
    1.89            return OP_GT;
    1.90 @@ -215,6 +235,22 @@
    1.91  }
    1.92  
    1.93  void
    1.94 +HIRTranslator::visitStore(HStore *store)
    1.95 +{
    1.96 +    store->lval()->bind(this, emitter_);
    1.97 +    if (store->kind() == TOK_ASSIGN) {
    1.98 +        store->rval()->accept(this);
    1.99 +    } else {
   1.100 +        // Advanced case: dup the ref, load, op, store.
   1.101 +        store->lval()->hold(emitter_);
   1.102 +        store->lval()->load(emitter_);
   1.103 +        store->rval()->accept(this);
   1.104 +        __ binary(TokenToOpcode(store->kind()));
   1.105 +    }
   1.106 +    store->lval()->store(emitter_);
   1.107 +}
   1.108 +
   1.109 +void
   1.110  HIRTranslator::visitBinary(HBinary *binary)
   1.111  {
   1.112      binary->left()->accept(this);