sm1.c

最終更新:2009/11/15

sm1.c

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 */
Copyright (C) KAKU PROJECT (2009)KAKU PROJECT (2009)