ChakraCore/JSRT使用問題匯總


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM