Value RuntimeInvoke(MethodMirror method, object target, Value[] values, bool enableOutArgs, out Value[] outArgs)
        {
            outArgs = null;
            if (values != null)
            {
                // Some arguments may need to be boxed
                var mparams = method.GetParameters();
                if (mparams.Length != values.Length)
                {
                    throw new EvaluatorException("Invalid number of arguments when calling: " + method.Name);
                }

                for (int n = 0; n < mparams.Length; n++)
                {
                    var tm = mparams[n].ParameterType;
                    if (tm.IsValueType || tm.IsPrimitive)
                    {
                        continue;
                    }

                    var type          = Adapter.GetValueType(this, values[n]);
                    var argTypeMirror = type as TypeMirror;
                    var argType       = type as Type;

                    if (IsValueTypeOrPrimitive(argTypeMirror) || IsValueTypeOrPrimitive(argType))
                    {
                        // A value type being assigned to a parameter which is not a value type. The value has to be boxed.
                        try {
                            values[n] = Thread.Domain.CreateBoxedValue(values [n]);
                        } catch (NotSupportedException) {
                            // This runtime doesn't support creating boxed values
                            throw new EvaluatorException("This runtime does not support creating boxed values.");
                        }
                    }
                }
            }

            if (!method.IsStatic && method.DeclaringType.IsClass && !IsValueTypeOrPrimitive(method.DeclaringType))
            {
                object type             = Adapter.GetValueType(this, target);
                var    targetTypeMirror = type as TypeMirror;
                var    targetType       = type as Type;

                if ((target is StructMirror && ((StructMirror)target).Type != method.DeclaringType) ||
                    (IsValueTypeOrPrimitive(targetTypeMirror) || IsValueTypeOrPrimitive(targetType)))
                {
                    // A value type being assigned to a parameter which is not a value type. The value has to be boxed.
                    try {
                        target = Thread.Domain.CreateBoxedValue((Value)target);
                    } catch (NotSupportedException) {
                        // This runtime doesn't support creating boxed values
                        throw new EvaluatorException("This runtime does not support creating boxed values.");
                    }
                }
            }

            try {
                return(method.Evaluate(target is TypeMirror ? null : (Value)target, values));
            } catch (NotSupportedException) {
                AssertTargetInvokeAllowed();

                var mc = new MethodCall(this, method, target, values, enableOutArgs);
                //Since runtime is returning NOT_SUSPENDED error if two methods invokes are executed
                //at same time we have to lock invoking to prevent this...
                lock (method.VirtualMachine) {
                    Adapter.AsyncExecute(mc, Options.EvaluationTimeout);
                }
                if (enableOutArgs)
                {
                    outArgs = mc.OutArgs;
                }
                return(mc.ReturnValue);
            }
        }
        public Value RuntimeInvoke(MethodMirror method, object target, Value[] values)
        {
            if (values != null)
            {
                // Some arguments may need to be boxed
                ParameterInfoMirror[] mparams = method.GetParameters();
                if (mparams.Length != values.Length)
                {
                    throw new EvaluatorException("Invalid number of arguments when calling: " + method.Name);
                }

                for (int n = 0; n < mparams.Length; n++)
                {
                    TypeMirror tm = mparams [n].ParameterType;
                    if (tm.IsValueType || tm.IsPrimitive)
                    {
                        continue;
                    }
                    object     type          = Adapter.GetValueType(this, values [n]);
                    TypeMirror argTypeMirror = type as TypeMirror;
                    Type       argType       = type as Type;
                    if ((argTypeMirror != null && (argTypeMirror.IsValueType || argTypeMirror.IsPrimitive)) || (argType != null && (argType.IsValueType || argType.IsPrimitive)))
                    {
                        // A value type being assigned to a parameter which is not a value type. The value has to be boxed.
                        try
                        {
                            values [n] = Thread.Domain.CreateBoxedValue(values [n]);
                        }
                        catch (NotSupportedException)
                        {
                            // This runtime doesn't support creating boxed values
                            throw new EvaluatorException("This runtime does not support creating boxed values.");
                        }
                    }
                }
            }

            if (!method.IsStatic && method.DeclaringType.IsClass)
            {
                object     type             = Adapter.GetValueType(this, target);
                TypeMirror targetTypeMirror = type as TypeMirror;
                Type       targetType       = type as Type;

                if ((targetTypeMirror != null && (targetTypeMirror.IsValueType || targetTypeMirror.IsPrimitive)) || (targetType != null && (targetType.IsValueType || targetType.IsPrimitive)))
                {
                    // A value type being assigned to a parameter which is not a value type. The value has to be boxed.
                    try
                    {
                        target = Thread.Domain.CreateBoxedValue((Value)target);
                    }
                    catch (NotSupportedException)
                    {
                        // This runtime doesn't support creating boxed values
                        throw new EvaluatorException("This runtime does not support creating boxed values.");
                    }
                }
            }

            MethodCall mc = new MethodCall(this, method, target, values);

            Adapter.AsyncExecute(mc, Options.EvaluationTimeout);
            return(mc.ReturnValue);
        }
예제 #3
0
        Value RuntimeInvoke(MethodMirror method, object target, Value[] values, bool enableOutArgs, out Value[] outArgs)
        {
            outArgs = null;
            if (values != null)
            {
                // Some arguments may need to be boxed
                var mparams = method.GetParameters();
                if (mparams.Length != values.Length)
                {
                    throw new EvaluatorException("Invalid number of arguments when calling: " + method.Name);
                }

                for (int n = 0; n < mparams.Length; n++)
                {
                    var tm = mparams[n].ParameterType;
                    if (tm.IsValueType || tm.IsPrimitive)
                    {
                        continue;
                    }

                    var type          = Adapter.GetValueType(this, values[n]);
                    var argTypeMirror = type as TypeMirror;
                    var argType       = type as Type;

                    if (IsValueTypeOrPrimitive(argTypeMirror) || IsValueTypeOrPrimitive(argType))
                    {
                        // A value type being assigned to a parameter which is not a value type. The value has to be boxed.
                        try {
                            values[n] = Thread.Domain.CreateBoxedValue(values [n]);
                        } catch (NotSupportedException) {
                            // This runtime doesn't support creating boxed values
                            throw new EvaluatorException("This runtime does not support creating boxed values.");
                        }
                    }
                }
            }

            if (!method.IsStatic && method.DeclaringType.IsClass && !IsValueTypeOrPrimitive(method.DeclaringType))
            {
                object type             = Adapter.GetValueType(this, target);
                var    targetTypeMirror = type as TypeMirror;
                var    targetType       = type as Type;

                if ((target is StructMirror && ((StructMirror)target).Type != method.DeclaringType) ||
                    (IsValueTypeOrPrimitive(targetTypeMirror) || IsValueTypeOrPrimitive(targetType)))
                {
                    // A value type being assigned to a parameter which is not a value type. The value has to be boxed.
                    try {
                        target = Thread.Domain.CreateBoxedValue((Value)target);
                    } catch (NotSupportedException) {
                        // This runtime doesn't support creating boxed values
                        throw new EvaluatorException("This runtime does not support creating boxed values.");
                    }
                }
            }

            try {
                return(method.Evaluate(target is TypeMirror ? null : (Value)target, values));
            } catch (NotSupportedException) {
                AssertTargetInvokeAllowed();
                var threadState = Thread.ThreadState;
                if ((threadState & ThreadState.WaitSleepJoin) == ThreadState.WaitSleepJoin)
                {
                    DC.DebuggerLoggingService.LogMessage("Thread state before evaluation is {0}", threadState);
                    throw new EvaluatorException("Evaluation is not allowed when the thread is in 'Wait' state");
                }
                var invocableMirror = target as IInvocableMethodOwnerMirror;
                if (invocableMirror == null)
                {
                    throw new ArgumentException("Soft debugger method calls cannot be invoked on objects of type " + target.GetType().Name);
                }
                var mc = new SoftMethodCall(this, method, invocableMirror, values, enableOutArgs);
                //Since runtime is returning NOT_SUSPENDED error if two methods invokes are executed
                //at same time we have to lock invoking to prevent this...
                lock (method.VirtualMachine) {
                    var result = (SoftOperationResult)Adapter.InvokeSync(mc, Options.EvaluationTimeout).ThrowIfException(this);
                    if (enableOutArgs)
                    {
                        outArgs = result.OutArgs;
                    }
                    return(result.Result);
                }
            }
        }
        protected override IEnumerable <ValueReference> GetMembers(EvaluationContext ctx, object t, object co, BindingFlags bindingFlags)
        {
            Dictionary <string, PropertyInfoMirror> subProps = new Dictionary <string, PropertyInfoMirror> ();
            TypeMirror type     = t as TypeMirror;
            TypeMirror realType = null;

            if (co != null && (bindingFlags & BindingFlags.Instance) != 0)
            {
                realType = GetValueType(ctx, co) as TypeMirror;
            }

            // First of all, get a list of properties overriden in sub-types
            while (realType != null && realType != type)
            {
                foreach (PropertyInfoMirror prop in realType.GetProperties(bindingFlags | BindingFlags.DeclaredOnly))
                {
                    MethodMirror met = prop.GetGetMethod(true);
                    if (met == null || met.GetParameters().Length != 0 || met.IsAbstract || !met.IsVirtual || met.IsStatic)
                    {
                        continue;
                    }
                    if (met.IsPublic && ((bindingFlags & BindingFlags.Public) == 0))
                    {
                        continue;
                    }
                    if (!met.IsPublic && ((bindingFlags & BindingFlags.NonPublic) == 0))
                    {
                        continue;
                    }
                    subProps [prop.Name] = prop;
                }
                realType = realType.BaseType;
            }

            while (type != null)
            {
                foreach (FieldInfoMirror field in type.GetFields())
                {
                    if (field.IsStatic && ((bindingFlags & BindingFlags.Static) == 0))
                    {
                        continue;
                    }
                    if (!field.IsStatic && ((bindingFlags & BindingFlags.Instance) == 0))
                    {
                        continue;
                    }
                    if (field.IsPublic && ((bindingFlags & BindingFlags.Public) == 0))
                    {
                        continue;
                    }
                    if (!field.IsPublic && ((bindingFlags & BindingFlags.NonPublic) == 0))
                    {
                        continue;
                    }
                    yield return(new FieldValueReference(ctx, field, co, type));
                }
                foreach (PropertyInfoMirror prop in type.GetProperties(bindingFlags))
                {
                    MethodMirror met = prop.GetGetMethod(true);
                    if (met == null || met.GetParameters().Length != 0 || met.IsAbstract)
                    {
                        continue;
                    }
                    if (met.IsStatic && ((bindingFlags & BindingFlags.Static) == 0))
                    {
                        continue;
                    }
                    if (!met.IsStatic && ((bindingFlags & BindingFlags.Instance) == 0))
                    {
                        continue;
                    }
                    if (met.IsPublic && ((bindingFlags & BindingFlags.Public) == 0))
                    {
                        continue;
                    }
                    if (!met.IsPublic && ((bindingFlags & BindingFlags.NonPublic) == 0))
                    {
                        continue;
                    }

                    // If a property is overriden, return the override instead of the base property
                    PropertyInfoMirror overriden;
                    if (met.IsVirtual && subProps.TryGetValue(prop.Name, out overriden))
                    {
                        yield return(new PropertyValueReference(ctx, overriden, co, overriden.DeclaringType, null));
                    }
                    else
                    {
                        yield return(new PropertyValueReference(ctx, prop, co, type, null));
                    }
                }
                if ((bindingFlags & BindingFlags.DeclaredOnly) != 0)
                {
                    break;
                }
                type = type.BaseType;
            }
        }