diff options
| author | Yukihiro Matz Matsumoto <[email protected]> | 2013-03-27 00:52:24 +0900 |
|---|---|---|
| committer | Yukihiro Matz Matsumoto <[email protected]> | 2013-03-27 00:52:24 +0900 |
| commit | a0f6e4d58edc296b0a3f8a3f7be5ab62ff61604d (patch) | |
| tree | 5c2c21a850129b3d596034d81bcdf063613305a4 /src/dump.c | |
| parent | 1abe678e1c0a5fd153c07d71634f262fd51b7668 (diff) | |
| parent | 974febd315a6520184f95cb50a7c2b46e4582002 (diff) | |
| download | mruby-a0f6e4d58edc296b0a3f8a3f7be5ab62ff61604d.tar.gz mruby-a0f6e4d58edc296b0a3f8a3f7be5ab62ff61604d.zip | |
resolve conflict from #964
Diffstat (limited to 'src/dump.c')
| -rw-r--r-- | src/dump.c | 775 |
1 files changed, 236 insertions, 539 deletions
diff --git a/src/dump.c b/src/dump.c index 9666f7562..d96b2778e 100644 --- a/src/dump.c +++ b/src/dump.c @@ -12,249 +12,86 @@ #include "mruby/irep.h" #include "mruby/numeric.h" -static const unsigned char def_rite_binary_header[] = - RITE_FILE_IDENFIFIER - RITE_FILE_FORMAT_VER - RITE_VM_VER - RITE_COMPILER_TYPE - RITE_COMPILER_VER - "0000" //Binary data size - "00" //Number of ireps - "00" //Start index - RITE_RESERVED -; - -static const unsigned char def_rite_file_header[] = - RITE_FILE_IDENFIFIER - RITE_FILE_FORMAT_VER - RITE_VM_VER - RITE_COMPILER_TYPE - RITE_COMPILER_VER - "00000000" //Binary data size - "0000" //Number of ireps - "0000" //Start index - RITE_RESERVED - "0000" //CRC -; - -const char bin2hex[] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -}; - -#define DUMP_SIZE(size, type) ((type == DUMP_TYPE_BIN) ? size : size * RITE_FILE_HEX_SIZE) - -enum { - DUMP_IREP_HEADER = 0, - DUMP_ISEQ_BLOCK, - DUMP_POOL_BLOCK, - DUMP_SYMS_BLOCK, - DUMP_SECTION_NUM, -}; +static size_t +get_irep_record_size(mrb_state *mrb, mrb_irep *irep); -#ifdef ENABLE_STDIO - -uint16_t calc_crc_16_ccitt(unsigned char*,int); -static inline int uint8_dump(uint8_t,char*,int); -static inline int uint16_dump(uint16_t,char*,int); -static inline int uint32_dump(uint32_t,char*,int); -static char* str_dump(char*,char*,uint16_t,int); -static uint16_t str_dump_len(char*,uint16_t, int); -static uint32_t get_irep_header_size(mrb_state*,int); -static uint32_t get_iseq_block_size(mrb_state*,mrb_irep*,int); -static uint32_t get_pool_block_size(mrb_state*,mrb_irep*,int); -static uint32_t get_syms_block_size(mrb_state*,mrb_irep*,int); -static uint32_t get_irep_record_size(mrb_state*,int,int); -static int write_irep_header(mrb_state*,mrb_irep*,char*,int); -static int write_iseq_block(mrb_state*,mrb_irep*,char*,int); -static int write_pool_block(mrb_state*,mrb_irep*,char*,int); -static int write_syms_block(mrb_state*,mrb_irep*,char*,int); -static int calc_crc_section(mrb_state*,mrb_irep*,uint16_t*,int); -static int write_rite_header(mrb_state*,int,char*,uint32_t); -static int dump_rite_header(mrb_state*,int,FILE*,uint32_t); -static int write_irep_record(mrb_state*,int,char*,uint32_t*,int); -static int dump_irep_record(mrb_state*,int,FILE*,uint32_t*); -static int mrb_write_irep(mrb_state*,int,char*); - - -static inline int -uint8_dump(uint8_t bin, char *hex, int type) +static uint32_t +get_irep_header_size(mrb_state *mrb) { - if (type == DUMP_TYPE_BIN) { - *hex = bin; - } else { - *hex++ = bin2hex[(bin >> 4) & 0x0f]; - *hex = bin2hex[bin & 0x0f]; - } - return DUMP_SIZE(MRB_DUMP_SIZE_OF_CHAR, type); -} + uint32_t size = 0; -static inline int -uint16_dump(uint16_t bin, char *hex, int type) -{ - if (type == DUMP_TYPE_BIN) { - return (uint16_to_bin(bin, hex)); - } else { - *hex++ = bin2hex[(bin >> 12)& 0x0f]; - *hex++ = bin2hex[(bin >> 8) & 0x0f]; - *hex++ = bin2hex[(bin >> 4) & 0x0f]; - *hex = bin2hex[bin & 0x0f]; - return DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); - } -} + size += sizeof(uint32_t) * 1; + size += sizeof(uint16_t) * 2; -static inline int -uint32_dump(uint32_t bin, char *hex, int type) -{ - if (type == DUMP_TYPE_BIN) { - return (uint32_to_bin(bin, hex)); - } else { - *hex++ = bin2hex[(bin >> 28) & 0x0f]; - *hex++ = bin2hex[(bin >> 24) & 0x0f]; - *hex++ = bin2hex[(bin >> 20) & 0x0f]; - *hex++ = bin2hex[(bin >> 16) & 0x0f]; - *hex++ = bin2hex[(bin >> 12) & 0x0f]; - *hex++ = bin2hex[(bin >> 8) & 0x0f]; - *hex++ = bin2hex[(bin >> 4) & 0x0f]; - *hex = bin2hex[bin & 0x0f]; - return DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type); - } + return size; } -#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ - -static char* -str_dump(char *str, char *hex, uint16_t len, int type) +static size_t +write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { - if (type == DUMP_TYPE_BIN) - memcpy(hex, str, len); - else { - char *src, *dst, buf[CHAR_ESC_LEN + 1]; - int n; - - for (src = str, dst = hex; len > 0; src++, dst++, len--) { - switch (*src) { - case 0x07:/* BEL */ *dst++ = '\\'; *dst = 'a'; break; - case 0x08:/* BS */ *dst++ = '\\'; *dst = 'b'; break; - case 0x09:/* HT */ *dst++ = '\\'; *dst = 't'; break; - case 0x0A:/* LF */ *dst++ = '\\'; *dst = 'n'; break; - case 0x0B:/* VT */ *dst++ = '\\'; *dst = 'v'; break; - case 0x0C:/* FF */ *dst++ = '\\'; *dst = 'f'; break; - case 0x0D:/* CR */ *dst++ = '\\'; *dst = 'r'; break; - case 0x5C:/* \ */ *dst++ = '\\'; *dst = '\\'; break; - case 0x22:/* " */ /* fall through */ - case 0x27:/* ' */ /* fall through */ - // case 0x3F:/* ? */ /* fall through */ - default: - if (*src >= ' ' && *src <= '~') { - *dst = *src; - } else { - n = sprintf(buf, "\\%03o", *src & 0377); - memcpy(dst, buf, n); - dst += (n-1); - } - break; - } - } - } - - return hex; -} + uint8_t *cur = buf; -static uint16_t -str_dump_len(char *str, uint16_t len, int type) -{ - uint16_t dump_len = 0; - - if (type == DUMP_TYPE_BIN) - dump_len = len; - else { - char *src; - - for (src = str; len > 0; src++, len--) { - switch (*src) { - case 0x07:/* BEL */ /* fall through */ - case 0x08:/* BS */ /* fall through */ - case 0x09:/* HT */ /* fall through */ - case 0x0A:/* LF */ /* fall through */ - case 0x0B:/* VT */ /* fall through */ - case 0x0C:/* FF */ /* fall through */ - case 0x0D:/* CR */ /* fall through */ - case 0x5C:/* \ */ /* fall through */ - dump_len += 2; - break; - - case 0x22:/* " */ /* fall through */ - case 0x27:/* ' */ /* fall through */ - // case 0x3F:/* ? */ /* fall through */ - default: - if (*src >= ' ' && *src <= '~') { - dump_len++; - } else { - dump_len += 4; /* octet "\\nnn" */ - } - break; - } - } - } + cur += uint32_to_bin(get_irep_record_size(mrb, irep), cur); /* record size */ + cur += uint16_to_bin((uint16_t)irep->nlocals, cur); /* number of local variable */ + cur += uint16_to_bin((uint16_t)irep->nregs, cur); /* number of register variable */ - return dump_len; + return (cur - buf); } + static uint32_t -get_irep_header_size(mrb_state *mrb, int type) +get_iseq_block_size(mrb_state *mrb, mrb_irep *irep) { uint32_t size = 0; - - size += 2; - size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type) * 4; - + size += sizeof(uint32_t); /* ilen */ + size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */ return size; } -static uint32_t -get_iseq_block_size(mrb_state *mrb, mrb_irep *irep, int type) +static int +write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { - uint32_t size = 0; + uint8_t *cur = buf; + size_t iseq_no; - size += MRB_DUMP_SIZE_OF_LONG; /* ilen */ - size += irep->ilen * MRB_DUMP_SIZE_OF_LONG; /* iseq(n) */ - size += MRB_DUMP_SIZE_OF_SHORT; /* crc */ + 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 */ + } - return DUMP_SIZE(size, type); + return (cur - buf); } -static uint32_t -get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type) + +static size_t +get_pool_block_size(mrb_state *mrb, mrb_irep *irep) { - uint32_t size = 0; - int pool_no; + size_t size = 0; + size_t pool_no; + int len; mrb_value str; char buf[32]; - size += MRB_DUMP_SIZE_OF_LONG; /* plen */ - size += irep->plen; /* tt(n) */ - size += irep->plen * MRB_DUMP_SIZE_OF_SHORT; /* len(n) */ - size += MRB_DUMP_SIZE_OF_SHORT; /* crc */ - size = DUMP_SIZE(size, type); + size += sizeof(uint32_t); /* plen */ + size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */ for (pool_no = 0; pool_no < irep->plen; pool_no++) { - uint16_t nlen =0; - int len; - switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: str = mrb_fix2str(mrb, irep->pool[pool_no], 10); - size += (uint32_t)RSTRING_LEN(str); + size += RSTRING_LEN(str); break; + case MRB_TT_FLOAT: - len = mrb_float_to_str( buf, mrb_float(irep->pool[pool_no])); - size += (uint32_t)len; + len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no])); + size += len; break; + case MRB_TT_STRING: - str = mrb_string_value( mrb, &irep->pool[pool_no]); - nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type); - size += nlen; + str = mrb_string_value(mrb, &irep->pool[pool_no]); + size += RSTRING_LEN(str); break; + default: break; } @@ -263,87 +100,15 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type) return size; } -static uint32_t -get_syms_block_size(mrb_state *mrb, mrb_irep *irep, int type) -{ - uint32_t size = 0; - int sym_no; - - size += MRB_DUMP_SIZE_OF_LONG; /* slen */ - size += MRB_DUMP_SIZE_OF_SHORT; /* crc */ - size = DUMP_SIZE(size, type); - - for (sym_no = 0; sym_no < irep->slen; sym_no++) { - const char * name; - uint16_t nlen =0; - - size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); /* snl(n) */ - if (irep->syms[sym_no] != 0) { - size_t len; - - name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); - nlen = str_dump_len((char*)name, len, type); - size += nlen; /* sn(n) */ - } - } - - return size; -} - -static uint32_t -get_irep_record_size(mrb_state *mrb, int irep_no, int type) -{ - uint32_t size = 0; - mrb_irep *irep = mrb->irep[irep_no]; - - size += DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type); /* rlen */ - size += get_irep_header_size(mrb, type); - size += get_iseq_block_size(mrb, irep, type); - size += get_pool_block_size(mrb, irep, type); - size += get_syms_block_size(mrb, irep, type); - - return size; -} - -static int -write_irep_header(mrb_state *mrb, mrb_irep *irep, char *buf, int type) -{ - char *buf_top = buf; - - *buf++ = RITE_IREP_IDENFIFIER; /* record identifier */ - *buf++ = RITE_IREP_TYPE_CLASS; /* class or module */ - buf += uint16_dump((uint16_t)irep->nlocals, buf, type); /* number of local variable */ - buf += uint16_dump((uint16_t)irep->nregs, buf, type); /* number of register variable */ - buf += uint16_dump(DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type)/* crc */, buf, type); /* offset of isec block */ - - return (int)(buf - buf_top); -} - static int -write_iseq_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) +write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { - char *buf_top = buf; - int iseq_no; - - buf += uint32_dump((uint32_t)irep->ilen, buf, type); /* number of opcode */ - - for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { - buf += uint32_dump((uint32_t)irep->iseq[iseq_no], buf, type); /* opcode */ - } - - return (int)(buf - buf_top); -} - -static int -write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) -{ - int pool_no; - mrb_value str; - char *buf_top = buf; - char *char_buf; - uint16_t buf_size =0; - uint16_t len =0; int result; + size_t pool_no; + uint8_t *cur = buf; + size_t buf_size, len; + mrb_value str; + char *char_buf = NULL; buf_size = MRB_DUMP_DEFAULT_STR_LEN; char_buf = (char *)mrb_malloc(mrb, buf_size); @@ -352,10 +117,10 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) goto error_exit; } - buf += uint32_dump((uint32_t)irep->plen, buf, type); /* number of pool */ + cur += uint32_to_bin(irep->plen, cur); /* number of pool */ for (pool_no = 0; pool_no < irep->plen; pool_no++) { - buf += uint8_dump(mrb_type(irep->pool[pool_no]), buf, type); /* data type */ + cur += uint8_to_bin(mrb_type(irep->pool[pool_no]), cur); /* data type */ memset(char_buf, 0, buf_size); switch (mrb_type(irep->pool[pool_no])) { @@ -371,7 +136,7 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) case MRB_TT_STRING: str = irep->pool[pool_no]; - len = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type); + len = RSTRING_LEN(str); if (len > buf_size - 1) { buf_size = len + 1; char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size); @@ -381,371 +146,303 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) } memset(char_buf, 0, buf_size); } - str_dump(RSTRING_PTR(str), char_buf, RSTRING_LEN(str), type); + memcpy(char_buf, RSTRING_PTR(str), RSTRING_LEN(str)); break; default: - buf += uint16_dump(0, buf, type); /* data length = 0 */ + len = 0; continue; } - buf += uint16_dump(len, buf, type); /* data length */ - - memcpy(buf, char_buf, len); - buf += len; + cur += uint16_to_bin(len, cur); /* data length */ + memcpy(cur, char_buf, len); + cur += len; } + result = (int)(cur - buf); - result = (int)(buf - buf_top); error_exit: mrb_free(mrb, char_buf); return result; } + +static size_t +get_syms_block_size(mrb_state *mrb, mrb_irep *irep) +{ + size_t size = 0; + size_t sym_no; + size_t len; + + size += sizeof(uint32_t); /* slen */ + for (sym_no = 0; sym_no < irep->slen; sym_no++) { + size += sizeof(uint16_t); /* snl(n) */ + if (irep->syms[sym_no] != 0) { + mrb_sym2name_len(mrb, irep->syms[sym_no], &len); + size += len; /* sn(n) */ + } + } + + return size; +} + static int -write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) +write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { - int sym_no; - char *buf_top = buf; - char *char_buf; - uint16_t buf_size =0; + int result; + size_t sym_no; + size_t buf_size; + uint8_t *cur = buf; + uint16_t nlen; + char *char_buf = NULL; + const char *name; buf_size = MRB_DUMP_DEFAULT_STR_LEN; char_buf = (char *)mrb_malloc(mrb, buf_size); - if (char_buf == NULL) + if (char_buf == NULL) { + result = MRB_DUMP_GENERAL_FAILURE; goto error_exit; + } - buf += uint32_dump((uint32_t)irep->slen, buf, type); /* number of symbol */ + cur += uint32_to_bin(irep->slen, cur); /* number of symbol */ for (sym_no = 0; sym_no < irep->slen; sym_no++) { - const char * name; - uint16_t nlen =0; - if (irep->syms[sym_no] != 0) { size_t len; name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); if (len > UINT16_MAX) goto error_exit; - nlen = str_dump_len((char*)name, len, type); - if ( nlen > buf_size - 1) { + nlen = (uint16_t)len; + if (nlen > buf_size - 1) { buf_size = nlen + 1; char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size); - if (char_buf == NULL) + if (char_buf == NULL) { + result = MRB_DUMP_GENERAL_FAILURE; goto error_exit; + } } memset(char_buf, 0, buf_size); - str_dump((char*)name, char_buf, len, type); + memcpy(char_buf, name, len); - buf += uint16_dump(nlen, buf, type); /* length of symbol name */ - memcpy(buf, char_buf, nlen); /* symbol name */ - buf += nlen; + cur += uint16_to_bin(nlen, cur); /* length of symbol name */ + memcpy(cur, char_buf, nlen); /* symbol name */ + cur += nlen; } else { - buf += uint16_dump(MRB_DUMP_NULL_SYM_LEN, buf, type); /* length of symbol name */ + cur += uint16_to_bin(MRB_DUMP_NULL_SYM_LEN, cur); /* length of symbol name */ } } + result = (int)(cur - buf); error_exit: mrb_free(mrb, char_buf); - return (int)(buf - buf_top); + return result; } -static int -calc_crc_section(mrb_state *mrb, mrb_irep *irep, uint16_t *crc, int section) + + +static size_t +get_irep_record_size(mrb_state *mrb, mrb_irep *irep) { - char *buf, *buf_top; - uint32_t buf_size; - int type = DUMP_TYPE_BIN; - int result; + uint32_t size = 0; - switch (section) { - case DUMP_IREP_HEADER: buf_size = get_irep_header_size(mrb, type); break; - case DUMP_ISEQ_BLOCK: buf_size = get_iseq_block_size(mrb, irep, type); break; - case DUMP_POOL_BLOCK: buf_size = get_pool_block_size(mrb, irep, type); break; - case DUMP_SYMS_BLOCK: buf_size = get_syms_block_size(mrb, irep, type); break; - default: return MRB_DUMP_GENERAL_FAILURE; - } + //size += sizeof(uint16_t); /* rlen */ + size += get_irep_header_size(mrb); + size += get_iseq_block_size(mrb, irep); + size += get_pool_block_size(mrb, irep); + size += get_syms_block_size(mrb, irep); - buf = (char *)mrb_calloc(mrb, 1, buf_size); - if (buf == NULL) - return MRB_DUMP_GENERAL_FAILURE; + return size; +} - buf_top = buf; - - switch (section) { - case DUMP_IREP_HEADER: - result = write_irep_header(mrb, irep, buf, type); - break; - case DUMP_ISEQ_BLOCK: - result = write_iseq_block(mrb, irep, buf, type); - break; - case DUMP_POOL_BLOCK: - result = write_pool_block(mrb, irep, buf, type); - break; - case DUMP_SYMS_BLOCK: - result = write_syms_block(mrb, irep, buf, type); - break; - default: - result = MRB_DUMP_GENERAL_FAILURE; - break; /* Already checked above. */ +static int +write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, uint32_t *irep_record_size) +{ + if (irep == NULL) { + return MRB_DUMP_INVALID_IREP; } - if (result < 0) { - goto error_exit; + + *irep_record_size = get_irep_record_size(mrb, irep); + if (*irep_record_size == 0) { + return MRB_DUMP_GENERAL_FAILURE; } - buf += result; - *crc = calc_crc_16_ccitt((unsigned char*)buf_top, (int)(buf - buf_top)); + memset(bin, 0, *irep_record_size); - mrb_free(mrb, buf_top); + //bin += uint16_to_bin(*irep_record_size, bin); + bin += write_irep_header(mrb, irep, bin); + bin += write_iseq_block(mrb, irep, bin); + bin += write_pool_block(mrb, irep, bin); + bin += write_syms_block(mrb, irep, bin); - result = MRB_DUMP_OK; - error_exit: - return result; + return MRB_DUMP_OK; } -static uint16_t -calc_rite_header_crc(mrb_state *mrb, int top, rite_binary_header *binary_header, uint32_t rbds, int type) +static size_t +mrb_write_eof(mrb_state *mrb, uint8_t *bin) { - memcpy( binary_header, def_rite_binary_header, sizeof(*binary_header)); + struct rite_binary_footer footer; - uint32_dump(rbds, (char*)binary_header->rbds, type); - uint16_dump((uint16_t)mrb->irep_len, (char*)binary_header->nirep, type); - uint16_dump((uint16_t)top, (char*)binary_header->sirep, type); + memcpy(footer.section_identify, RITE_BINARY_EOF, sizeof(footer.section_identify)); + uint32_to_bin(sizeof(struct rite_binary_footer), footer.section_size); + memcpy(bin, &footer, sizeof(struct rite_binary_footer)); - return calc_crc_16_ccitt((unsigned char*)binary_header, sizeof(*binary_header)); + return sizeof(struct rite_binary_footer); } + static int -write_rite_header(mrb_state *mrb, int top, char* bin, uint32_t rbds) -{ - rite_binary_header *binary_header; - uint16_t crc; - int type = DUMP_TYPE_BIN; +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; - binary_header = (rite_binary_header*)bin; - crc = calc_rite_header_crc(mrb, top, binary_header, rbds, type); - bin += sizeof(*binary_header); - uint16_dump(crc, bin, type); + memcpy(header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(header->section_identify)); + uint32_to_bin(section_size, header->section_size); + memcpy(header->rite_version, RITE_VM_VER, sizeof(header->rite_version)); + uint16_to_bin(nirep, header->nirep); + uint16_to_bin(sirep, header->sirep); return MRB_DUMP_OK; } static int -calc_rite_file_header(mrb_state *mrb, int top, uint32_t rbds, rite_file_header *file_header) +mrb_write_section_irep(mrb_state *mrb, size_t start_index, uint8_t *bin) { - rite_binary_header *binary_header, b_header; - uint16_t crc; - int type; + int result; + size_t irep_no; + uint32_t section_size = 0, rlen = 0; /* size of irep record */ + uint8_t *cur = bin; + + if (mrb == NULL || start_index >= mrb->irep_len || bin == NULL) { + return MRB_DUMP_INVALID_ARGUMENT; + } - /* calc crc */ - type = DUMP_TYPE_BIN; - binary_header = &b_header; - crc = calc_rite_header_crc(mrb, top, binary_header, rbds, type); + cur += sizeof(struct rite_section_irep_header); + section_size += sizeof(struct rite_section_irep_header); - /* dump rbc header */ - memcpy( file_header, def_rite_file_header, sizeof(*file_header)); + for (irep_no = start_index; irep_no < mrb->irep_len; irep_no++) { + result = write_irep_record(mrb, mrb->irep[irep_no], cur, &rlen); + if (result != MRB_DUMP_OK) { + return result; + } + cur += rlen; + section_size += rlen; + } - type = DUMP_TYPE_HEX; - uint32_dump(rbds, (char*)file_header->rbds, type); - uint16_dump((uint16_t)mrb->irep_len, (char*)file_header->nirep, type); - uint16_dump((uint16_t)top, (char*)file_header->sirep, type); - uint16_dump(crc, (char*)file_header->hcrc, type); + mrb_write_section_irep_header(mrb, section_size, mrb->irep_len - start_index, start_index, bin); return MRB_DUMP_OK; } static int -dump_rite_header(mrb_state *mrb, int top, FILE* fp, uint32_t rbds) -{ - int rc = MRB_DUMP_OK; - rite_file_header file_header; - - if (fseek(fp, 0, SEEK_SET) != 0) - return MRB_DUMP_GENERAL_FAILURE; - - rc = calc_rite_file_header(mrb, top, rbds, &file_header); - if (rc != MRB_DUMP_OK) - return rc; - - if (fwrite(&file_header, sizeof(file_header), 1, fp) != 1) - return MRB_DUMP_WRITE_FAULT; +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; + + memcpy(header->binary_identify, RITE_BINARY_IDENFIFIER, 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)); + 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); return MRB_DUMP_OK; } static int -write_irep_record(mrb_state *mrb, int irep_no, char* bin, uint32_t *rlen, int type) +mrb_dump_irep(mrb_state *mrb, size_t start_index, uint8_t **bin, size_t *bin_size) { - uint32_t irep_record_size; - mrb_irep *irep = mrb->irep[irep_no]; - int section; - - if (irep == NULL) - return MRB_DUMP_INVALID_IREP; + int result = MRB_DUMP_GENERAL_FAILURE; + size_t section_irep_size; + size_t irep_no; + uint8_t *cur = NULL; - /* buf alloc */ - irep_record_size = get_irep_record_size(mrb, irep_no, type); - if (irep_record_size == 0) + if (mrb == NULL || start_index >= mrb->irep_len) { + *bin = NULL; return MRB_DUMP_GENERAL_FAILURE; - - memset( bin, 0, irep_record_size); - - /* rlen */ - *rlen = irep_record_size - DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, type); - - bin += uint32_dump(*rlen, bin, type); - - for (section = 0; section < DUMP_SECTION_NUM; section++) { - int rc; - uint16_t crc; - - switch (section) { - case DUMP_IREP_HEADER: bin += write_irep_header(mrb, irep, bin, type); break; - case DUMP_ISEQ_BLOCK: bin += write_iseq_block(mrb, irep, bin, type); break; - case DUMP_POOL_BLOCK: bin += write_pool_block(mrb, irep, bin, type); break; - case DUMP_SYMS_BLOCK: bin += write_syms_block(mrb, irep, bin, type); break; - default: break; - } - - rc = calc_crc_section(mrb, irep, &crc, section); - if (rc != MRB_DUMP_OK) - return rc; - - bin += uint16_dump(crc, bin, type); /* crc */ } - return MRB_DUMP_OK; -} - -static int -dump_irep_record(mrb_state *mrb, int irep_no, FILE* fp, uint32_t *rlen) -{ - int rc = MRB_DUMP_OK; - uint32_t irep_record_size; - char *buf; - mrb_irep *irep = mrb->irep[irep_no]; - - if (irep == NULL) - return MRB_DUMP_INVALID_IREP; + 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]); + } - /* buf alloc */ - irep_record_size = get_irep_record_size(mrb, irep_no, DUMP_TYPE_HEX); - if (irep_record_size == 0) - return MRB_DUMP_GENERAL_FAILURE; + *bin_size += sizeof(struct rite_binary_header) + section_irep_size + sizeof(struct rite_binary_footer); + cur = *bin = (uint8_t *)mrb_malloc(mrb, *bin_size); + if(cur == NULL) { + goto error_exit; + } - buf = (char *)mrb_calloc(mrb, 1, irep_record_size); - if (buf == NULL) - return MRB_DUMP_GENERAL_FAILURE; + cur += sizeof(struct rite_binary_header); - rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX); - if (rc != MRB_DUMP_OK) { - rc = MRB_DUMP_GENERAL_FAILURE; + result = mrb_write_section_irep(mrb, start_index, cur); + if (result != MRB_DUMP_OK) { goto error_exit; } + cur += section_irep_size; + mrb_write_eof(mrb, cur); - if (fwrite(buf, irep_record_size, 1, fp) != 1) - rc = MRB_DUMP_WRITE_FAULT; + result = write_rite_binary_header(mrb, *bin_size, *bin); error_exit: - mrb_free(mrb, buf); - - return rc; -} - -static int -mrb_write_irep(mrb_state *mrb, int top, char *bin) -{ - int rc; - uint32_t rlen=0; /* size of irep record */ - int irep_no; - char *bin_top; - - if (mrb == NULL || top < 0 || top >= mrb->irep_len || bin == NULL) - return MRB_DUMP_INVALID_ARGUMENT; - - bin_top = bin; - bin += sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */; - - for (irep_no=top; irep_no<mrb->irep_len; irep_no++) { - rc = write_irep_record(mrb, irep_no, bin, &rlen, DUMP_TYPE_BIN); - if (rc != MRB_DUMP_OK) - return rc; - - bin += (rlen + DUMP_SIZE(MRB_DUMP_SIZE_OF_LONG, DUMP_TYPE_BIN)); + if (result != MRB_DUMP_OK) { + mrb_free(mrb, *bin); + *bin = NULL; } + return result; +} - bin += uint32_dump(0, bin, DUMP_TYPE_BIN); /* end of file */ - - rc = write_rite_header(mrb, top, bin_top, (bin - bin_top)); //TODO: Remove top(SIREP) - return rc; -} +#ifdef ENABLE_STDIO int -mrb_dump_irep(mrb_state *mrb, int top, FILE* fp) +mrb_dump_irep_binary(mrb_state *mrb, size_t start_index, FILE* fp) { - int rc; - uint32_t rbds=0; /* size of Rite Binary Data */ - uint32_t rlen=0; /* size of irep record */ - int irep_no; + uint8_t *bin = NULL; + size_t bin_size = 0; + int result; - if (mrb == NULL || top < 0 || top >= mrb->irep_len || fp == NULL) + if (fp == NULL) { return MRB_DUMP_INVALID_ARGUMENT; - - if (fwrite(&def_rite_file_header, sizeof(rite_file_header), 1, fp) != 1) /* dummy write */ - return MRB_DUMP_WRITE_FAULT; - - for (irep_no=top; irep_no<mrb->irep_len; irep_no++) { - rc = dump_irep_record(mrb, irep_no, fp, &rlen); - if (rc != MRB_DUMP_OK) - return rc; - - rbds += rlen; } - if (fwrite("00000000"/* end of file */, 8, 1, fp) != 1) - return MRB_DUMP_WRITE_FAULT; - - rc = dump_rite_header(mrb, top, fp, rbds); //TODO: Remove top(SIREP) + result = mrb_dump_irep(mrb, start_index, &bin, &bin_size); + if (result == MRB_DUMP_OK) { + fwrite(bin, bin_size, 1, fp); + } - return rc; + mrb_free(mrb, bin); + return result; } int -mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname) +mrb_dump_irep_cfunc(mrb_state *mrb, size_t start_index, FILE *fp, const char *initname) { - int rc; - int irep_no; - char *buf; - int buf_size = 0; - int buf_idx = 0; + uint8_t *bin = NULL; + size_t bin_size = 0, bin_idx = 0; + int result; - if (mrb == NULL || n < 0 || n >= mrb->irep_len || f == NULL || initname == NULL) + if (fp == NULL || initname == NULL) { return MRB_DUMP_INVALID_ARGUMENT; + } - buf_size = sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */; - for (irep_no=n; irep_no<mrb->irep_len; irep_no++) - buf_size += get_irep_record_size(mrb, irep_no, DUMP_TYPE_BIN); - buf_size += MRB_DUMP_SIZE_OF_LONG; /* end of file */ - - buf = (char *)mrb_malloc(mrb, buf_size); - if (buf == NULL) - return MRB_DUMP_GENERAL_FAILURE; - - rc = mrb_write_irep(mrb, n, buf); - - if (rc == MRB_DUMP_OK) { - fprintf(f, "const char %s[] = {", initname); - while (buf_idx < buf_size ) { - if (buf_idx % 16 == 0 ) fputs("\n", f); - fprintf(f, "0x%02x,", (unsigned char)buf[buf_idx++]); + result = mrb_dump_irep(mrb, start_index, &bin, &bin_size); + if (result == MRB_DUMP_OK) { + fprintf(fp, "const uint8_t %s[] = {", initname); + while (bin_idx < bin_size) { + if (bin_idx % 16 == 0 ) fputs("\n", fp); + fprintf(fp, "0x%02x,", bin[bin_idx++]); } - fputs("\n};\n", f); + fputs("\n};\n", fp); } - mrb_free(mrb, buf); - - return rc; + mrb_free(mrb, bin); + return result; } #endif /* ENABLE_STDIO */ |
