Esempio n. 1
0
        private static DynValue ___eq(ScriptExecutionContext context, CallbackArguments args)
        {
            T        lhs;
            DynValue rhs;

            {
                //Raw get and nullchecks
                DynValue r_lhs = args.RawGet(0, true);
                DynValue r_rhs = args.RawGet(1, true);

                if (r_lhs.IsNil() || r_rhs.IsNil())
                {
                    return(DynValue.False);
                }

                //Make sure lhs is a proper T
                {
                    LuaEnumProxy <T> holder;
                    if (r_lhs.Type == DataType.UserData && r_lhs.UserData.TryGet(out holder))
                    {
                        rhs = r_rhs;
                    }
                    else if (r_rhs.Type == DataType.UserData && r_rhs.UserData.TryGet(out holder))
                    {
                        rhs = r_lhs;
                    }
                    else
                    {
                        return(DynValue.False);
                    }
                    lhs = holder.value;
                }
            }

            //Test T against rhs
            if (rhs.Type == DataType.Number)
            {
                return(DynValue.NewBoolean(lhs.Equals(Enum.ToObject(typeof(T), (int)rhs.Number))));
            }
            if (rhs.Type == DataType.String)
            {
                return(DynValue.NewBoolean(lhs.Equals(Enum.Parse(typeof(T), rhs.String))));
            }
            if (rhs.Type == DataType.UserData)
            {
                LuaEnumProxy <T> t2;
                if (rhs.UserData.TryGet(out t2))
                {
                    return(DynValue.NewBoolean(lhs.Equals(t2.value)));
                }
            }
            return(DynValue.False);
        }
Esempio n. 2
0
        public static DynValue concat(ScriptExecutionContext executionContext, CallbackArguments args)
        {
            if (args.Count < 1)
            {
                throw ScriptRuntimeException.BadArgumentValueExpected(0, "concat");
            }

            string toreturn = "";

            if (args.Count == 1)
            {
                toreturn = _castToString(args.RawGet(0, true));
            }
            else if (args.Count == 2)
            {
                toreturn = _castToString(args.RawGet(0, true)) + _castToString(args.RawGet(1, true));
            }
            else if (args.Count == 3)
            {
                toreturn = _castToString(args.RawGet(0, true)) + _castToString(args.RawGet(1, true)) + _castToString(args.RawGet(2, true));
            }
            else if (args.Count == 4)
            {
                toreturn = _castToString(args.RawGet(0, true)) + _castToString(args.RawGet(1, true)) + _castToString(args.RawGet(2, true)) + _castToString(args.RawGet(3, true));
            }
            else
            {
                for (int i = 0; i != args.Count; i++)
                {
                    toreturn += _castToString(args.RawGet(i + 1, true));
                }
            }
            return(DynValue.NewString(toreturn));
        }
Esempio n. 3
0
        private static DynValue Dump(ScriptExecutionContext context, CallbackArguments args)
        {
            var val = args.RawGet(0, true);

            if (val == null)
            {
                throw new ScriptRuntimeException("Missing a value to dump");
            }
            var maxDepthVal = args.RawGet(1, true);
            var maxDepth    = maxDepthVal != null ? (int)(maxDepthVal.CastToNumber() ?? -1) : -1;

            Dump(context.GetScript(), val, maxDepth);
            Console.WriteLine();
            return(DynValue.Void);
        }
Esempio n. 4
0
        DynValue Callback(Script script, object obj, ScriptExecutionContext context, CallbackArguments args)
        {
            if (AccessMode == InteropAccessMode.LazyOptimized &&
                m_OptimizedFunc == null && m_OptimizedAction == null)
            {
                Optimize();
            }

            object[] pars = new object[m_Arguments.Length];

            int j = args.IsMethodCall ? 1 : 0;

            for (int i = 0; i < pars.Length; i++)
            {
                if (m_Arguments[i] == typeof(Script))
                {
                    pars[i] = script;
                }
                else if (m_Arguments[i] == typeof(ScriptExecutionContext))
                {
                    pars[i] = context;
                }
                else if (m_Arguments[i] == typeof(CallbackArguments))
                {
                    pars[i] = args.SkipMethodCall();
                }
                else
                {
                    var arg = args.RawGet(j, false) ?? DynValue.Void;
                    pars[i] = ConversionHelper.MoonSharpValueToObjectOfType(arg, m_Arguments[i], m_Defaults[i]);
                    j++;
                }
            }


            object retv = null;

            if (m_OptimizedFunc != null)
            {
                retv = m_OptimizedFunc(obj, pars);
            }
            else if (m_OptimizedAction != null)
            {
                m_OptimizedAction(obj, pars);
                retv = DynValue.Void;
            }
            else if (m_IsAction)
            {
                MethodInfo.Invoke(obj, pars);
                retv = DynValue.Void;
            }
            else
            {
                retv = MethodInfo.Invoke(obj, pars);
            }

            return(ConversionHelper.ClrObjectToComplexMoonSharpValue(script, retv));
        }
Esempio n. 5
0
    private DynValue lua_print_generic(ScriptExecutionContext context, CallbackArguments args)
    {
        for (var i = 0; i < args.Count; ++i)
        {
            var arg = args.RawGet(i, false);
            Debug.Log(arg.ToPrintString());
        }

        return(DynValue.Nil);
    }
Esempio n. 6
0
        public static DynValue format(ScriptExecutionContext executionContext, CallbackArguments args)
        {
            string format = args.AsString(0, "format");
            string toreturn;

            if (args.Count == 1)
            {
                toreturn = string.Format(format);
            }
            else if (args.Count == 2)
            {
                toreturn = string.Format(format, args.RawGet(1, true).ToString());
            }
            else if (args.Count == 3)
            {
                toreturn = string.Format(format, args.RawGet(1, true).ToString(), args.RawGet(2, true).ToString());
            }
            else if (args.Count == 4)
            {
                toreturn = string.Format(format, args.RawGet(1, true).ToString(), args.RawGet(2, true).ToString(), args.RawGet(3, true).ToString());
            }
            else
            {
                string[] array = new string[args.Count - 1];
                for (int i = 0; i != array.Length; i++)
                {
                    array[i] = args.RawGet(i + 1, true).ToString();
                }
                toreturn = string.Format(format, array);
            }
            return(DynValue.NewString(toreturn));
        }
Esempio n. 7
0
    private DynValue Place(ScriptExecutionContext _context, CallbackArguments _args)
    {
        // get the argument
        DynValue argument = _args.RawGet(0, true);

        // cast to number
        int type = (int)argument.CastToNumber();

        // call the place func
        m_builder.Place((PrimitiveType)type);

        return(DynValue.Void);
    }
        /// <summary>
        /// Builds the argument list.
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="obj">The object.</param>
        /// <param name="context">The context.</param>
        /// <param name="args">The arguments.</param>
        /// <param name="outParams">Output: A list containing the indices of all "out" parameters, or null if no out parameters are specified.</param>
        /// <returns>The arguments, appropriately converted.</returns>
        protected virtual object[] BuildArgumentList(Script script, object obj, ScriptExecutionContext context, CallbackArguments args,
                                                     out List <int> outParams)
        {
            ParameterDescriptor[] parameters = Parameters;

            object[] pars = new object[parameters.Length];

            int j = args.IsMethodCall ? 1 : 0;

            outParams = null;

            for (int i = 0; i < pars.Length; i++)
            {
                // keep track of out and ref params
                if (parameters[i].Type.IsByRef)
                {
                    if (outParams == null)
                    {
                        outParams = new List <int>();
                    }
                    outParams.Add(i);
                }

                // if an ext method, we have an obj -> fill the first param
                if (ExtensionMethodType != null && obj != null && i == 0)
                {
                    pars[i] = obj;
                    continue;
                }
                // else, fill types with a supported type
                else if (parameters[i].Type == typeof(Script))
                {
                    pars[i] = script;
                }
                else if (parameters[i].Type == typeof(ScriptExecutionContext))
                {
                    pars[i] = context;
                }
                else if (parameters[i].Type == typeof(CallbackArguments))
                {
                    pars[i] = args.SkipMethodCall();
                }
                // else, ignore out params
                else if (parameters[i].IsOut)
                {
                    pars[i] = null;
                }
                else if (i == parameters.Length - 1 && VarArgsArrayType != null)
                {
                    List <DynValue> extraArgs = new List <DynValue>();

                    while (true)
                    {
                        DynValue arg = args.RawGet(j, false);
                        j += 1;
                        if (arg != null)
                        {
                            extraArgs.Add(arg);
                        }
                        else
                        {
                            break;
                        }
                    }

                    // here we have to worry we already have an array.. damn. We only support this for userdata.
                    // remains to be analyzed what's the correct behavior here. For example, let's take a params object[]..
                    // given a single table parameter, should it use it as an array or as an object itself ?
                    if (extraArgs.Count == 1)
                    {
                        DynValue arg = extraArgs[0];

                        if (arg.Type == DataType.UserData && arg.UserData.Object != null)
                        {
                            if (Framework.Do.IsAssignableFrom(VarArgsArrayType, arg.UserData.Object.GetType()))
                            {
                                pars[i] = arg.UserData.Object;
                                continue;
                            }
                        }
                    }

                    // ok let's create an array, and loop
                    Array vararg = Array.CreateInstance(VarArgsElementType, extraArgs.Count);

                    for (int ii = 0; ii < extraArgs.Count; ii++)
                    {
                        vararg.SetValue(ScriptToClrConversions.DynValueToObjectOfType(extraArgs[ii], VarArgsElementType,
                                                                                      null, false), ii);
                    }

                    pars[i] = vararg;
                }
                // else, convert it
                else
                {
                    var arg = args.RawGet(j, false) ?? DynValue.Void;
                    pars[i] = ScriptToClrConversions.DynValueToObjectOfType(arg, parameters[i].Type,
                                                                            parameters[i].DefaultValue, parameters[i].HasDefaultValue);
                    j += 1;
                }
            }

            return(pars);
        }
        /// <summary>
        /// Calculates the score for the overload.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="args">The arguments.</param>
        /// <param name="method">The method.</param>
        /// <param name="isExtMethod">if set to <c>true</c>, is an extension method.</param>
        /// <returns></returns>
        private int CalcScoreForOverload(ScriptExecutionContext context, CallbackArguments args, IOverloadableMemberDescriptor method, bool isExtMethod)
        {
            int  totalScore  = ScriptToClrConversions.WEIGHT_EXACT_MATCH;
            int  argsBase    = args.IsMethodCall ? 1 : 0;
            int  argsCnt     = argsBase;
            bool varArgsUsed = false;


            for (int i = 0; i < method.Parameters.Length; i++)
            {
                if (isExtMethod && i == 0)
                {
                    continue;
                }

                if (method.Parameters[i].IsOut)
                {
                    continue;
                }

                Type parameterType = method.Parameters[i].Type;

                if ((parameterType == typeof(Script)) || (parameterType == typeof(ScriptExecutionContext)) || (parameterType == typeof(CallbackArguments)))
                {
                    continue;
                }

                if (i == method.Parameters.Length - 1 && method.VarArgsArrayType != null)
                {
                    int      varargCnt          = 0;
                    DynValue firstArg           = null;
                    int      scoreBeforeVargars = totalScore;

                    // update score for varargs
                    while (true)
                    {
                        var arg = args.RawGet(argsCnt, false);
                        if (arg == null)
                        {
                            break;
                        }

                        if (firstArg == null)
                        {
                            firstArg = arg;
                        }

                        argsCnt += 1;

                        varargCnt += 1;

                        int score = CalcScoreForSingleArgument(method.Parameters[i], method.VarArgsElementType, arg, isOptional: false);
                        totalScore = Math.Min(totalScore, score);
                    }

                    // check if exact-match
                    if (varargCnt == 1)
                    {
                        if (firstArg.Type == DataType.UserData && firstArg.UserData.Object != null)
                        {
                            if (Framework.Do.IsAssignableFrom(method.VarArgsArrayType, firstArg.UserData.Object.GetType()))
                            {
                                totalScore = scoreBeforeVargars;
                                continue;
                            }
                        }
                    }

                    // apply varargs penalty to score
                    if (varargCnt == 0)
                    {
                        totalScore = Math.Min(totalScore, ScriptToClrConversions.WEIGHT_VARARGS_EMPTY);
                    }

                    varArgsUsed = true;
                }
                else
                {
                    var arg = args.RawGet(argsCnt, false) ?? DynValue.Void;

                    int score = CalcScoreForSingleArgument(method.Parameters[i], parameterType, arg, method.Parameters[i].HasDefaultValue);

                    totalScore = Math.Min(totalScore, score);

                    argsCnt += 1;
                }
            }

            if (totalScore > 0)
            {
                if ((args.Count - argsBase) <= method.Parameters.Length)
                {
                    totalScore += ScriptToClrConversions.WEIGHT_NO_EXTRA_PARAMS_BONUS;
                    totalScore *= 1000;
                }
                else if (varArgsUsed)
                {
                    totalScore -= ScriptToClrConversions.WEIGHT_VARARGS_MALUS;
                    totalScore *= 1000;
                }
                else
                {
                    totalScore *= 1000;
                    totalScore -= ScriptToClrConversions.WEIGHT_EXTRA_PARAMS_MALUS * ((args.Count - argsBase) - method.Parameters.Length);
                    totalScore  = Math.Max(1, totalScore);
                }
            }

#if DEBUG_OVERLOAD_RESOLVER
            System.Diagnostics.Debug.WriteLine(string.Format("[OVERLOAD] : Score {0} for method {1}", totalScore, method.SortDiscriminant));
#endif
            return(totalScore);
        }
		/// <summary>
		/// Builds the argument list.
		/// </summary>
		/// <param name="script">The script.</param>
		/// <param name="obj">The object.</param>
		/// <param name="context">The context.</param>
		/// <param name="args">The arguments.</param>
		/// <param name="outParams">Output: A list containing the indices of all "out" parameters, or null if no out parameters are specified.</param>
		/// <returns>The arguments, appropriately converted.</returns>
		protected virtual object[] BuildArgumentList(Script script, object obj, ScriptExecutionContext context, CallbackArguments args,
			out List<int> outParams)
		{
			ParameterDescriptor[] parameters = Parameters;

			object[] pars = new object[parameters.Length];

			int j = args.IsMethodCall ? 1 : 0;

			outParams = null;

			for (int i = 0; i < pars.Length; i++)
			{
				// keep track of out and ref params
				if (parameters[i].Type.IsByRef)
				{
					if (outParams == null) outParams = new List<int>();
					outParams.Add(i);
				}

				// if an ext method, we have an obj -> fill the first param
				if (ExtensionMethodType != null && obj != null && i == 0)
				{
					pars[i] = obj;
					continue;
				}
				// else, fill types with a supported type
				else if (parameters[i].Type == typeof(Script))
				{
					pars[i] = script;
				}
				else if (parameters[i].Type == typeof(ScriptExecutionContext))
				{
					pars[i] = context;
				}
				else if (parameters[i].Type == typeof(CallbackArguments))
				{
					pars[i] = args.SkipMethodCall();
				}
				// else, ignore out params
				else if (parameters[i].IsOut)
				{
					pars[i] = null;
				}
				else if (i == parameters.Length - 1 && VarArgsArrayType != null)
				{
					List<DynValue> extraArgs = new List<DynValue>();

					while (true)
					{
						DynValue arg = args.RawGet(j, false);
						j += 1;
						if (arg != null)
							extraArgs.Add(arg);
						else
							break;
					}

					// here we have to worry we already have an array.. damn. We only support this for userdata.
					// remains to be analyzed what's the correct behavior here. For example, let's take a params object[]..
					// given a single table parameter, should it use it as an array or as an object itself ?
					if (extraArgs.Count == 1)
					{
						DynValue arg = extraArgs[0];

						if (arg.Type == DataType.UserData && arg.UserData.Object != null)
						{
							if (VarArgsArrayType.IsAssignableFrom(arg.UserData.Object.GetType()))
							{
								pars[i] = arg.UserData.Object;
								continue;
							}
						}
					}

					// ok let's create an array, and loop
					Array vararg = Array.CreateInstance(VarArgsElementType, extraArgs.Count);

					for (int ii = 0; ii < extraArgs.Count; ii++)
					{
						vararg.SetValue(ScriptToClrConversions.DynValueToObjectOfType(extraArgs[ii], VarArgsElementType,
						null, false), ii);
					}

					pars[i] = vararg;

				}
				// else, convert it
				else
				{
					var arg = args.RawGet(j, false) ?? DynValue.Void;
					pars[i] = ScriptToClrConversions.DynValueToObjectOfType(arg, parameters[i].Type,
						parameters[i].DefaultValue, parameters[i].HasDefaultValue);
					j += 1;
				}
			}

			return pars;
		}
        /// <summary>
        /// The internal callback which actually executes the method
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="obj">The object.</param>
        /// <param name="context">The context.</param>
        /// <param name="args">The arguments.</param>
        /// <returns></returns>
        internal DynValue Callback(Script script, object obj, ScriptExecutionContext context, CallbackArguments args)
        {
            if (ValueTypeDefaultCtor != null)
            {
                object vto = Activator.CreateInstance(ValueTypeDefaultCtor);
                return(ClrToScriptConversions.ObjectToDynValue(script, vto));
            }

            if (AccessMode == InteropAccessMode.LazyOptimized &&
                m_OptimizedFunc == null && m_OptimizedAction == null)
            {
                Optimize();
            }

            object[] pars = new object[Parameters.Length];

            int j = args.IsMethodCall ? 1 : 0;

            List <int> outParams = null;

            for (int i = 0; i < pars.Length; i++)
            {
                // keep track of out and ref params
                if (Parameters[i].ParameterType.IsByRef)
                {
                    if (outParams == null)
                    {
                        outParams = new List <int>();
                    }
                    outParams.Add(i);
                }

                // if an ext method, we have an obj -> fill the first param
                if (ExtensionMethodType != null && obj != null && i == 0)
                {
                    pars[i] = obj;
                    continue;
                }
                // else, fill types with a supported type
                else if (Parameters[i].ParameterType == typeof(Script))
                {
                    pars[i] = script;
                }
                else if (Parameters[i].ParameterType == typeof(ScriptExecutionContext))
                {
                    pars[i] = context;
                }
                else if (Parameters[i].ParameterType == typeof(CallbackArguments))
                {
                    pars[i] = args.SkipMethodCall();
                }
                // else, ignore out params
                else if (Parameters[i].IsOut)
                {
                    pars[i] = null;
                }
                else if (i == Parameters.Length - 1 && VarArgsArrayType != null)
                {
                    List <DynValue> extraArgs = new List <DynValue>();

                    while (true)
                    {
                        DynValue arg = args.RawGet(j, false);
                        j += 1;
                        if (arg != null)
                        {
                            extraArgs.Add(arg);
                        }
                        else
                        {
                            break;
                        }
                    }

                    // here we have to worry we already have an array.. damn. We only support this for userdata.
                    // remains to be analyzed what's the correct behavior here. For example, let's take a params object[]..
                    // given a single table parameter, should it use it as an array or as an object itself ?
                    if (extraArgs.Count == 1)
                    {
                        DynValue arg = extraArgs[0];

                        if (arg.Type == DataType.UserData && arg.UserData.Object != null)
                        {
                            if (VarArgsArrayType.IsAssignableFrom(arg.UserData.Object.GetType()))
                            {
                                pars[i] = arg.UserData.Object;
                                continue;
                            }
                        }
                    }

                    // ok let's create an array, and loop
                    Array vararg = CreateVarArgArray(extraArgs.Count);

                    for (int ii = 0; ii < extraArgs.Count; ii++)
                    {
                        vararg.SetValue(ScriptToClrConversions.DynValueToObjectOfType(extraArgs[ii], VarArgsElementType,
                                                                                      null, false), ii);
                    }

                    pars[i] = vararg;
                }
                // else, convert it
                else
                {
                    var arg = args.RawGet(j, false) ?? DynValue.Void;
                    pars[i] = ScriptToClrConversions.DynValueToObjectOfType(arg, Parameters[i].ParameterType,
                                                                            Parameters[i].DefaultValue, !Parameters[i].DefaultValue.IsDbNull());
                    j += 1;
                }
            }


            object retv = null;

            if (m_OptimizedFunc != null)
            {
                retv = m_OptimizedFunc(obj, pars);
            }
            else if (m_OptimizedAction != null)
            {
                m_OptimizedAction(obj, pars);
                retv = DynValue.Void;
            }
            else if (m_IsAction)
            {
                MethodInfo.Invoke(obj, pars);
                retv = DynValue.Void;
            }
            else
            {
                if (IsConstructor)
                {
                    retv = ((ConstructorInfo)MethodInfo).Invoke(pars);
                }
                else
                {
                    retv = MethodInfo.Invoke(obj, pars);
                }
            }

            if (outParams == null)
            {
                return(ClrToScriptConversions.ObjectToDynValue(script, retv));
            }
            else
            {
                DynValue[] rets = new DynValue[outParams.Count + 1];

                rets[0] = ClrToScriptConversions.ObjectToDynValue(script, retv);

                for (int i = 0; i < outParams.Count; i++)
                {
                    rets[i + 1] = ClrToScriptConversions.ObjectToDynValue(script, pars[outParams[i]]);
                }

                return(DynValue.NewTuple(rets));
            }
        }