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 size_t write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) { size_t size, len; size_t irep_no; size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len); bin += len; for (irep_no = 0; irep_no < irep->rlen; irep_no++) { len = write_debug_record(mrb, irep->reps[irep_no], bin, filenames, filenames_len); bin += len; size += len; } mrb_assert(size == get_debug_record_size(mrb, irep)); return size; }
static size_t get_debug_record_size(mrb_state *mrb, mrb_irep *irep) { size_t ret = 0; uint32_t f_idx; size_t i; ret += sizeof(uint32_t); // record size ret += sizeof(uint16_t); // file count for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { mrb_irep_debug_info_file const* file = irep->debug_info->files[f_idx]; ret += sizeof(uint32_t); // position ret += sizeof(uint16_t); // filename index // lines ret += sizeof(uint32_t); // entry count ret += sizeof(uint8_t); // line type switch(file->line_type) { case mrb_debug_line_ary: ret += sizeof(uint16_t) * file->line_entry_count; break; case mrb_debug_line_flat_map: ret += (sizeof(uint32_t) + sizeof(uint16_t)) * file->line_entry_count; break; default: mrb_assert(0); break; } } for (i=0; i<irep->rlen; i++) { ret += get_debug_record_size(mrb, irep->reps[i]); } return ret; }
static int dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size) { int result = MRB_DUMP_GENERAL_FAILURE; size_t section_irep_size; size_t section_lineno_size = 0; uint8_t *cur = NULL; mrb_bool const debug_info_defined = is_debug_info_defined(irep); if (mrb == NULL) { *bin = NULL; return MRB_DUMP_GENERAL_FAILURE; } section_irep_size = sizeof(struct rite_section_irep_header); section_irep_size += get_irep_record_size(mrb, irep); /* DEBUG section size */ if (debug_info) { if (debug_info_defined) { mrb_sym *filenames; section_lineno_size += sizeof(struct rite_section_debug_header); // filename table filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym *) + 1); // filename table size section_lineno_size += sizeof(uint16_t); section_lineno_size += get_filename_table_size(mrb, irep, &filenames, NULL); mrb_free(mrb, filenames); section_lineno_size += get_debug_record_size(mrb, irep); } else { section_lineno_size += sizeof(struct rite_section_lineno_header); section_lineno_size += get_lineno_record_size(mrb, irep); } } *bin_size = sizeof(struct rite_binary_header) + section_irep_size + section_lineno_size + sizeof(struct rite_binary_footer); cur = *bin = (uint8_t*)mrb_malloc(mrb, *bin_size); if (cur == NULL) { goto error_exit; } cur += sizeof(struct rite_binary_header); result = write_section_irep(mrb, irep, cur); if (result != MRB_DUMP_OK) { goto error_exit; } cur += section_irep_size; /* write DEBUG section */ if (debug_info) { if (debug_info_defined) { result = write_section_debug(mrb, irep, cur); } else { result = write_section_lineno(mrb, irep, cur); } if (result != MRB_DUMP_OK) { goto error_exit; } cur += section_lineno_size; } write_footer(mrb, cur); write_rite_binary_header(mrb, *bin_size, *bin); error_exit: if (result != MRB_DUMP_OK) { mrb_free(mrb, *bin); *bin = NULL; } return result; }
static int dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size) { int result = MRB_DUMP_GENERAL_FAILURE; size_t malloc_size; size_t section_irep_size; size_t section_lineno_size = 0, section_lv_size = 0; uint8_t *cur = NULL; mrb_bool const debug_info_defined = is_debug_info_defined(irep), lv_defined = is_lv_defined(irep); mrb_sym *lv_syms = NULL; uint32_t lv_syms_len = 0; mrb_sym *filenames = NULL; uint16_t filenames_len = 0; if (mrb == NULL) { *bin = NULL; return MRB_DUMP_GENERAL_FAILURE; } section_irep_size = sizeof(struct rite_section_irep_header); section_irep_size += get_irep_record_size(mrb, irep); /* DEBUG section size */ if (flags & DUMP_DEBUG_INFO) { if (debug_info_defined) { section_lineno_size += sizeof(struct rite_section_debug_header); /* filename table */ filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) + 1); /* filename table size */ section_lineno_size += sizeof(uint16_t); section_lineno_size += get_filename_table_size(mrb, irep, &filenames, &filenames_len); section_lineno_size += get_debug_record_size(mrb, irep); } else { section_lineno_size += sizeof(struct rite_section_lineno_header); section_lineno_size += get_lineno_record_size(mrb, irep); } } if (lv_defined) { section_lv_size += sizeof(struct rite_section_lv_header); create_lv_sym_table(mrb, irep, &lv_syms, &lv_syms_len); section_lv_size += get_lv_section_size(mrb, irep, lv_syms, lv_syms_len); } malloc_size = sizeof(struct rite_binary_header) + section_irep_size + section_lineno_size + section_lv_size + sizeof(struct rite_binary_footer); cur = *bin = (uint8_t*)mrb_malloc(mrb, malloc_size); cur += sizeof(struct rite_binary_header); result = write_section_irep(mrb, irep, cur, §ion_irep_size, flags); if (result != MRB_DUMP_OK) { goto error_exit; } cur += section_irep_size; *bin_size = sizeof(struct rite_binary_header) + section_irep_size + section_lineno_size + section_lv_size + sizeof(struct rite_binary_footer); /* write DEBUG section */ if (flags & DUMP_DEBUG_INFO) { if (debug_info_defined) { result = write_section_debug(mrb, irep, cur, filenames, filenames_len); } else { result = write_section_lineno(mrb, irep, cur); } if (result != MRB_DUMP_OK) { goto error_exit; } cur += section_lineno_size; } if (lv_defined) { result = write_section_lv(mrb, irep, cur, lv_syms, lv_syms_len); if (result != MRB_DUMP_OK) { goto error_exit; } cur += section_lv_size; } write_footer(mrb, cur); write_rite_binary_header(mrb, *bin_size, *bin, flags); error_exit: if (result != MRB_DUMP_OK) { mrb_free(mrb, *bin); *bin = NULL; } if (lv_syms) { mrb_free(mrb, lv_syms); } if (filenames) { mrb_free(mrb, filenames); } return result; }
static int mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin, size_t *bin_size) { int result = MRB_DUMP_GENERAL_FAILURE; size_t section_size = 0; size_t section_irep_size; size_t section_lineno_size = 0; size_t irep_no; uint8_t *cur = NULL; if (mrb == NULL || start_index >= mrb->irep_len) { *bin = NULL; return MRB_DUMP_GENERAL_FAILURE; } section_irep_size = sizeof(struct rite_section_irep_header); for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { section_irep_size += get_irep_record_size(mrb, mrb->irep[irep_no]); } section_size += section_irep_size; /* DEBUG section size */ if(debug_info) { section_lineno_size += sizeof(struct rite_section_lineno_header); for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { section_lineno_size += get_debug_record_size(mrb, mrb->irep[irep_no]); } section_size += section_lineno_size; } *bin_size += sizeof(struct rite_binary_header) + section_size + sizeof(struct rite_binary_footer); cur = *bin = (uint8_t *)mrb_malloc(mrb, *bin_size); if(cur == NULL) { goto error_exit; } cur += sizeof(struct rite_binary_header); result = mrb_write_section_irep(mrb, start_index, cur); if (result != MRB_DUMP_OK) { goto error_exit; } cur += section_irep_size; /* write DEBUG section */ if(debug_info) { result = mrb_write_section_lineno(mrb, start_index, cur); if (result != MRB_DUMP_OK) { goto error_exit; } cur += section_lineno_size; } mrb_write_eof(mrb, cur); result = write_rite_binary_header(mrb, *bin_size, *bin); error_exit: if (result != MRB_DUMP_OK) { mrb_free(mrb, *bin); *bin = NULL; } return result; }