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/load.c | |
| parent | bc131350d416409220fd3294d2ffcea3ae73027d (diff) | |
| download | mruby-3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9.tar.gz mruby-3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9.zip | |
support multiple filename in irep
Diffstat (limited to 'src/load.c')
| -rw-r--r-- | src/load.c | 114 |
1 files changed, 113 insertions, 1 deletions
diff --git a/src/load.c b/src/load.c index 092ddbde8..3bdf39e73 100644 --- a/src/load.c +++ b/src/load.c @@ -16,6 +16,8 @@ #include "mruby/irep.h" #include "mruby/proc.h" #include "mruby/string.h" +#include "mruby/debug.h" +#include "mruby/array.h" #if !defined(_WIN32) && SIZE_MAX < UINT32_MAX # define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y)) @@ -299,6 +301,97 @@ error_exit: return result; } +static int read_rite_debug_record(mrb_state* mrb, uint8_t const *start, size_t irepno, uint32_t *len, mrb_value const filenames) { + uint8_t const* bin = start; + + mrb_irep* const irep = mrb->irep[irepno]; + + if(irep->debug_info) { return MRB_DUMP_INVALID_IREP; } + + irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info)); + irep->debug_info->pc_count = irep->ilen; + + size_t const record_size = bin_to_uint32(bin); bin += sizeof(uint32_t); + + irep->debug_info->flen = bin_to_uint16(bin); + irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen); + bin += sizeof(uint16_t); + + for (uint16_t f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { + mrb_irep_debug_info_file* const file = (mrb_irep_debug_info_file*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_file)); + irep->debug_info->files[f_idx] = file; + + file->start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); + + // filename + file->filename_sym = mrb_symbol(RARRAY_PTR(filenames)[bin_to_uint16(bin)]); + size_t len = 0; + file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len); + bin += sizeof(uint16_t); + + file->line_entry_count = bin_to_uint32(bin); bin += sizeof(uint32_t); + file->line_type = bin_to_uint8(bin); bin += sizeof(uint8_t); + switch(file->line_type) { + case mrb_debug_line_ary: + file->line_ary = mrb_malloc(mrb, sizeof(uint16_t) * file->line_entry_count); + for(size_t l = 0; l < file->line_entry_count; ++l) { + file->line_ary[l] = bin_to_uint16(bin); bin += sizeof(uint16_t); + } + break; + + case mrb_debug_line_flat_map: + file->line_flat_map = mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * file->line_entry_count); + for(size_t l = 0; l < file->line_entry_count; ++l) { + file->line_flat_map[l].start_pos = bin_to_uint32(bin); bin += sizeof(uint32_t); + file->line_flat_map[l].line = bin_to_uint16(bin); bin += sizeof(uint16_t); + } + break; + + default: return MRB_DUMP_GENERAL_FAILURE; + } + } + + if((long)record_size != (bin - start)) { + return MRB_DUMP_GENERAL_FAILURE; + } + + *len = bin - start; + + return MRB_DUMP_OK; +} + +static int +read_rite_section_debug(mrb_state* mrb, const uint8_t* start, size_t sirep) +{ + uint8_t const* bin = start; + struct rite_section_debug_header const* header = (struct rite_section_debug_header const*)bin; + bin += sizeof(struct rite_section_debug_header); + + uint16_t const nirep = bin_to_uint16(header->nirep); + + uint16_t const filenames_len = bin_to_uint16(bin); + mrb_value const filenames = mrb_ary_new_capa(mrb, filenames_len); + bin += sizeof(uint16_t); + for(uint16_t i = 0; i < filenames_len; ++i) { + uint16_t const f_len = bin_to_uint16(bin); + bin += sizeof(uint16_t); + mrb_ary_push(mrb, filenames, mrb_symbol_value(mrb_intern2(mrb, (char const*)bin, f_len))); + bin += f_len; + } + + for(uint16_t i = sirep; i < (sirep + nirep); ++i) { + uint32_t len = 0; + int result = read_rite_debug_record(mrb, bin, i, &len, filenames); + if (result != MRB_DUMP_OK) { return result; } + bin += len; + } + + if ((bin - start) != bin_to_uint32(header->section_size)) { + return MRB_DUMP_GENERAL_FAILURE; + } + + return sirep + bin_to_uint16(header->sirep); +} static int read_rite_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc) @@ -364,6 +457,12 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) return result; } } + else if (memcmp(section_header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { + result = read_rite_section_debug(mrb, bin, sirep); + if (result < MRB_DUMP_OK) { + return result; + } + } bin += bin_to_uint32(section_header->section_size); } while (memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0); @@ -566,7 +665,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) /* You don't need use SIZE_ERROR as block_size is enough small. */ for (i = 0; i < block_fallback_count; i++,block_size >>= 1){ buf = mrb_malloc_simple(mrb, block_size); - if (buf) break; + if (buf) break; } if (!buf) { return MRB_DUMP_GENERAL_FAILURE; @@ -608,6 +707,19 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) return result; } } + else if (memcmp(section_header.section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header.section_identify)) == 0) { + uint8_t* const bin = mrb_malloc(mrb, section_size); + fseek(fp, fpos, SEEK_SET); + if(fread((char*)bin, section_size, 1, fp) != section_size) { + mrb_free(mrb, bin); + return MRB_DUMP_READ_FAULT; + } + result = read_rite_section_debug(mrb, bin, sirep); + mrb_free(mrb, bin); + if (result < MRB_DUMP_OK) { + return result; + } + } fseek(fp, fpos + section_size, SEEK_SET); } while (memcmp(section_header.section_identify, RITE_BINARY_EOF, sizeof(section_header.section_identify)) != 0); |
