/* sm2.c * SpiderMonkey を C プログラムから使う例 * * 使い方:コマンドライン引数で JavaScript のファイル名を指定する。 */ #define USAGE "Usage: sm2 " #include #include "jsapi.h" /* グローバルオブジェクトのクラス */ static JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS }; /* * 組込み関数の定義 */ JSBool myjs_print( JSContext *jsctx , JSObject *obj , uintN argc , jsval *argv , jsval *rval ) { uintN i = 0; JSString *str = NULL; char *bytes = NULL; for (i = 0; i < argc; i++) { str = JS_ValueToString(jsctx, argv[i]); if (!str) return JS_FALSE; bytes = JS_EncodeString(jsctx, str); if (!bytes) return JS_FALSE; printf("%s%s", i ? " " : "", bytes); JS_free(jsctx, bytes); } *rval = JSVAL_VOID; /* return undefined */ return JS_TRUE; } static JSFunctionSpec myjs_global_functions[] = { JS_FS("print", myjs_print, 0, 0, 0), JS_FS_END }; /* エラーレポート用コールバック関数 */ void reportError( JSContext *jsctx , const char *message , JSErrorReport *report ) { fprintf(stderr, "%s:%u:%s\n", report->filename ? report->filename : "", (unsigned int) report->lineno, message); } JSBool execute_script( JSContext *jsctx , char *filename , JSScript **js_script , jsval *rval ) { if (! filename) { return JS_FALSE; } *js_script = JS_CompileFile(jsctx, JS_GetGlobalObject(jsctx), filename); if (! *js_script) { return JS_FALSE; } return JS_ExecuteScript(jsctx, JS_GetGlobalObject(jsctx), *js_script, rval); } int main(int ac, char **av) { int error_flag = 0; JSRuntime *jsrt = NULL; JSContext *jsctx = NULL; JSObject *global = NULL; char *filename = NULL; if (ac < 2) { fprintf(stderr, "%s\n", USAGE); error_flag = 1; goto _FINALLY_; } filename = av[1]; /* 初期化 */ /* プロセス単位でランタイムを生成 */ jsrt = JS_NewRuntime(8L * 1024L * 1024L); if (!jsrt) { fprintf(stderr, "ERROR: JS_NewRuntime "); error_flag = 1; goto _FINALLY_; } /* スレッド単位でコンテクスト生成 */ jsctx = JS_NewContext(jsrt, 8192); if (!jsctx) { fprintf(stderr, "ERROR: JS_NewContext "); error_flag = 1; goto _FINALLY_; } JS_SetOptions(jsctx, JSOPTION_VAROBJFIX); JS_SetVersion(jsctx, JSVERSION_LATEST); JS_SetErrorReporter(jsctx, reportError); /* コンテクスト単位でグローバルオブジェクトを生成 */ global = JS_NewObject(jsctx, &global_class, NULL, NULL); if (!global) { fprintf(stderr, "ERROR: JS_NewObject "); error_flag = 1; goto _FINALLY_; } if (!JS_InitStandardClasses(jsctx, global)) { fprintf(stderr, "ERROR: JS_InitStandardClasses "); error_flag = 1; goto _FINALLY_; } if (!JS_DefineFunctions(jsctx, global, myjs_global_functions)) { fprintf(stderr, "ERROR: JS_DefineFunctions "); error_flag = 1; goto _FINALLY_; } /* スクリプトの実行 */ { JSScript *js_script=NULL; jsval rval; if(execute_script(jsctx, filename, &js_script, &rval)) { JSString *str = JS_ValueToString(jsctx, rval); if (str) { printf("script result: %s\n", JS_GetStringBytes(str)); } } if (js_script) { //JS_MaybeGC(jsctx); JS_DestroyScript(jsctx, js_script); } } _FINALLY_: /* JSContext と JSRuntime リソースの解放 */ if (jsctx) { JS_DestroyContext(jsctx); jsctx = NULL; } if (jsrt) { JS_DestroyRuntime(jsrt); jsrt = NULL; } JS_ShutDown(); if (error_flag) { fprintf(stderr, "failed.\n"); return 1; } /* printf("done.\n"); */ return 0; } /* End of main */