Exemple #1
0
 /// <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));
 }
Exemple #2
0
        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;
            }
        }