Exemple #1
0
        /// <summary>
        /// Calls the specified function.
        /// </summary>
        /// <param name="function">The Lua/MoonSharp function to be called</param>
        /// <param name="args">The arguments to pass to the function.</param>
        /// <returns>
        /// The return value(s) of the function call.
        /// </returns>
        /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception>
        public DynValue Call(DynValue function, params DynValue[] args)
        {
            this.CheckScriptOwnership(function);
            this.CheckScriptOwnership(args);

            if (function.Type != DataType.Function && function.Type != DataType.ClrFunction)
            {
                DynValue metafunction = m_MainProcessor.GetMetamethod(function, "__call");

                if (metafunction.IsNotNil())
                {
                    DynValue[] metaargs = new DynValue[args.Length + 1];
                    metaargs[0] = function;
                    for (int i = 0; i < args.Length; i++)
                    {
                        metaargs[i + 1] = args[i];
                    }

                    function = metafunction;
                    args     = metaargs;
                }
                else
                {
                    throw new ArgumentException("function is not a function and has no __call metamethod.");
                }
            }
            else if (function.Type == DataType.ClrFunction)
            {
                return(function.Callback.ClrCallback(this.CreateDynamicExecutionContext(function.Callback), new CallbackArguments(args, false)));
            }

            return(m_MainProcessor.Call(function, args));
        }
Exemple #2
0
        private void PerformTableSet <T>(LinkedListIndex <T, TablePair> listIndex, T key, DynValue keyDynValue, DynValue value, bool isNumber, int appendKey)
        {
            if (!_isAlive)
            {
                throw new InvalidOperationException(string.Format("Attempting to PerformTableSet on dead Table"));
            }
            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)
                    {
                        if (m_ArrayMap == null)
                        {
                            m_CachedLength += 1;
                        }
                        else
                        {
                            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 #3
0
 /// <summary>
 /// Performs a message decoration before unwinding after an error. To be used in the implementation of xpcall like functions.
 /// </summary>
 /// <param name="messageHandler">The message handler.</param>
 /// <param name="exception">The exception.</param>
 public void PerformMessageDecorationBeforeUnwind(DynValue messageHandler, ScriptRuntimeException exception)
 {
     if (messageHandler.IsNotNil())
     {
         exception.DecoratedMessage = m_Processor.PerformMessageDecorationBeforeUnwind(messageHandler, exception.Message, CallingLocation);
     }
     else
     {
         exception.DecoratedMessage = exception.Message;
     }
 }
Exemple #4
0
 /// <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()));
     }
     else if (r.IsNotNil() && r.Type != DataType.Number && r.Type != DataType.String)
     {
         return(new ScriptRuntimeException("attempt to concatenate a {0} value", r.Type.ToLuaTypeString()));
     }
     else
     {
         throw new InternalErrorException("ConcatOnNonString - both are numbers/strings");
     }
 }
Exemple #5
0
 /// <summary>
 /// Determines whether this instance is a constant expression
 /// </summary>
 /// <returns></returns>
 public bool IsConstant()
 {
     return(m_Constant.IsNotNil());
 }