summaryrefslogtreecommitdiffhomepage
path: root/src/load.c
diff options
context:
space:
mode:
authordearblue <[email protected]>2020-05-24 00:19:04 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2020-10-12 16:21:32 +0900
commita54a3df32c379a6953664f1d9241c731066915ec (patch)
tree37ef8811bfe2aaf8533253f6a1025a35bdc58d4d /src/load.c
parent3ad6bbc40c87f24819c6d8f25446bc74d348c822 (diff)
downloadmruby-a54a3df32c379a6953664f1d9241c731066915ec.tar.gz
mruby-a54a3df32c379a6953664f1d9241c731066915ec.zip
Extended mruby binary format
The catch handler table is combined with iseq block. This is to prevent the structure from growing by adding a field for the catch handler table to the `mrb_irep` structure. "iseq block" and "catch handler table": [number of catch handler table (2 bytes)] [number of byte code (4 bytes)] [iseq (any bytes)] [catch handlers (multiple of 7 bytes)] catch handler: [catch type (1 byte)] [begin offset (2 bytes)] [end offset (2 bytes)] [target offset (2 bytes)] catch type: enum mrb_catch_type (0 = rescue, 1 = ensure) begin offset: Includes the specified instruction address end offset: Does not include the specified instruction address target offset: replaces pc with the specified instruction address This table is not expanded by `read_irep_record_1()`. The necessary elements are expanded one by one when used.
Diffstat (limited to 'src/load.c')
-rw-r--r--src/load.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/load.c b/src/load.c
index 1118fc2ad..59790bc17 100644
--- a/src/load.c
+++ b/src/load.c
@@ -96,27 +96,30 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
src += sizeof(uint16_t);
/* Binary Data Section */
- /* ISEQ BLOCK */
+ /* ISEQ BLOCK (and CATCH HANDLER TABLE BLOCK) */
+ irep->clen = bin_to_uint16(src); /* number of catch handler */
+ src += sizeof(uint16_t);
irep->ilen = (uint16_t)bin_to_uint32(src);
src += sizeof(uint32_t);
src += skip_padding(src);
if (irep->ilen > 0) {
+ size_t data_len = sizeof(mrb_code) * irep->ilen +
+ sizeof(struct mrb_irep_catch_hander) * irep->clen;
+ mrb_static_assert1(sizeof(struct mrb_irep_catch_hander) == 7);
if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) {
return NULL;
}
if ((flags & FLAG_SRC_MALLOC) == 0) {
irep->iseq = (mrb_code*)src;
- src += sizeof(mrb_code) * irep->ilen;
irep->flags |= MRB_ISEQ_NO_FREE;
}
else {
- size_t data_len = sizeof(mrb_code) * irep->ilen;
void *buf = mrb_malloc(mrb, data_len);
irep->iseq = (mrb_code *)buf;
memcpy(buf, src, data_len);
- src += data_len;
}
+ src += data_len;
}
/* POOL BLOCK */