Exemple #1
0
        /// <summary>
        /// Marks variable as being referenced.
        /// </summary>
        public void MarkLocalByRef(VariableHandle handle)
        {
            handle.ThrowIfInvalid();

            this.FlowContext.SetReference(handle);
            this.SetVarInitialized(handle);
            _flowCtx.SetUsed(handle);
        }
Exemple #2
0
        public void SetVarInitialized(VariableHandle handle)
        {
            int varindex = handle.Slot;

            if (varindex >= 0 && varindex < FlowContext.BitsCount)
            {
                _initializedMask |= 1u << varindex;
            }
        }
Exemple #3
0
        public void SetVarUninitialized(VariableHandle handle)
        {
            var varindex = handle.Slot;

            if (varindex >= 0 && varindex < FlowContext.BitsCount)
            {
                _initializedMask &= ~(1u << varindex);
            }
        }
Exemple #4
0
 void SetConstrain(VariableHandle variable, NoteKind kind, bool set)
 {
     if (set)
     {
         AddConstrain(variable, kind);
     }
     else
     {
         RemoveConstrain(variable, kind);
     }
 }
Exemple #5
0
        void AddConstrain(VariableHandle variable, NoteKind kind)
        {
            if (variable.IsValid)
            {
                var notes = _notes;
                if (notes == null)
                {
                    _notes = notes = new HashSet <NoteData>();
                }

                notes.Add(new NoteData(variable, kind));
            }
        }
Exemple #6
0
        void RemoveConstrain(VariableHandle variable, NoteKind kind)
        {
            if (variable.IsValid)
            {
                var notes = _notes;
                if (notes != null)
                {
                    notes.Remove(new NoteData(variable, kind));

                    if (notes.Count == 0)
                    {
                        _notes = null;
                    }
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Sets variable type in this state.
        /// </summary>
        /// <param name="handle">Variable handle.</param>
        /// <param name="tmask">Variable type. If <c>uninitialized</c>, the variable is set as not initialized in this state.</param>
        public void SetLocalType(VariableHandle handle, TypeRefMask tmask)
        {
            handle.ThrowIfInvalid();

            if (handle >= _varsType.Length)
            {
                Array.Resize(ref _varsType, handle + 1);
            }

            _varsType[handle] = tmask;

            this.FlowContext.AddVarType(handle, tmask);    // TODO: collect merged type information at the end of analysis

            // update the _initializedMask
            SetVarInitialized(handle);
        }
Exemple #8
0
        //#region Variable Kind

        //Dictionary<VariableName, VariableKind> _varKindMap;

        /// <summary>
        /// Declares variable with a specific kind (static or global).
        /// </summary>
        public void SetVarKind(VariableHandle handle, VariableKind kind)
        {
            //if (_varKindMap == null)
            //{
            //    _varKindMap = new Dictionary<VariableName, VariableKind>();
            //}
            //else
            //{
            //    VariableKind old;
            //    if (_varKindMap.TryGetValue(varname, out old))
            //    {
            //        if (old != kind) throw new ArgumentException("redeclaration with a different kind not supported", nameof(kind));
            //    }
            //}

            //_varKindMap[varname] = kind;
        }
Exemple #9
0
        /// <summary>
        /// Gets kind of variable declaration in this state.
        /// </summary>
        public VariableKind GetVarKind(VariableHandle handle)
        {
            handle.ThrowIfInvalid();

            //// explicit variable declaration
            //if (_varKindMap != null)
            //{
            //    VariableKind kind = VariableKind.LocalVariable;

            //    if (_varKindMap.TryGetValue(varname, out kind))
            //    {
            //        return kind;
            //    }
            //}

            // already declared on locals label
            return(Routine.LocalsTable.GetVariableKind(handle.Name));
        }
Exemple #10
0
 /// <summary>
 /// Sets or removes LTInt64 flag for a variable.
 /// </summary>
 public void LTInt64Max(VariableHandle handle, bool lt)
 {
     if (lt)
     {
         if (_lessThanLongMax == null)
         {
             _lessThanLongMax = new HashSet <VariableHandle>();
         }
         _lessThanLongMax.Add(handle);
     }
     else
     {
         if (_lessThanLongMax != null)
         {
             _lessThanLongMax.Remove(handle);
         }
     }
 }
Exemple #11
0
 /// <summary>
 /// Sets or removes GTInt64 flag for a variable.
 /// </summary>
 public void SetGreaterThanLongMin(VariableHandle handle, bool lt) => SetConstrain(handle, NoteKind.GreaterThanLongMin, lt);
Exemple #12
0
 /// <summary>
 /// Sets variable type with byref flag in this state.
 /// </summary>
 /// <param name="handle">Variable handle.</param>
 public void SetLocalRef(VariableHandle handle)
 {
     SetLocalType(handle, GetLocalType(handle).WithRefFlag);
 }
Exemple #13
0
 /// <summary>
 /// Gets value indicating the variable is set in all code paths.
 /// Gets also <c>true</c> if we don't known.
 /// </summary>
 public bool IsLocalSet(VariableHandle handle)
 {
     handle.ThrowIfInvalid();
     return(handle.Slot >= FlowContext.BitsCount || (_initializedMask & (1u << handle)) != 0);
 }
Exemple #14
0
 /// <summary>
 /// Handles use of a local variable.
 /// </summary>
 public void VisitLocal(VariableHandle handle)
 {
     handle.ThrowIfInvalid();
     _flowCtx.SetUsed(handle);
 }
Exemple #15
0
 TypeRefMask GetUnknownLocalType(VariableHandle handle)
 {
     return(IsLocalSet(handle)
         ? TypeRefMask.AnyType.WithRefFlag   // <= SetAllUnknown() called
         : 0);                               // variable was not initialized in the state yet
 }
Exemple #16
0
 /// <summary>
 /// Gets type of variable at this state.
 /// </summary>
 public TypeRefMask GetLocalType(VariableHandle handle)
 {
     handle.ThrowIfInvalid();
     return((handle < _varsType.Length) ? _varsType[handle] : 0);
 }
Exemple #17
0
 /// <summary>
 /// Handles use of a local variable.
 /// </summary>
 public void VisitLocal(VariableHandle handle)
 {
     handle.ThrowIfInvalid();
     FlowContext.SetUsed(handle);
 }
Exemple #18
0
        private static bool HandleTypeChecking(
            TypeRefMask currentType,
            TypeRefMask targetType,
            ConditionBranch branch,
            FlowState flowState,
            VariableHandle handle,
            bool skipTrueIfAnyType)
        {
            // Information whether this path can ever be taken
            bool isFeasible = true;

            if (branch == ConditionBranch.ToTrue)
            {
                // In the true branch the IsAnyType case can be optionally skipped
                if (skipTrueIfAnyType && currentType.IsAnyType)
                {
                    return(isFeasible);
                }

                // Intersect the possible types with those checked by the function, always keeping the IsRef flag.
                // IncludesSubclasses is kept only if it is specified in targetType.
                TypeRefMask resultType = (currentType & (targetType | TypeRefMask.IsRefMask));

                if (resultType.IsVoid)
                {
                    // Clearing the type out in this branch means the variable will never be of that type.
                    // In order to prevent errors in analysis and code generation, set the type to the one specified.
                    resultType = targetType | (currentType & TypeRefMask.IsRefMask);

                    isFeasible = false;
                }

                flowState.SetLocalType(handle, resultType);
            }
            else
            {
                Debug.Assert(branch == ConditionBranch.ToFalse);

                // In the false branch we cannot handle the IsAnyType case
                if (currentType.IsAnyType)
                {
                    return(isFeasible);
                }

                // Remove the types and flags excluded by the fact that the function returned false
                TypeRefMask resultType = currentType & (~targetType);

                if (resultType.IsVoid)
                {
                    // Clearing the type out in this branch means the variable will always be of that type
                    // In order to prevent errors in analysis and code generation, do not alter the type in this case.

                    isFeasible = false;
                }
                else
                {
                    flowState.SetLocalType(handle, resultType);
                }
            }

            return(isFeasible);
        }
Exemple #19
0
        private static bool TryGetVariableHandle(BoundVariable boundvar, FlowState state, out VariableHandle varHandle)
        {
            if (boundvar.Name != null)  // direct variable name
            {
                if (boundvar.VariableKind == VariableKind.LocalVariable ||
                    boundvar.VariableKind == VariableKind.Parameter ||
                    boundvar.VariableKind == VariableKind.LocalTemporalVariable)
                {
                    varHandle = state.GetLocalHandle(new VariableName(boundvar.Name));
                    return(true);
                }
            }

            //
            varHandle = default(VariableHandle);
            return(false);
        }
Exemple #20
0
 /// <summary>
 /// Gets GTInt64 flag for a variable.
 /// </summary>
 public bool IsGreaterThanLongMin(VariableHandle handle) => HasConstrain(handle, NoteKind.GreaterThanLongMin) && TypeRefContext.IsLongOnly(GetLocalType(handle));
Exemple #21
0
 public NoteData(VariableHandle variable, NoteKind kind)
 {
     this.Variable = variable;
     this.Kind     = kind;
 }
Exemple #22
0
 /// <summary>
 /// Gets LTInt64 flag for a variable.
 /// </summary>
 public bool IsLessThanLongMax(VariableHandle handle) => HasConstrain(handle, NoteKind.LessThanLongMax);
Exemple #23
0
 /// <summary>
 /// Sets or removes LTInt64 flag for a variable.
 /// </summary>
 public void SetLessThanLongMax(VariableHandle handle, bool lt) => SetConstrain(handle, NoteKind.LessThanLongMax, lt);
Exemple #24
0
 bool HasConstrain(VariableHandle variable, NoteKind kind) => _notes != null && _notes.Contains(new NoteData(variable, kind));
Exemple #25
0
 /// <summary>
 /// Gets LTInt64 flag for a variable.
 /// </summary>
 public bool IsLTInt64Max(VariableHandle handle) => _lessThanLongMax != null && _lessThanLongMax.Contains(handle);
Exemple #26
0
 /// <summary>
 /// Gets GTInt64 flag for a variable.
 /// </summary>
 public bool IsGreaterThanLongMin(VariableHandle handle) => HasConstrain(handle, NoteKind.GreaterThanLongMin);
Exemple #27
0
        private static bool TryGetVariableHandle(IVariableReference boundvar, FlowState state, out VariableHandle varHandle)
        {
            if (boundvar is LocalVariableReference local && local.BoundName.IsDirect)  // direct variable name
            {
                if (local.VariableKind == VariableKind.LocalVariable ||
                    local.VariableKind == VariableKind.Parameter ||
                    local.VariableKind == VariableKind.LocalTemporalVariable)
                {
                    varHandle = state.GetLocalHandle(local.BoundName.NameValue);
                    return(true);
                }
            }

            //
            varHandle = default(VariableHandle);
            return(false);
        }
Exemple #28
0
 /// <summary>
 /// Gets LTInt64 flag for a variable.
 /// </summary>
 public bool IsLessThanLongMax(VariableHandle handle) => HasConstrain(handle, NoteKind.LessThanLongMax) && TypeRefContext.IsLongOnly(GetLocalType(handle));