diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dump.c | 59 | ||||
| -rw-r--r-- | src/load.c | 84 |
2 files changed, 101 insertions, 42 deletions
diff --git a/src/dump.c b/src/dump.c index f529c4f02..905bfc72b 100644 --- a/src/dump.c +++ b/src/dump.c @@ -13,6 +13,9 @@ #include "mruby/numeric.h" #include "mruby/debug.h" +#define FLAG_BYTEORDER_NATIVE 2 +#define FLAG_BYTEORDER_NONATIVE 0 + #ifdef ENABLE_STDIO static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); @@ -58,14 +61,20 @@ get_iseq_block_size(mrb_state *mrb, mrb_irep *irep) } static ptrdiff_t -write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) +write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags) { uint8_t *cur = buf; uint32_t iseq_no; cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */ - for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { - cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ + if (flags & FLAG_BYTEORDER_NATIVE) { + memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); + cur += irep->ilen * sizeof(mrb_code); + } + else { + for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { + cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ + } } return cur - buf; @@ -263,7 +272,7 @@ get_irep_record_size(mrb_state *mrb, mrb_irep *irep) } static int -write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size) +write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size, uint8_t flags) { uint32_t i; @@ -279,7 +288,7 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_rec memset(bin, 0, *irep_record_size); bin += write_irep_header(mrb, irep, bin); - bin += write_iseq_block(mrb, irep, bin); + bin += write_iseq_block(mrb, irep, bin, flags); bin += write_pool_block(mrb, irep, bin); bin += write_syms_block(mrb, irep, bin); @@ -287,7 +296,7 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_rec int result; size_t rsize; - result = write_irep_record(mrb, irep->reps[i], bin, &rsize); + result = write_irep_record(mrb, irep->reps[i], bin, &rsize, flags); if (result != MRB_DUMP_OK) { return result; } @@ -325,7 +334,7 @@ write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin) } static int -write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) +write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, uint8_t flags) { int result; size_t section_size = 0; /* size of irep record */ @@ -339,7 +348,7 @@ write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) cur += sizeof(struct rite_section_irep_header); section_size += sizeof(struct rite_section_irep_header); - result = write_irep_record(mrb, irep, cur, &rsize); + result = write_irep_record(mrb, irep, cur, &rsize, flags); if (result != MRB_DUMP_OK) { return result; } @@ -795,13 +804,25 @@ lv_section_exit: } static int -write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin) +write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags) { struct rite_binary_header *header = (struct rite_binary_header *)bin; uint16_t crc; uint32_t offset; - memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)); + if (flags & FLAG_BYTEORDER_NATIVE) { + uint32_t ident = 0; + size_t i; + + for(i=0; i<sizeof(ident); i++) { + ident<<=8; + ident|=RITE_BINARY_IDENTIFIER[i]; + } + memcpy(header->binary_identify, (char*)&ident, sizeof(uint32_t)); + } + else { + memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)); + } memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)); memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name)); memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version)); @@ -841,8 +862,8 @@ is_lv_defined(mrb_irep *irep) return FALSE; } -int -mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size) +static int +dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size, uint8_t flags) { int result = MRB_DUMP_GENERAL_FAILURE; size_t section_irep_size; @@ -891,7 +912,7 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz cur = *bin = (uint8_t*)mrb_malloc(mrb, *bin_size); cur += sizeof(struct rite_binary_header); - result = write_section_irep(mrb, irep, cur); + result = write_section_irep(mrb, irep, cur, flags); if (result != MRB_DUMP_OK) { goto error_exit; } @@ -920,7 +941,7 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz } write_footer(mrb, cur); - write_rite_binary_header(mrb, *bin_size, *bin); + write_rite_binary_header(mrb, *bin_size, *bin, flags); error_exit: if (result != MRB_DUMP_OK) { @@ -937,6 +958,12 @@ error_exit: } int +mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size) +{ + return dump_irep(mrb, irep, debug_info, bin, bin_size, FLAG_BYTEORDER_NONATIVE); +} + +int mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp) { uint8_t *bin = NULL; @@ -947,7 +974,7 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp) return MRB_DUMP_INVALID_ARGUMENT; } - result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size); + result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NATIVE); if (result == MRB_DUMP_OK) { if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) { result = MRB_DUMP_WRITE_FAULT; @@ -985,7 +1012,7 @@ mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE *fp, co return MRB_DUMP_INVALID_ARGUMENT; } - result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size); + result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NATIVE); if (result == MRB_DUMP_OK) { if (fprintf(fp, "#include <stdint.h>\n") < 0) { /* for uint8_t under at least Darwin */ mrb_free(mrb, bin); diff --git a/src/load.c b/src/load.c index 9e8325022..80fc719c2 100644 --- a/src/load.c +++ b/src/load.c @@ -14,6 +14,11 @@ #include "mruby/debug.h" #include "mruby/error.h" +#define FLAG_BYTEORDER_NATIVE 2 +#define FLAG_BYTEORDER_NONATIVE 0 +#define FLAG_SRC_MALLOC 1 +#define FLAG_SRC_STATIC 0 + #if !defined(_WIN32) && SIZE_MAX < UINT32_MAX # define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y)) # define SIZE_ERROR(x) ((x) > SIZE_MAX) @@ -34,7 +39,7 @@ offset_crc_body(void) } static mrb_irep* -read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc) +read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) { size_t i; const uint8_t *src = bin; @@ -67,10 +72,18 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) { return NULL; } - irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); - for (i = 0; i < irep->ilen; i++) { - irep->iseq[i] = (size_t)bin_to_uint32(src); /* iseq */ - src += sizeof(uint32_t); + if (!(flags & FLAG_SRC_MALLOC) && + (flags & FLAG_BYTEORDER_NATIVE)) { + irep->iseq = (mrb_code*)src; + src += sizeof(uint32_t) * irep->ilen; + irep->flags |= MRB_ISEQ_NO_FREE; + } + else { + irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); + for (i = 0; i < irep->ilen; i++) { + irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */ + src += sizeof(uint32_t); + } } } @@ -89,7 +102,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all tt = *src++; /* pool TT */ pool_data_len = bin_to_uint16(src); /* pool data length */ src += sizeof(uint16_t); - if (alloc) { + if (flags & FLAG_SRC_MALLOC) { s = mrb_str_new(mrb, (char *)src, pool_data_len); } else { @@ -137,7 +150,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all continue; } - if (alloc) { + if (flags & FLAG_SRC_MALLOC) { irep->syms[i] = mrb_intern(mrb, (char *)src, snl); } else { @@ -159,9 +172,9 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all } static mrb_irep* -read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc) +read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) { - mrb_irep *irep = read_irep_record_1(mrb, bin, len, alloc); + mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags); size_t i; if (irep == NULL) { @@ -172,7 +185,7 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc for (i=0; i<irep->rlen; i++) { size_t rlen; - irep->reps[i] = read_irep_record(mrb, bin, &rlen, alloc); + irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags); if (irep->reps[i] == NULL) { return NULL; } @@ -183,12 +196,12 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc } static mrb_irep* -read_section_irep(mrb_state *mrb, const uint8_t *bin, mrb_bool alloc) +read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags) { size_t len; bin += sizeof(struct rite_section_irep_header); - return read_irep_record(mrb, bin, &len, alloc); + return read_irep_record(mrb, bin, &len, flags); } static int @@ -357,7 +370,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t * } static int -read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc) +read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) { const uint8_t *bin; ptrdiff_t diff; @@ -378,7 +391,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_boo for (i = 0; i < filenames_len; ++i) { uint16_t f_len = bin_to_uint16(bin); bin += sizeof(uint16_t); - if (alloc) { + if (flags & FLAG_SRC_MALLOC) { filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); } else { @@ -446,7 +459,7 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec } static int -read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc) +read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) { const uint8_t *bin; ptrdiff_t diff; @@ -456,7 +469,8 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool a int result; uint32_t syms_len; mrb_sym *syms; - mrb_sym (*intern_func)(mrb_state*, const char*, size_t) = alloc? mrb_intern : mrb_intern_static; + mrb_sym (*intern_func)(mrb_state*, const char*, size_t) = + (flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static; bin = start; header = (struct rite_section_lv_header const*)bin; @@ -489,12 +503,25 @@ lv_exit: } static int -read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc) +read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, mrb_bool *byteorder) { const struct rite_binary_header *header = (const struct rite_binary_header *)bin; + *byteorder = FALSE; if (memcmp(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)) != 0) { - return MRB_DUMP_INVALID_FILE_HEADER; + uint32_t ident = 0; + size_t i; + + for(i=0; i<sizeof(ident); i++) { + ident<<=8; + ident|=RITE_BINARY_IDENTIFIER[i]; + } + if (ident == *(uint32_t*)header->binary_identify) { + *byteorder = TRUE; + } + else { + return MRB_DUMP_INVALID_FILE_HEADER; + } } if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) { @@ -518,15 +545,20 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) uint16_t crc; size_t bin_size = 0; size_t n; + mrb_bool byteorder; + uint8_t flags = FLAG_SRC_STATIC; if ((mrb == NULL) || (bin == NULL)) { return NULL; } - result = read_binary_header(bin, &bin_size, &crc); + result = read_binary_header(bin, &bin_size, &crc, &byteorder); if (result != MRB_DUMP_OK) { return NULL; } + if (byteorder) { + flags |= FLAG_BYTEORDER_NATIVE; + } n = offset_crc_body(); if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) { @@ -537,7 +569,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) do { section_header = (const struct rite_section_header *)bin; if (memcmp(section_header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { - irep = read_section_irep(mrb, bin, FALSE); + irep = read_section_irep(mrb, bin, flags); if (!irep) return NULL; } else if (memcmp(section_header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { @@ -549,14 +581,14 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) } else if (memcmp(section_header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { if (!irep) return NULL; /* corrupted data */ - result = read_section_debug(mrb, bin, irep, FALSE); + result = read_section_debug(mrb, bin, irep, flags); if (result < MRB_DUMP_OK) { return NULL; } } else if (memcmp(section_header->section_identify, RITE_SECTION_LV_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { if (!irep) return NULL; - result = read_section_lv(mrb, bin, irep, FALSE); + result = read_section_lv(mrb, bin, irep, flags); if (result < MRB_DUMP_OK) { return NULL; } @@ -668,7 +700,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp) if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) { return NULL; } - irep = read_irep_record_1(mrb, buf, &len, TRUE); + irep = read_irep_record_1(mrb, buf, &len, FLAG_SRC_MALLOC); mrb_free(mrb, ptr); if (!irep) return NULL; for (i=0; i<irep->rlen; i++) { @@ -715,7 +747,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) mrb_free(mrb, buf); return NULL; } - result = read_binary_header(buf, NULL, &crc); + result = read_binary_header(buf, NULL, &crc, NULL); mrb_free(mrb, buf); if (result != MRB_DUMP_OK) { return NULL; @@ -773,7 +805,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) mrb_free(mrb, bin); return NULL; } - result = read_section_debug(mrb, bin, irep, TRUE); + result = read_section_debug(mrb, bin, irep, FLAG_SRC_MALLOC); mrb_free(mrb, bin); } if (result < MRB_DUMP_OK) return NULL; @@ -788,7 +820,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) mrb_free(mrb, bin); return NULL; } - result = read_section_lv(mrb, bin, irep, TRUE); + result = read_section_lv(mrb, bin, irep, FLAG_SRC_MALLOC); mrb_free(mrb, bin); } if (result < MRB_DUMP_OK) return NULL; |
