Exemplo n.º 1
0
        internal JsValue KeepAliveDeleteProperty(int slot, string name)
        {
#if DEBUG_TRACE_API
            Console.WriteLine("deleting prop " + name);
#endif
            // TODO: This is pretty slow: use a cache of generated code to make it faster.
            var obj = KeepAliveGet(slot);
            if (obj != null)
            {
#if DEBUG_TRACE_API
                Console.WriteLine("deleting prop " + name + " type " + type);
#endif
                if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
                {
                    IDictionary dictionary = (IDictionary)obj;
                    if (dictionary.Contains(name))
                    {
                        dictionary.Remove(name);
                        return(_convert.ToJsValue(true));
                    }
                }
                return(_convert.ToJsValue(false));
            }
            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 2
0
        internal JsValue KeepAliveEnumerateProperties(int slot)
        {
#if DEBUG_TRACE_API
            Console.WriteLine("deleting prop " + name);
#endif
            // TODO: This is pretty slow: use a cache of generated code to make it faster.
            var obj = KeepAliveGet(slot);
            if (obj != null)
            {
#if DEBUG_TRACE_API
                Console.WriteLine("deleting prop " + name + " type " + type);
#endif

                if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
                {
                    IDictionary dictionary = (IDictionary)obj;
                    string[]    keys       = dictionary.Keys.Cast <string>().ToArray();
                    return(_convert.ToJsValue(keys));
                }

                string[] values = obj.GetType().GetMembers(
                    BindingFlags.Public |
                    BindingFlags.Instance).Where(m => {
                    var method = m as MethodBase;
                    return(method == null || !method.IsSpecialName);
                }).Select(z => z.Name).ToArray();
                return(_convert.ToJsValue(values));
            }
            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 3
0
        JsValue KeepAliveInvoke(int slot, JsValue args)
        {
            // TODO: This is pretty slow: use a cache of generated code to make it faster.

            Console.WriteLine(args);

            var obj = KeepAliveGet(slot) as WeakDelegate;

            if (obj != null)
            {
                Type     type = obj.Target.GetType();
                object[] a    = (object[])_convert.FromJsValue(args);

                try {
                    const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public
                                               | BindingFlags.InvokeMethod | BindingFlags.FlattenHierarchy;
                    return(_convert.ToJsValue(type.InvokeMember(obj.MethodName, flags, null, obj.Target, a)));
                }
                catch (Exception e) {
                    return(JsValue.Error(KeepAliveAdd(e)));
                }
            }

            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 4
0
        JsValue KeepAliveSetPropertyValue(int slot, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue value)
        {
            // TODO: This is pretty slow: use a cache of generated code to make it faster.

            var obj = KeepAliveGet(slot);

            if (obj != null)
            {
                Type type = obj.GetType();

                // We can only set properties; everything else is an error.
                try {
                    PropertyInfo pi = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty);
                    if (pi != null)
                    {
                        pi.SetValue(obj, _convert.FromJsValue(value), null);
                        return(JsValue.Null);
                    }

                    return(JsValue.Error(KeepAliveAdd(
                                             new InvalidOperationException(String.Format("property not found on {0}: {1} ", type, name)))));
                }
                catch (Exception e) {
                    return(JsValue.Error(KeepAliveAdd(e)));
                }
            }

            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 5
0
        JsValue KeepAliveGetPropertyValue(int slot, [MarshalAs(UnmanagedType.LPWStr)] string name)
        {
            // TODO: This is pretty slow: use a cache of generated code to make it faster.

            var obj = KeepAliveGet(slot);

            if (obj != null)
            {
                Type type = obj.GetType();

                try {
                    // First of all try with a public property (the most common case).

                    PropertyInfo pi = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
                    if (pi != null)
                    {
                        return(_convert.ToJsValue(pi.GetValue(obj, null)));
                    }

                    // Then with an instance method: the problem is that we don't have a list of
                    // parameter types so we just check if any method with the given name exists
                    // and then keep alive a "weak delegate", i.e., just a name and the target.
                    // The real method will be resolved during the invokation itself.

                    const BindingFlags mFlags = BindingFlags.Instance | BindingFlags.Public
                                                | BindingFlags.InvokeMethod | BindingFlags.FlattenHierarchy;
                    // TODO: This is probably slooow.
                    if (type.GetMethods(mFlags).Any(x => x.Name == name))
                    {
                        return(_convert.ToJsValue(new WeakDelegate(obj, name)));
                    }

                    // Else an error.

                    return(JsValue.Error(KeepAliveAdd(
                                             new InvalidOperationException(String.Format("property not found on {0}: {1} ", type, name)))));
                }
                catch (TargetInvocationException e) {
                    // Client code probably isn't interested in the exception part related to
                    // reflection, so we unwrap it and pass to V8 only the real exception thrown.
                    if (e.InnerException != null)
                    {
                        return(JsValue.Error(KeepAliveAdd(e.InnerException)));
                    }
                    throw;
                }
                catch (Exception e) {
                    return(JsValue.Error(KeepAliveAdd(e)));
                }
            }

            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 6
0
        internal JsValue KeepAliveEnumerateProperties(int slot)
        {
#if DEBUG_TRACE_API
            Console.WriteLine("deleting prop " + name);
#endif
            // TODO: This is pretty slow: use a cache of generated code to make it faster.
            var obj = KeepAliveGet(slot);
            if (obj != null)
            {
#if DEBUG_TRACE_API
                Console.WriteLine("deleting prop " + name + " type " + type);
#endif

                if (typeof(IDictionary).IsAssignableFrom(obj.GetType()))
                {
                    IDictionary dictionary = (IDictionary)obj;
                    //string[] keys = dictionary.Keys.Cast<string>().ToArray();

                    var keys01 = new System.Collections.Generic.List <string>();
                    foreach (var k in dictionary.Keys)
                    {
                        keys01.Add(k.ToString());
                    }

                    return(_convert.ToJsValue(keys01.ToArray()));
                }

                var mbNameList = new System.Collections.Generic.List <string>();
                foreach (var mb in obj.GetType().GetMembers(BindingFlags.Public |
                                                            BindingFlags.Instance))
                {
                    var met = mb as MethodBase;
                    if (met != null && !met.IsSpecialName)
                    {
                        mbNameList.Add(mb.Name);
                    }
                }
                //string[] values = obj.GetType().GetMembers(
                //    BindingFlags.Public |
                //    BindingFlags.Instance).Where(m =>
                //    {
                //        var method = m as MethodBase;
                //        return method == null || !method.IsSpecialName;
                //    }).Select(z => z.Name).ToArray();
                return(_convert.ToJsValue(mbNameList.ToArray()));
            }
            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 7
0
        internal JsValue KeepAliveSetPropertyValue(int slot, string name, JsValue value)
        {
#if DEBUG_TRACE_API
            Console.WriteLine("setting prop " + name);
#endif
            // TODO: This is pretty slow: use a cache of generated code to make it faster.

            var obj = KeepAliveGet(slot);
            if (obj != null)
            {
                Type type;
                if (obj is Type)
                {
                    type = (Type)obj;
                }
                else
                {
                    type = obj.GetType();
                }
#if DEBUG_TRACE_API
                Console.WriteLine("setting prop " + name + " type " + type);
#endif
                try
                {
                    if (!string.IsNullOrEmpty(name))
                    {
                        var upperCamelCase = Char.ToUpper(name[0]) + name.Substring(1);
                        if (TrySetMemberValue(type, obj, upperCamelCase, value))
                        {
                            return(JsValue.Null);
                        }
                        if (TrySetMemberValue(type, obj, name, value))
                        {
                            return(JsValue.Null);
                        }
                    }

                    return(JsValue.Error(KeepAliveAdd(
                                             new InvalidOperationException(String.Format("property not found on {0}: {1} ", type, name)))));
                }
                catch (Exception e)
                {
                    return(JsValue.Error(KeepAliveAdd(e)));
                }
            }

            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 8
0
        internal JsValue KeepAliveValueOf(int slot)
        {
            var obj = KeepAliveGet(slot);

            if (obj != null)
            {
                Type       type = obj.GetType();
                MethodInfo mi   = type.GetMethod("valueOf") ?? type.GetMethod("ValueOf");
                if (mi != null)
                {
                    object result = mi.Invoke(obj, new object[0]);
                    return(_convert.ToJsValue(result));
                }
                return(_convert.ToJsValue(obj));
            }
            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 9
0
        internal JsValue KeepAliveInvoke(int slot, JsValue args)
        {
            // TODO: This is pretty slow: use a cache of generated code to make it faster.
#if DEBUG_TRACE_API
            Console.WriteLine("invoking");
#endif
            //   Console.WriteLine(args);

            var obj = KeepAliveGet(slot);
            if (obj != null)
            {
                Type constructorType = obj as Type;
                if (constructorType != null)
                {
#if DEBUG_TRACE_API
                    Console.WriteLine("constructing " + constructorType.Name);
#endif
                    object[] constructorArgs = (object[])_convert.FromJsValue(args);
                    return(_convert.ToJsValue(Activator.CreateInstance(constructorType, constructorArgs)));
                }

                WeakDelegate func = obj as WeakDelegate;
                if (func == null)
                {
                    throw new Exception("not a function.");
                }

                Type type = func.Target != null?func.Target.GetType() : func.Type;

#if DEBUG_TRACE_API
                Console.WriteLine("invoking " + obj.Target + " method " + obj.MethodName);
#endif
                object[] a = (object[])_convert.FromJsValue(args);

                BindingFlags flags = BindingFlags.Public
                                     | BindingFlags.FlattenHierarchy;

                if (func.Target != null)
                {
                    flags |= BindingFlags.Instance;
                }
                else
                {
                    flags |= BindingFlags.Static;
                }

                if (obj is BoundWeakDelegate)
                {
                    flags |= BindingFlags.NonPublic;
                }

                // need to convert methods from JsFunction's into delegates?
                if (a.Any(z => z != null && z.GetType() == typeof(JsFunction)))
                {
                    CheckAndResolveJsFunctions(type, func.MethodName, flags, a);
                }

                try {
                    object result = type.GetMethod(func.MethodName, flags).Invoke(func.Target, a);
                    return(_convert.ToJsValue(result));
                } catch (TargetInvocationException e) {
                    return(JsValue.Error(KeepAliveAdd(e.InnerException)));
                } catch (Exception e) {
                    return(JsValue.Error(KeepAliveAdd(e)));
                }
            }

            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 10
0
        internal JsValue KeepAliveGetPropertyValue(int slot, string name)
        {
#if DEBUG_TRACE_API
            Console.WriteLine("getting prop " + name);
#endif
            // we need to fall back to the prototype verison we set up because v8 won't call an object as a function, it needs
            // to be from a proper FunctionTemplate.
            if (!string.IsNullOrEmpty(name) && name.Equals("valueOf", StringComparison.CurrentCultureIgnoreCase))
            {
                return(JsValue.Empty);
            }

            // TODO: This is pretty slow: use a cache of generated code to make it faster.
            var obj = KeepAliveGet(slot);
            if (obj != null)
            {
                Type type;
                if (obj is Type)
                {
                    type = (Type)obj;
                }
                else
                {
                    type = obj.GetType();
                }
#if DEBUG_TRACE_API
                Console.WriteLine("getting prop " + name + " type " + type);
#endif
                try {
                    if (!string.IsNullOrEmpty(name))
                    {
                        var     upperCamelCase = Char.ToUpper(name[0]) + name.Substring(1);
                        JsValue value;
                        if (TryGetMemberValue(type, obj, upperCamelCase, out value))
                        {
                            return(value);
                        }
                        if (TryGetMemberValue(type, obj, name, out value))
                        {
                            return(value);
                        }
                    }

                    // Else an error.
                    return(JsValue.Error(KeepAliveAdd(
                                             new InvalidOperationException(String.Format("property not found on {0}: {1} ", type, name)))));
                } catch (TargetInvocationException e) {
                    // Client code probably isn't interested in the exception part related to
                    // reflection, so we unwrap it and pass to V8 only the real exception thrown.
                    if (e.InnerException != null)
                    {
                        return(JsValue.Error(KeepAliveAdd(e.InnerException)));
                    }
                    throw;
                } catch (Exception e) {
                    return(JsValue.Error(KeepAliveAdd(e)));
                }
            }

            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }
Exemplo n.º 11
0
        internal JsValue KeepAliveInvoke(int slot, JsValue args)
        {
            // TODO: This is pretty slow: use a cache of generated code to make it faster.
#if DEBUG_TRACE_API
            Console.WriteLine("invoking");
#endif
            //   Console.WriteLine(args);

            var obj = KeepAliveGet(slot);
            if (obj != null)
            {
                Type constructorType = obj as Type;
                if (constructorType != null)
                {
#if DEBUG_TRACE_API
                    Console.WriteLine("constructing " + constructorType.Name);
#endif
                    object[] constructorArgs = (object[])_convert.FromJsValue(args);
                    return(_convert.AnyToJsValue(Activator.CreateInstance(constructorType, constructorArgs)));
                }

                WeakDelegate func = obj as WeakDelegate;
                if (func == null)
                {
                    throw new Exception("not a function.");
                }

                Type type = func.Target != null?func.Target.GetType() : func.Type;

#if DEBUG_TRACE_API
                Console.WriteLine("invoking " + obj.Target + " method " + obj.MethodName);
#endif
                object[] a = (object[])_convert.FromJsValue(args);


                // need to convert methods from JsFunction's into delegates?
                foreach (var a_elem in a)
                {
                    if (a.GetType() == typeof(JsFunction))
                    {
                        CheckAndResolveJsFunctions(type, func.MethodName, a);
                        break;
                    }
                }
                //if (a.Any(z => z != null && z.GetType() == typeof(JsFunction)))
                //{
                //    CheckAndResolveJsFunctions(type, func.MethodName, flags, a);
                //}

                try
                {
                    var    method = type.GetRuntimeMethod(func.MethodName, null);
                    object result = method.Invoke(func.Target, a);
                    //object result = type.InvokeMember(func.MethodName, flags, null, func.Target, a);
                    return(_convert.AnyToJsValue(result));
                }
                catch (TargetInvocationException e)
                {
                    return(JsValue.Error(KeepAliveAdd(e.InnerException)));
                }
                catch (Exception e)
                {
                    return(JsValue.Error(KeepAliveAdd(e)));
                }
            }

            return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot))));
        }