sm2.c
最終更新:2009/11/15
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 */
![]() | KAKU PROJECT (2009) |