public Value RuntimeInvoke(MethodMirror method, object target, Value[] values)
        {
            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);
                Adapter.AsyncExecute(mc, Options.EvaluationTimeout);

                return(mc.ReturnValue);
            }
        }
Beispiel #2
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);
                }
            }
        }