/// <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)); }
public DynValue GetValue(Script script, object obj) { this.CheckAccess(MemberDescriptorAccess.CanRead, obj); var result = this.GetValueImpl(script, obj); return(ClrToScriptConversions.ObjectToDynValue(script, result)); }
/// <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)); }
/// <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)); }
/// <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)); } }
/// <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)); }
/// <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)); }
/// <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); } }
/// <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); }
/// <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; }
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)); }
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))); }
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)); }
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); }
/// <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)); }
/// <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); }
/// <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)); } }