public bool GetBoolean(IntPtr isolate, IntPtr holder, bool isByRef) { return(PuertsDLL.GetBooleanFromResult(holder)); }
public void SetByRefValue(bool val) { PuertsDLL.SetBooleanToOutValue(isolate, value, val); }
public void SetByRefValue(string val) { PuertsDLL.SetStringToOutValue(isolate, value, val); }
public double GetDouble(bool isByRef) { return(PuertsDLL.GetNumberFromValue(isolate, value, isByRef)); }
public void SetByRefValue(float val) { PuertsDLL.SetNumberToOutValue(isolate, value, val); }
public ushort GetUInt16(bool isByRef) { return((ushort)PuertsDLL.GetNumberFromValue(isolate, value, isByRef)); }
public ulong GetUInt64(bool isByRef) { return((ulong)PuertsDLL.GetBigIntFromValueChecked(isolate, value, isByRef)); }
public void SetByRefValue(DateTime val) { PuertsDLL.SetDateToOutValue(isolate, value, (val - new DateTime(1970, 1, 1)).TotalMilliseconds); }
public char GetChar(bool isByRef) { return((char)PuertsDLL.GetNumberFromValue(isolate, value, isByRef)); }
// #lizard forgives private int RegisterType(IntPtr isolate, Type type, bool includeNoPublic) { TypeRegisterInfo registerInfo = null; if (lazyStaticWrapLoaders.ContainsKey(type)) { registerInfo = lazyStaticWrapLoaders[type](); lazyStaticWrapLoaders.Remove(type); } BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; if (includeNoPublic) { flag = flag | BindingFlags.NonPublic; } MethodInfo[] methods = type.GetMethods(flag); Dictionary <MethodKey, List <MethodInfo> > methodGroup = new Dictionary <MethodKey, List <MethodInfo> >(); Dictionary <string, ProperyMethods> propertyGroup = new Dictionary <string, ProperyMethods>(); for (int i = 0; i < methods.Length; ++i) { MethodInfo method = methods[i]; MethodKey methodKey = new MethodKey { Name = method.Name, IsStatic = method.IsStatic }; if (registerInfo != null && registerInfo.Methods.ContainsKey(methodKey)) { continue; } if (!method.IsConstructor && method.IsGenericMethodDefinition && Utils.IsSupportedMethod(method)) { var genericArguments = method.GetGenericArguments(); var constraintedArgumentTypes = new Type[genericArguments.Length]; for (var j = 0; j < genericArguments.Length; j++) { constraintedArgumentTypes[j] = genericArguments[j].BaseType; } method = method.MakeGenericMethod(constraintedArgumentTypes); } if (method.IsConstructor || method.IsGenericMethodDefinition) { continue; } if (method.IsSpecialName && method.Name.StartsWith("get_") && method.GetParameters().Length != 1) // getter of property { string propName = method.Name.Substring(4); if (registerInfo != null && registerInfo.Properties.ContainsKey(propName)) { continue; } ProperyMethods properyMethods; if (!propertyGroup.TryGetValue(propName, out properyMethods)) { properyMethods = new ProperyMethods(); propertyGroup.Add(propName, properyMethods); } properyMethods.Getter = method; continue; } else if (method.IsSpecialName && method.Name.StartsWith("set_") && method.GetParameters().Length != 2) // setter of property { string propName = method.Name.Substring(4); if (registerInfo != null && registerInfo.Properties.ContainsKey(propName)) { continue; } ProperyMethods properyMethods; if (!propertyGroup.TryGetValue(propName, out properyMethods)) { properyMethods = new ProperyMethods(); propertyGroup.Add(propName, properyMethods); } properyMethods.Setter = method; continue; } List <MethodInfo> overloads; if (!methodGroup.TryGetValue(methodKey, out overloads)) { overloads = new List <MethodInfo>(); methodGroup.Add(methodKey, overloads); } overloads.Add(method); } ConstructorCallback constructorCallback = null; if (typeof(Delegate).IsAssignableFrom(type)) { DelegateConstructWrap delegateConstructWrap = new DelegateConstructWrap(type, jsEnv.GeneralGetterManager); constructorCallback = delegateConstructWrap.Construct; } else { bool hasNoParametersCtor = false; var constructorWraps = type.GetConstructors(flag) .Select(m => { if (m.GetParameters().Length == 0) { hasNoParametersCtor = true; } return(new OverloadReflectionWrap(m, jsEnv.GeneralGetterManager, jsEnv.GeneralSetterManager)); }) .ToList(); if (type.IsValueType && !hasNoParametersCtor) { constructorWraps.Add(new OverloadReflectionWrap(type, jsEnv.GeneralGetterManager)); } MethodReflectionWrap constructorReflectionWrap = new MethodReflectionWrap(".ctor", constructorWraps); constructorCallback = constructorReflectionWrap.Construct; } int baseTypeId = -1; if (type.BaseType != null) { baseTypeId = GetTypeId(isolate, type.BaseType); } var fields = type.GetFields(flag); HashSet <string> readonlyStaticFields = new HashSet <string>(); foreach (var field in fields) { if (field.IsStatic && (field.IsInitOnly || field.IsLiteral)) { readonlyStaticFields.Add(field.Name); } } int typeId = -1; if (registerInfo == null) { typeId = PuertsDLL.RegisterClass(jsEnv.isolate, baseTypeId, type.AssemblyQualifiedName, constructorWrap, null, jsEnv.AddConstructor(constructorCallback)); } else { if (registerInfo.BlittableCopy) { typeId = PuertsDLL.RegisterStruct(jsEnv.isolate, -1, type.AssemblyQualifiedName, registerInfo.Constructor, null, jsEnv.Idx, System.Runtime.InteropServices.Marshal.SizeOf(type)); } else { typeId = PuertsDLL.RegisterClass(jsEnv.isolate, baseTypeId, type.AssemblyQualifiedName, registerInfo.Constructor, null, jsEnv.Idx); } foreach (var kv in registerInfo.Methods) { PuertsDLL.RegisterFunction(jsEnv.isolate, typeId, kv.Key.Name, kv.Key.IsStatic, kv.Value, jsEnv.Idx); } foreach (var kv in registerInfo.Properties) { PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, kv.Key, kv.Value.IsStatic, kv.Value.Getter, jsEnv.Idx, kv.Value.Setter, jsEnv.Idx, !readonlyStaticFields.Contains(kv.Key)); } } //int typeId = PuertsDLL.RegisterClass(jsEngine, type.AssemblyQualifiedName, null, null, Utils.TwoIntToLong(idx, 0)); foreach (var kv in methodGroup) { MethodReflectionWrap methodReflectionWrap = new MethodReflectionWrap(kv.Key.Name, kv.Value.Select(m => new OverloadReflectionWrap(m, jsEnv.GeneralGetterManager, jsEnv.GeneralSetterManager)).ToList()); PuertsDLL.RegisterFunction(jsEnv.isolate, typeId, kv.Key.Name, kv.Key.IsStatic, callbackWrap, jsEnv.AddCallback(methodReflectionWrap.Invoke)); } foreach (var kv in propertyGroup) { V8FunctionCallback getter = null; long getterData = 0; bool isStatic = false; if (kv.Value.Getter != null) { getter = callbackWrap; MethodReflectionWrap methodReflectionWrap = new MethodReflectionWrap(kv.Value.Getter.Name, new List <OverloadReflectionWrap>() { new OverloadReflectionWrap(kv.Value.Getter, jsEnv.GeneralGetterManager, jsEnv.GeneralSetterManager) }); getterData = jsEnv.AddCallback(methodReflectionWrap.Invoke); isStatic = kv.Value.Getter.IsStatic; } V8FunctionCallback setter = null; long setterData = 0; if (kv.Value.Setter != null) { setter = callbackWrap; MethodReflectionWrap methodReflectionWrap = new MethodReflectionWrap(kv.Value.Setter.Name, new List <OverloadReflectionWrap>() { new OverloadReflectionWrap(kv.Value.Setter, jsEnv.GeneralGetterManager, jsEnv.GeneralSetterManager) }); setterData = jsEnv.AddCallback(methodReflectionWrap.Invoke); isStatic = kv.Value.Setter.IsStatic; } PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, kv.Key, isStatic, getter, getterData, setter, setterData, true); } foreach (var field in fields) { if (registerInfo != null && registerInfo.Properties.ContainsKey(field.Name)) { continue; } var getterData = jsEnv.AddCallback(GenFieldGetter(type, field)); V8FunctionCallback setter = null; long setterData = 0; if (!field.IsInitOnly && !field.IsLiteral) { setter = callbackWrap; setterData = jsEnv.AddCallback(GenFieldSetter(type, field)); } PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, field.Name, field.IsStatic, callbackWrap, getterData, setter, setterData, !readonlyStaticFields.Contains(field.Name)); } var translateFunc = jsEnv.GeneralSetterManager.GetTranslateFunc(typeof(Type)); PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, "__p_innerType", true, callbackWrap, jsEnv.AddCallback((IntPtr isolate1, IntPtr info, IntPtr self, int argumentsLen) => { translateFunc(isolate1, NativeValueApi.SetValueToResult, info, type); }), null, 0, true); if (type.IsEnum) { PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, "__p_isEnum", true, returnTrue, 0, null, 0, false); } return(typeId); }
public long GetInt64(bool isByRef) { return(PuertsDLL.GetBigIntFromValue(isolate, value, isByRef)); }
public void Tick() { PuertsDLL.InspectorTick(isolate); }
internal void InitArrayTypeId(IntPtr isolate) { arrayTypeId = PuertsDLL.RegisterClass(jsEnv.isolate, GetTypeId(isolate, typeof(Array)), "__puerts.Array", null, null, 0); PuertsDLL.RegisterProperty(jsEnv.isolate, arrayTypeId, "length", false, callbackWrap, jsEnv.AddCallback(ArrayLength), null, 0, true); PuertsDLL.RegisterIndexedProperty(jsEnv.isolate, arrayTypeId, StaticCallbacks.IndexedGetterWrap, StaticCallbacks.IndexedSetterWrap, Utils.TwoIntToLong(jsEnv.Idx, 0)); }
public double GetDate(IntPtr isolate, IntPtr holder, bool isByRef) { return(PuertsDLL.GetDateFromResult(holder)); }
bool FastArrayGet(IntPtr isolate, IntPtr info, IntPtr self, object obj, uint index) { bool hited = true; var type = obj.GetType(); if (type == typeof(int[])) { int[] array = obj as int[]; PuertsDLL.ReturnNumber(isolate, info, array[index]); } else if (type == typeof(float[])) { float[] array = obj as float[]; PuertsDLL.ReturnNumber(isolate, info, array[index]); } else if (type == typeof(double[])) { double[] array = obj as double[]; PuertsDLL.ReturnNumber(isolate, info, array[index]); } else if (type == typeof(bool[])) { bool[] array = obj as bool[]; PuertsDLL.ReturnBoolean(isolate, info, array[index]); } else if (type == typeof(long[])) { long[] array = obj as long[]; PuertsDLL.ReturnBigInt(isolate, info, array[index]); } else if (type == typeof(ulong[])) { ulong[] array = obj as ulong[]; PuertsDLL.ReturnBigInt(isolate, info, (long)array[index]); } else if (type == typeof(sbyte[])) { sbyte[] array = obj as sbyte[]; PuertsDLL.ReturnNumber(isolate, info, array[index]); } else if (type == typeof(short[])) { short[] array = obj as short[]; PuertsDLL.ReturnNumber(isolate, info, array[index]); } else if (type == typeof(ushort[])) { ushort[] array = obj as ushort[]; PuertsDLL.ReturnNumber(isolate, info, array[index]); } else if (type == typeof(char[])) { char[] array = obj as char[]; PuertsDLL.ReturnNumber(isolate, info, array[index]); } else if (type == typeof(uint[])) { uint[] array = obj as uint[]; PuertsDLL.ReturnNumber(isolate, info, array[index]); } else if (type == typeof(string[])) { string[] array = obj as string[]; string str = array[index]; if (str == null) { PuertsDLL.ReturnNull(isolate, info); } else { PuertsDLL.ReturnString(isolate, info, str); } } else { hited = false; } return(hited); }
internal static void ReturnTrue(IntPtr isolate, IntPtr info, IntPtr self, int paramLen, long data) { PuertsDLL.ReturnBoolean(isolate, info, true); }
public byte GetByte(bool isByRef) { return((byte)PuertsDLL.GetNumberFromValue(isolate, value, isByRef)); }
public JsEnv(ILoader loader, int debugPort = -1) { const int libVersionExpect = 2; int libVersion = PuertsDLL.GetLibVersion(); if (libVersion != libVersionExpect) { throw new InvalidProgramException("expect lib version " + libVersionExpect + ", but got " + libVersion); } //PuertsDLL.SetLogCallback(LogCallback, LogWarningCallback, LogErrorCallback); this.loader = loader; isolate = PuertsDLL.CreateJSEngine(); lock (jsEnvs) { Idx = -1; for (int i = 0; i < jsEnvs.Count; i++) { if (jsEnvs[i] == null) { Idx = i; jsEnvs[Idx] = this; break; } } if (Idx == -1) { Idx = jsEnvs.Count; jsEnvs.Add(this); } } objectPool = new ObjectPool(); TypeRegister = new TypeRegister(this); GeneralGetterManager = new GeneralGetterManager(this); GeneralSetterManager = new GeneralSetterManager(this); PuertsDLL.SetGeneralDestructor(isolate, StaticCallbacks.GeneralDestructor); TypeRegister.InitArrayTypeId(isolate); PuertsDLL.SetGlobalFunction(isolate, "__tgjsRegisterTickHandler", StaticCallbacks.JsEnvCallbackWrap, AddCallback(RegisterTickHandler)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsLoadType", StaticCallbacks.JsEnvCallbackWrap, AddCallback(LoadType)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsGetNestedTypes", StaticCallbacks.JsEnvCallbackWrap, AddCallback(GetNestedTypes)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsGetLoader", StaticCallbacks.JsEnvCallbackWrap, AddCallback(GetLoader)); const string AutoStaticCodeRegisterClassName = "PuertsStaticWrap.AutoStaticCodeRegister"; var autoRegister = Type.GetType(AutoStaticCodeRegisterClassName, false); if (autoRegister == null) { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { autoRegister = assembly.GetType(AutoStaticCodeRegisterClassName, false); if (autoRegister != null) { break; } } } if (autoRegister != null) { var methodInfoOfRegister = autoRegister.GetMethod("Register"); methodInfoOfRegister.Invoke(null, new object[] { this }); } if (debugPort != -1) { PuertsDLL.CreateInspector(isolate, debugPort); } ExecuteFile("puerts/init.js"); ExecuteFile("puerts/log.js"); ExecuteFile("puerts/cjsload.js"); ExecuteFile("puerts/modular.js"); ExecuteFile("puerts/csharp.js"); ExecuteFile("puerts/timer.js"); }
public uint GetUInt32(bool isByRef) { return((uint)PuertsDLL.GetNumberFromValue(isolate, value, isByRef)); }
public void LowMemoryNotification() { PuertsDLL.LowMemoryNotification(isolate); }
public void SetByRefValue(ulong val) { PuertsDLL.SetBigIntToOutValue(isolate, value, (long)val); }
public void WaitDebugger() { while (!PuertsDLL.InspectorTick(isolate)) { } }
public float GetFloat(bool isByRef) { return((float)PuertsDLL.GetNumberFromValue(isolate, value, isByRef)); }
public JsEnv(ILoader loader, int debugPort, IntPtr externalRuntime, IntPtr externalContext) { const int libVersionExpect = 11; int libVersion = PuertsDLL.GetLibVersion(); if (libVersion != libVersionExpect) { throw new InvalidProgramException("expect lib version " + libVersionExpect + ", but got " + libVersion); } //PuertsDLL.SetLogCallback(LogCallback, LogWarningCallback, LogErrorCallback); this.loader = loader; if (externalRuntime != IntPtr.Zero && externalContext != IntPtr.Zero) { isolate = PuertsDLL.CreateJSEngineWithExternalEnv(externalRuntime, externalContext); } else { isolate = PuertsDLL.CreateJSEngine(); } if (isolate == IntPtr.Zero) { throw new InvalidProgramException("create jsengine fail"); } lock (jsEnvs) { Idx = -1; for (int i = 0; i < jsEnvs.Count; i++) { if (jsEnvs[i] == null) { Idx = i; jsEnvs[Idx] = this; break; } } if (Idx == -1) { Idx = jsEnvs.Count; jsEnvs.Add(this); } } objectPool = new ObjectPool(); TypeRegister = new TypeRegister(this); genericDelegateFactory = new GenericDelegateFactory(this); jsObjectFactory = new JSObjectFactory(); GeneralGetterManager = new GeneralGetterManager(this); GeneralSetterManager = new GeneralSetterManager(this); // 注册JS对象通用GC回调 PuertsDLL.SetGeneralDestructor(isolate, StaticCallbacks.GeneralDestructor); TypeRegister.InitArrayTypeId(isolate); // 把JSEnv的id和Callback的id拼成一个long存起来,并将StaticCallbacks.JsEnvCallbackWrap注册给V8。而后通过StaticCallbacks.JsEnvCallbackWrap从long中取出函数和envid并调用。 PuertsDLL.SetGlobalFunction(isolate, "__tgjsRegisterTickHandler", StaticCallbacks.JsEnvCallbackWrap, AddCallback(RegisterTickHandler)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsLoadType", StaticCallbacks.JsEnvCallbackWrap, AddCallback(LoadType)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsGetNestedTypes", StaticCallbacks.JsEnvCallbackWrap, AddCallback(GetNestedTypes)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsGetLoader", StaticCallbacks.JsEnvCallbackWrap, AddCallback(GetLoader)); //可以DISABLE掉自动注册,通过手动调用PuertsStaticWrap.AutoStaticCodeRegister.Register(jsEnv)来注册 #if !DISABLE_AUTO_REGISTER const string AutoStaticCodeRegisterClassName = "PuertsStaticWrap.AutoStaticCodeRegister"; var autoRegister = Type.GetType(AutoStaticCodeRegisterClassName, false); if (autoRegister == null) { foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { autoRegister = assembly.GetType(AutoStaticCodeRegisterClassName, false); if (autoRegister != null) { break; } } } if (autoRegister != null) { var methodInfoOfRegister = autoRegister.GetMethod("Register"); methodInfoOfRegister.Invoke(null, new object[] { this }); } #endif if (debugPort != -1) { PuertsDLL.CreateInspector(isolate, debugPort); } ExecuteFile("puerts/init.js"); ExecuteFile("puerts/log.js"); ExecuteFile("puerts/cjsload.js"); ExecuteFile("puerts/modular.js"); ExecuteFile("puerts/csharp.js"); ExecuteFile("puerts/timer.js"); ExecuteFile("puerts/events.js"); ExecuteFile("puerts/promises.js"); ExecuteFile("puerts/polyfill.js"); }
public bool GetBoolean(bool isByRef) { return(PuertsDLL.GetBooleanFromValue(isolate, value, isByRef)); }
bool FastArraySet(IntPtr isolate, IntPtr info, IntPtr self, object obj, uint index, IntPtr value) { bool hited = true; var jsType = PuertsDLL.GetJsValueType(isolate, value, false); var type = obj.GetType(); if (type == typeof(int[]) && jsType == JsValueType.Number) { int[] array = obj as int[]; array[index] = (int)PuertsDLL.GetNumberFromValue(isolate, value, false); } else if (type == typeof(float[]) && jsType == JsValueType.Number) { float[] array = obj as float[]; array[index] = (float)PuertsDLL.GetNumberFromValue(isolate, value, false); } else if (type == typeof(double[]) && jsType == JsValueType.Number) { double[] array = obj as double[]; array[index] = PuertsDLL.GetNumberFromValue(isolate, value, false); } else if (type == typeof(bool[]) && jsType == JsValueType.Boolean) { bool[] array = obj as bool[]; array[index] = PuertsDLL.GetBooleanFromValue(isolate, value, false); } else if (type == typeof(long[]) && jsType == JsValueType.BigInt) { long[] array = obj as long[]; array[index] = PuertsDLL.GetBigIntFromValueChecked(isolate, value, false); } else if (type == typeof(ulong[]) && jsType == JsValueType.BigInt) { ulong[] array = obj as ulong[]; array[index] = (ulong)PuertsDLL.GetBigIntFromValueChecked(isolate, value, false); } else if (type == typeof(sbyte[]) && jsType == JsValueType.Number) { sbyte[] array = obj as sbyte[]; array[index] = (sbyte)PuertsDLL.GetNumberFromValue(isolate, value, false); } else if (type == typeof(short[]) && jsType == JsValueType.Number) { short[] array = obj as short[]; array[index] = (short)PuertsDLL.GetNumberFromValue(isolate, value, false); } else if (type == typeof(ushort[]) && jsType == JsValueType.Number) { ushort[] array = obj as ushort[]; array[index] = (ushort)PuertsDLL.GetNumberFromValue(isolate, value, false); } else if (type == typeof(char[]) && jsType == JsValueType.Number) { char[] array = obj as char[]; array[index] = (char)PuertsDLL.GetNumberFromValue(isolate, value, false); } else if (type == typeof(uint[]) && jsType == JsValueType.Number) { uint[] array = obj as uint[]; array[index] = (uint)PuertsDLL.GetNumberFromValue(isolate, value, false); } else if (type == typeof(string[]) && jsType == JsValueType.String) { string[] array = obj as string[]; array[index] = PuertsDLL.GetStringFromValue(isolate, value, false); } else if (type == typeof(string[]) && jsType == JsValueType.NullOrUndefined) { string[] array = obj as string[]; array[index] = null; } else { hited = false; } return(hited); }
public string GetString(bool isByRef) { return(PuertsDLL.GetStringFromValue(isolate, value, isByRef)); }
// #lizard forgives private int RegisterType(IntPtr isolate, Type type, bool includeNoPublic) { TypeRegisterInfo registerInfo = null; if (lazyStaticWrapLoaders.ContainsKey(type)) { registerInfo = lazyStaticWrapLoaders[type](); lazyStaticWrapLoaders.Remove(type); } BindingFlags flag = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; if (includeNoPublic) { flag = flag | BindingFlags.NonPublic; } // baseType int baseTypeId = -1; if (type.BaseType != null) { baseTypeId = GetTypeId(isolate, type.BaseType); } Dictionary <MethodKey, List <MethodInfo> > slowBindingMethodGroup = new Dictionary <MethodKey, List <MethodInfo> >(); Dictionary <string, ProperyMethods> slowBindingProperties = new Dictionary <string, ProperyMethods>(); List <FieldInfo> slowBindingFields = new List <FieldInfo>(); Dictionary <MethodKey, List <MethodInfo> > lazyBindingMethodGroup = new Dictionary <MethodKey, List <MethodInfo> >(); Dictionary <string, ProperyMethods> lazyBindingProperties = new Dictionary <string, ProperyMethods>(); List <FieldInfo> lazyBindingFields = new List <FieldInfo>(); Func <MethodKey, MethodInfo, bool> AddMethodToSlowBindingGroup = (MethodKey methodKey, MethodInfo method) => { if (method.IsGenericMethodDefinition) { if (!Utils.IsSupportedMethod(method)) { return(false); } var genericArguments = method.GetGenericArguments(); var constraintedArgumentTypes = new Type[genericArguments.Length]; for (var j = 0; j < genericArguments.Length; j++) { constraintedArgumentTypes[j] = genericArguments[j].BaseType; } method = method.MakeGenericMethod(constraintedArgumentTypes); } if (method.IsSpecialName && method.Name.StartsWith("get_") && method.GetParameters().Length != 1) // getter of property { string propName = method.Name.Substring(4); ProperyMethods properyMethods; if (!slowBindingProperties.TryGetValue(propName, out properyMethods)) { properyMethods = new ProperyMethods(); slowBindingProperties.Add(propName, properyMethods); } properyMethods.Getter = method; } else if (method.IsSpecialName && method.Name.StartsWith("set_") && method.GetParameters().Length != 2) // setter of property { string propName = method.Name.Substring(4); ProperyMethods properyMethods; if (!slowBindingProperties.TryGetValue(propName, out properyMethods)) { properyMethods = new ProperyMethods(); slowBindingProperties.Add(propName, properyMethods); } properyMethods.Setter = method; } else { List <MethodInfo> overloads; if (!slowBindingMethodGroup.TryGetValue(methodKey, out overloads)) { overloads = new List <MethodInfo>(); slowBindingMethodGroup.Add(methodKey, overloads); } overloads.Add(method); } return(true); }; HashSet <string> readonlyStaticFields = new HashSet <string>(); int typeId = -1; if (registerInfo == null) { // registerInfo is null, then all the member use the SlowBinding // constructors JSConstructorCallback constructorCallback = null; if (typeof(Delegate).IsAssignableFrom(type)) { DelegateConstructWrap delegateConstructWrap = new DelegateConstructWrap(type, jsEnv.GeneralGetterManager); constructorCallback = delegateConstructWrap.Construct; } else { bool hasNoParametersCtor = false; var constructorWraps = type.GetConstructors(flag) .Select(m => { if (m.GetParameters().Length == 0) { hasNoParametersCtor = true; } return(new OverloadReflectionWrap(m, jsEnv.GeneralGetterManager, jsEnv.GeneralSetterManager)); }) .ToList(); if (type.IsValueType && !hasNoParametersCtor) { constructorWraps.Add(new OverloadReflectionWrap(type, jsEnv.GeneralGetterManager)); } MethodReflectionWrap constructorReflectionWrap = new MethodReflectionWrap(".ctor", constructorWraps); constructorCallback = constructorReflectionWrap.Construct; } typeId = PuertsDLL.RegisterClass(jsEnv.isolate, baseTypeId, type.AssemblyQualifiedName, constructorWrap, null, jsEnv.AddConstructor(constructorCallback)); // methods and properties MethodInfo[] methods = Puerts.Utils.GetMethodAndOverrideMethod(type, flag); for (int i = 0; i < methods.Length; ++i) { MethodInfo method = methods[i]; MethodKey methodKey = new MethodKey { Name = method.Name, IsStatic = method.IsStatic }; if (!method.IsConstructor) { AddMethodToSlowBindingGroup(methodKey, method); } } // extensionMethods // 因为内存问题与crash问题移入宏中 #if PUERTS_REFLECT_ALL_EXTENSION || UNITY_EDITOR IEnumerable <MethodInfo> extensionMethods = Utils.GetExtensionMethodsOf(type); if (extensionMethods != null) { var enumerator = extensionMethods.GetEnumerator(); while (enumerator.MoveNext()) { MethodInfo method = enumerator.Current; MethodKey methodKey = new MethodKey { Name = method.Name, IsStatic = false, IsExtension = true }; AddMethodToSlowBindingGroup(methodKey, method); } } #endif // fields var fields = type.GetFields(flag); foreach (var field in fields) { slowBindingFields.Add(field); if (field.IsStatic && (field.IsInitOnly || field.IsLiteral)) { readonlyStaticFields.Add(field.Name); } } } else { // otherwise when registerInfo is not null, most of member use FastBinding, some member with IsLazyMember=true use LazyBinding if (registerInfo.BlittableCopy) { typeId = PuertsDLL.RegisterStruct(jsEnv.isolate, -1, type.AssemblyQualifiedName, registerInfo.Constructor, null, jsEnv.Idx, System.Runtime.InteropServices.Marshal.SizeOf(type)); } else { typeId = PuertsDLL.RegisterClass(jsEnv.isolate, baseTypeId, type.AssemblyQualifiedName, registerInfo.Constructor, null, jsEnv.Idx); } foreach (var kv in registerInfo.Methods) { PuertsDLL.RegisterFunction(jsEnv.isolate, typeId, kv.Key.Name, kv.Key.IsStatic, kv.Value, jsEnv.Idx); if (kv.Key.Name == "ToString" && registerInfo.BlittableCopy) { PuertsDLL.RegisterFunction(jsEnv.isolate, typeId, "toString", false, kv.Value, jsEnv.Idx); } } foreach (var kv in registerInfo.Properties) { PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, kv.Key, kv.Value.IsStatic, kv.Value.Getter, jsEnv.Idx, kv.Value.Setter, jsEnv.Idx, !readonlyStaticFields.Contains(kv.Key)); } foreach (LazyMemberRegisterInfo lazyinfo in registerInfo.LazyMembers) { switch (lazyinfo.Type) { case LazyMemberType.Method: LazyMethodWrap lazyMethodWrap = new LazyMethodWrap(lazyinfo.Name, jsEnv, type); long callback = jsEnv.AddCallback(lazyMethodWrap.Invoke); PuertsDLL.RegisterFunction(jsEnv.isolate, typeId, lazyinfo.Name, lazyinfo.IsStatic, callbackWrap, callback); if (lazyinfo.Name == "ToString" && registerInfo.BlittableCopy) { PuertsDLL.RegisterFunction(jsEnv.isolate, typeId, "toString", false, callbackWrap, jsEnv.Idx); } break; case LazyMemberType.Constructor: // TODO break; case LazyMemberType.Field: LazyFieldWrap lazyFieldWrap = new LazyFieldWrap(lazyinfo.Name, jsEnv, type); PuertsDLL.RegisterProperty( jsEnv.isolate, typeId, lazyinfo.Name, lazyinfo.IsStatic, callbackWrap, jsEnv.AddCallback(lazyFieldWrap.InvokeGetter), lazyinfo.HasSetter ? callbackWrap : null, lazyinfo.HasSetter ? jsEnv.AddCallback(lazyFieldWrap.InvokeSetter) : 0, !readonlyStaticFields.Contains(lazyinfo.Name) ); break; case LazyMemberType.Property: LazyPropertyWrap getterLazyPropertyWrap = new LazyPropertyWrap("get_" + lazyinfo.Name, jsEnv, type); LazyPropertyWrap setterLazyPropertyWrap = new LazyPropertyWrap("set_" + lazyinfo.Name, jsEnv, type); PuertsDLL.RegisterProperty( jsEnv.isolate, typeId, lazyinfo.Name, lazyinfo.IsStatic, lazyinfo.HasGetter ? callbackWrap : null, lazyinfo.HasGetter ? jsEnv.AddCallback(getterLazyPropertyWrap.Invoke) : 0, lazyinfo.HasSetter ? callbackWrap : null, lazyinfo.HasSetter ? jsEnv.AddCallback(setterLazyPropertyWrap.Invoke) : 0, true ); break; } } //if (registerInfo.LazyMethods != null) //{ // // register all the methods marked as lazy // foreach (var kv in registerInfo.LazyMethods) // { // //TODO: change to LazyBinding instead of SlowBinding // MethodKey methodKey = kv.Key; // MemberInfo[] members = type.GetMember(methodKey.Name, flag); // var enumerator = members.GetEnumerator(); // while (enumerator.MoveNext()) // { // AddMethodToSlowBindingGroup(methodKey, (MethodInfo)enumerator.Current); // } // } //} //if (registerInfo.LazyProperties != null) //{ // // register all the properties marked as lazy // foreach (var kv in registerInfo.LazyProperties) // { // //TODO: change to LazyBinding instead of SlowBinding // string name = kv.Key; // MethodKey getMethodKey = new MethodKey { Name = "get_" + name, IsStatic = kv.Value.IsStatic }; // MethodInfo getMethod = type.GetMethod(getMethodKey.Name, flag); // MethodKey setMethodKey = new MethodKey { Name = "set_" + name, IsStatic = kv.Value.IsStatic }; // MethodInfo setMethod = type.GetMethod(getMethodKey.Name, flag); // if (getMethod != null) // { // AddMethodToSlowBindingGroup(getMethodKey, getMethod); // } // if (setMethod != null) // { // AddMethodToSlowBindingGroup(setMethodKey, setMethod); // } // } //} } foreach (var kv in slowBindingMethodGroup) { var overloadWraps = kv.Value.Select(m => new OverloadReflectionWrap(m, jsEnv.GeneralGetterManager, jsEnv.GeneralSetterManager, kv.Key.IsExtension)).ToList(); MethodReflectionWrap methodReflectionWrap = new MethodReflectionWrap(kv.Key.Name, overloadWraps); PuertsDLL.RegisterFunction(jsEnv.isolate, typeId, kv.Key.Name, kv.Key.IsStatic, callbackWrap, jsEnv.AddCallback(methodReflectionWrap.Invoke)); } foreach (var kv in slowBindingProperties) { V8FunctionCallback getter = null; long getterData = 0; bool isStatic = false; if (kv.Value.Getter != null) { getter = callbackWrap; MethodReflectionWrap methodReflectionWrap = new MethodReflectionWrap(kv.Value.Getter.Name, new List <OverloadReflectionWrap>() { new OverloadReflectionWrap(kv.Value.Getter, jsEnv.GeneralGetterManager, jsEnv.GeneralSetterManager) }); getterData = jsEnv.AddCallback(methodReflectionWrap.Invoke); isStatic = kv.Value.Getter.IsStatic; } V8FunctionCallback setter = null; long setterData = 0; if (kv.Value.Setter != null) { setter = callbackWrap; MethodReflectionWrap methodReflectionWrap = new MethodReflectionWrap(kv.Value.Setter.Name, new List <OverloadReflectionWrap>() { new OverloadReflectionWrap(kv.Value.Setter, jsEnv.GeneralGetterManager, jsEnv.GeneralSetterManager) }); setterData = jsEnv.AddCallback(methodReflectionWrap.Invoke); isStatic = kv.Value.Setter.IsStatic; } PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, kv.Key, isStatic, getter, getterData, setter, setterData, true); } foreach (var field in slowBindingFields) { var getterData = jsEnv.AddCallback(GenFieldGetter(type, field)); V8FunctionCallback setter = null; long setterData = 0; if (!field.IsInitOnly && !field.IsLiteral) { setter = callbackWrap; setterData = jsEnv.AddCallback(GenFieldSetter(type, field)); } PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, field.Name, field.IsStatic, callbackWrap, getterData, setter, setterData, !readonlyStaticFields.Contains(field.Name)); } var translateFunc = jsEnv.GeneralSetterManager.GetTranslateFunc(typeof(Type)); PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, "__p_innerType", true, callbackWrap, jsEnv.AddCallback((IntPtr isolate1, IntPtr info, IntPtr self, int argumentsLen) => { translateFunc(isolate1, NativeValueApi.SetValueToResult, info, type); }), null, 0, true); if (type.IsEnum) { PuertsDLL.RegisterProperty(jsEnv.isolate, typeId, "__p_isEnum", true, returnTrue, 0, null, 0, false); } return(typeId); }
public DateTime GetDateTime(bool isByRef) { var ticks = PuertsDLL.GetDateFromValue(isolate, value, isByRef); return((new DateTime(1970, 1, 1)).AddMilliseconds(ticks)); }
public long GetBigInt(IntPtr isolate, IntPtr holder, bool isByRef) { return(PuertsDLL.GetBigIntFromResultCheck(holder)); }