QQ交流群:523723780(ChakraCore)
ChakraCore是什么?
一個微軟開源的,用於Windows IE/Edge內核的高效JS腳本引擎。
前不久微軟開源了ChakraCore,並且支持跨平台。在Github可以搜到。即使在開源之前,Windows SDK也支持你的程序去Hosting JS,只需要簡單的包含jsrt.h,鏈接jsrt.lib即可調用JSRT的API。只是舊版本的Windows系統所帶引擎性能沒有Windows10 Edge性能好.
關於Chakra與JSV8的性能比較
http://browserbench.org/JetStream/是一個瀏覽器評分工具(越高越好),在我平板的得分Chrome54(JSV8)是126.59,Edge(Chakra)是152.06。在cnblog某個用戶的渲染評測中,Chrome54是83秒,Edge是110秒,越快越好。所以我也不好說哪個更快,就瀏覽器日常使用,肯定是Edge更快,更節能。
JS腳本支持有哪些優勢?
在流行的腳本語言中,Lua的小巧高性能(性能指LuaJit的性能),Python的功能性一直受開發者青睞。有什么理由使用JS腳本呢?
JS腳本有眾多的庫支持
JS腳本被用於HTML網頁開發,開發者眾多
JS有眾多大公司的支持
JS有優秀的即時編譯(JIT)性能
JS有無敵的開發工具Visual Studio的支持
JS語言特性更類似C/C++,相比Lua要舒服很多
Chakra的嵌入優勢:相比Lua的堆棧式API,Chakra的API更容易寫膠水代碼。
很多游戲使用Lua的原因是比Python性能好,沒有其他可選方案了。Chakra的開源,應該帶動開發者去使用JS腳本。Chakra對於大型Windows游戲開發者更大的好處在於系統支持,Lua需要去下載編譯,而Chakra只需要包含頭文件,鏈接lib。
如何在Windows嵌入Chakra?
請看我以前的文章。
如何在linux嵌入ChakraCore去實現一個JavaScript運行時容器?
如果你像Windows上一樣使用ChakraCore,用動態鏈接的方式,那肯定會產生JsErrorNoCurrentContext錯誤。
我詢問過微軟,這是因為在Windows下,系統加載DLL時會調用DLL的入口DllMain,而Linux沒有這個機制,而Linux下的Chakra卻有這樣的設計。
所以在Linux加載動態庫(libChakraCore.so)以后,應該顯式的調用DllMain。下面是我的實現,非官方。官方接受了我的意見,大概會在以后版本中改進linux版本的初始化方式。
2016年11月19日,我寫這段話時的兩天前,官方正則討論這方面的設計細則。Github鏈接
#ifdef __linux__ typedef int (*DllMainPtr)(void* hmod, DWORD dwReason, void* pvReserved); DllMainPtr dllmain; void* handle = dlopen("libChakraCore.so", RTLD_LAZY); if (handle == nullptr) throw runtime_error("Failed load library libChakraCore.so"); char* errstr = dlerror(); if (errstr != nullptr) throw runtime_error(errstr); dllmain = (DllMainPtr)dlsym(handle, "DllMain"); errstr = dlerror(); if (errstr != nullptr) { dlclose(handle); throw runtime_error(errstr); } if (dllmain == nullptr) { dlclose(handle); throw runtime_error("find not DllMain"); } //模擬WIN DLL加載 dllmain(0, 1, 0); dllmain(0, 2, 0); dlclose(handle); #endif // __linux__
可以列出全局對象或函數嗎?
可以,除了Intl,這是個特例
JS可以使用引用(c++的&,c#的ref)參數嗎?
不可以,即使你為傳入Native的函數參數修改值也是沒用的。
如果一定要用,那只能傳一個引用類型的對象,在函數內部修改此對象的成員。var arr=[];(function (v){v[1]=1;})(arr);//arr[1] == 1
Chakra的API支持多線程嗎?
支持,據我當前的研究,不同線程必須有各自的runtime對象,每個runtime可以有多個環境(context),同一個runtime下的多個環境可以自由交換數據,但環境之間不共享數據。也就是說api級別可以把環境1的數據帶到環境2,但是腳本里,環境2是看不到環境1的數據的。
Chakra支持ES6的Symbol嗎?
完全支持。
Chakra如何在原生函數里支持JS的閉包?
函數(function)也是對象(object),可以有自定義屬性,所以,在原生API級別操作Chakra時,可以把需要閉包的變量放在函數的屬性里。如果希望在腳本中是只讀的,那么可以設置屬性描述。如果希望在腳本中是隱藏的,那么可以用符號屬性。
如何用API實現原生對象的多次繼承?
假設需要我們有一個移動設備類,手機類從它繼承,iPhone從手機繼承,那么應該這樣:
一個JsObject(用JsCreateObject),用來表示移動設備,可以添加成員,另一個JsObject用來表示手機,再有一個ExternalObject(用JsCreateExternalObject)用來表示一個實際的原生對象實例(iPhone)。
手機JsObject從移動設備JsObject繼承(JsSetPrototype),iPhone從手機繼承。
ChakraCore API的對象管理該如何做?
ChakraCore API的都在操作核心對象JsValueRef,Chakra內部會把生成的對象放在堆上。用API生成一個JsValueRef對象后,運行一段時間會垃圾回收掉。所以如果在你的程序中長期使用JsValueRef,需要保存它,那么應該調用調用JsAddRef為其添加引用計數。在不用時調用JsRelease減少引用計數。【2017/5/27】
附錄:
1、JS的符號 ES6-Symbol