sm1.c
最終更新:2009/11/15
001: /* sm1.c 002: * SpiderMonkey を C プログラムから使う例 003: * 004: * 使い方:コマンドライン引数で JavaScript のコードを指定する。 005: * % sm1 "function f(x){if(x<=0){return 1;}else{return x*f(x-1);}};f(5)" 006: * script result: 120 007: * done. 008: */ 009: 010: #define USAGE "Usage: sm1 <script>" 011: 012: #include <string.h> 013: #include "jsapi.h" 014: 015: /* グローバルオブジェクトのクラス */ 016: static JSClass global_class = { 017: "global", 018: JSCLASS_GLOBAL_FLAGS, 019: JS_PropertyStub, 020: JS_PropertyStub, 021: JS_PropertyStub, 022: JS_PropertyStub, 023: JS_EnumerateStub, 024: JS_ResolveStub, 025: JS_ConvertStub, 026: JS_FinalizeStub, 027: JSCLASS_NO_OPTIONAL_MEMBERS 028: }; 029: 030: /* エラーレポート用コールバック関数 */ 031: void reportError( 032: JSContext *jsctx 033: , const char *message 034: , JSErrorReport *report 035: ) { 036: fprintf(stderr, "%s:%u:%s\n", 037: report->filename ? report->filename : "<no filename>", 038: (unsigned int) report->lineno, 039: message); 040: } 041: 042: int main(int ac, char **av) 043: { 044: int error_flag = 0; 045: 046: JSRuntime *jsrt = NULL; 047: JSContext *jsctx = NULL; 048: JSObject *global = NULL; 049: 050: char *script = NULL; 051: 052: if (ac < 2) { 053: fprintf(stderr, "%s\n", USAGE); 054: error_flag = 1; 055: goto _FINALLY_; 056: } 057: script = av[1]; 058: 059: /* 初期化 */ 060: 061: /* プロセス単位でランタイムを生成 */ 062: jsrt = JS_NewRuntime(8L * 1024L * 1024L); 063: if (!jsrt) { 064: fprintf(stderr, "ERROR: JS_NewRuntime "); 065: error_flag = 1; 066: goto _FINALLY_; 067: } 068: 069: /* スレッド単位でコンテクスト生成 */ 070: jsctx = JS_NewContext(jsrt, 8192); 071: if (!jsctx) { 072: fprintf(stderr, "ERROR: JS_NewContext "); 073: error_flag = 1; 074: goto _FINALLY_; 075: } 076: 077: JS_SetOptions(jsctx, JSOPTION_VAROBJFIX); 078: JS_SetVersion(jsctx, JSVERSION_LATEST); 079: JS_SetErrorReporter(jsctx, reportError); 080: 081: /* コンテクスト単位でグローバルオブジェクトを生成 */ 082: global = JS_NewObject(jsctx, &global_class, NULL, NULL); 083: if (!global) { 084: fprintf(stderr, "ERROR: JS_NewObject "); 085: error_flag = 1; 086: goto _FINALLY_; 087: } 088: 089: if (!JS_InitStandardClasses(jsctx, global)) { 090: fprintf(stderr, "ERROR: JS_InitStandardClasses "); 091: error_flag = 1; 092: goto _FINALLY_; 093: } 094: 095: /* スクリプトの実行 */ 096: 097: if (script) { 098: jsval rval; 099: JSBool ok = JS_EvaluateScript(jsctx, global, script, strlen(script), 100: __FILE__, __LINE__, &rval); 101: if (ok != JS_TRUE) { 102: error_flag = 1; 103: goto _FINALLY_; 104: } 105: { 106: JSString *str = JS_ValueToString(jsctx, rval); 107: if (str) { 108: printf("script result: %s\n", JS_GetStringBytes(str)); 109: } 110: } 111: } 112: 113: _FINALLY_: 114: 115: /* JSContext と JSRuntime リソースの解放 */ 116: if (jsctx) { 117: JS_DestroyContext(jsctx); 118: jsctx = NULL; 119: } 120: if (jsrt) { 121: JS_DestroyRuntime(jsrt); 122: jsrt = NULL; 123: } 124: 125: JS_ShutDown(); 126: 127: if (error_flag) { 128: fprintf(stderr, "failed.\n"); 129: return 1; 130: } 131: 132: printf("done.\n"); 133: return 0; 134: } /* End of main */
KAKU PROJECT (2009) |