diff options
| author | take_cheeze <[email protected]> | 2013-09-01 22:43:17 +0900 |
|---|---|---|
| committer | take_cheeze <[email protected]> | 2013-09-02 00:48:06 +0900 |
| commit | 3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9 (patch) | |
| tree | 35d6c58a23442ca055671c3b9e34f736153bc4ec /src/dump.c | |
| parent | bc131350d416409220fd3294d2ffcea3ae73027d (diff) | |
| download | mruby-3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9.tar.gz mruby-3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9.zip | |
support multiple filename in irep
Diffstat (limited to 'src/dump.c')
| -rw-r--r-- | src/dump.c | 221 |
1 files changed, 206 insertions, 15 deletions
diff --git a/src/dump.c b/src/dump.c index 72ca9e0c3..92b1b011a 100644 --- a/src/dump.c +++ b/src/dump.c @@ -11,6 +11,8 @@ #include "mruby/string.h" #include "mruby/irep.h" #include "mruby/numeric.h" +#include "mruby/debug.h" +#include "mruby/array.h" static size_t get_irep_record_size(mrb_state *mrb, mrb_irep *irep); @@ -257,7 +259,7 @@ mrb_write_eof(mrb_state *mrb, uint8_t *bin) static int mrb_write_section_irep_header(mrb_state *mrb, uint32_t section_size, uint16_t nirep, uint16_t sirep, uint8_t *bin) -{ +{ struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin; memcpy(header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(header->section_identify)); @@ -300,7 +302,7 @@ mrb_write_section_irep(mrb_state *mrb, size_t start_index, uint8_t *bin) static int mrb_write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint16_t nirep, uint16_t sirep, uint8_t *bin) -{ +{ struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin; // TODO @@ -313,7 +315,7 @@ mrb_write_section_lineno_header(mrb_state *mrb, uint32_t section_size, uint16_t } static size_t -get_debug_record_size(mrb_state *mrb, mrb_irep *irep) +get_lineno_record_size(mrb_state *mrb, mrb_irep *irep) { size_t size = 0; @@ -388,9 +390,152 @@ mrb_write_section_lineno(mrb_state *mrb, size_t start_index, uint8_t *bin) return MRB_DUMP_OK; } +static size_t +get_debug_record_size(mrb_state* mrb, mrb_irep *irep) { + (void)mrb; + size_t ret = 0; + + ret += sizeof(uint32_t); // record size + ret += sizeof(uint16_t); // file count + + for(uint32_t 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; + } + } + + return ret; +} + +static int +find_filename_index(mrb_value const ary, mrb_sym s) { + for(mrb_int i = 0; i < RARRAY_LEN(ary); ++i) { + mrb_assert(mrb_symbol_p(RARRAY_PTR(ary)[i])); + if(mrb_symbol(RARRAY_PTR(ary)[i]) == s) { return i; } + } + return -1; +} + +static int +write_debug_record(mrb_state* mrb, mrb_irep *irep, uint8_t * const bin, mrb_value filenames) +{ + uint8_t *cur = bin + sizeof(uint32_t); // skip record size + + cur += uint16_to_bin(irep->debug_info->flen, cur); // file count + for(uint32_t f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { + mrb_irep_debug_info_file const* file = irep->debug_info->files[f_idx]; + + // position + cur += uint32_to_bin(file->start_pos, cur); + + // filename index + int const filename_idx = find_filename_index(filenames, 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: { + for(size_t l = 0; l < file->line_entry_count; ++l) { + cur += uint16_to_bin(file->line_ary[l], cur); + } + } break; + + case mrb_debug_line_flat_map: + for(uint32_t 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; + } + } + + size_t const ret = cur - bin; + uint32_to_bin(ret, bin); + + mrb_assert((cur - bin) == (int)get_debug_record_size(mrb, irep)); + + return ret; +} + +static int +mrb_write_section_debug(mrb_state* mrb, size_t start_index, uint8_t *cur) +{ + uint32_t section_size = 0; + uint8_t* const bin = cur; + + if (mrb == NULL || start_index >= mrb->irep_len || cur == NULL) { + return MRB_DUMP_INVALID_ARGUMENT; + } + + struct rite_section_debug_header* header = (struct rite_section_debug_header*)bin; + cur += sizeof(struct rite_section_debug_header); + section_size += sizeof(struct rite_section_debug_header); + + // filename table + mrb_value const filenames = mrb_ary_new(mrb); + uint8_t* const filenames_len = cur; + cur += sizeof(uint16_t); + section_size += sizeof(uint16_t); + for (size_t irep_i = start_index; irep_i < mrb->irep_len; ++irep_i) { + mrb_irep_debug_info const* debug_info = mrb->irep[irep_i]->debug_info; + + for(size_t file_i = 0; file_i < debug_info->flen; ++file_i) { + mrb_irep_debug_info_file const* file = debug_info->files[file_i]; + if(find_filename_index(filenames, file->filename_sym) != -1) continue; + + // register filename + mrb_ary_push(mrb, filenames, mrb_symbol_value(file->filename_sym)); + + // filename + uint16_t const fn_len = strlen(file->filename); + cur += uint16_to_bin(fn_len, cur); + memcpy(cur, file->filename, fn_len); + cur += fn_len; + + section_size += sizeof(uint16_t) + fn_len; + } + } + uint16_to_bin(RARRAY_LEN(filenames), filenames_len); + + // records + for (size_t i = start_index; i < mrb->irep_len; ++i) { + uint32_t rlen = write_debug_record(mrb, mrb->irep[i], cur, filenames); + cur += rlen; + section_size += rlen; + } + + memcpy(header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(header->section_identify)); + uint32_to_bin(section_size, header->section_size); + uint16_to_bin(mrb->irep_len - start_index, header->nirep); + uint16_to_bin(start_index, header->sirep); + + return MRB_DUMP_OK; +} + static int write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t* bin) -{ +{ struct rite_binary_header *header = (struct rite_binary_header*)bin; uint16_t crc; size_t offset; @@ -400,7 +545,7 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t* bin) memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name)); memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version)); uint32_to_bin(binary_size, header->binary_size); - + offset = (&(header->binary_crc[0]) - bin) + sizeof(uint16_t); crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0); uint16_to_bin(crc, header->binary_crc); @@ -408,6 +553,13 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t* bin) return MRB_DUMP_OK; } +mrb_bool is_debug_info_defined(mrb_state* mrb, size_t const start_index) { + for (size_t i = start_index; i < mrb->irep_len; ++i) { + if (!mrb->irep[i]->debug_info) { return 0; } + } + return 1; +} + static int mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin, size_t *bin_size) { @@ -418,6 +570,8 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin, size_t irep_no; uint8_t *cur = NULL; + mrb_bool const debug_info_defined = is_debug_info_defined(mrb, start_index); + if (mrb == NULL || start_index >= mrb->irep_len) { *bin = NULL; return MRB_DUMP_GENERAL_FAILURE; @@ -431,11 +585,39 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin, /* 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]); + if (debug_info_defined) { + section_lineno_size += sizeof(struct rite_section_debug_header); + + // filename table + mrb_value const filenames = mrb_ary_new(mrb); + // filename table size + section_lineno_size += sizeof(uint16_t); + for (size_t irep_i = start_index; irep_i < mrb->irep_len; ++irep_i) { + mrb_irep_debug_info const* di = mrb->irep[irep_i]->debug_info; + + for(size_t file_i = 0; file_i < di->flen; ++file_i) { + mrb_irep_debug_info_file const* file = di->files[file_i]; + if(find_filename_index(filenames, file->filename_sym) != -1) continue; + + // register filename + mrb_ary_push(mrb, filenames, mrb_symbol_value(file->filename_sym)); + // filename + section_lineno_size += sizeof(uint16_t) + strlen(file->filename); + } + } + + 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; + } + else { + 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_lineno_record_size(mrb, mrb->irep[irep_no]); + } + section_size += section_lineno_size; } - section_size += section_lineno_size; } *bin_size += sizeof(struct rite_binary_header) + section_size + sizeof(struct rite_binary_footer); @@ -450,16 +632,25 @@ mrb_dump_irep(mrb_state *mrb, size_t start_index, int debug_info, uint8_t **bin, 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; + if(debug_info_defined) { + result = mrb_write_section_debug(mrb, start_index, cur); + if(result != MRB_DUMP_OK) { + goto error_exit; + } + cur += section_lineno_size; + } + else { + result = mrb_write_section_lineno(mrb, start_index, cur); + if (result != MRB_DUMP_OK) { + goto error_exit; + } + cur += section_lineno_size; } - cur += section_lineno_size; } mrb_write_eof(mrb, cur); |
