Open3

Ribbon: FFIに対応する^2

okuokuokuoku

これガチのマジで面倒だな。。

とりあえず、ライブラリ情報のポインタを拾ってくるところまでは実装した。一旦遅延解決、動的bindingで実装する方向で行こう。。

ライブラリ (yuni compat nccc) を追加した。Ribbonはバイトコードコンパイラの都合で全てのプリミティブはbootstrap時に使用されていなければならないので、とりあえず (rvm-primitives) ライブラリにもダミーのexportを追加している。

https://github.com/okuoku/yuniribbit-proto/commit/dfa3b49efe6a8fef9aa339f2250a7b771862442a

okuokuokuoku

長さの無いbytevector

Ribbonでは有限長のbytevectorに加えて無限長のbytevectorを扱えるようにしてみた。 ...が、ちょっとバグってたので直した。

https://github.com/okuoku/ribbon/commit/8621a93786f4b82096972289a465beac4703d322

Ribbonは一度確保したbytevectorのアドレスが変化しないことが保証されているので、このような無限長のbytevectorを仮定できると、任意のポインタをbytevectorと見做せる。

他所のScheme処理系ではあんまり一般的でない概念なので、どこかのタイミングで変えちゃうかもしれない。。

ここまでの対応で、とりあえず NCCC の関数をlookupして呼ぶところまではできた。

okuokuokuoku

とりあえず呼べるようになった

(import (yuni scheme) (yuni nccc core))

(nccc-init-embedded-bundle!)

(let ((miniio_ioctx_create (nccc-lookup 'miniio 'miniio_ioctx_create))
      (miniio_ioctx_process (nccc-lookup 'miniio 'miniio_ioctx_process))
      (miniio_timer_create (nccc-lookup 'miniio 'miniio_timer_create))
      (miniio_timer_start (nccc-lookup 'miniio 'miniio_timer_start))
      (miniio_get_events (nccc-lookup 'miniio 'miniio_get_events)))

  (let* ((ctx (miniio_ioctx_create))
         (timer (miniio_timer_create ctx 1))
         (r (miniio_timer_start ctx timer 1000 2000))
         (evtbuf (make-bytevector (* 8 128)))
         (buf-writecnt (make-bytevector 4))
         (buf-currentcnt (make-bytevector 4)))
   (write ctx) (newline)
   (unless (= r 0)
     (error "Couldn't start timer" r))

   (let loop ()
    (let ((r (miniio_ioctx_process ctx)))
     (write (list 'PROCESS: r)) (newline))
    (let ((r (miniio_get_events ctx (bytevector->address evtbuf) 128
                                (bytevector->address buf-writecnt)
                                (bytevector->address buf-currentcnt))))
      (let ((written (bv-ref/u32 buf-writecnt 0))
            (current (bv-ref/u32 buf-currentcnt 0)))
        (write (list 'EVENT: r written current)) (newline)
        (loop))))))

(exit 0)

... う〜ん。。

  • たぶんFFIのlookupはSchemeシンボルじゃなくて文字列の方が良いんじゃないかという気はする。。内部的には文字列のハッシュテーブルで持って、lookupのAPIで適宜変換するのが良いかな。
  • address は微妙なのでやっぱり pointer に戻したい
  • bytevector のアドレスを取得できることを前提にするのはやっぱりよくないので、やっぱり抽象化した pointer オブジェクトを用意することにしたい

bytevectorのアドレスを 取得できない 処理系というのが存在する可能性がある。要はGCでオブジェクトを移動する可能性がある処理系が該当する。