/// <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)); }
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; } } } }
/// <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; } }
/// <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"); } }
/// <summary> /// Determines whether this instance is a constant expression /// </summary> /// <returns></returns> public bool IsConstant() { return(m_Constant.IsNotNil()); }