ruby-changes:50906
From: nobu <ko1@a...>
Date: Sun, 8 Apr 2018 14:22:54 +0900 (JST)
Subject: [ruby-changes:50906] nobu:r63113 (trunk): compile.c: align IBF dumped data
nobu 2018-04-08 14:22:49 +0900 (Sun, 08 Apr 2018) New Revision: 63113 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=63113 Log: compile.c: align IBF dumped data Modified files: trunk/compile.c trunk/test/ruby/test_iseq.rb Index: compile.c =================================================================== --- compile.c (revision 63112) +++ compile.c (revision 63113) @@ -8272,7 +8272,9 @@ ibf_load_alloc(const struct ibf_load *lo https://github.com/ruby/ruby/blob/trunk/compile.c#L8272 return buff; } -#define IBF_W(b, type, n) (type *)(VALUE)ibf_dump_write(dump, (b), sizeof(type) * (n)) +#define IBF_W_ALIGN(type) (RUBY_ALIGNOF(type) > 1 ? ibf_dump_align(dump, RUBY_ALIGNOF(type)) : (void)0) + +#define IBF_W(b, type, n) (IBF_W_ALIGN(type), (type *)(VALUE)IBF_WP(b, type, n)) #define IBF_WV(variable) ibf_dump_write(dump, &(variable), sizeof(variable)) #define IBF_WP(b, type, n) ibf_dump_write(dump, (b), sizeof(type) * (n)) #define IBF_R(val, type, n) (type *)ibf_load_alloc(load, IBF_OFFSET(val), sizeof(type) * (n)) @@ -8798,7 +8800,8 @@ ibf_dump_iseq_each(struct ibf_dump *dump https://github.com/ruby/ruby/blob/trunk/compile.c#L8800 dump_body.variable.coverage = Qnil; dump_body.variable.original_iseq = Qnil; - return ibf_dump_write(dump, &dump_body, sizeof(dump_body)); + IBF_W_ALIGN(struct rb_iseq_constant_body); + return IBF_WV(dump_body); } static VALUE @@ -9009,7 +9012,10 @@ struct ibf_object_symbol { https://github.com/ruby/ruby/blob/trunk/compile.c#L9012 }; #define IBF_OBJHEADER(offset) (struct ibf_object_header *)(load->buff + (offset)) -#define IBF_OBJBODY(type, offset) (type *)(load->buff + sizeof(struct ibf_object_header) + (offset)) +#define IBF_OBJBODY(type, offset) (type *)(load->buff + IBF_OBJALIGNED(type, offset)) +#define IBF_OBJALIGNED(type, offset) \ + (((sizeof(struct ibf_object_header) + (offset) - 1) / RUBY_ALIGNOF(type) + 1) * \ + RUBY_ALIGNOF(type)) NORETURN(static void ibf_dump_object_unsupported(struct ibf_dump *dump, VALUE obj)); @@ -9071,7 +9077,7 @@ static void https://github.com/ruby/ruby/blob/trunk/compile.c#L9077 ibf_dump_object_float(struct ibf_dump *dump, VALUE obj) { double dbl = RFLOAT_VALUE(obj); - ibf_dump_write(dump, &dbl, sizeof(dbl)); + IBF_W(&dbl, double, 1); } static VALUE @@ -9087,6 +9093,7 @@ ibf_dump_object_string(struct ibf_dump * https://github.com/ruby/ruby/blob/trunk/compile.c#L9093 long encindex = (long)rb_enc_get_index(obj); long len = RSTRING_LEN(obj); const char *ptr = RSTRING_PTR(obj); + long buff[2]; if (encindex > RUBY_ENCINDEX_BUILTIN_MAX) { rb_encoding *enc = rb_enc_from_index((int)encindex); @@ -9094,8 +9101,9 @@ ibf_dump_object_string(struct ibf_dump * https://github.com/ruby/ruby/blob/trunk/compile.c#L9101 encindex = RUBY_ENCINDEX_BUILTIN_MAX + ibf_dump_object(dump, rb_str_new2(enc_name)); } - IBF_WV(encindex); - IBF_WV(len); + buff[0] = encindex; + buff[1] = len; + IBF_W(buff, long, 2); IBF_WP(ptr, char, len); } @@ -9126,7 +9134,7 @@ ibf_dump_object_regexp(struct ibf_dump * https://github.com/ruby/ruby/blob/trunk/compile.c#L9134 IBF_ZERO(regexp); regexp.option = (char)rb_reg_options(obj); regexp.srcstr = (long)ibf_dump_object(dump, srcstr); - IBF_WV(regexp); + IBF_W(®exp, struct ibf_object_regexp, 1); } static VALUE @@ -9146,7 +9154,7 @@ static void https://github.com/ruby/ruby/blob/trunk/compile.c#L9154 ibf_dump_object_array(struct ibf_dump *dump, VALUE obj) { long i, len = (int)RARRAY_LEN(obj); - IBF_WV(len); + IBF_W(&len, long, 1); for (i=0; i<len; i++) { long index = (long)ibf_dump_object(dump, RARRAY_AREF(obj, i)); IBF_WV(index); @@ -9174,10 +9182,10 @@ static int https://github.com/ruby/ruby/blob/trunk/compile.c#L9182 ibf_dump_object_hash_i(st_data_t key, st_data_t val, st_data_t ptr) { struct ibf_dump *dump = (struct ibf_dump *)ptr; - long key_index = (long)ibf_dump_object(dump, (VALUE)key); - long val_index = (long)ibf_dump_object(dump, (VALUE)val); - IBF_WV(key_index); - IBF_WV(val_index); + long keyval[2]; + keyval[0] = (long)ibf_dump_object(dump, (VALUE)key); + keyval[1] = (long)ibf_dump_object(dump, (VALUE)val); + IBF_W(keyval, long, 2); return ST_CONTINUE; } @@ -9185,7 +9193,7 @@ static void https://github.com/ruby/ruby/blob/trunk/compile.c#L9193 ibf_dump_object_hash(struct ibf_dump *dump, VALUE obj) { long len = RHASH_SIZE(obj); - IBF_WV(len); + IBF_W(&len, long, 1); if (len > 0) st_foreach(RHASH(obj)->ntbl, ibf_dump_object_hash_i, (st_data_t)dump); } @@ -9249,7 +9257,7 @@ ibf_dump_object_bignum(struct ibf_dump * https://github.com/ruby/ruby/blob/trunk/compile.c#L9257 ssize_t slen = BIGNUM_SIGN(obj) > 0 ? len : len * -1; BDIGIT *d = BIGNUM_DIGITS(obj); - IBF_WV(slen); + IBF_W(&slen, ssize_t, 1); IBF_WP(d, BDIGIT, len); } @@ -9272,10 +9280,11 @@ ibf_dump_object_data(struct ibf_dump *du https://github.com/ruby/ruby/blob/trunk/compile.c#L9280 if (rb_data_is_encoding(obj)) { rb_encoding *enc = rb_to_encoding(obj); const char *name = rb_enc_name(enc); - enum ibf_object_data_type type = IBF_OBJECT_DATA_ENCODING; long len = strlen(name) + 1; - IBF_WV(type); - IBF_WV(len); + long data[2]; + data[0] = IBF_OBJECT_DATA_ENCODING; + data[1] = len; + IBF_W(data, long, 2); IBF_WP(name, char, len); } else { @@ -9304,11 +9313,11 @@ ibf_load_object_data(const struct ibf_lo https://github.com/ruby/ruby/blob/trunk/compile.c#L9313 static void ibf_dump_object_complex_rational(struct ibf_dump *dump, VALUE obj) { - long real = (long)ibf_dump_object(dump, RCOMPLEX(obj)->real); - long imag = (long)ibf_dump_object(dump, RCOMPLEX(obj)->imag); + long data[2]; + data[0] = (long)ibf_dump_object(dump, RCOMPLEX(obj)->real); + data[1] = (long)ibf_dump_object(dump, RCOMPLEX(obj)->imag); - IBF_WV(real); - IBF_WV(imag); + IBF_W(data, long, 2); } static VALUE @@ -9330,7 +9339,7 @@ ibf_dump_object_symbol(struct ibf_dump * https://github.com/ruby/ruby/blob/trunk/compile.c#L9339 { VALUE str = rb_sym2str(obj); long str_index = (long)ibf_dump_object(dump, str); - IBF_WV(str_index); + IBF_W(&str_index, long, 1); } static VALUE @@ -9376,7 +9385,7 @@ static ibf_dump_object_function dump_obj https://github.com/ruby/ruby/blob/trunk/compile.c#L9385 ibf_dump_object_unsupported, /* T_ICLASS 0x1c */ ibf_dump_object_unsupported, /* T_ZOMBIE 0x1d */ ibf_dump_object_unsupported, /* 0x1e */ - ibf_dump_object_unsupported /* 0x1f */ + ibf_dump_object_unsupported, /* 0x1f */ }; static ibf_offset_t @@ -9397,7 +9406,7 @@ ibf_dump_object_object(struct ibf_dump * https://github.com/ruby/ruby/blob/trunk/compile.c#L9406 obj_header.frozen = TRUE; obj_header.internal = TRUE; IBF_WV(obj_header); - IBF_WV(obj); + IBF_W(&obj, VALUE, 1); } else { obj_header.internal = (RBASIC_CLASS(obj) == 0) ? TRUE : FALSE; @@ -9444,7 +9453,7 @@ static ibf_load_object_function load_obj https://github.com/ruby/ruby/blob/trunk/compile.c#L9453 ibf_load_object_unsupported, /* T_ICLASS 0x1c */ ibf_load_object_unsupported, /* T_ZOMBIE 0x1d */ ibf_load_object_unsupported, /* 0x1e */ - ibf_load_object_unsupported /* 0x1f */ + ibf_load_object_unsupported, /* 0x1f */ }; static VALUE @@ -9489,7 +9498,7 @@ ibf_dump_object_list(struct ibf_dump *du https://github.com/ruby/ruby/blob/trunk/compile.c#L9498 rb_ary_push(list, UINT2NUM(offset)); } size = i; - ibf_dump_align(dump, sizeof(ibf_offset_t)); + IBF_W_ALIGN(ibf_offset_t); header->object_list_offset = ibf_dump_pos(dump); for (i=0; i<size; i++) { @@ -9609,10 +9618,6 @@ iseq_ibf_dump(const rb_iseq_t *iseq, VAL https://github.com/ruby/ruby/blob/trunk/compile.c#L9618 static const ibf_offset_t * ibf_iseq_list(const struct ibf_load *load) { - if (load->header->iseq_list_offset % sizeof(ibf_offset_t)) { - rb_raise(rb_eArgError, "unaligned iseq list offset: %u", - load->header->iseq_list_offset); - } return (ibf_offset_t *)(load->buff + load->header->iseq_list_offset); } @@ -9621,19 +9626,18 @@ ibf_load_iseq_complete(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/compile.c#L9626 { struct ibf_load *load = RTYPEDDATA_DATA(iseq->aux.loader.obj); rb_iseq_t *prev_src_iseq = load->iseq; + const ibf_offset_t offset = ibf_iseq_list(load)[iseq->aux.loader.index]; load->iseq = iseq; #if IBF_ISEQ_DEBUG - fprintf(stderr, "ibf_load_iseq_complete: load=%p iseq=%p prev=%p\n", - load, iseq, prev_src_iseq); - fprintf(stderr, "ibf_load_iseq_complete: list=%p(%p+%#x) index=%i/%u\n", - ibf_iseq_list(load), - load->buff, load->header->iseq_list_offset, - iseq->aux.loader.index, load->header->iseq_list_size); - fprintf(stderr, "ibf_load_iseq_complete: offset=%#x size=%#x\n", - ibf_iseq_list(load)[iseq->aux.loader.index], + fprintf(stderr, "ibf_load_iseq_complete: index=%#x offset=%#x size=%#x\n", + iseq->aux.loader.index, offset, load->header->size); #endif - ibf_load_iseq_each(load, iseq, ibf_iseq_list(load)[iseq->aux.loader.index]); + if (offset % sizeof(VALUE)) { + rb_raise(rb_eArgError, "unaligned iseq offset: %#x @ %u", + offset, iseq->aux.loader.index); + } + ibf_load_iseq_each(load, iseq, offset); ISEQ_COMPILE_DATA_CLEAR(iseq); FL_UNSET(iseq, ISEQ_NOT_LOADED_YET); load->iseq = prev_src_iseq; @@ -9730,6 +9734,18 @@ ibf_load_setup(struct ibf_load *load, VA https://github.com/ruby/ruby/blob/trunk/compile.c#L9734 if (strcmp(load->buff + sizeof(struct ibf_header), RUBY_PLATFORM) != 0) { rb_raise(rb_eRuntimeError, "unmatched platform"); } + if (load->header->iseq_list_offset % RUBY_ALIGNOF(ibf_offset_t)) { + rb_raise(rb_eArgError, "unaligned iseq list offset: %u", + load->header->iseq_list_offset); + } + if (load->header->id_list_offset % RUBY_ALIGNOF(long)) { + rb_raise(rb_eArgError, "unaligned ID list offset: %u", + load->header->id_list_offset); + } + if (load->header->object_list_offset % RUBY_ALIGNOF(ibf_offset_t)) { + rb_raise(rb_eArgError, "unaligned object list offset: %u", + load->header->object_list_offset); + } } static void Index: test/ruby/test_iseq.rb =================================================================== --- test/ruby/test_iseq.rb (revision 63112) +++ test/ruby/test_iseq.rb (revision 63113) @@ -403,7 +403,6 @@ class TestISeq < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_iseq.rb#L403 end def assert_iseq_to_binary(code, mesg = nil) - skip "does not work on other than x86" unless /x(?:86|64)|i\d86/ =~ RUBY_PLATFORM iseq = RubyVM::InstructionSequence.compile(code) bin = assert_nothing_raised(mesg) do iseq.to_binary -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/