Exemple #1
0
        private void PerformTableSet <T>(LinkedListIndex <T, TablePair> listIndex, T key, DynValue keyDynValue, DynValue value, bool isNumber, int appendKey)
        {
            TablePair prev = listIndex.Set(key, new TablePair(keyDynValue, value));

            // If this is an insert, we can invalidate all iterators and collect dead keys
            if (m_ContainsNilEntries && value.IsNotNil() && prev.Value.IsNil())
            {
                CollectDeadKeys();
            }
            // If this value is nil (and we didn't collect), set that there are nil entries, and invalidate array len cache
            else if (value.IsNil())
            {
                m_ContainsNilEntries = true;

                if (isNumber)
                {
                    m_CachedLength = -1;
                }
            }
            else if (isNumber)
            {
                // If this is an array insert, we might have to invalidate the array length
                if (prev.Value.IsNilOrNan())
                {
                    // If this is an array append, let's check the next element before blindly invalidating
                    if (appendKey >= 0)
                    {
                        LinkedListNode <TablePair> next = m_ArrayMap.Find(appendKey + 1);
                        if (next == null || next.Value.Value.IsNil())
                        {
                            m_CachedLength += 1;
                        }
                        else
                        {
                            m_CachedLength = -1;
                        }
                    }
                    else
                    {
                        m_CachedLength = -1;
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Sets the value associated to the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public void Set(DynValue key, DynValue value)
        {
            if (!_isAlive)
            {
                throw new InvalidOperationException(string.Format("Attempting to Set on dead Table"));
            }
            if (key.IsNilOrNan())
            {
                if (key.IsNil())
                {
                    throw ScriptRuntimeException.TableIndexIsNil();
                }
                else
                {
                    throw ScriptRuntimeException.TableIndexIsNaN();
                }
            }

            if (key.Type == DataType.String)
            {
                Set(key.String, value);
                return;
            }

            if (key.Type == DataType.Number)
            {
                int idx = GetIntegralKey(key.Number);

                if (idx > 0)
                {
                    Set(idx, value);
                    return;
                }
            }

            this.CheckScriptOwnership(key);
            this.CheckScriptOwnership(value);

            if (m_ValueMap == null)
            {
                m_ValueMap = new LinkedListIndex <DynValue, TablePair>(ValuesList);
            }
            PerformTableSet(m_ValueMap, key, key, value, false, -1);
        }
        /// <summary>
        /// Creates a ScriptRuntimeException with a predefined error message specifying that
        /// a concat operation was attempted on non-strings
        /// </summary>
        /// <param name="l">The left operand.</param>
        /// <param name="r">The right operand.</param>
        /// <returns>The exception to be raised.</returns>
        /// <exception cref="InternalErrorException">If both are numbers or strings</exception>
        public static ScriptRuntimeException ConcatOnNonString(DynValue l, DynValue r)
        {
            if (l.Type != DataType.Number && l.Type != DataType.String)
            {
                return(new ScriptRuntimeException("Attempt to concatenate a {0} value", l.Type.ToLuaTypeString()));
            }

            if (r != null && r.Type != DataType.Number && r.Type != DataType.String)
            {
                return(new ScriptRuntimeException("Attempt to concatenate a {0} value", r.Type.ToLuaTypeString()));
            }

            if (l.IsNil() || l.String == null || (r?.IsNil() ?? true) || r.String == null)
            {
                throw new ScriptRuntimeException("Attempt to concatenate a nil value.");
            }

            throw new InternalErrorException("ConcatOnNonString - both are numbers/strings");
        }
Exemple #4
0
        /// <summary>
        /// Checks if the type is a specific userdata type, and returns it or throws.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="funcName">Name of the function.</param>
        /// <param name="argNum">The argument number.</param>
        /// <param name="flags">The flags.</param>
        /// <returns></returns>
        public T CheckUserDataType <T>(string funcName, int argNum = -1, TypeValidationFlags flags = TypeValidationFlags.Default)
        {
            DynValue v        = this.CheckType(funcName, DataType.UserData, argNum, flags);
            bool     allowNil = ((int)(flags & TypeValidationFlags.AllowNil) != 0);

            if (v.IsNil())
            {
                return(default(T));
            }

            object o = v.UserData.Object;

            if (o != null && o is T)
            {
                return((T)o);
            }

            throw ScriptRuntimeException.BadArgumentUserData(argNum, funcName, typeof(T), o, allowNil);
        }
Exemple #5
0
        private void PerformTableSet <T>(LinkedListIndex <T, TablePair> listIndex, T key, DynValue keyDynValue, DynValue value, bool isNumber)
        {
            TablePair prev = listIndex.Set(key, new TablePair(keyDynValue, value));

            if (prev.Value == null || prev.Value.IsNil())
            {
                CollectDeadKeys();

                if (isNumber)
                {
                    m_CachedLength = -1;
                }
            }

            if (isNumber && value.IsNil())
            {
                m_CachedLength = -1;
            }
        }
Exemple #6
0
        /// <summary>
        /// Returns the next pair from a value
        /// </summary>
        public TablePair?NextKey(DynValue v)
        {
            if (v.IsNil())
            {
                LinkedListNode <TablePair> node = m_Values.First;

                if (node == null)
                {
                    return(TablePair.Nil);
                }
                else
                {
                    if (node.Value.Value.IsNil())
                    {
                        return(NextKey(node.Value.Key));
                    }
                    else
                    {
                        return(node.Value);
                    }
                }
            }

            if (v.Type == DataType.String)
            {
                return(GetNextOf(m_StringMap.Find(v.String)));
            }

            if (v.Type == DataType.Number)
            {
                int idx = GetIntegralKey(v.Number);

                if (idx >= (OwnerScript.Options.ZeroIndexTables ? 0 : 1))
                {
                    return(GetNextOf(m_ArrayMap.Find(idx)));
                }
            }

            return(GetNextOf(m_ValueMap.Find(v)));
        }
Exemple #7
0
        /// <summary>
        /// Sets the value associated to the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public void Set(DynValue key, DynValue value)
        {
            if (key.IsNilOrNan())
            {
                if (key.IsNil())
                {
                    throw ScriptRuntimeException.TableIndexIsNil();
                }
                else
                {
                    throw ScriptRuntimeException.TableIndexIsNaN();
                }
            }

            if (key.Type == DataType.String)
            {
                Set(key.String, value);
                return;
            }

            if (key.Type == DataType.Number)
            {
                int idx = GetIntegralKey(key.Number);

                if (idx >= (OwnerScript.Options.ZeroIndexTables ? 0 : 1))
                {
                    Set(idx, value);
                    return;
                }
            }

            this.CheckScriptOwnership(key);
            this.CheckScriptOwnership(value);

            PerformTableSet(m_ValueMap, key, key, value, false, -1);
        }
Exemple #8
0
        /// <summary>
        /// Sets the value associated to the specified key.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public void Set(DynValue key, DynValue value)
        {
            if (key.IsNilOrNan())
            {
                if (key.IsNil())
                {
                    throw ScriptRuntimeException.TableIndexIsNil();
                }
                else
                {
                    throw ScriptRuntimeException.TableIndexIsNaN();
                }
            }

            if (key.Type == DataType.String)
            {
                Set(key.String, value);
                return;
            }

            if (key.Type == DataType.Number)
            {
                int idx = GetIntegralKey(key.Number);

                if (idx > 0)
                {
                    Set(idx, value);
                    return;
                }
            }

            CheckValueOwner(key);
            CheckValueOwner(value);

            PerformTableSet(m_ValueMap, key, key, value, false);
        }