Ejemplo n.º 1
0
 internal static extern void ResultSetJsValue(IntPtr callingArgsPtr, JsValue jsvalue);
Ejemplo n.º 2
0
 internal static extern JsValue jscontext_invoke(HandleRef engine, IntPtr funcPtr, IntPtr thisPtr, JsValue args);
Ejemplo n.º 3
0
        public object FromJsValue(JsValue v)
        {
            switch (v.Type)
            {
                case JsValueType.Null:
                    return null;

                case JsValueType.Boolean:
                    return v.I32 != 0;

                case JsValueType.Integer:
                    return v.I32;

                case JsValueType.Number:
                    return v.Num;

                case JsValueType.String:
                    return Marshal.PtrToStringUni(v.Ptr);

                case JsValueType.Date:
                    // The formula (v.num * 10000) + 621355968000000000L was taken from a StackOverflow
                    // question and should be OK. Then why do we need to compensate by -26748000000000L
                    // (a value determined from the failing tests)?!
                    return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L);

                case JsValueType.Array: {
                    var r = new object[v.Length];
                    for (int i=0 ; i < v.Length ; i++) {
                        var vi =(JsValue)Marshal.PtrToStructure((v.Ptr + 16*i), typeof(JsValue));
                        r[i] = FromJsValue(vi);
                    }
                    return r;
                }

                case JsValueType.UnknownError:
                    if (v.Ptr != IntPtr.Zero)
                        return new JsException(Marshal.PtrToStringUni(v.Ptr));
                    return new JsInteropException("unknown error without reason");

                case JsValueType.Error:
                    return new JsException(Marshal.PtrToStringUni(v.Ptr));

                case JsValueType.Managed:
                    return _engine.KeepAliveGet(v.Index);

                case JsValueType.ManagedError:
                    string msg = null;
                    if (v.Ptr != IntPtr.Zero)
                        msg = Marshal.PtrToStringUni(v.Ptr);
                    return new JsException(msg, _engine.KeepAliveGet(v.Index) as Exception);

                case JsValueType.Wrapped:
                    return new JsObject(_engine, v.Ptr);

                case JsValueType.WrappedError:
                    return new JsException(new JsObject(_engine, v.Ptr));

                default:
                    throw new InvalidOperationException("unknown type code: " + v.Type);
            }
        }
Ejemplo n.º 4
0
 static extern JsValue jscontext_set_property_value(IntPtr engine, IntPtr ptr, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue value);
Ejemplo n.º 5
0
 private JsObject JsDictionaryObject(JsValue v)
 {
     JsObject obj = new JsObject(this._context, v.Ptr);
     int len = v.Length * 2;
     for (int i = 0; i < len; i += 2)
     {
         var key = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue));
         var value = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * (i + 1))), typeof(JsValue));
         obj[(string)FromJsValue(key)] = FromJsValue(value);
     }
     return obj;
 }
Ejemplo n.º 6
0
 static extern JsValue jsengine_set_property_value(HandleRef engine, IntPtr ptr, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue value);
Ejemplo n.º 7
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)));
        }
Ejemplo n.º 8
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)));
        }
Ejemplo n.º 9
0
        internal bool TryGetMemberValue(Type type, object obj, string name, out JsValue value)
        {
            object result;

            // dictionaries.
            if (typeof(IDictionary).IsAssignableFrom(type)) {
                IDictionary dictionary = (IDictionary)obj;
                if (dictionary.Contains(name)) {
                    result = dictionary[name];
                    value = _convert.ToJsValue(result);
                } else {
                    value = JsValue.Null;
                }
                return true;
            }

            BindingFlags flags;
            if (type == obj) {
                flags = BindingFlags.Public | BindingFlags.Static;
            } else {
                flags = BindingFlags.Public | BindingFlags.Instance;
            }

            // First of all try with a public property (the most common case).
            PropertyInfo pi = type.GetProperty(name, flags);
            if (pi != null) {
                result = pi.GetValue(obj, null);
                value = _convert.ToJsValue(result);
                return true;
            }

            // try field.
            FieldInfo fi = type.GetField(name, flags);
            if (fi != null) {
                result = fi.GetValue(obj);
                value = _convert.ToJsValue(result);
                return true;
            }

            // 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.
            BindingFlags mFlags = flags | BindingFlags.FlattenHierarchy;

            // TODO: This is probably slooow.
            if (type.GetMethods(mFlags).Any(x => x.Name == name)) {
                if (type == obj) {
                    result = new WeakDelegate(type, name);
                } else {
                    result = new WeakDelegate(obj, name);
                }
                value = _convert.ToJsValue(result);
                return true;
            }

            value = JsValue.Null;
            return false;
        }
Ejemplo n.º 10
0
 private JsValue KeepAliveSetPropertyValue(int contextId, int slot, string name, JsValue value)
 {
     #if DEBUG_TRACE_API
     Console.WriteLine("set prop " + contextId + " " + slot);
     #endif
     JsContext context;
     if (!_aliveContexts.TryGetValue(contextId, out context)) {
         throw new Exception("fail");
     }
     return context.KeepAliveSetPropertyValue(slot, name, value);
 }
Ejemplo 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.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)));
        }
Ejemplo n.º 12
0
 private JsValue KeepAliveInvoke(int contextId, int slot, JsValue args)
 {
     JsContext context;
     if (!_aliveContexts.TryGetValue(contextId, out context)) {
         throw new Exception("fail");
     }
     return context.KeepAliveInvoke(slot, args);
 }
Ejemplo n.º 13
0
        public object FromJsValue(JsValue v)
        {
#if DEBUG_TRACE_API
            Console.WriteLine("Converting Js value to .net");
#endif
            switch (v.Type)
            {
            case JsValueType.Empty:
            case JsValueType.Null:
                return(null);

            case JsValueType.Boolean:
                return(v.I32 != 0);

            case JsValueType.Integer:
                return(v.I32);

            case JsValueType.Index:
                return((UInt32)v.I64);

            case JsValueType.Number:
                return(v.Num);

            case JsValueType.String:
                return(Marshal.PtrToStringUni(v.Ptr));

            case JsValueType.Date:
                /*
                 * // The formula (v.num * 10000) + 621355968000000000L was taken from a StackOverflow
                 * // question and should be OK. Then why do we need to compensate by -26748000000000L
                 * // (a value determined from the failing tests)?!
                 * return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L);
                 */

                //var msFromJsTime = v.I64 % 1000;
                return(EPOCH_LocalTime.AddMilliseconds(v.I64));   // + new TimeSpan(7, 0, 0);

            //return EPOCH_LocalTime.AddMilliseconds(v.I64);// + new TimeSpan(7, 0, 0);
            //return EPOCH.AddMilliseconds(v.I64);

            //return EPOCH.AddMilliseconds(v.Num);
            //return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L);
            case JsValueType.Array:
            {
                int len = v.Length;
                var r   = new object[len];
                for (int i = 0; i < len; i++)
                {
                    var vi = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue));
                    r[i] = FromJsValue(vi);
                }
                return(r);
            }

            case JsValueType.UnknownError:
                if (v.Ptr != IntPtr.Zero)
                {
                    return(new JsException(Marshal.PtrToStringUni(v.Ptr)));
                }
                return(new JsInteropException("unknown error without reason"));

            case JsValueType.StringError:
                return(new JsException(Marshal.PtrToStringUni(v.Ptr)));

            case JsValueType.Managed:
                return(_context.KeepAliveGet(v.Index));

            case JsValueType.JsTypeWrap:
                //auto unwrap
                return(this._context.GetObjectProxy(v.Index).WrapObject);

            case JsValueType.ManagedError:
                Exception inner = _context.KeepAliveGet(v.Index) as Exception;
                string    msg   = null;
                if (v.Ptr != IntPtr.Zero)
                {
                    msg = Marshal.PtrToStringUni(v.Ptr);
                }
                else
                {
                    if (inner != null)
                    {
                        msg = inner.Message;
                    }
                }
                return(new JsException(msg, inner));

#if NET40
            case JsValueType.Wrapped:
                return(new JsObject(_context, v.Ptr));
#else
            case JsValueType.Dictionary:
                return(JsDictionaryObject(v));
#endif
            case JsValueType.Wrapped:
                return(new JsObject(_context, v.Ptr));

            case JsValueType.Error:
                return(JsException.Create(this, (JsError)Marshal.PtrToStructure(v.Ptr, typeof(JsError))));

            case JsValueType.Function:
                var fa = new JsValue[2];
                for (int i = 0; i < 2; i++)
                {
                    fa[i] = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue));
                }
                return(new JsFunction(_context, fa[0].Ptr, fa[1].Ptr));

            default:
                throw new InvalidOperationException("unknown type code: " + v.Type);
            }
        }
Ejemplo n.º 14
0
        public JsValue AnyToJsValue(object obj)
        {
            if (obj == null)
            {
                return new JsValue {
                           Type = JsValueType.Null
                }
            }
            ;

            if (obj is INativeRef)
            {
                //extension
                INativeRef prox = (INativeRef)obj;

                int keepAliveId = _context.KeepAliveAdd(obj);
                return(new JsValue {
                    Type = JsValueType.JsTypeWrap, Ptr = prox.UnmanagedPtr, Index = keepAliveId
                });
            }

            Type type = obj.GetType();

            // Check for nullable types (we will cast the value out of the box later).

            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                type = type.GetGenericArguments()[0];
            }

            if (type == typeof(Boolean))
            {
                return new JsValue {
                           Type = JsValueType.Boolean, I32 = (bool)obj ? 1 : 0
                }
            }
            ;

            if (type == typeof(String) || type == typeof(Char))
            {
                // We need to allocate some memory on the other side; will be free'd by unmanaged code.
                return(JsContext.jsvalue_alloc_string(obj.ToString()));
            }

            if (type == typeof(Byte))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)(Byte)obj
                }
            }
            ;
            if (type == typeof(Int16))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)(Int16)obj
                }
            }
            ;
            if (type == typeof(UInt16))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)(UInt16)obj
                }
            }
            ;
            if (type == typeof(Int32))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)obj
                }
            }
            ;
            if (type == typeof(UInt32))
            {
                return new JsValue {
                           Type = JsValueType.Integer, I32 = (int)(UInt32)obj
                }
            }
            ;

            if (type == typeof(Int64))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)(Int64)obj
                }
            }
            ;
            if (type == typeof(UInt64))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)(UInt64)obj
                }
            }
            ;
            if (type == typeof(Single))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)(Single)obj
                }
            }
            ;
            if (type == typeof(Double))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)obj
                }
            }
            ;
            if (type == typeof(Decimal))
            {
                return new JsValue {
                           Type = JsValueType.Number, Num = (double)(Decimal)obj
                }
            }
            ;

            if (type == typeof(DateTime))
            {
                return new JsValue
                       {
                           Type = JsValueType.Date,
                           Num  = Convert.ToInt64(((DateTime)obj).Subtract(EPOCH).TotalMilliseconds) /*(((DateTime)obj).Ticks - 621355968000000000.0 + 26748000000000.0)/10000.0*/
                       }
            }
            ;

            // Arrays of anything that can be cast to object[] are recursively convertef after
            // allocating an appropriate jsvalue on the unmanaged side.

            var array = obj as object[];

            if (array != null)
            {
                JsValue v = JsContext.jsvalue_alloc_array(array.Length);

                if (v.Length != array.Length)
                {
                    throw new JsInteropException("can't allocate memory on the unmanaged side");
                }
                for (int i = 0; i < array.Length; i++)
                {
                    Marshal.StructureToPtr(AnyToJsValue(array[i]), new IntPtr(v.Ptr.ToInt64() + (16 * i)), false);
                }
                return(v);
            }

            // Every object explicitly converted to a value becomes an entry of the
            // _keepalives list, to make sure the GC won't collect it while still in
            // use by the unmanaged Javascript engine. We don't try to track duplicates
            // because adding the same object more than one time acts more or less as
            // reference counting.
            //check

            var        jsTypeDefinition = _context.GetJsTypeDefinition2(type);
            INativeRef prox2            = _context.CreateWrapper(obj, jsTypeDefinition);

            //int keepAliveId2 = _context.KeepAliveAdd(prox2);
            return(new JsValue {
                Type = JsValueType.JsTypeWrap, Ptr = prox2.UnmanagedPtr, Index = prox2.ManagedIndex
            });
            //return new JsValue { Type = JsValueType.JsTypeWrap, Ptr = prox2.UnmanagedPtr, Index = keepAliveId2 };

            //return new JsValue { Type = JsValueType.Managed, Index = _context.KeepAliveAdd(obj) };
        }
    }
}
Ejemplo n.º 15
0
 internal static extern void jsvalue_dispose(JsValue value);
Ejemplo n.º 16
0
        internal bool TrySetMemberValue(Type type, object obj, string name, JsValue value)
        {
            // dictionaries.
            if (typeof(IDictionary).IsAssignableFrom(type)) {
                IDictionary dictionary = (IDictionary)obj;
                dictionary[name] = _convert.FromJsValue(value);
                return true;
            }

            BindingFlags flags;
            if (type == obj) {
                flags = BindingFlags.Public | BindingFlags.Static;
            } else {
                flags = BindingFlags.Public | BindingFlags.Instance;
            }

            PropertyInfo pi = type.GetProperty(name, flags);
            if (pi != null) {
                pi.SetValue(obj, _convert.FromJsValue(value), null);
                return true;
            }

            return false;
        }
Ejemplo n.º 17
0
 static extern JsValue jsengine_invoke_property(HandleRef engine, IntPtr ptr, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue args);
Ejemplo n.º 18
0
 static extern JsValue jscontext_set_variable(IntPtr engine, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue value);
Ejemplo n.º 19
0
 static extern JsValue jsengine_set_variable(HandleRef engine, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue value);
Ejemplo n.º 20
0
        public object FromJsValue(JsValue v)
        {
            #if DEBUG_TRACE_API
            Console.WriteLine("Converting Js value to .net");
            #endif
            switch (v.Type)
            {
                case JsValueType.Empty:
                case JsValueType.Null:
                    return null;

                case JsValueType.Boolean:
                    return v.I32 != 0;

                case JsValueType.Integer:
                    return v.I32;

                case JsValueType.Index:
                    return (UInt32)v.I64;

                case JsValueType.Number:
                    return v.Num;

                case JsValueType.String:
                    return Marshal.PtrToStringUni(v.Ptr);

                case JsValueType.Date:
                    /*
                    // The formula (v.num * 10000) + 621355968000000000L was taken from a StackOverflow
                    // question and should be OK. Then why do we need to compensate by -26748000000000L
                    // (a value determined from the failing tests)?!
                    return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L);
                     */

                    //var msFromJsTime = v.I64 % 1000;
                    return EPOCH_LocalTime.AddMilliseconds(v.I64);// + new TimeSpan(7, 0, 0);
                //return EPOCH_LocalTime.AddMilliseconds(v.I64);// + new TimeSpan(7, 0, 0);
                //return EPOCH.AddMilliseconds(v.I64);

                //return EPOCH.AddMilliseconds(v.Num);
                //return new DateTime((long)(v.Num * 10000) + 621355968000000000L - 26748000000000L);
                case JsValueType.Array:
                    {
                        int len = v.Length;
                        var r = new object[len];
                        for (int i = 0; i < len; i++)
                        {
                            var vi = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue));
                            r[i] = FromJsValue(vi);
                        }
                        return r;
                    }

                case JsValueType.UnknownError:
                    if (v.Ptr != IntPtr.Zero)
                        return new JsException(Marshal.PtrToStringUni(v.Ptr));
                    return new JsInteropException("unknown error without reason");

                case JsValueType.StringError:
                    return new JsException(Marshal.PtrToStringUni(v.Ptr));

                case JsValueType.Managed:
                    return _context.KeepAliveGet(v.Index);
                case JsValueType.JsTypeWrap:
                    //auto unwrap
                    return this._context.GetObjectProxy(v.Index).WrapObject;
                case JsValueType.ManagedError:
                    Exception inner = _context.KeepAliveGet(v.Index) as Exception;
                    string msg = null;
                    if (v.Ptr != IntPtr.Zero)
                    {
                        msg = Marshal.PtrToStringUni(v.Ptr);
                    }
                    else
                    {
                        if (inner != null)
                        {
                            msg = inner.Message;
                        }
                    }
                    return new JsException(msg, inner);
            #if NET40
                case JsValueType.Wrapped:
                    return new JsObject(_context, v.Ptr);
            #else
                case JsValueType.Dictionary:
                    return JsDictionaryObject(v);
            #endif
                case JsValueType.Wrapped:
                    return new JsObject(_context, v.Ptr);

                case JsValueType.Error:
                    return JsException.Create(this, (JsError)Marshal.PtrToStructure(v.Ptr, typeof(JsError)));

                case JsValueType.Function:
                    var fa = new JsValue[2];
                    for (int i = 0; i < 2; i++)
                    {
                        fa[i] = (JsValue)Marshal.PtrToStructure(new IntPtr(v.Ptr.ToInt64() + (16 * i)), typeof(JsValue));
                    }
                    return new JsFunction(_context, fa[0].Ptr, fa[1].Ptr);
                default:
                    throw new InvalidOperationException("unknown type code: " + v.Type);
            }
        }
Ejemplo n.º 21
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)));
        }
Ejemplo n.º 22
0
 static extern JsValue jscontext_invoke_property(IntPtr engine, IntPtr ptr, [MarshalAs(UnmanagedType.LPWStr)] string name, JsValue args);