static ptrdiff_t write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { size_t pool_no; uint8_t *cur = buf; uint16_t len; mrb_value str; const char *char_ptr; cur += uint32_to_bin(irep->plen, cur); /* number of pool */ for (pool_no = 0; pool_no < irep->plen; pool_no++) { int ai = mrb_gc_arena_save(mrb); switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: cur += uint8_to_bin(IREP_TT_FIXNUM, cur); /* data type */ str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); break; case MRB_TT_FLOAT: cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); break; case MRB_TT_STRING: cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */ str = irep->pool[pool_no]; break; default: continue; } char_ptr = RSTRING_PTR(str); { mrb_int tlen = RSTRING_LEN(str); mrb_assert_int_fit(mrb_int, tlen, uint16_t, UINT16_MAX); len = (uint16_t)tlen; } cur += uint16_to_bin(len, cur); /* data length */ memcpy(cur, char_ptr, (size_t)len); cur += len; mrb_gc_arena_restore(mrb, ai); } return cur - buf; }
static size_t write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) { uint8_t *cur; uint16_t f_idx; ptrdiff_t ret; cur = bin + sizeof(uint32_t); /* skip record size */ cur += uint16_to_bin(irep->debug_info->flen, cur); /* file count */ for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { int filename_idx; const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx]; /* position */ cur += uint32_to_bin(file->start_pos, cur); /* filename index */ filename_idx = find_filename_index(filenames, filenames_len, file->filename_sym); mrb_assert(filename_idx >= 0); mrb_assert(filename_idx <= UINT16_MAX); cur += uint16_to_bin((uint16_t)filename_idx, cur); /* lines */ cur += uint32_to_bin(file->line_entry_count, cur); cur += uint8_to_bin(file->line_type, cur); switch(file->line_type) { case mrb_debug_line_ary: { uint32_t l; for (l = 0; l < file->line_entry_count; ++l) { cur += uint16_to_bin(file->line_ary[l], cur); } } break; case mrb_debug_line_flat_map: { uint32_t line; for (line = 0; line < file->line_entry_count; ++line) { cur += uint32_to_bin(file->line_flat_map[line].start_pos, cur); cur += uint16_to_bin(file->line_flat_map[line].line, cur); } } break; default: mrb_assert(0); break; } } ret = cur - bin; mrb_assert(ret >= 0); mrb_assert(ret <= UINT32_MAX); uint32_to_bin(ret, bin); mrb_assert((size_t)ret <= SIZE_MAX); return (size_t)ret; }
static int write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, size_t filenames_len) { uint8_t *cur; uint32_t f_idx; size_t ret; cur = bin + sizeof(uint32_t); // skip record size cur += uint16_to_bin(irep->debug_info->flen, cur); // file count for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { int filename_idx; const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx]; // position cur += uint32_to_bin(file->start_pos, cur); // filename index filename_idx = find_filename_index(filenames, filenames_len, file->filename_sym); mrb_assert(filename_idx != -1); cur += uint16_to_bin(filename_idx, cur); // lines cur += uint32_to_bin(file->line_entry_count, cur); cur += uint8_to_bin(file->line_type, cur); switch(file->line_type) { case mrb_debug_line_ary: { size_t l; for (l = 0; l < file->line_entry_count; ++l) { cur += uint16_to_bin(file->line_ary[l], cur); } } break; case mrb_debug_line_flat_map: { uint32_t line; for (line = 0; line < file->line_entry_count; ++line) { cur += uint32_to_bin(file->line_flat_map[line].start_pos, cur); cur += uint16_to_bin(file->line_flat_map[line].line, cur); } } break; default: mrb_assert(0); break; } } ret = cur - bin; uint32_to_bin(ret, bin); mrb_assert((cur - bin) == (int)get_debug_record_size(mrb, irep)); return ret; }
static int write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { size_t pool_no; uint8_t *cur = buf; size_t len; mrb_value str; const char *char_ptr; char char_buf[30]; cur += uint32_to_bin(irep->plen, cur); /* number of pool */ for (pool_no = 0; pool_no < irep->plen; pool_no++) { int ai = mrb_gc_arena_save(mrb); cur += uint8_to_bin(mrb_type(irep->pool[pool_no]), cur); /* data type */ switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); char_ptr = RSTRING_PTR(str); len = RSTRING_LEN(str); break; case MRB_TT_FLOAT: len = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no])); char_ptr = &char_buf[0]; break; case MRB_TT_STRING: str = irep->pool[pool_no]; char_ptr = RSTRING_PTR(str); len = RSTRING_LEN(str); break; default: continue; } cur += uint16_to_bin(len, cur); /* data length */ memcpy(cur, char_ptr, len); cur += len; mrb_gc_arena_restore(mrb, ai); } return (int)(cur - buf); }
static int write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { int result; size_t pool_no; uint8_t *cur = buf; size_t buf_size, len; mrb_value str; char *char_buf = NULL; buf_size = MRB_DUMP_DEFAULT_STR_LEN; char_buf = (char *)mrb_malloc(mrb, buf_size); if (char_buf == NULL) { result = MRB_DUMP_GENERAL_FAILURE; goto error_exit; } cur += uint32_to_bin(irep->plen, cur); /* number of pool */ for (pool_no = 0; pool_no < irep->plen; pool_no++) { int ai = mrb_gc_arena_save(mrb); cur += uint8_to_bin(mrb_type(irep->pool[pool_no]), cur); /* data type */ memset(char_buf, 0, buf_size); switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: str = mrb_fix2str(mrb, irep->pool[pool_no], 10); memcpy(char_buf, RSTRING_PTR(str), RSTRING_LEN(str)); len = RSTRING_LEN(str); break; case MRB_TT_FLOAT: len = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no])); break; case MRB_TT_STRING: str = irep->pool[pool_no]; len = RSTRING_LEN(str); if (len > buf_size - 1) { buf_size = len + 1; char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size); if (char_buf == NULL) { mrb_gc_arena_restore(mrb, ai); result = MRB_DUMP_GENERAL_FAILURE; goto error_exit; } memset(char_buf, 0, buf_size); } memcpy(char_buf, RSTRING_PTR(str), RSTRING_LEN(str)); break; default: len = 0; continue; } cur += uint16_to_bin(len, cur); /* data length */ memcpy(cur, char_buf, len); cur += len; mrb_gc_arena_restore(mrb, ai); } result = (int)(cur - buf); error_exit: mrb_free(mrb, char_buf); return result; }