mozilla 的 java script engine.
一開始先找最新版的(v24.2.0), 結果公司兩台 build server 都不支援,
一個是 python 版本太舊, 一個是 gcc 版本太舊,
所以改舊版(v17.0.0).
build spidermonkey for mips:
(1) cd js/src; mkdir make-release; cd make-release
(2) vim do_config.sh ; sh ./do_config.sh
AR=ar CC="mips-linux-gnu-gcc -EL" CXX="mips-linux-gnu-g++ -EL" ../configure --prefix=$release_dir --target=mips-linux-gnu
(3) make
在此會有 compilation error
改變 1412 ~ 1416 行的內容, 只保留 return CallNonGenericMethod(cx, IsThisClass, GetterImpl<ValueGetter>, args);
(4) make install
會把必要的檔案, 包含 so 和 header files, 放在 make-install 裡,
也就是 js/src/make-release/make-release.
(5) 把 ./make-release/include/js-17.0 整包, 和 ./make-release/lib/libmozjs-17.0.so 放到 file system 對應的位置.
apply to application:
照 doc 敘述, 不同版本間的 api 似乎改變很大,
實際驗證結果, doc 列的 api 有些不支援, 有些 complie 不過, 有些 run 了會 crash ... 很麻煩.
最終試驗範本:
目標:
執行一個 java script, 輸入一字串, 得到另一字串
/* The class of the global object. */
static JSClass global_class = {
"global",
JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub,
JS_PropertyStub,
JS_PropertyStub,
JS_StrictPropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub,
NULL
// JS_FinalizeStub,
//JSCLASS_NO_OPTIONAL_MEMBERS
};
/* 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);
}
JSBool func_test(JSContext *context,const char *location,char *output,const int sizeoutput)
{
jsval res;
JSObject *global = JS_GetGlobalObject(context);
jsval argv[1];
JSString *string = JS_NewStringCopyZ(context,location);
if( string )
{
argv[0] = STRING_TO_JSVAL(string);
}
JS_CallFunctionName(context, global, "JavaScriptFuncName", 1, argv, &res); // 要呼叫的 javascipt api
return JS_TRUE;
}
JSBool evalScriptFromFile(JSContext *context, const char *file)
{
JSScript *script;
JSString *jss;
JSBool status;
jsval value;
//get the global object
JSObject *global = JS_GetGlobalObject(context);
//compile the script for further using
//script = JS_CompileFile(context, global, file); // failed to compile
script = JS_CompileUTF8File(context, global, file);
if(script == NULL)
{
return JS_FALSE;
}
//execute it once
status = JS_ExecuteScript(context, global, script, &value);
//destory the script object
//JS_DestroyScript(context, script); // undefined symbol while running
return status;
}
void scriptTest(const char *location,char *output,const int sizeoutput)
{
JSRuntime *runtime;
JSContext *context;
JSObject *global;
runtime = JS_NewRuntime(8L * 1024L * 1024L);
if(runtime == NULL)
{
return;
}
context = JS_NewContext(runtime, 8*1024);
if(context == NULL)
{
return;
}
JS_SetOptions(context, JSOPTION_VAROBJFIX);
JS_SetErrorReporter(context, reportError);
//global = JS_NewObject(context, &global_class, NULL, NULL); // crash
global = JS_NewGlobalObject(context, &global_class, NULL);
if (global == NULL)
{
return;
}
if (!JS_InitStandardClasses(context, global))
{
return;
}
//----------------------------------------------------------
//
JSBool status = evalScriptFromFile(context, "/mnt/user1/testjavascript.js"); // 要執行的 path to java script
if(status == JS_FALSE){
fprintf(stderr, "error while evaluate the script\n");
}
func_test(context,location,output,sizeoutput);
//----------------------------------------------------------
JS_DestroyContext(context);
JS_DestroyRuntime(runtime);
JS_ShutDown();
}
void main()
{
char *location = "aaaaaaaaaaaaaaaa";
char location2[512] = {0};
scriptTest(location,location2,512);
// location2 即為執行結果
}
Reference:
1. spidermonkey doc
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey
2. versions of spidermonkey
http://ftp.mozilla.org/pub/mozilla.org/js/
3. 使用流程 (call function)
http://www.oschina.net/question/12_16100
留言列表