예제 #1
0
        internal Slot CreateSlot(CodeGen cg)
        {
            switch (_kind) {
                case VariableKind.Local:
                    if (_storage == null) {
                        // Fall back on a runtime lookup if this variable does not have storage associated with it
                        // (e.g. if the variable belongs to a block in interpreted mode).
                        return new LocalNamedFrameSlot(cg.ContextSlot, _name);
                    } else {
                        return CreateSlotForVariable(cg);
                    }

                case VariableKind.Parameter:
                    if (_lift) {
                        if (_storage == null) {
                            return new LocalNamedFrameSlot(cg.ContextSlot, _name);
                        } else {
                            return CreateSlotForVariable(cg);
                        }
                    } else {
                        //Debug.Assert(cg.Allocator.ActiveScope == _block);
                        return MarkLocal(GetArgumentSlot(cg));
                    }

                case VariableKind.Global:
                    if (_storage == null) {
                        return new NamedFrameSlot(cg.ContextSlot, _name);
                    } else {
                        // Globals are accessed via context slot
                        return _storage.CreateSlot(cg.ContextSlot);
                    }

                case VariableKind.Temporary:
                    return cg.GetNamedLocal(_type, SymbolTable.IdToString(_name));

                case VariableKind.GeneratorTemporary:
                    if (!cg.IsGenerator) {
                        goto case VariableKind.Temporary;
                    }

                    // Allocate in environment if emitting generator.
                    // This must be done here for now because the environment
                    // allocation, which is generally done in Allocate(),
                    // is done in the context of the outer generator codegen,
                    // which is not marked IsGenerator so the generator temps
                    // would go onto CLR stack rather than environment.
                    // TODO: Fix this once we have lifetime analysis in place.
                    _storage = _block.EnvironmentFactory.MakeEnvironmentReference(_name, _type);
                    return CreateSlotForVariable(cg);
            }

            Debug.Assert(false, "Unexpected variable kind: " + _kind.ToString());
            return null;
        }
예제 #2
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));
 }
예제 #3
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;
            }
        }