summaryrefslogtreecommitdiffhomepage
path: root/src/load.c
diff options
context:
space:
mode:
authortake_cheeze <[email protected]>2013-09-01 22:43:17 +0900
committertake_cheeze <[email protected]>2013-09-02 00:48:06 +0900
commit3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9 (patch)
tree35d6c58a23442ca055671c3b9e34f736153bc4ec /src/load.c
parentbc131350d416409220fd3294d2ffcea3ae73027d (diff)
downloadmruby-3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9.tar.gz
mruby-3d1fffbd6bce3a6f9a77af3116078574ce8d5fe9.zip
support multiple filename in irep
Diffstat (limited to 'src/load.c')
-rw-r--r--src/load.c114
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);