sm2.c

最終更新:2009/11/15

sm2.c

001: /* sm2.c
002:  * SpiderMonkey を C プログラムから使う例
003:  *
004:  * 使い方:コマンドライン引数で JavaScript のファイル名を指定する。
005:  */
006: 
007: #define USAGE "Usage: sm2 <script_file>"
008: 
009: #include <string.h>
010: #include "jsapi.h"
011: 
012: /* グローバルオブジェクトのクラス */
013: static JSClass global_class = {
014:   "global",
015:   JSCLASS_GLOBAL_FLAGS,
016:   JS_PropertyStub,
017:   JS_PropertyStub,
018:   JS_PropertyStub,
019:   JS_PropertyStub,
020:   JS_EnumerateStub,
021:   JS_ResolveStub,
022:   JS_ConvertStub,
023:   JS_FinalizeStub,
024:   JSCLASS_NO_OPTIONAL_MEMBERS
025: };
026: 
027: /*
028:  * 組込み関数の定義
029:  */
030: JSBool myjs_print(
031:   JSContext *jsctx
032:   , JSObject *obj
033:   , uintN argc
034:   , jsval *argv
035:   , jsval *rval
036: ) {
037:   uintN i = 0;
038:   JSString *str = NULL;
039:   char *bytes = NULL;
040: 
041:   for (i = 0; i < argc; i++) {
042:     str = JS_ValueToString(jsctx, argv[i]);
043:     if (!str)
044:       return JS_FALSE;
045:     bytes = JS_EncodeString(jsctx, str);
046:     if (!bytes)
047:       return JS_FALSE;
048:     printf("%s%s", i ? " " : "", bytes);
049:     JS_free(jsctx, bytes);
050:   }
051: 
052:   *rval = JSVAL_VOID;  /* return undefined */
053: 
054:   return JS_TRUE;
055: }
056: 
057: static JSFunctionSpec myjs_global_functions[] = {
058:   JS_FS("print",  myjs_print,  0, 0, 0),
059:   JS_FS_END
060: };
061: 
062: /* エラーレポート用コールバック関数 */
063: void reportError(
064:   JSContext *jsctx
065:   , const char *message
066:   , JSErrorReport *report
067: ) {
068:   fprintf(stderr, "%s:%u:%s\n",
069:     report->filename ? report->filename : "<no filename>",
070:     (unsigned int) report->lineno,
071:     message);
072: }
073: 
074: JSBool execute_script(
075:   JSContext *jsctx
076:   , char *filename
077:   , JSScript **js_script
078:   , jsval *rval
079: ) {
080:   if (! filename) {
081:     return JS_FALSE;
082:   }
083:   *js_script = JS_CompileFile(jsctx, JS_GetGlobalObject(jsctx), filename);
084:   if (! *js_script) {
085:     return JS_FALSE;
086:   }
087:   return JS_ExecuteScript(jsctx, JS_GetGlobalObject(jsctx), *js_script, rval);
088: }
089: 
090: int main(int ac, char **av)
091: {
092:   int error_flag = 0;
093: 
094:   JSRuntime *jsrt = NULL;
095:   JSContext *jsctx = NULL;
096:   JSObject  *global = NULL;
097: 
098:   char *filename = NULL;
099: 
100:   if (ac < 2) {
101:     fprintf(stderr, "%s\n", USAGE);
102:     error_flag = 1;
103:     goto _FINALLY_;
104:   }
105:   filename = av[1];
106: 
107:   /* 初期化 */
108: 
109:   /* プロセス単位でランタイムを生成 */
110:   jsrt = JS_NewRuntime(8L * 1024L * 1024L);
111:   if (!jsrt) {
112:     fprintf(stderr, "ERROR: JS_NewRuntime ");
113:     error_flag = 1;
114:     goto _FINALLY_;
115:   }
116:   
117:   /* スレッド単位でコンテクスト生成 */
118:   jsctx = JS_NewContext(jsrt, 8192);
119:   if (!jsctx) {
120:     fprintf(stderr, "ERROR: JS_NewContext ");
121:     error_flag = 1;
122:     goto _FINALLY_;
123:   }
124:   
125:   JS_SetOptions(jsctx, JSOPTION_VAROBJFIX);
126:   JS_SetVersion(jsctx, JSVERSION_LATEST);
127:   JS_SetErrorReporter(jsctx, reportError);
128:   
129:   /* コンテクスト単位でグローバルオブジェクトを生成 */
130:   global = JS_NewObject(jsctx, &global_class, NULL, NULL);
131:   if (!global) {
132:     fprintf(stderr, "ERROR: JS_NewObject ");
133:     error_flag = 1;
134:     goto _FINALLY_;
135:   }
136:   
137:   if (!JS_InitStandardClasses(jsctx, global)) {
138:     fprintf(stderr, "ERROR: JS_InitStandardClasses ");
139:     error_flag = 1;
140:     goto _FINALLY_;
141:   }
142:   
143:   if (!JS_DefineFunctions(jsctx, global, myjs_global_functions)) {
144:     fprintf(stderr, "ERROR: JS_DefineFunctions ");
145:     error_flag = 1;
146:     goto _FINALLY_;
147:   }
148:   
149:   /* スクリプトの実行 */
150:   {
151:     JSScript *js_script=NULL;
152:     jsval rval;
153:     if(execute_script(jsctx, filename, &js_script, &rval)) {
154:       JSString *str = JS_ValueToString(jsctx, rval);
155:       if (str) {
156:         printf("script result: %s\n", JS_GetStringBytes(str));
157:       }
158:     }
159:     if (js_script) {
160:       //JS_MaybeGC(jsctx);
161:       JS_DestroyScript(jsctx, js_script);
162:     }
163:   }
164:   
165:   _FINALLY_:
166:   
167:   /* JSContext と JSRuntime リソースの解放 */
168:   if (jsctx) {
169:     JS_DestroyContext(jsctx);
170:     jsctx = NULL;
171:   }
172:   if (jsrt) {
173:     JS_DestroyRuntime(jsrt);
174:     jsrt = NULL;
175:   }
176:   
177:   JS_ShutDown();
178:     
179:   if (error_flag) {
180:     fprintf(stderr, "failed.\n");
181:     return 1;
182:   }
183: 
184: /*
185:   printf("done.\n");
186: */
187:   return 0;
188: } /* End of main */
Copyright (C) KAKU PROJECT (2009)KAKU PROJECT (2009)