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

原文地址:https://www.cnblogs.com/fyter/p/chakracore-faq.html