IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

JavaScriptCore を自分でビルドして、遊んでみる

http://d.hatena.ne.jp/amachang/20080610/1213099780 の続きです。

どうせなら

JavaScriptCore も自分でビルドしようぜ!ってことで

JavaScriptCore のソースを持ってくる

$ svn co http://svn.webkit.org/repository/webkit/trunk/JavaScriptCore/
A    JavaScriptCore/os-win32
A    JavaScriptCore/os-win32/stdint.h
A    JavaScriptCore/os-win32/stdbool.h
A    JavaScriptCore/profiler
A    JavaScriptCore/profiler/Profile.cpp
A    JavaScriptCore/profiler/Profiler.cpp
A    JavaScriptCore/profiler/Profile.h
A    JavaScriptCore/profiler/ProfileNode.cpp
A    JavaScriptCore/profiler/Profiler.h
A    JavaScriptCore/profiler/ProfileNode.h
A    JavaScriptCore/JavaScriptCorePrefix.h
A    JavaScriptCore/GNUmakefile.am
A    JavaScriptCore/AUTHORS
A    JavaScriptCore/kjs
:
約 5 分くらいかかる
:
$

ビルド

xcodebuild というコマンドラインツールがちょー便利
XcodeGUI でやらなくてもいい!

$ cd JavaScriptCore
$ xcodebuild -list
Information about project "JavaScriptCore":
    Targets:
        All (Active)
        JavaScriptCore
        Derived Sources
        minidom
        testapi
        testkjs

    Build Configurations:
        Debug
        Release
        Production (Active)

    If no build configuration is specified "Production" is used.
$ xcodebuild -target JavaScriptCore -configuration Debug
:
ダーっと処理が進む
:
すっごい CPU 負荷かかる(2 分くらい)
:
** BUILD SUCCEEDED **
$ 

さっきのエントリーhoge.c にこっちの JavaScriptCore を使ってみる

「-F」で -framework で探索するディレクトリを指定できるみたい。

$ cd ..
$ gcc hoge.c -FJavaScriptCore/build/Debug -framework JavaScriptCore
$

a.out を実行

えいや!

$ ./a.out "print('hoge')"
ASSERTION FAILED: startingLineNumber > 0
(/Users/amachang/Desktop/JavaScriptCore/kjs/Parser.cpp:66 void KJS::Parser::parse(KJS::ExecState*, const KJS::UString&, int, WTF::PassRefPtr<KJS::SourceProvider>, int*, int*, KJS::UString*))
Segmentation fault
$ 

あうあう><セグフォでたよ><

ASSERT 出てる kjs/Parser.cpp 66 行目を見てみる

    
    // ココ!
    ASSERT(startingLineNumber > 0);
    if (startingLineNumber <= 0)
        startingLineNumber = 1;
    

startingLineNumber。。。

ぴこーん!(電球 )

そういえば hoge.c で JSEvaluateScript するとき。。。

    JSEvaluateScript(
        ctx,
        jstrSource,
        NULL,
        NULL,
        0,                // ←こいつだ!
        NULL);

0 行目から開始ってしてたのがダメみたい><
1 行目から数えるのか!

    JSEvaluateScript(
        ctx,
        jstrSource,
        NULL,
        NULL,
        1,                // ←直してみた
        NULL);

もっかいコンパイル

$ gcc hoge.c -FJavaScriptCore/build/Debug -framework JavaScriptCore
$

ドキドキ

$ ./a.out "print('hoge')"
hoge
$ 

おおおおお!うごいた!

デバッガで追えるかな?

「-g -O0」でコンパイル

$ gcc -g -O0 hoge.c -FJavaScriptCore/build/Debug -framework JavaScriptCore
$
$ gdb a.out

(gdb) b main 
Breakpoint 1 at 0x1e5f: file hoge.c, line 13.
(gdb) r "print('hoge')"
Starting program: /Users/amachang/Desktop/a.out "print('hoge')"
Reading symbols for shared libraries +++......................... done
Reading symbols for shared libraries . done

Breakpoint 1, main (argc=2, argv=0xbffff974) at hoge.c:13
13	    if (argc == 1) exit(0);
(gdb) n
17	    JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);
(gdb) s
JSGlobalContextCreate (globalObjectClass=0x0) at /Users/amachang/Desktop/JavaScriptCore/API/JSContextRef.cpp:42
42	    initializeThreading();
(gdb) n
Current language:  auto; currently c++
44	    JSLock lock;
(gdb) 
46	    if (!globalObjectClass) {
(gdb) 
47	        JSGlobalObject* globalObject = new JSGlobalObject;
(gdb) 
48	        return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
(gdb) 
58	}
(gdb) 
main (argc=2, argv=0xbffff974) at hoge.c:20
20	    JSObjectRef jobjGlobal = JSContextGetGlobalObject(ctx);
(gdb) 
Current language:  auto; currently c
24	    JSStringRef jstrPrint = JSStringCreateWithUTF8CString("print");
(gdb) 

おおおお!なんか JavaScriptCore の中のコードが読めて楽しい!

という訳で

id:hyoshiok さんのプログラミングキャンプでの講義「コードリーディング」にご期待ください(嘘)
というのは冗談です><
でも、 JavaScript の中のソースコードをこうやってちょっとずつ読んでみるのは楽しいです。
ドラクエとかで、初めて洞窟に入ったときのあの感覚ですね。