src/compiler/HIR.cpp
changeset 222 0cde1379b29f
parent 221 0c588a96837c
child 234 26e3035cdffc
     1.1 --- a/src/compiler/HIR.cpp	Mon Nov 19 02:12:13 2012 -0800
     1.2 +++ b/src/compiler/HIR.cpp	Thu Dec 20 00:59:38 2012 -0800
     1.3 @@ -47,6 +47,7 @@
     1.4      void visitConvert(HConvert *convert);
     1.5      void visitIndex(HIndex *index);
     1.6      void visitPostIncDec(HPostIncDec *hir);
     1.7 +    void visitToRef(HToRef *hir);
     1.8  
     1.9    private:
    1.10      Zone *zone_;
    1.11 @@ -114,6 +115,26 @@
    1.12      __ getglobal(sym_);
    1.13  }
    1.14  
    1.15 +bool
    1.16 +HGlobal::ref(BytecodeEmitter &emitter_)
    1.17 +{
    1.18 +    return false;
    1.19 +}
    1.20 +
    1.21 +static inline Type *
    1.22 +MaybeDereference(Type *type)
    1.23 +{
    1.24 +    if (type->isReference())
    1.25 +        return ReferenceType::cast(type)->contained();
    1.26 +    return type;
    1.27 +}
    1.28 +
    1.29 +HLocal::HLocal(AstNode *node, VariableSymbol *sym)
    1.30 +  : HLValue(node, MaybeDereference(sym->type())),
    1.31 +    sym_(sym)
    1.32 +{
    1.33 +}
    1.34 +
    1.35  void
    1.36  HLocal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
    1.37  {
    1.38 @@ -149,7 +170,7 @@
    1.39  HLocal::store(BytecodeEmitter &emitter_)
    1.40  {
    1.41      if (sym_->type()->isReference()) {
    1.42 -        __ setref(sym_->type()->contained_ref());
    1.43 +        __ setref(ReferenceType::cast(sym_->type())->contained());
    1.44      } else {
    1.45          if (sym_->storage() == VariableSymbol::Local)
    1.46              __ setlocal(sym_);
    1.47 @@ -164,7 +185,7 @@
    1.48  HLocal::load(BytecodeEmitter &emitter_)
    1.49  {
    1.50      if (sym_->type()->isReference())
    1.51 -        __ getref(sym_->type());
    1.52 +        __ getref(ReferenceType::cast(sym_->type())->contained());
    1.53      else if (sym_->storage() == VariableSymbol::Local)
    1.54          __ getlocal(sym_);
    1.55      else if (sym_->storage() == VariableSymbol::Arg)
    1.56 @@ -173,6 +194,33 @@
    1.57          assert(false);
    1.58  }
    1.59  
    1.60 +bool
    1.61 +HLocal::ref(BytecodeEmitter &emitter_)
    1.62 +{
    1.63 +    if (sym_->storage() == VariableSymbol::Heap) {
    1.64 +        // Closing over a reference should never pass SemA.
    1.65 +        assert(!sym_->type()->isReference());
    1.66 +
    1.67 +        // We don't support direct references to heap-allocated locals. This
    1.68 +        // should probably be banned in SemA? But for now, just assert. :TODO:
    1.69 +        assert(false);
    1.70 +        return false;
    1.71 +    }
    1.72 +        
    1.73 +    if (sym_->type()->isReference()) {
    1.74 +        if (sym_->storage() == VariableSymbol::Local)
    1.75 +            __ getlocal(sym_);
    1.76 +        else if (sym_->storage() == VariableSymbol::Arg)
    1.77 +            __ getarg(sym_);
    1.78 +        else
    1.79 +            assert(false);
    1.80 +    } else {
    1.81 +        __ newref(sym_);
    1.82 +    }
    1.83 +
    1.84 +    return true;
    1.85 +}
    1.86 +
    1.87  void
    1.88  HIndex::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
    1.89  {
    1.90 @@ -208,6 +256,12 @@
    1.91      __ getelem(type());
    1.92  }
    1.93  
    1.94 +bool
    1.95 +HIndex::ref(BytecodeEmitter &emitter_)
    1.96 +{
    1.97 +    return false;
    1.98 +}
    1.99 +
   1.100  void
   1.101  HIRTranslator::visitLocal(HLocal *local)
   1.102  {
   1.103 @@ -350,6 +404,20 @@
   1.104  }
   1.105  
   1.106  void
   1.107 +HIRTranslator::visitToRef(HToRef *hir)
   1.108 +{
   1.109 +    HIR *in = hir->in();
   1.110 +
   1.111 +    // See if we can bind a direct reference.
   1.112 +    if (in->isLValue() && in->toLValue()->ref(emitter_))
   1.113 +        return;
   1.114 +
   1.115 +    // No, we can't. So instead we create an on-stack reference.
   1.116 +    in->accept(this);
   1.117 +    __ slotref_lifo();
   1.118 +}
   1.119 +
   1.120 +void
   1.121  ke::EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir)
   1.122  {
   1.123      HIRTranslator translator(zone, emitter);