SpiderMonkey 入门翻译

来源:互联网 发布:网络教育专科报名条件 编辑:程序博客网 时间:2024/06/07 05:17

SpiderMonkey
从源码中建立 SpiderMonkey 看 SpiderMonkey Build Documentation(https://developer.mozilla.org/En/SpiderMonkey/Build_Documentation).

一些系统(例如 Debian) 提供了预设包。 代替从源码中建立 SpiderMonkey。 你的程序更容易调试。

c++ 代码使用 SpiderMonkey 是通过 JSAPI, 输入头文件 “jsapi.h”. 下面是 JSAPI 功能概述。 更多细节请看JSAPI Reference.

SpiderMonkey世界

为了在SpiderMonkey中运行任何的JavaScript代码, 一个应用必须要有3个关键因素:一个 JSRuntime, 一个 JSContext, 和一个 global object. 这节描述这些是什么。 下节解释如何通过JSAPI设立他们。

Runtimes。
一个JSRuntime 或者 runtime, 是一个空间,其中分配着JavaScript 变量, 对象, 脚本, 和上下文 被你的应用所使用。 在应用中的每一个JSContext 和每一个对象 都活在JSRuntime中。 他们不能游历或者共享到另一个runtimes中。 大多数应用只需要一个runtime。

Contexts。
一个JSContext 或者 context, 更像一个小机器, 能够做很多涉及到js代码 和 对象 的事。 他能够编译和运行脚本, get 和 set 对象属性, 调用 js函数, 转换js数据 从一个类型到另一个类型, 创建对象, 等等。 大多数JSAPI 函数需要一个JSContext* 作为开头声明, 犹如大多数

include “jsapi.h”

using namespace JS;

// The class of the global object. 全局对象
static JSClass globalClass = {
“global”,
JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub,
JS_DeletePropertyStub,
JS_PropertyStub,
JS_StrictPropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
nullptr, nullptr, nullptr, nullptr,
JS_GlobalObjectTraceHook
};

// The error reporter callback. 错误处理回调
void reportError(JSContext *cx, const char *message, JSErrorReport *report) {
fprintf(stderr, “%s:%u:%s\n”,
report->filename ? report->filename : “[no filename]”,
(unsigned int) report->lineno,
message);
}

int run(JSContext *cx) {
// Enter a request before running anything in the context.输入一个请求
JSAutoRequest ar(cx);

// Create the global object and a new compartment.创建一个对象//声明对象RootedObject global(cx);//global = JS_NewGlobalObject(cx, &globalClass, nullptr,                            JS::DontFireOnNewGlobalHook);if (!global)    return 1;// Enter the new global object's compartment.JSAutoCompartment ac(cx, global);// Populate the global object with the standard globals, like Object and// Array.if (!JS_InitStandardClasses(cx, global))    return 1;// Your application code here. This may include JSAPI calls to create your// own custom JS objects and run scripts.return 0;

}

int main(int argc, const char *argv[]) {
// Initialize the JS engine.
if (!JS_Init())
return 1;

// Create a JS runtime.JSRuntime *rt = JS_NewRuntime(8L * 1024L * 1024L);if (!rt)   return 1;// Create a context.JSContext *cx = JS_NewContext(rt, 8192);if (!cx)   return 1;JS_SetErrorReporter(rt, reportError);int status = run(cx);// Shut everything down.JS_DestroyContext(cx);JS_DestroyRuntime(rt);JS_ShutDown();return status;

}

每个jsnative具有相同的签名, 无论从js众接收到任何的参数。

JavaScript函数的参数是argc和vp。 argc说明发来了多少个实际参数, JS_ARGV(cx, vp) (高版本使用 JS::CallArgs args = JS::CallArgsFromVp(argc, vp); ) 返回一个数组,里面包含了这些参数。 这些参数不是传统的c++类型,例如int float; 而是jsvals, js类型。 使用 JS_ConvertArguments转换到c++类型,并储存在局部变量中。 使用 JS_SET_RVAL(cx, vp, val)(高版本使用args.rval().set(jsret);)返回给js的值。

如果成功, JSNative会调用JS_SET_RVAL并返回true。 该值会通过JS_SET_RVAL返回给js调用者。

如果失败, JSNative调用一个error-reporting函数, 该例为JS_ReportError, 并且返回错误。 这会导致js抛出一个异常。 调用者能通过js的 try/catch 捕获异常。

让js能够调用native的函数, 通过 JSFunctionSpec 声明一个表格来描述函数。然后调用 JS_DefineFunctions(高版本调用JS_DefineFunction 一个个函数设置).

static JSFunctionSpec myjs_global_functions[] = {
JS_FS(“rand”, myjs_rand, 0, 0),
JS_FS(“srand”, myjs_srand, 0, 0),
JS_FS(“system”, myjs_system, 1, 0),
JS_FS_END
};

...if (!JS_DefineFunctions(cx, global, myjs_global_functions))    return false;...

一旦函数被定义到global中, 任何的脚本使用global都能调用他们, 就像任何的网页能调用alert。 在环境中我们创建 “hello world” 脚本 像下面:
system(“echo hello world”);

1 0