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)))); }
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 NET20 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)); #else if (typeof(IDictionary).GetTypeInfo().IsAssignableFrom(obj.GetType().GetTypeInfo())) { IDictionary dictionary = (IDictionary)obj; if (dictionary.Contains(name)) { dictionary.Remove(name); return(_convert.ToJsValue(true)); } } return(_convert.ToJsValue(false)); #endif } return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot)))); }
internal JsValue KeepAliveValueOf(int slot) { var obj = KeepAliveGet(slot); if (obj != null) { Type type = obj.GetType(); MethodInfo mi; #if NET20 mi = type.GetMethod("valueOf") ?? type.GetMethod("ValueOf"); #else mi = type.GetRuntimeMethod("ValueOf", new Type[0]); #endif if (mi != null) { object result = mi.Invoke(obj, new object[0]); return(_convert.AnyToJsValue(result)); } return(_convert.AnyToJsValue(obj)); } return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot)))); }
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)))); }
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.OrdinalIgnoreCase)) { 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)))); }
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 NET20 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); } } #else if (typeof(IDictionary).GetTypeInfo().IsAssignableFrom(obj.GetType().GetTypeInfo())) { 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()) { var met = mb as MethodBase; if (met != null && !met.IsSpecialName) { mbNameList.Add(mb.Name); } } #endif return(_convert.ToJsValue(mbNameList.ToArray())); } return(JsValue.Error(KeepAliveAdd(new IndexOutOfRangeException("invalid keepalive slot: " + slot)))); }