protected void CreateLocalSlots(CodeGen cg)
 {
     foreach (KeyValuePair <Name, Binding> kv in names)
     {
         if (kv.Value.IsLocal)
         {
             Slot local = cg.Names.EnsureLocalSlot(kv.Key);
             local.Local = true;
             if (kv.Value.Unassigned)
             {
                 local.EmitSetUninitialized(cg, kv.Key);
             }
         }
     }
 }
示例#2
0
 public override void EmitSetUninitialized(CodeGen cg, Name name)
 {
     attribute.EmitSetUninitialized(cg, name);
 }
        protected Slot CreateEnvironment(CodeGen cg)
        {
            // Get the environment size
            int size = CalculateEnvironmentSize();

            // Create the array for the names
            Slot namesSlot = cg.GetLocalTmp(typeof(SymbolId[]));

            cg.EmitInt(size - tempsCount);
            cg.Emit(System.Reflection.Emit.OpCodes.Newarr, typeof(SymbolId));
            namesSlot.EmitSet(cg);

            // Find the right environment type
            ConstructorInfo    ctor;
            EnvironmentFactory esf;
            Type envType = GetEnvironmentType(size, cg, out ctor, out esf);

            // Emit the static link for the environment constructor
            cg.EmitStaticLinkOrNull();
            cg.EmitCallerContext();
            // Emit the names array for the environment constructor
            namesSlot.EmitGet(cg);
            cg.EmitNew(ctor);

            // Store the environment reference in the local
            Slot environmentSlot = cg.GetFrameSlot(envType);

            environmentSlot.EmitSet(cg);

            // Remember the environment factory for parent access
            environmentFactory = esf;

            // Create environment references
            environment = new Dictionary <Name, EnvironmentReference>();

            foreach (KeyValuePair <Name, Binding> kv in names)
            {
                if (!kv.Value.IsEnvironment)
                {
                    continue;
                }
                Name name = kv.Key;
                EnvironmentReference er = esf.MakeEnvironmentReference(name);
                Slot slot = er.CreateSlot(environmentSlot);
                Slot current;
                if (cg.Names.Slots.TryGetValue(name, out current))
                {
                    slot.EmitSet(cg, current);
                }
                else
                {
                    slot.EmitSetUninitialized(cg, name);
                }

                // Set the name into the array
                namesSlot.EmitGet(cg);
                cg.EmitInt(er.Index);
                cg.Emit(OpCodes.Ldelema, typeof(SymbolId));
                cg.EmitSymbolIdInt(name.GetString());
                cg.Emit(OpCodes.Call, typeof(SymbolId).GetConstructor(new Type[] { typeof(int) }));

                // The full slot goes to the codegen's namespace
                cg.Names.SetSlot(name, slot);
                // Environment reference goes to the environment
                environment[name] = er;
            }

            return(environmentSlot);
        }