一往確認日記 |
2021年01月15日 [長年日記]
_ PLCでmruby (7) irep_header
前回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のバージョンは多分ここを調べれば良いことが分かりました。