コード例 #1
0
        /// <summary>
        /// Gets the value of the property
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="obj">The object.</param>
        /// <returns></returns>
        public override DynValue GetValue <TFieldContainer>(Script script, TFieldContainer objWithField)
        {
            this.CheckAccess(MemberDescriptorAccess.CanRead, objWithField);

            if (m_OptimizedGetter != null)
            {
                TObj tObj = ValueConverter <TFieldContainer, TObj> .Instance.Convert(objWithField);

                return(m_OptimizedGetter(script, tObj));
            }
            // optimization+workaround of Unity bug..
            if (IsConst)
            {
                return(ClrToScriptConversions.ObjectToDynValue(script, m_ConstValue));
            }

            if (AccessMode == InteropAccessMode.LazyOptimized && m_OptimizedGetter == null)
            {
                OptimizeGetter(FieldInfo);
                if (m_OptimizedGetter != null)
                {
                    TObj tObj = ValueConverter <TFieldContainer, TObj> .Instance.Convert(objWithField);

                    return(m_OptimizedGetter(script, tObj));
                }
            }

            object result = FieldInfo.GetValue(objWithField);

            return(ClrToScriptConversions.ObjectToDynValue(script, result));
        }
コード例 #2
0
        public DynValue GetValue(Script script, object obj)
        {
            this.CheckAccess(MemberDescriptorAccess.CanRead, obj);
            var result = this.GetValueImpl(script, obj);

            return(ClrToScriptConversions.ObjectToDynValue(script, result));
        }
コード例 #3
0
        /// <summary>
        /// Gets the value of the property
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="obj">The object.</param>
        /// <returns></returns>
        public DynValue GetValue(Script script, object obj)
        {
            this.CheckAccess(MemberDescriptorAccess.CanRead, obj);

            if (m_Getter == null)
            {
                throw new ScriptRuntimeException("userdata property '{0}.{1}' cannot be read from.", this.PropertyInfo.DeclaringType.Name, this.Name);
            }

            if (AccessMode == InteropAccessMode.LazyOptimized && m_OptimizedGetter == null)
            {
                OptimizeGetter();
            }

            object result = null;

            if (m_OptimizedGetter != null)
            {
                result = m_OptimizedGetter(obj);
            }
            else
            {
                result = m_Getter.Invoke(IsStatic ? null : obj, null);                 // convoluted workaround for --full-aot Mono execution
            }
            return(ClrToScriptConversions.ObjectToDynValue(script, result));
        }
コード例 #4
0
        /// <summary>
        /// Gets the value of the property
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="obj">The object.</param>
        /// <returns></returns>
        public DynValue GetValue(Script script, object obj)
        {
            this.CheckAccess(MemberDescriptorAccess.CanRead, obj);

            // optimization+workaround of Unity bug..
            if (IsConst)
            {
                return(ClrToScriptConversions.ObjectToDynValue(script, m_ConstValue));
            }

            if (AccessMode == InteropAccessMode.LazyOptimized && m_OptimizedGetter == null)
            {
                OptimizeGetter();
            }

            object result = null;

            if (m_OptimizedGetter != null)
            {
                result = m_OptimizedGetter(obj);
            }
            else
            {
                result = FieldInfo.GetValue(obj);
            }

            return(ClrToScriptConversions.ObjectToDynValue(script, result));
        }
コード例 #5
0
        /// <summary>
        /// Builds the return value of a call
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="outParams">The out parameters indices, or null. See <see cref="BuildArgumentList" />.</param>
        /// <param name="pars">The parameters passed to the function.</param>
        /// <param name="retv">The return value from the function. Use DynValue.Void if the function returned no value.</param>
        /// <returns>A DynValue to be returned to scripts</returns>
        protected static DynValue BuildReturnValue(Script script, List <int> outParams, object[] pars, object retv)
        {
            if (outParams == null)
            {
                return(ClrToScriptConversions.ObjectToDynValue(script, retv));
            }
            else
            {
                DynValue[] rets = new DynValue[outParams.Count + 1];

                if (retv is DynValue && ((DynValue)retv).IsVoid())
                {
                    rets[0] = DynValue.Nil;
                }
                else
                {
                    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));
            }
        }
コード例 #6
0
        /// <summary>
        /// Invokes the member from script.
        /// Implementors should raise exceptions if the value cannot be executed or if access to an
        /// instance member through a static userdata is attempted.
        /// </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>
        public DynValue Execute(Script script, object obj, ScriptExecutionContext context, CallbackArguments args)
        {
            this.CheckAccess(MemberDescriptorAccess.CanRead, obj);

            object vto = Activator.CreateInstance(ValueTypeDefaultCtor);

            return(ClrToScriptConversions.ObjectToDynValue(script, vto));
        }
コード例 #7
0
        /// <summary>
        /// Gets the value of this member as a
        /// <see cref="DynValue" /> to be exposed to scripts.
        /// Implementors should raise exceptions if the value cannot be read or if access to an
        /// instance member through a static userdata is attempted.
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="obj">The object owning this member, or null if static.</param>
        /// <returns>
        /// The value of this member as a <see cref="DynValue" />.
        /// </returns>
        public DynValue GetValue(Script script, object obj)
        {
            this.CheckAccess(MemberDescriptorAccess.CanRead, obj);

            object vto = Activator.CreateInstance(ValueTypeDefaultCtor);

            return(ClrToScriptConversions.ObjectToDynValue(script, vto));
        }
コード例 #8
0
        /// <summary>
        /// Gets a "meta" operation on this userdata. If a descriptor does not support this functionality,
        /// it should return "null" (not a nil).
        /// See <see cref="IUserDataDescriptor.MetaIndex" /> for further details.
        ///
        /// If a method exists marked with <see cref="MoonSharpUserDataMetamethodAttribute" /> for the specific
        /// metamethod requested, that method is returned.
        ///
        /// If the above fails, the following dispatching occur:
        ///
        /// __add, __sub, __mul, __div, __mod and __unm are dispatched to C# operator overloads (if they exist)
        /// __eq is dispatched to System.Object.Equals.
        /// __lt and __le are dispatched IComparable.Compare, if the type implements IComparable or IComparable{object}
        /// __len is dispatched to Length and Count properties, if those exist.
        /// __iterator is handled if the object implements IEnumerable or IEnumerator.
        /// __tonumber is dispatched to implicit or explicit conversion operators to standard numeric types.
        /// __tobool is dispatched to an implicit or explicit conversion operator to bool. If that fails, operator true is used.
        ///
        /// <param name="script">The script originating the request</param>
        /// <param name="obj">The object (null if a static request is done)</param>
        /// <param name="metaname">The name of the metamember.</param>
        /// </summary>
        /// <returns></returns>
        public virtual DynValue MetaIndex(Script script, object obj, string metaname)
        {
            IMemberDescriptor desc = m_MetaMembers.GetOrDefault(metaname);

            if (desc != null)
            {
                return(desc.GetValue(script, obj));
            }

            switch (metaname)
            {
            case "__add":
                return(DispatchMetaOnMethod(script, obj, "op_Addition"));

            case "__sub":
                return(DispatchMetaOnMethod(script, obj, "op_Subtraction"));

            case "__mul":
                return(DispatchMetaOnMethod(script, obj, "op_Multiply"));

            case "__div":
                return(DispatchMetaOnMethod(script, obj, "op_Division"));

            case "__mod":
                return(DispatchMetaOnMethod(script, obj, "op_Modulus"));

            case "__unm":
                return(DispatchMetaOnMethod(script, obj, "op_UnaryNegation"));

            case "__eq":
                return(MultiDispatchEqual(script, obj));

            case "__lt":
                return(MultiDispatchLessThan(script, obj));

            case "__le":
                return(MultiDispatchLessThanOrEqual(script, obj));

            case "__len":
                return(TryDispatchLength(script, obj));

            case "__tonumber":
                return(TryDispatchToNumber(script, obj));

            case "__tobool":
                return(TryDispatchToBool(script, obj));

            case "__iterator":
                return(ClrToScriptConversions.EnumerationToDynValue(script, obj));

            default:
                return(null);
            }
        }
コード例 #9
0
        /// <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>
        public override DynValue Execute(Script script, object obj, ScriptExecutionContext context,
                                         CallbackArguments args)
        {
            if (m_CallbackFunc != null)
            {
                var retv = m_CallbackFunc(obj, context, args);
                return(ClrToScriptConversions.ObjectToDynValue(script, retv));
            }

            return(DynValue.Void);
        }
コード例 #10
0
        /// <summary>
        /// Builds the return value of a call
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="outParams">The out parameters indices, or null. See <see cref="BuildArgumentList" />.</param>
        /// <param name="pars">The parameters passed to the function.</param>
        /// <param name="retv">The return value from the function. Use DynValue.Void if the function returned no value.</param>
        /// <returns>A DynValue to be returned to scripts</returns>
        protected static DynValue BuildReturnValue(Script script, List <int> outParams, object[] pars, object retv)
        {
            if (outParams == null)
            {
                return(ClrToScriptConversions.ObjectToDynValue(script, retv));
            }

            var rets = new DynValue[outParams.Count + 1];

            if (retv is DynValue value && value.IsVoid())
            {
                rets[0] = DynValue.Nil;
            }
コード例 #11
0
        public static DynValue SerializeObjectToDynValue(Script script, object o, DynValue valueForNulls = null, DynValue valueForEmptyEnumerable = null)
        {
            if (o == null)
            {
                return(valueForNulls ?? DynValue.Nil);
            }

            DynValue v = ClrToScriptConversions.TryObjectToTrivialDynValue(script, o);

            if (v != null)
            {
                return(v);
            }

            if (o is Enum)
            {
                return(DynValue.NewNumber(NumericConversions.TypeToDouble(Enum.GetUnderlyingType(o.GetType()), o)));
            }

            Table t = new Table(script);

            System.Collections.IEnumerable ienum = o as System.Collections.IEnumerable;

            if (ienum != null)
            {
                foreach (object obj in ienum)
                {
                    t.Append(SerializeObjectToDynValue(script, obj, valueForNulls, valueForEmptyEnumerable));
                }

                if (valueForEmptyEnumerable != null && t.Length == 0)
                {
                    return(valueForEmptyEnumerable);
                }
            }
            else
            {
                Type type = o.GetType();

                foreach (PropertyInfo pi in Framework.Do.GetProperties(type))
                {
                    var getter   = Framework.Do.GetGetMethod(pi);
                    var isStatic = getter.IsStatic;
                    var obj      = getter.Invoke(isStatic ? null : o, null);                // convoluted workaround for --full-aot Mono execution

                    t.Set(pi.Name, SerializeObjectToDynValue(script, obj, valueForNulls, valueForEmptyEnumerable));
                }
            }

            return(DynValue.NewTable(t));
        }
コード例 #12
0
        public static DynValue TaskResultToDynValue(Script script, Task task)
        {
            var voidTaskType = typeof(Task <>).MakeGenericType(Type.GetType("System.Threading.Tasks.VoidTaskResult"));

            if (voidTaskType.IsAssignableFrom(task.GetType()))
            {
                return(DynValue.Nil); //no return type
            }
            var property = task.GetType().GetProperty("Result", BindingFlags.Public | BindingFlags.Instance);

            if (property == null)
            {
                return(DynValue.Nil);
            }
            return(ClrToScriptConversions.ObjectToDynValue(script, property.GetValue(task)));
        }
コード例 #13
0
        public static DynValue SerializeObjectToDynValue(Script script, object o, DynValue valueForNulls = null)
        {
            if (o == null)
            {
                return(valueForNulls ?? DynValue.Nil);
            }

            var v = ClrToScriptConversions.TryObjectToTrivialDynValue(script, o);

            if (v != null)
            {
                return(v);
            }

            if (o is Enum)
            {
                return(DynValue.NewNumber(NumericConversions.TypeToDouble(Enum.GetUnderlyingType(o.GetType()), o)));
            }

            var t = new Table(script);

            if (o is IEnumerable ienum)
            {
                foreach (var obj in ienum)
                {
                    t.Append(SerializeObjectToDynValue(script, obj, valueForNulls));
                }
            }
            else
            {
                var type = o.GetType();

                foreach (var pi in Framework.Do.GetProperties(type))
                {
                    var  getter   = Framework.Do.GetGetMethod(pi);
                    bool isStatic = getter.IsStatic;
                    var  obj      = getter.Invoke(isStatic ? null : o,
                                                  null); // convoluted workaround for --full-aot Mono execution

                    t.Set(pi.Name, SerializeObjectToDynValue(script, obj, valueForNulls));
                }
            }

            return(DynValue.NewTable(t));
        }
コード例 #14
0
        private DynValue GetNext(DynValue prev)
        {
            if (prev.IsNil())
            {
                Reset();
            }

            while (m_Enumerator.MoveNext())
            {
                DynValue v = ClrToScriptConversions.ObjectToDynValue(m_Script, m_Enumerator.Current);

                if (!v.IsNil())
                {
                    return(v);
                }
            }

            return(DynValue.Nil);
        }
コード例 #15
0
ファイル: DynValue.cs プロジェクト: blakepell/AvalonMudClient
 /// <summary>
 /// Creates a new DynValue from a CLR object
 /// </summary>
 /// <param name="script">The script.</param>
 /// <param name="obj">The object.</param>
 public static DynValue FromObject(Script script, object obj)
 {
     return(ClrToScriptConversions.ObjectToDynValue(script, obj));
 }
コード例 #16
0
        /// <summary>
        /// Creates a new DynValue from a CLR genetic value
        /// </summary>
        /// <param name="script">The script.</param>
        /// <param name="obj">The object.</param>
        /// <returns></returns>
        public static DynValue FromObject <T>(Script script, T value, bool readOnly = false)
        {
            DynValue dynValue = ClrToScriptConversions.GenericToDynValue <T>(script, value);

            return(dynValue);
        }
コード例 #17
0
        /// <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));
            }
        }