Пример #1
0
 private Variable GetAndCreateVariable(uint vid, bool create)
 {
     Variable v = vars[vid] as Variable;
     if(v == null) {
         if(IsBlock) {
             Variable dv = GetMethodScope().vars[vid] as Variable;
             if(dv != null) {
                 if(create) {
                     dv.IsDynamic = true;
                     dv.closure_slot = GetMethodScope().CreateClosureSlot();
                 } else if(!dv.IsDynamic) {
                     throw new Exception("bug: missing dynamic data for dynamic var: " + context.id2name(vid));
                 }
                 return dv;
             }
         }
         if(create) {
             v = new Variable();
             vars[vid] = v;
             return v;
         } else {
             throw new Exception("Local not found: " + context.id2name(vid));
         }
     }
     return v;
 }
Пример #2
0
        internal override void Walk(EmitContext ec)
        {
            // Due to the slightly weird RNode inheritance hierarchy
            bool is_load = this is RNLVar || this is RNDVar;
            
            if(!(is_load || this is RNDAsgn || this is RNLAsgn)) {
                throw new NotSupportedException("bug: variable type not supported: " + this.GetType().Name);
            }

            if(ec.Resolving) {
                v = ec.scope.MarkVariable(vid);
            }

            if(!is_load)
                val.Walk(ec);
            
            if(ec.Emitting) {
                if(is_load) {
                    Variable v = ec.scope.GetVariable(vid);
                    ec.EmitLoadVar(v);
                } else {
                    ec.EmitDup();
                    ec.EmitStoreVar(v);
                }
            }
        }
Пример #3
0
 // ( -- val )
 internal void EmitLoadVar(Variable v)
 {
     if(v.IsDynamic) {
         EmitLoadClosureArray();
         EmitInt(v.closure_slot);
         ig.Emit(OpCodes.Ldelem_Ref);
     } else {
         AllocateLocal(v);
         ig.Emit(OpCodes.Ldloc, v.local);
     }
 }
Пример #4
0
 // ( -- )
 internal void EmitStoreVar(Variable v)
 {
     if(v.IsDynamic) {
         LocalBuilder tmp = EmitStoreTemp();
         EmitLoadClosureArray();
         EmitInt(v.closure_slot);
         EmitLoadTemp(tmp);
         ig.Emit(OpCodes.Stelem_Ref);
     } else {
         AllocateLocal(v);
         ig.Emit(OpCodes.Stloc, v.local);
     }
 }
Пример #5
0
 void AllocateLocal(Variable v)
 {
     if(v.local == null) {
         v.local = ig.DeclareLocal(typeof(RBasic));
     }
 }