public override string CallToString(EvaluationContext ctx, object obj)
        {
            SoftEvaluationContext cx = (SoftEvaluationContext)ctx;

            if (obj is StringMirror)
            {
                return(((StringMirror)obj).Value);
            }
            else if (obj is EnumMirror)
            {
                EnumMirror eob = (EnumMirror)obj;
                return(eob.StringValue);
            }
            else if (obj is PrimitiveValue)
            {
                return(((PrimitiveValue)obj).Value.ToString());
            }
            else if ((obj is StructMirror) && ((StructMirror)obj).Type.IsPrimitive)
            {
                // Boxed primitive
                StructMirror sm = (StructMirror)obj;
                if (sm.Fields.Length > 0 && (sm.Fields[0] is PrimitiveValue))
                {
                    return(((PrimitiveValue)sm.Fields[0]).Value.ToString());
                }
            }
            else if (obj == null)
            {
                return(string.Empty);
            }
            else if ((obj is ObjectMirror) && cx.Options.AllowTargetInvoke)
            {
                ObjectMirror ob     = (ObjectMirror)obj;
                MethodMirror method = OverloadResolve(cx, "ToString", ob.Type, new TypeMirror[0], true, false, false);
                if (method != null && method.DeclaringType.FullName != "System.Object")
                {
                    StringMirror res = cx.RuntimeInvoke(method, obj, new Value[0]) as StringMirror;
                    return(res != null ? res.Value : string.Empty);
                }
            }
            else if ((obj is StructMirror) && cx.Options.AllowTargetInvoke)
            {
                StructMirror ob     = (StructMirror)obj;
                MethodMirror method = OverloadResolve(cx, "ToString", ob.Type, new TypeMirror[0], true, false, false);
                if (method != null && method.DeclaringType.FullName != "System.ValueType")
                {
                    StringMirror res = cx.RuntimeInvoke(method, obj, new Value[0]) as StringMirror;
                    return(res != null ? res.Value : string.Empty);
                }
            }
            return(GetDisplayTypeName(GetValueTypeName(ctx, obj)));
        }
        public override object RuntimeInvoke(EvaluationContext gctx, object targetType, object target, string methodName, object[] argTypes, object[] argValues)
        {
            SoftEvaluationContext ctx = (SoftEvaluationContext)gctx;

            ctx.AssertTargetInvokeAllowed();

            TypeMirror type = target != null ? ((ObjectMirror)target).Type : (TypeMirror)targetType;

            TypeMirror[] types = new TypeMirror [argTypes.Length];
            for (int n = 0; n < argTypes.Length; n++)
            {
                types [n] = ToTypeMirror(ctx, argTypes [n]);
            }

            Value[] values = new Value[argValues.Length];
            for (int n = 0; n < argValues.Length; n++)
            {
                values[n] = (Value)argValues [n];
            }

            MethodMirror method = OverloadResolve(ctx, methodName, type, types, target != null, target == null, true);

            return(ctx.RuntimeInvoke(method, target ?? targetType, values));
        }