iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
自我挑戰組

C again系列 第 17

VALUE (2)

  • 分享至 

  • xImage
  •  

認為 VALUE 在 function 傳遞參數時大量使用是 YARV 程式不易理解的原因之一。
例如 load_file_internal

static VALUE
load_file_internal(VALUE argp_v)
{
    struct load_file_arg *argp = (struct load_file_arg *)argp_v;
    //...

argp_v 應該要在 function declaration 明確定義型別就好,這裡卻宣告成 VALUE 再 type cast。function return type 也是,看完程式可以知道回傳的是 rb_ast_t* 但也是宣告成 VALUE 然後 return 時多 type cast。

推想這樣實作的原因,看能否幫助理解。看呼叫 load_file_internal 的程式,只有一個地方:

static rb_ast_t *
load_file(VALUE parser, VALUE fname, VALUE f, int script, ruby_cmdline_options_t *opt)
{
    struct load_file_arg arg;
    arg.parser = parser;
    arg.fname = fname;
    arg.script = script;
    arg.opt = opt;
    arg.f = f;
    return (rb_ast_t *)rb_ensure(load_file_internal, (VALUE)&arg,
                              restore_load_file, (VALUE)&arg);
}

在呼叫時並不是直接呼叫,而是將 function pointer 透過 rb_ensure 呼叫,在交給 rb_ensure 時將要傳入的參數都轉型成 VALUE。應該是因為這個需求所以設計了 VALUE 這樣中介的型別。另一個問題是那為什麼不是用 void* 呢?猜測是因為類似 rb_ensure 這樣的 API 除了在 YARV 內部的實作使用之外,可能 ruby 程式經過 parse/compile 之後也會呼叫到,那個場景下傳的參數就會是 Ruby object,有可能出現 FIXNUM 這種不是 pointer 的 object。為了一致性所以傳 VALUE 再於 function 內 cast type。

由此衍生出來的觀察是 YARV 內的 C function 是自己的邏輯與 ruby 程式都會使用到,所以 interface 上使用 VALUE 的設計。這個作法好壞目前還無法判斷。


上一篇
VALUE
下一篇
Ruby code to YARV C code
系列文
C again30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言