<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢(mèng)蝶

    生活、程序、未來(lái)
       :: 首頁(yè) ::  ::  :: 聚合  :: 管理

    XRuby是什么?它是一個(gè)編譯器。與其它編譯器一樣,它完成的工作是將一種格式的語(yǔ)言轉(zhuǎn)換成另一種。與大多數(shù)編譯器不同的是,它是將Ruby的代碼(.rb)轉(zhuǎn)換成Java的bytecode(.class)。

    Xruby是一群中國(guó)開(kāi)發(fā)者維護(hù)的項(xiàng)目,它的目的如上所述。它的主頁(yè)是http://code.google.com/p/xruby/。與JRuby不同,JRuby一開(kāi)始是想使用java寫ruby解析器,性能上是個(gè)大問(wèn)題,當(dāng)然現(xiàn)在也走上了編譯這條路。而XRuby是第一個(gè)實(shí)現(xiàn)這種想法的人。

    我翻譯下了《XRuby Hacking Guide》,這篇文章是XRuby的入門指南。

    介紹

    這篇文章是為了幫助用戶/開(kāi)發(fā)者理解xruby的內(nèi)部結(jié)構(gòu)而寫的。

    如何編譯ruby?

    怎么將ruby編譯成java字節(jié)碼呢?首先,你不必成為一名字節(jié)碼方面的專家來(lái)考慮這個(gè)問(wèn)題,Java的字節(jié)碼是對(duì)原生機(jī)器語(yǔ)言的較高層次的抽象,非常類似于java源代碼。你可以簡(jiǎn)化這個(gè)問(wèn)題為:如何用java表示一段ruby程序?

    這兩門語(yǔ)言有很多的相同之處:ruby是一門OO語(yǔ)言,它有類、方法、變量等,java也是如此。這是否意味著我們可以將一個(gè)ruby類類比為java類,ruby方法作為java方法?可是,除了這些相同之處外,它們之間有足夠的不同點(diǎn)讓你打消這個(gè)主意:首先,ruby是一門動(dòng)態(tài)類型語(yǔ)言,因此一個(gè)方法可以接受不同類型的參數(shù),而在java中,參數(shù)類型是方法簽名(signature)的一部分。其次,在ruby中,方法可以從一個(gè)類中動(dòng)態(tài)地添加和移除;但是目前的JVM并不支持這樣的行為。值的注意的上述的這些問(wèn)題也許會(huì)在將來(lái)的JVM版本中解決,請(qǐng)參考Gilad Bracha's work at JSR 292.

    第一個(gè)辦法是我們自己維護(hù)一個(gè)類型系統(tǒng),這正是xruby目前采用的辦法(Ruby.net好像也是如此)。從JVM的角度看,一個(gè)ruby類只是一個(gè)Object,這個(gè)Object中包含著代表方法等的其他object。我們將在后面更多討論這點(diǎn)。

    另一個(gè)辦法是動(dòng)態(tài)地編譯(ruby)源代碼,在運(yùn)行時(shí)獲得類型信息,將源代碼編譯成高效的代碼(字節(jié)碼?)是可能的。(一些方法由于duct typeing的特性將被編譯成好幾個(gè)版本)

    我們將比較這兩個(gè)辦法,

    實(shí)例

    通過(guò)一個(gè)例子來(lái)了解xruby:
    def?say_hello_three_times
    ????
    3.times?{puts?'hello'}
    end

    say_hello_three_times

    將上面的代碼存為test.rb,使用xruby編譯(下載的xruby解壓后運(yùn)行build.bat或者build.sh生成xruby-0.1.3.jar):
    java?-jar?xruby-0.1.3.jar?-c?test.rb

    可以看到生成了一個(gè)test.jar文件,執(zhí)行下面的命令來(lái)運(yùn)行這個(gè)程序:
    java?-jar?test.jar

    當(dāng)然,你將看到下面的輸出:

    hello
    hello
    hello
    如果你查看test.jar文件,你將看到以下3個(gè)class文件:
  • test/BLOCK$1.class
  • test/say_hello_three_times$0.class
  • test/main.class
    這些class文件等價(jià)于下面這段java程序:
    //test/main.class
    public?class?main
    ????
    implements?RubyProgram
    {

    ????
    public?main()
    ????{
    ????}

    ????
    public?static?void?main(String?args[])
    ????{
    ????????RubyRuntime.init(args);
    ????????(
    new?main()).run();
    ????????RubyRuntime.fini();
    ????}

    ????
    public?RubyValue?run()
    ????{
    ????????RubyRuntime.ObjectClass.defineMethod(
    "say_hello_three_times",?new?say_hello_three_times._cls0());
    ????????
    return?RubyRuntime.callMethod(ObjectFactory.topLevelSelfValue,?null,?null,?"say_hello_three_times");
    ????}
    }


    //say_hello_three_times$0.class
    class?say_hello_three_times$0?extends?RubyMethod
    {

    ????
    protected?RubyValue?run(RubyValue?rubyvalue,?RubyArray?arrayvalue,?RubyBlock?rubyblock)
    ????{
    ????????
    return?RubyRuntime.callPublicMethod(ObjectFactory.createFixnum(3),?null,?new?BLOCK._cls1(),?"times");
    ????}

    ????
    public?say_hello_three_times$0()
    ????{
    ????????
    super(0,?false);
    ????}
    }


    //test/BLOCK$1.class
    class?BLOCK$1?extends?RubyBlock
    {

    ????
    protected?RubyValue?run(RubyValue?rubyvalue,?RubyArray?arrayvalue)
    ????{
    ????????RubyArray?arrayvalue1?
    =?new?RubyArray(1);
    ????????arrayvalue1.add(ObjectFactory.createString(
    "hello"));
    ????????
    return?RubyRuntime.callMethod(rubyvalue,?arrayvalue1,?null,?"puts");
    ????}

    ????
    public?BLOCK$1()
    ????{
    ????????
    super(0,?false);
    ????}
    }

    在main類中:首先在"Object"類中定義了一個(gè)私有的方法"say_hello_three_times",然后通過(guò)no parameter, no block和一個(gè)top level "self"作為接收者的方式調(diào)用這個(gè)方法。

    "say_hello_three_times$0"類表示say_hello_three_times方法的實(shí)現(xiàn)(參考command模式)。在代碼中,我們可以看到Fixnum"3"(接收者)調(diào)用了"timer"這個(gè)方法,仍然沒(méi)有parameter,但是有一個(gè)block被傳進(jìn)去(方法)。

    BLOCK$1類則表示傳進(jìn)"3.times"方法中的block,代碼中是"puts 'hello'"的實(shí)現(xiàn)。

    源碼結(jié)構(gòu)

    • com.xruby.compiler.parser 提供了一個(gè)compiler前端(parser and tree parser)。 Parser轉(zhuǎn)換ruby腳本成AST (Abstract Syntax Tree),然后 tree parser將AST轉(zhuǎn)換為內(nèi)部結(jié)構(gòu)(internal structure)。
      編譯器前端使用 Antlr 作為語(yǔ)法分析器的生成器.實(shí)踐證明,將這個(gè)前端分為兩部分可以帶來(lái)好處:parser 和 tree parser;其中 parser 解析腳本,而tree parser生成內(nèi)部結(jié)構(gòu)(internal structure)。
    • com.xruby.compiler.codedom 定義了描述ruby腳本結(jié)構(gòu)的內(nèi)部結(jié)構(gòu)(internal structure)。內(nèi)部結(jié)構(gòu)作為前端和后端的接口,對(duì)于xruby是非常重要的。
    • com.xruby.compiler.codegen 實(shí)現(xiàn)了編譯器的后端(代碼生成)。后端將前端生成的內(nèi)部結(jié)構(gòu)轉(zhuǎn)換為java字節(jié)碼。代碼生成是通過(guò)ASM實(shí)現(xiàn)的,ASM簡(jiǎn)化了對(duì)字節(jié)碼的操作。
    • com.xruby.runtime 實(shí)現(xiàn)了xruby運(yùn)行時(shí)(runtime),它維護(hù)著運(yùn)行ruby腳本必需的類型系統(tǒng), com.xruby.runtime.lang 描述了ruby類型的運(yùn)行時(shí)結(jié)構(gòu),一些ruby內(nèi)建標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)在 com.xruby.runtime.builtin.

    內(nèi)建庫(kù)

    通往xuby hacking之路最簡(jiǎn)便的辦法就是學(xué)習(xí) 'com.xruby.runtime.builtin'包的源代碼。

    下面是來(lái)自Fixnum::+方法實(shí)現(xiàn)的代碼片段:

    class?Fixnum_operator_plus?extends?RubyMethod?{
    ????
    public?Fixnum_operator_plus()?{
    ????????
    super(1);
    ????}

    ????
    protected?RubyValue?run(RubyValue?receiver,?RubyArray?args,?RubyBlock?block)?{
    ????????RubyFixnum?value1?
    =?(RubyFixnum)receiver.getValue();
    ????????RubyFixnum?value2?
    =?(RubyFixnum)args.get(0).getValue();
    ????????
    return?ObjectFactory.createFixnum(value1.intValue()?+?value2.intValue());
    ????}
    }


    RubyClass?c?
    =?RubyRuntime.GlobalScope.defineNewClass("Fixnum",?RubyRuntime.IntegerClass);
    c.defineMethod(
    "+",?new?Fixnum_operator_plus());

    XRuby的語(yǔ)法解析器

    Xruby的解析器使用 Antlr 作為解析器的生成器。 這是目前相比于c ruby唯一另類的ruby語(yǔ)法。

    對(duì)于大部分編程語(yǔ)言來(lái)說(shuō),詞法分析(lexing)和語(yǔ)法解析是兩個(gè)不同的步驟:首先詞法分析器將輸入的字符組織成單詞(token),然后解析器將單詞組織成句法單元。但是在ruby(和perl語(yǔ)言)中,詞法分析器和語(yǔ)法解析器是緊緊地耦合在一起的:有時(shí)候詞法分析器需要從語(yǔ)法分析器中獲取上下文信息。

    疑難解決

    作為Xruby的開(kāi)發(fā)者,我們的任何改變都可能導(dǎo)致編譯器出錯(cuò)并且生成有問(wèn)題的字節(jié)碼。當(dāng)這種情況發(fā)生時(shí),我們可以依賴3樣工具:javap,ASM和你所喜歡的java反編譯器(比如jad

    如果生成的class文件格式正確但是運(yùn)行結(jié)果不是預(yù)期的,我們可以簡(jiǎn)單地使用反編譯工具將字節(jié)碼轉(zhuǎn)換成可讀的java源代碼,以便查找錯(cuò)誤。

    如果你遇到是一個(gè)verifier error,大部分的反編譯器都不能正常工作(jad在這種情況也許會(huì)crash掉)。我們不得不使用javap來(lái)研讀字節(jié)碼。多數(shù)情況下,JVM class驗(yàn)證器(verifier)給出的信息沒(méi)什么用處,但是我們可以通過(guò)ASM更快地找到錯(cuò)誤發(fā)生點(diǎn)。(see ASM FAQ: Why do I get the [xxx] verifier error?).


  • 主站蜘蛛池模板: 最近免费中文字幕大全免费版视频| 久草免费手机视频| 国产成人久久AV免费| 黄色网址免费大全| 亚洲av无码天堂一区二区三区| 无码乱人伦一区二区亚洲| 亚洲精品无码久久久久久| a视频在线免费观看| 大学生一级特黄的免费大片视频| 国产亚洲人成网站在线观看| 亚洲影视自拍揄拍愉拍| 一日本道a高清免费播放| 97人妻无码一区二区精品免费| 亚洲国产精品自在拍在线播放| 亚洲福利电影一区二区?| 人妻免费久久久久久久了| 精品国产污污免费网站aⅴ| 亚洲国产黄在线观看| 亚洲人成7777影视在线观看| 国产男女爽爽爽免费视频| 成年人在线免费观看| 久久久久亚洲av无码尤物| 亚洲AV无码一区二区大桥未久| 999久久久免费精品播放| 亚洲第一网站男人都懂| 亚洲国产最大av| 久久久久久AV无码免费网站下载| 啊灬啊灬别停啊灬用力啊免费看| 亚洲精品国产成人中文| 中文字幕无线码免费人妻| 在线观看亚洲免费| 亚洲明星合成图综合区在线| 中国一级全黄的免费观看| 国产资源免费观看| 亚洲国产综合精品| 国内精品免费视频精选在线观看 | 5g影院5g天天爽永久免费影院| 亚洲性日韩精品一区二区三区| 亚洲人成色777777老人头| 亚洲精品在线免费观看视频| 亚洲AV无码国产丝袜在线观看|