DIY系列之Web浏览器(1)——Javascript

DIY系列之Web浏览器(1)——Javascript

  • 本文介绍如何使用SpiderMonkey Javascript引擎来执行复杂的Javascript脚本

1. 准备工作

  • 下载SpiderMonkey31、编译、链接SpiderMonkey,详见这里。其中一定要用autoconf-2.13,使用更新的版本会导致无法编译。
$ cd js/src
$ autoconf-2.13
$ mkdir build_DBG.OBJ
$ cd build_DBG.OBJ
$ ../configure --enable-debug --disable-optimize --disable-threadsafe
$ make
  • 测试构建的SpiderMonkey
$ cd js/src
$ ./js -e "print(1+2)"
3
  • SpiderMonkey控制台的选项和内置函数见这里

2. 将SpiderMonkey嵌入C++程序中

  • 通过以下示例代码(参考自这里)来说明
#include <assert.h>
#include "jsapi.h"

static JSClass global_class = {
    "global",
    JSCLASS_GLOBAL_FLAGS,

    JS_PropertyStub,
    JS_DeletePropertyStub,
    JS_PropertyStub,
    JS_StrictPropertyStub,
    JS_EnumerateStub,
    JS_ResolveStub,
    JS_ConvertStub,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    JS_GlobalObjectTraceHook,
};

int main(int argc, const char *argv[])
{
    assert(JS_Init());
    JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024, JS_NO_HELPER_THREADS);
    assert(rt);
    JSContext *cx = JS_NewContext(rt, 8192);
    assert(cx);

    {
        JS::RootedObject global(cx);
        global = JS_NewGlobalObject(cx, &global_class, nullptr, JS::FireOnNewGlobalHook);
        assert(global);

        JSAutoCompartment ac(cx, global);
        assert(JS_InitStandardClasses(cx, global));

        JS::RootedValue rval(cx);

        const char *script = "'hello'+'world, it is '+new Date()";
        const char *filename = "noname";
        int lineno = 1;
        bool ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno, &rval);
        assert(ok);

        JSString *str = rval.toString();
        printf("%s\n", JS_EncodeString(cx, str));
    }

    JS_DestroyContext(cx);
    JS_DestroyRuntime(rt);
    JS_ShutDown();
    return 0;
}

和出处代码不同的是,globalrval 都需要在local scope中定义和使用,这是因为JS_DestroyContext 需要 globalrval 都不在当前可使用范围中(即调用他们的destructor)。

  • 以下代码为编译所需要的makefile文件,直接编译连接后,将libmozjs-31.so 路径嵌入在elf文件中。
OBJDIR  = /path/to/mozjs-31.2.0/js/src/build_DBG.OBJ
SODIR   = ${OBJDIR}/dist/lib
SONAME  = mozjs-31
CFLAGS  = -Wno-invalid-offsetof -std=c++11 -I${OBJDIR}/dist/include -g
LDFLAGS = -Wl,-rpath,${SODIR} -L${SODIR} -l${SONAME} -lz -lpthread -ldl

all:
    colorg++ ${CFLAGS} helloworld.cpp -o helloworld ${LDFLAGS}

运行结果如下

$ make
$ ./helloworld
helloworld, it is Sun Aug 16 2015 11:18:07 GMT+0800 (CST)

3. 观察、追踪Javascript脚本的执行

4. Javascript和C/C++相互调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值