public JsEnv(ILoader loader, int debugPort, IntPtr externalRuntime, IntPtr externalContext) { const int libVersionExpect = 14; 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) { 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); } bool isNode = PuertsDLL.GetLibBackend() == 1; 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"); #if !PUERTS_GENERAL if (!isNode) { #endif ExecuteFile("puerts/polyfill.js"); #if !PUERTS_GENERAL } else { ExecuteFile("puerts/nodepatch.js"); } #endif #if UNITY_EDITOR if (OnJsEnvCreate != null) { OnJsEnvCreate(this, loader, debugPort); } this.debugPort = debugPort; #endif }