/// <summary> /// Will allocate the storage in the environment and return slot to access /// the variable in the current scope (so that it can be initialized) /// </summary> private Slot AllocInEnv(CodeGen cg) { //Debug.Assert(_storage == null); Debug.Assert(_block.EnvironmentFactory != null, "Allocating in environment without environment factory.\nIs HasEnvironment set?"); _storage = _block.EnvironmentFactory.MakeEnvironmentReference(_name, _type); return _storage.CreateSlot(cg.Allocator.GetClosureAccessSlot(_block)); }
internal void Allocate(CodeGen cg) { Debug.Assert(cg.Allocator.Block == Block); switch (_kind) { case VariableKind.Local: if (_block.IsGlobal) { // Local on global level, simply allocate the storage _storage = cg.Allocator.LocalAllocator.AllocateStorage(_name, _type); if (_defaultValue != null) { Slot slot = CreateSlotForVariable(cg); _defaultValue.Emit(cg); slot.EmitSet(cg); } } else { Slot slot; // If lifting local into closure, allocate in the environment if (_lift) { // allocate space in the environment and set it to Uninitialized slot = AllocInEnv(cg); } else { // Allocate the storage _storage = cg.Allocator.LocalAllocator.AllocateStorage(_name, _type); // No access slot for local variables, pass null. slot = _storage.CreateSlot(_storage.RequireAccessSlot ? cg.Allocator.GetScopeAccessSlot(_block) : null); MarkLocal(slot); } if (_uninitialized || _defaultValue != null) { // Emit initialization (environments will be initialized all at once) if (_defaultValue != null) { _defaultValue.Emit(cg); slot.EmitSet(cg); } else if (_type == typeof(object)) { // Only set variables of type object to "Uninitialized" //throw new UnInitializedUsageException(this, "Attempted to use uninitialized variable"); slot.EmitSetUninitialized(cg); } } } break; case VariableKind.Parameter: // Lifting parameter into closure, allocate in env and move. if (_lift) { Slot slot = AllocInEnv(cg); Slot src = GetArgumentSlot(cg); // Copy the value from the parameter (src) into the environment (slot) slot.EmitSet(cg, src); } else { Debug.Assert(cg.Allocator.Block == Block); // Nothing to do here } break; case VariableKind.Global: if (_defaultValue is UnboundExpression || cg.Allocator.Parent.Parent.Parent != null) { _storage = cg.Allocator.GlobalAllocator.AllocateStorage(_name, _type); } else { _storage = cg.Allocator.Parent.LocalAllocator.AllocateStorage(_name, _type); } Debug.Assert(_storage != null); break; case VariableKind.Temporary: // Nothing to do here break; case VariableKind.GeneratorTemporary: // Do the work in CreateSlot break; } }