«前の日(01-14) 最新 次の日(01-16)» 追記

一往確認日記


2021年01月15日

_ PLCでmruby (7) irep_header

mrubyをPLCで動かせないかな〜という企画です。

前回rite_binary_headerについて調べました。
その次は何になるのか?ということです。

手がかりはdump.cのdump_irep関数です。

この中でバイナリーのサイズを計算しているところがあるのですが、rite_binary_headerの次はどうやらirepセクション、linenoセクション、lvセクション、rite_binary_footerと続くようです。

  *bin_size = sizeof(struct rite_binary_header) +
              section_irep_size + section_lineno_size + section_lv_size +
              sizeof(struct rite_binary_footer);

irepセクションの手がかりはsection_irep_sizeを計算しているところで、

  section_irep_size = sizeof(struct rite_section_irep_header);
  section_irep_size += get_irep_record_size(mrb, irep);

まずはrite_section_irep_headerがあることがわかりました。
恐らくrite_section_irep_headerは子ノードがあるので再起的にサイズを計算しているのがget_irep_record_sizeではないかと思います。

それではrite_section_irep_headerについて調べます。
dump.hに定義があります。

struct rite_section_irep_header {
  RITE_SECTION_HEADER;

  uint8_t rite_version[4];    /* Rite Instruction Specification Version */
};

RITE_SECTION_HEADERはマクロになっているので、展開するとこの様になります。

struct rite_section_irep_header {
  uint8_t section_ident[4];
  uint8_t section_size[4];

  uint8_t rite_version[4];    /* Rite Instruction Specification Version */
};

Rubyで確認するコードを書きます。

# read binary codes
codes = File.read "a.mrb"

# read rite_section_irep_header
size_of_rite_binary_header = 22
section_top = size_of_rite_binary_header
section_ident = codes[section_top + 0, 4]
section_size = codes[section_top + 4, 4].unpack("N").first
rite_version = codes[section_top + 8, 4]

pp section_ident: section_ident, section_size: section_size, rite_version: rite_version

結果はこのようになります。

{:section_ident=>"IREP",
 :section_size=>38,
 :rite_version=>"0300"}

IREPというIDがあり、サイズは38でバージョンは300となっています。 300は多分mruby 3.0を示していると思われます。
mrubyのバージョンは多分ここを調べれば良いことが分かりました。

つづく