ひとり勉強会

ひとり楽しく勉強会

おまけ:LuLu (1)

読んだコードの確認として、"LuaVM on Lua" 略して "LuLu" を作ってみようと思います。

Luaの字句解析や構文解析から入るのは大変そうなので、まずは、プリコンパイル済みのコードを読み込んで実行するVMを作ります。読み込み分は、lundump.c/lundump.h の luaU_undump関数を参考に実装します。コンパイルはluacコマンドでできます。

luac.outの構造

luacの出力をロードするコードのツリーはこんなんでした。

  • luaU_undump
    • LoadHeader (12バイトのヘッダ情報)
      • [\033]
      • [L]
      • [u]
      • [a]
      • luacのバージョン番号
      • luacの形式番号
      • エンディアン (1ならリトル、0ならビッグ)
      • sizeof(int)
      • sizeof(size_t)
      • sizeof(Instruction)
      • sizeof(lua_Number)
      • lua_Numberが整数型なら1、実数型なら0
    • LoadFunction (トップレベルのスクリプト)
      • LoadString (ソースコード名)
      • LoadInt (開始行番号)
      • LoadInt (終了行番号)
      • LoadByte (UpValueの数)
      • LoadByte (引数の数)
      • LoadByte (可変長引数かどうか?)
      • LoadByte (使用するスタックサイズ)
      • LoadCode (命令列)
        • n = LoadSizeT (命令の個数)
        • n個のInstruction
      • LoadConstants (定数表)
        • n = LoadInt (定数の個数)
        • n個のNil/Boolean/Number/String
        • m = LoadInt (関数内関数の個数)
        • m個のLoadFunction
      • LoadDebug (デバッグ情報)
        • 色々(詳細略)

あとはこれをそのままLuaに移植するだけです。とりあえず、TValue はそのままLuaの値で表現することにしました。(Functionについては後で考えなおすかも。)手抜きなのでsizeof(int)==sizeof(size_t)==4、sizeof(lua_Number==double)==8、リトルエンディアン前提です。

今のソースコード

実は10行以上のLuaのコード書くのこれが始めてです。変なことしてたらすみません。ビット演算が無いみたいだったので無駄に苦労してます。もっとちゃんとした方法あるのかな・・・。