OSDN Git Service

Major change; Object oriented re-design, re-structure.
[localjavascript/localJS-dev.git] / interpreter.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #define ARG_ERR_MSG "Wrong argument. Aborting…\n"
5
6 #include <JavascriptCore/JavascriptCore.h>//-framework JavaScriptCoreオプションを使用の事
7
8 extern void functionLoader(JSGlobalContextRef ctx, JSObjectRef jobjGlobal);
9 void classWrapper(JSGlobalContextRef ctx, JSObjectRef jobjGlobal, char* name, JSObjectRef* classObject);
10 void functionWrapper(JSGlobalContextRef ctx, JSObjectRef parentObj, char* name, JSObjectCallAsFunctionCallback jsGlobalFunction);
11
12 int interpreter(char* code)
13 {
14 #ifdef DEBUG
15     printf("JavaScript interpreter has been started.\n");
16 #endif
17         
18 #ifdef DEBUG
19     printf("Creating Global context..");
20 #endif
21         
22     JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);
23         
24 #ifdef DEBUG
25     printf("Done!\n");
26 #endif
27         
28     // グローバル実行コンテキストが持つグローバルオブジェクトを取得する
29     // ブラウザでいうところの window オブジェクトのようなもの
30     JSObjectRef jobjGlobal = JSContextGetGlobalObject(ctx);
31         
32     functionLoader(ctx, jobjGlobal);
33         
34     // JavaScript のソースを JS の文字列にする
35     JSStringRef jstrSource = JSStringCreateWithUTF8CString(code);
36         
37 #ifdef DEBUG
38     printf("JavaScript source is now ready to execute. Starting ..\n\n");
39 #endif
40         
41     // 実行、 this を NULL とするとグローバルオブジェクトが this になるらしい
42     JSEvaluateScript(ctx, jstrSource, NULL, NULL, 1, NULL); 
43     // 文字列のリファレンスカウンタをデクリメント
44     JSStringRelease(jstrSource);
45         
46 #ifdef DEBUG
47     printf("Script execution has came to the end. Terminating JavaScript instance ..\n");
48 #endif
49         
50     // 解放許可?
51     JSGlobalContextRelease(ctx);
52     // 解放実行?EXC_BAD_ACCESSが来る。
53     //JSGarbageCollect(ctx);
54     return 0;
55         
56 }
57
58 void classWrapper(JSGlobalContextRef ctx, JSObjectRef jobjGlobal, char* name, JSObjectRef* classObject)
59 {
60         //クラスの定義を保持する変数を作成
61         JSClassDefinition classDefinition       = kJSClassDefinitionEmpty;
62         //クラス型の変数を作成
63         JSClassRef classSubstance;
64         //クラスの名前を決定
65         classDefinition.className = name;
66         // プロトタイプ は 手動 で作成という事にする
67         classDefinition.attributes = kJSClassAttributeNoAutomaticPrototype; 
68         //クラス型を作成
69         classSubstance = JSClassCreate(&classDefinition);
70         //クラスをオブジェクト化
71         *classObject = JSObjectMakeConstructor(ctx, classSubstance, NULL);
72         //プロトタイプ継承
73         JSObjectSetPrototype(ctx, *classObject, JSObjectGetPrototype(ctx, jobjGlobal));
74         //クラスを持ったオブジェクトの名前を作る
75         JSStringRef jstr = JSStringCreateWithUTF8CString(name);
76         //クラスのオブジェクトをCTXに公開
77         JSObjectSetProperty(ctx, jobjGlobal, jstr, *classObject, kJSPropertyAttributeNone, NULL);
78         // 文字列のリファレンスカウンタをデクリメント
79     JSStringRelease(jstr);
80 }
81
82 void functionWrapper(JSGlobalContextRef ctx, JSObjectRef parentObj, char* name, JSObjectCallAsFunctionCallback jsGlobalFunction)
83 {
84     // JavaScript で扱える文字列を作る
85     JSStringRef jstr = JSStringCreateWithUTF8CString(name);
86     // C の関数を JS の関数オブジェクトにする
87     JSObjectRef jfunc = JSObjectMakeFunctionWithCallback(ctx, jstr, jsGlobalFunction);
88         //プロトタイプ継承
89         JSObjectSetPrototype(ctx, jfunc, JSObjectGetPrototype(ctx, parentObj));
90     // オブジェクトのPrototypeのプロパティとして追加
91     JSObjectSetProperty(ctx, JSObjectGetPrototype(ctx, parentObj), jstr, jfunc, kJSPropertyAttributeNone, NULL);
92     // 文字列のリファレンスカウンタをデクリメント
93     JSStringRelease(jstr);
94 }