public void SetValue <T>(Script script, T obj, DynValue value) { this.CheckAccess(MemberDescriptorAccess.CanWrite, obj); object v = ScriptToClrConversions.DynValueToTypedValue <T>(value, default(T), false); SetValueImpl(script, obj, v); }
public void SetValue(Script script, object obj, DynValue value) { this.CheckAccess(MemberDescriptorAccess.CanWrite, obj); var v = ScriptToClrConversions.DynValueToObjectOfType(value, this.MemberType, null, false); this.SetValueImpl(script, obj, v); }
/// <summary> /// Sets the value of the property /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object.</param> /// <param name="v">The value to set.</param> public void SetValue(Script script, object obj, DynValue v) { this.CheckAccess(MemberDescriptorAccess.CanWrite, obj); if (IsReadonly || IsConst) throw new ScriptRuntimeException("userdata field '{0}.{1}' cannot be written to.", this.FieldInfo.DeclaringType.Name, this.Name); object value = ScriptToClrConversions.DynValueToObjectOfType(v, this.FieldInfo.FieldType, null, false); try { if (value is double) value = NumericConversions.DoubleToType(FieldInfo.FieldType, (double)value); FieldInfo.SetValue(IsStatic ? null : obj, value); } catch (ArgumentException) { // non-optimized setters fall here throw ScriptRuntimeException.UserDataArgumentTypeMismatch(v.Type, FieldInfo.FieldType); } catch (InvalidCastException) { // optimized setters fall here throw ScriptRuntimeException.UserDataArgumentTypeMismatch(v.Type, FieldInfo.FieldType); } catch (FieldAccessException ex) { throw new ScriptRuntimeException(ex); } }
private static int CalcScoreForSingleArgument(ParameterDescriptor desc, Type parameterType, DynValue arg, bool isOptional) { int score = ScriptToClrConversions.DynValueToObjectOfTypeWeight(arg, parameterType, isOptional); if (parameterType.IsByRef || desc.IsOut || desc.IsRef) { score = Math.Max(0, score + ScriptToClrConversions.WEIGHT_BYREF_BONUSMALUS); } return(score); }
private static object ArrayIndexerSet(object arrayObj, ScriptExecutionContext ctx, CallbackArguments args) { var array = (Array)arrayObj; var indices = BuildArrayIndices(args, args.Count - 1); var value = args[args.Count - 1]; var elemType = array.GetType().GetElementType(); var objValue = ScriptToClrConversions.DynValueToObjectOfType(value, elemType, null, false); array.SetValue(objValue, indices); return(DynValue.Void); }
private static object ArrayIndexerSet(object arrayObj, ScriptExecutionContext ctx, CallbackArguments args) { Array array = (Array)arrayObj; int[] indices = BuildArrayIndices(args, args.Count - 1); DynValue value = args[args.Count - 1]; Type elemType = array.GetType().GetElementType(); object objValue = ScriptToClrConversions.DynValueToTypedValue <object>(value, null, false); array.SetValue(objValue, indices); return(DynValue.Void); }
/// <summary> /// Sets the value of the property /// </summary> /// <param name="script">The script.</param> /// <param name="obj">The object.</param> /// <param name="v">The value to set.</param> public void SetValue(Script script, object obj, DynValue v) { this.CheckAccess(MemberDescriptorAccess.CanWrite, obj); if (m_Setter == null) { throw new ScriptRuntimeException("userdata property '{0}.{1}' cannot be written to.", this.PropertyInfo.DeclaringType.Name, this.Name); } var value = ScriptToClrConversions.DynValueToObjectOfType(v, this.PropertyInfo.PropertyType, null, false); try { if (value is double d) { value = NumericConversions.DoubleToType(this.PropertyInfo.PropertyType, d); } if (this.AccessMode == InteropAccessMode.LazyOptimized && m_OptimizedSetter == null) { this.OptimizeSetter(); } if (m_OptimizedSetter != null) { m_OptimizedSetter(obj, value); } else { m_Setter.Invoke(this.IsStatic ? null : obj, new[] { value }); // convoluted workaround for --full-aot Mono execution } } catch (ArgumentException) { // non-optimized setters fall here throw ScriptRuntimeException.UserDataArgumentTypeMismatch(v.Type, this.PropertyInfo.PropertyType); } catch (InvalidCastException) { // optimized setters fall here throw ScriptRuntimeException.UserDataArgumentTypeMismatch(v.Type, this.PropertyInfo.PropertyType); } }
/// <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> /// Converts this MoonSharp DynValue to a CLR object. /// </summary> public T ToObject <T>() { return(ScriptToClrConversions.DynValueToTypedValue(this, default(T), true)); }
/// <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)); } }
/// <summary> /// Converts this MoonSharp DynValue to a CLR object, marked as dynamic /// </summary> public dynamic ToDynamic() { return(ScriptToClrConversions.DynValueToObject(this)); }
/// <summary> /// Converts this MoonSharp DynValue to a CLR object of the specified type. /// </summary> public object ToObject(Type desiredType) { //Contract.Requires(desiredType != null); return(ScriptToClrConversions.DynValueToObjectOfType(this, desiredType, null, false)); }
/// <summary> /// Converts this MoonSharp DynValue to a CLR object. /// </summary> public object ToObject() { return(ScriptToClrConversions.DynValueToObject(this)); }