コード例 #1
0
        private bool TryGetEnvironmentReference(Name name, out EnvironmentReference er)
        {
            Binding binding;

            if (TryGetBinding(name, out binding))
            {
                Debug.Assert(binding.IsBound);
                Debug.Assert(environment.ContainsKey(name));
                er = environment[name];
                return(true);
            }
            er = null;
            return(false);
        }
コード例 #2
0
        public override Slot GetOrMakeSlot(Name name, Type type)
        {
            EnvironmentReference es = en.GetOrMakeReference(name, type);

            return(es.CreateSlot(instance));
        }
コード例 #3
0
        public override Slot GetSlot(Name name)
        {
            EnvironmentReference es = en.GetReference(name);

            return(es.CreateSlot(instance));
        }
コード例 #4
0
        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);
        }