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;
}
和出处代码不同的是,global
和 rval
都需要在local scope中定义和使用,这是因为JS_DestroyContext
需要 global
和 rval
都不在当前可使用范围中(即调用他们的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)