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); }
public override Slot GetOrMakeSlot(Name name, Type type) { EnvironmentReference es = en.GetOrMakeReference(name, type); return(es.CreateSlot(instance)); }
public override Slot GetSlot(Name name) { EnvironmentReference es = en.GetReference(name); return(es.CreateSlot(instance)); }
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); }