mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
mbed-mruby
How to use
Class
src/dump.c@1:8ccd1d494a4b, 2015-04-13 (annotated)
- Committer:
- mzta
- Date:
- Mon Apr 13 05:20:15 2015 +0000
- Revision:
- 1:8ccd1d494a4b
- Parent:
- 0:158c61bb030f
- code refactoring.; - add SPI, SPISlave, I2C class to mruby-mbed (Incomplete).
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mzta | 0:158c61bb030f | 1 | /* |
mzta | 0:158c61bb030f | 2 | ** dump.c - mruby binary dumper (mrbc binary format) |
mzta | 0:158c61bb030f | 3 | ** |
mzta | 0:158c61bb030f | 4 | ** See Copyright Notice in mruby.h |
mzta | 0:158c61bb030f | 5 | */ |
mzta | 0:158c61bb030f | 6 | |
mzta | 0:158c61bb030f | 7 | #include <ctype.h> |
mzta | 0:158c61bb030f | 8 | #include <string.h> |
mzta | 0:158c61bb030f | 9 | #include <limits.h> |
mzta | 0:158c61bb030f | 10 | #include "mruby/dump.h" |
mzta | 0:158c61bb030f | 11 | #include "mruby/string.h" |
mzta | 0:158c61bb030f | 12 | #include "mruby/irep.h" |
mzta | 0:158c61bb030f | 13 | #include "mruby/numeric.h" |
mzta | 0:158c61bb030f | 14 | #include "mruby/debug.h" |
mzta | 0:158c61bb030f | 15 | |
mzta | 0:158c61bb030f | 16 | #define FLAG_BYTEORDER_NATIVE 2 |
mzta | 0:158c61bb030f | 17 | #define FLAG_BYTEORDER_NONATIVE 0 |
mzta | 0:158c61bb030f | 18 | |
mzta | 0:158c61bb030f | 19 | #ifdef ENABLE_STDIO |
mzta | 0:158c61bb030f | 20 | |
mzta | 0:158c61bb030f | 21 | static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); |
mzta | 0:158c61bb030f | 22 | |
mzta | 0:158c61bb030f | 23 | #if UINT32_MAX > SIZE_MAX |
mzta | 0:158c61bb030f | 24 | # error This code cannot be built on your environment. |
mzta | 0:158c61bb030f | 25 | #endif |
mzta | 0:158c61bb030f | 26 | |
mzta | 0:158c61bb030f | 27 | static size_t |
mzta | 0:158c61bb030f | 28 | write_padding(uint8_t *buf) |
mzta | 0:158c61bb030f | 29 | { |
mzta | 0:158c61bb030f | 30 | const size_t align = MRB_DUMP_ALIGNMENT; |
mzta | 0:158c61bb030f | 31 | size_t pad_len = -(intptr_t)buf & (align-1); |
mzta | 0:158c61bb030f | 32 | if (pad_len > 0) { |
mzta | 0:158c61bb030f | 33 | memset(buf, 0, pad_len); |
mzta | 0:158c61bb030f | 34 | } |
mzta | 0:158c61bb030f | 35 | return pad_len; |
mzta | 0:158c61bb030f | 36 | } |
mzta | 0:158c61bb030f | 37 | |
mzta | 0:158c61bb030f | 38 | static size_t |
mzta | 0:158c61bb030f | 39 | get_irep_header_size(mrb_state *mrb) |
mzta | 0:158c61bb030f | 40 | { |
mzta | 0:158c61bb030f | 41 | size_t size = 0; |
mzta | 0:158c61bb030f | 42 | |
mzta | 0:158c61bb030f | 43 | size += sizeof(uint32_t) * 1; |
mzta | 0:158c61bb030f | 44 | size += sizeof(uint16_t) * 3; |
mzta | 0:158c61bb030f | 45 | |
mzta | 0:158c61bb030f | 46 | return size; |
mzta | 0:158c61bb030f | 47 | } |
mzta | 0:158c61bb030f | 48 | |
mzta | 0:158c61bb030f | 49 | static ptrdiff_t |
mzta | 0:158c61bb030f | 50 | write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) |
mzta | 0:158c61bb030f | 51 | { |
mzta | 0:158c61bb030f | 52 | uint8_t *cur = buf; |
mzta | 0:158c61bb030f | 53 | |
mzta | 0:158c61bb030f | 54 | cur += uint32_to_bin(get_irep_record_size_1(mrb, irep), cur); /* record size */ |
mzta | 0:158c61bb030f | 55 | cur += uint16_to_bin((uint16_t)irep->nlocals, cur); /* number of local variable */ |
mzta | 0:158c61bb030f | 56 | cur += uint16_to_bin((uint16_t)irep->nregs, cur); /* number of register variable */ |
mzta | 0:158c61bb030f | 57 | cur += uint16_to_bin((uint16_t)irep->rlen, cur); /* number of child irep */ |
mzta | 0:158c61bb030f | 58 | |
mzta | 0:158c61bb030f | 59 | return cur - buf; |
mzta | 0:158c61bb030f | 60 | } |
mzta | 0:158c61bb030f | 61 | |
mzta | 0:158c61bb030f | 62 | |
mzta | 0:158c61bb030f | 63 | static size_t |
mzta | 0:158c61bb030f | 64 | get_iseq_block_size(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 65 | { |
mzta | 0:158c61bb030f | 66 | size_t size = 0; |
mzta | 0:158c61bb030f | 67 | |
mzta | 0:158c61bb030f | 68 | size += sizeof(uint32_t); /* ilen */ |
mzta | 0:158c61bb030f | 69 | size += sizeof(uint32_t); /* max padding */ |
mzta | 0:158c61bb030f | 70 | size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */ |
mzta | 0:158c61bb030f | 71 | |
mzta | 0:158c61bb030f | 72 | return size; |
mzta | 0:158c61bb030f | 73 | } |
mzta | 0:158c61bb030f | 74 | |
mzta | 0:158c61bb030f | 75 | static ptrdiff_t |
mzta | 0:158c61bb030f | 76 | write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags) |
mzta | 0:158c61bb030f | 77 | { |
mzta | 0:158c61bb030f | 78 | uint8_t *cur = buf; |
mzta | 0:158c61bb030f | 79 | uint32_t iseq_no; |
mzta | 0:158c61bb030f | 80 | |
mzta | 0:158c61bb030f | 81 | cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */ |
mzta | 0:158c61bb030f | 82 | cur += write_padding(cur); |
mzta | 0:158c61bb030f | 83 | if (flags & FLAG_BYTEORDER_NATIVE) { |
mzta | 0:158c61bb030f | 84 | memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); |
mzta | 0:158c61bb030f | 85 | cur += irep->ilen * sizeof(mrb_code); |
mzta | 0:158c61bb030f | 86 | } |
mzta | 0:158c61bb030f | 87 | else { |
mzta | 0:158c61bb030f | 88 | for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { |
mzta | 0:158c61bb030f | 89 | cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ |
mzta | 0:158c61bb030f | 90 | } |
mzta | 0:158c61bb030f | 91 | } |
mzta | 0:158c61bb030f | 92 | |
mzta | 0:158c61bb030f | 93 | return cur - buf; |
mzta | 0:158c61bb030f | 94 | } |
mzta | 0:158c61bb030f | 95 | |
mzta | 0:158c61bb030f | 96 | |
mzta | 0:158c61bb030f | 97 | static size_t |
mzta | 0:158c61bb030f | 98 | get_pool_block_size(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 99 | { |
mzta | 0:158c61bb030f | 100 | size_t size = 0; |
mzta | 0:158c61bb030f | 101 | size_t pool_no; |
mzta | 0:158c61bb030f | 102 | mrb_value str; |
mzta | 0:158c61bb030f | 103 | char buf[32]; |
mzta | 0:158c61bb030f | 104 | |
mzta | 0:158c61bb030f | 105 | size += sizeof(uint32_t); /* plen */ |
mzta | 0:158c61bb030f | 106 | size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */ |
mzta | 0:158c61bb030f | 107 | |
mzta | 0:158c61bb030f | 108 | for (pool_no = 0; pool_no < irep->plen; pool_no++) { |
mzta | 0:158c61bb030f | 109 | int ai = mrb_gc_arena_save(mrb); |
mzta | 0:158c61bb030f | 110 | |
mzta | 0:158c61bb030f | 111 | switch (mrb_type(irep->pool[pool_no])) { |
mzta | 0:158c61bb030f | 112 | case MRB_TT_FIXNUM: |
mzta | 0:158c61bb030f | 113 | str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); |
mzta | 0:158c61bb030f | 114 | { |
mzta | 0:158c61bb030f | 115 | mrb_int len = RSTRING_LEN(str); |
mzta | 0:158c61bb030f | 116 | mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 117 | size += (size_t)len; |
mzta | 0:158c61bb030f | 118 | } |
mzta | 0:158c61bb030f | 119 | break; |
mzta | 0:158c61bb030f | 120 | |
mzta | 0:158c61bb030f | 121 | case MRB_TT_FLOAT: |
mzta | 0:158c61bb030f | 122 | { |
mzta | 0:158c61bb030f | 123 | int len; |
mzta | 0:158c61bb030f | 124 | len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no])); |
mzta | 0:158c61bb030f | 125 | mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 126 | size += (size_t)len; |
mzta | 0:158c61bb030f | 127 | } |
mzta | 0:158c61bb030f | 128 | break; |
mzta | 0:158c61bb030f | 129 | |
mzta | 0:158c61bb030f | 130 | case MRB_TT_STRING: |
mzta | 0:158c61bb030f | 131 | { |
mzta | 0:158c61bb030f | 132 | mrb_int len = RSTRING_LEN(irep->pool[pool_no]); |
mzta | 0:158c61bb030f | 133 | mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 134 | size += (size_t)len; |
mzta | 0:158c61bb030f | 135 | } |
mzta | 0:158c61bb030f | 136 | break; |
mzta | 0:158c61bb030f | 137 | |
mzta | 0:158c61bb030f | 138 | default: |
mzta | 0:158c61bb030f | 139 | break; |
mzta | 0:158c61bb030f | 140 | } |
mzta | 0:158c61bb030f | 141 | mrb_gc_arena_restore(mrb, ai); |
mzta | 0:158c61bb030f | 142 | } |
mzta | 0:158c61bb030f | 143 | |
mzta | 0:158c61bb030f | 144 | return size; |
mzta | 0:158c61bb030f | 145 | } |
mzta | 0:158c61bb030f | 146 | |
mzta | 0:158c61bb030f | 147 | static ptrdiff_t |
mzta | 0:158c61bb030f | 148 | write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) |
mzta | 0:158c61bb030f | 149 | { |
mzta | 0:158c61bb030f | 150 | size_t pool_no; |
mzta | 0:158c61bb030f | 151 | uint8_t *cur = buf; |
mzta | 0:158c61bb030f | 152 | uint16_t len; |
mzta | 0:158c61bb030f | 153 | mrb_value str; |
mzta | 0:158c61bb030f | 154 | const char *char_ptr; |
mzta | 0:158c61bb030f | 155 | char char_buf[30]; |
mzta | 0:158c61bb030f | 156 | |
mzta | 0:158c61bb030f | 157 | cur += uint32_to_bin(irep->plen, cur); /* number of pool */ |
mzta | 0:158c61bb030f | 158 | |
mzta | 0:158c61bb030f | 159 | for (pool_no = 0; pool_no < irep->plen; pool_no++) { |
mzta | 0:158c61bb030f | 160 | int ai = mrb_gc_arena_save(mrb); |
mzta | 0:158c61bb030f | 161 | |
mzta | 0:158c61bb030f | 162 | switch (mrb_type(irep->pool[pool_no])) { |
mzta | 0:158c61bb030f | 163 | case MRB_TT_FIXNUM: |
mzta | 0:158c61bb030f | 164 | cur += uint8_to_bin(IREP_TT_FIXNUM, cur); /* data type */ |
mzta | 0:158c61bb030f | 165 | str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); |
mzta | 0:158c61bb030f | 166 | char_ptr = RSTRING_PTR(str); |
mzta | 0:158c61bb030f | 167 | { |
mzta | 0:158c61bb030f | 168 | mrb_int tlen; |
mzta | 0:158c61bb030f | 169 | |
mzta | 0:158c61bb030f | 170 | tlen = RSTRING_LEN(str); |
mzta | 0:158c61bb030f | 171 | mrb_assert_int_fit(mrb_int, tlen, uint16_t, UINT16_MAX); |
mzta | 0:158c61bb030f | 172 | len = (uint16_t)tlen; |
mzta | 0:158c61bb030f | 173 | } |
mzta | 0:158c61bb030f | 174 | break; |
mzta | 0:158c61bb030f | 175 | |
mzta | 0:158c61bb030f | 176 | case MRB_TT_FLOAT: |
mzta | 0:158c61bb030f | 177 | cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ |
mzta | 0:158c61bb030f | 178 | { |
mzta | 0:158c61bb030f | 179 | int tlen; |
mzta | 0:158c61bb030f | 180 | tlen = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no])); |
mzta | 0:158c61bb030f | 181 | mrb_assert_int_fit(int, tlen, uint16_t, UINT16_MAX); |
mzta | 0:158c61bb030f | 182 | len = (uint16_t)tlen; |
mzta | 0:158c61bb030f | 183 | } |
mzta | 0:158c61bb030f | 184 | char_ptr = &char_buf[0]; |
mzta | 0:158c61bb030f | 185 | break; |
mzta | 0:158c61bb030f | 186 | |
mzta | 0:158c61bb030f | 187 | case MRB_TT_STRING: |
mzta | 0:158c61bb030f | 188 | cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */ |
mzta | 0:158c61bb030f | 189 | char_ptr = RSTRING_PTR(irep->pool[pool_no]); |
mzta | 0:158c61bb030f | 190 | { |
mzta | 0:158c61bb030f | 191 | mrb_int tlen; |
mzta | 0:158c61bb030f | 192 | |
mzta | 0:158c61bb030f | 193 | tlen = RSTRING_LEN(irep->pool[pool_no]); |
mzta | 0:158c61bb030f | 194 | mrb_assert_int_fit(mrb_int, tlen, uint16_t, UINT16_MAX); |
mzta | 0:158c61bb030f | 195 | len = (uint16_t)tlen; |
mzta | 0:158c61bb030f | 196 | } |
mzta | 0:158c61bb030f | 197 | break; |
mzta | 0:158c61bb030f | 198 | |
mzta | 0:158c61bb030f | 199 | default: |
mzta | 0:158c61bb030f | 200 | continue; |
mzta | 0:158c61bb030f | 201 | } |
mzta | 0:158c61bb030f | 202 | |
mzta | 0:158c61bb030f | 203 | cur += uint16_to_bin(len, cur); /* data length */ |
mzta | 0:158c61bb030f | 204 | memcpy(cur, char_ptr, (size_t)len); |
mzta | 0:158c61bb030f | 205 | cur += len; |
mzta | 0:158c61bb030f | 206 | |
mzta | 0:158c61bb030f | 207 | mrb_gc_arena_restore(mrb, ai); |
mzta | 0:158c61bb030f | 208 | } |
mzta | 0:158c61bb030f | 209 | |
mzta | 0:158c61bb030f | 210 | return cur - buf; |
mzta | 0:158c61bb030f | 211 | } |
mzta | 0:158c61bb030f | 212 | |
mzta | 0:158c61bb030f | 213 | |
mzta | 0:158c61bb030f | 214 | static size_t |
mzta | 0:158c61bb030f | 215 | get_syms_block_size(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 216 | { |
mzta | 0:158c61bb030f | 217 | size_t size = 0; |
mzta | 0:158c61bb030f | 218 | uint32_t sym_no; |
mzta | 0:158c61bb030f | 219 | mrb_int len; |
mzta | 0:158c61bb030f | 220 | |
mzta | 0:158c61bb030f | 221 | size += sizeof(uint32_t); /* slen */ |
mzta | 0:158c61bb030f | 222 | for (sym_no = 0; sym_no < irep->slen; sym_no++) { |
mzta | 0:158c61bb030f | 223 | size += sizeof(uint16_t); /* snl(n) */ |
mzta | 0:158c61bb030f | 224 | if (irep->syms[sym_no] != 0) { |
mzta | 0:158c61bb030f | 225 | mrb_sym2name_len(mrb, irep->syms[sym_no], &len); |
mzta | 0:158c61bb030f | 226 | size += len + 1; /* sn(n) + null char */ |
mzta | 0:158c61bb030f | 227 | } |
mzta | 0:158c61bb030f | 228 | } |
mzta | 0:158c61bb030f | 229 | |
mzta | 0:158c61bb030f | 230 | return size; |
mzta | 0:158c61bb030f | 231 | } |
mzta | 0:158c61bb030f | 232 | |
mzta | 0:158c61bb030f | 233 | static ptrdiff_t |
mzta | 0:158c61bb030f | 234 | write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) |
mzta | 0:158c61bb030f | 235 | { |
mzta | 0:158c61bb030f | 236 | uint32_t sym_no; |
mzta | 0:158c61bb030f | 237 | uint8_t *cur = buf; |
mzta | 0:158c61bb030f | 238 | const char *name; |
mzta | 0:158c61bb030f | 239 | |
mzta | 0:158c61bb030f | 240 | cur += uint32_to_bin(irep->slen, cur); /* number of symbol */ |
mzta | 0:158c61bb030f | 241 | |
mzta | 0:158c61bb030f | 242 | for (sym_no = 0; sym_no < irep->slen; sym_no++) { |
mzta | 0:158c61bb030f | 243 | if (irep->syms[sym_no] != 0) { |
mzta | 0:158c61bb030f | 244 | mrb_int len; |
mzta | 0:158c61bb030f | 245 | |
mzta | 0:158c61bb030f | 246 | name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); |
mzta | 0:158c61bb030f | 247 | |
mzta | 0:158c61bb030f | 248 | mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX); |
mzta | 0:158c61bb030f | 249 | cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */ |
mzta | 0:158c61bb030f | 250 | memcpy(cur, name, len); /* symbol name */ |
mzta | 0:158c61bb030f | 251 | cur += (uint16_t)len; |
mzta | 0:158c61bb030f | 252 | *cur++ = '\0'; |
mzta | 0:158c61bb030f | 253 | } |
mzta | 0:158c61bb030f | 254 | else { |
mzta | 0:158c61bb030f | 255 | cur += uint16_to_bin(MRB_DUMP_NULL_SYM_LEN, cur); /* length of symbol name */ |
mzta | 0:158c61bb030f | 256 | } |
mzta | 0:158c61bb030f | 257 | } |
mzta | 0:158c61bb030f | 258 | |
mzta | 0:158c61bb030f | 259 | return cur - buf; |
mzta | 0:158c61bb030f | 260 | } |
mzta | 0:158c61bb030f | 261 | |
mzta | 0:158c61bb030f | 262 | static size_t |
mzta | 0:158c61bb030f | 263 | get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 264 | { |
mzta | 0:158c61bb030f | 265 | size_t size = 0; |
mzta | 0:158c61bb030f | 266 | |
mzta | 0:158c61bb030f | 267 | size += get_irep_header_size(mrb); |
mzta | 0:158c61bb030f | 268 | size += get_iseq_block_size(mrb, irep); |
mzta | 0:158c61bb030f | 269 | size += get_pool_block_size(mrb, irep); |
mzta | 0:158c61bb030f | 270 | size += get_syms_block_size(mrb, irep); |
mzta | 0:158c61bb030f | 271 | return size; |
mzta | 0:158c61bb030f | 272 | } |
mzta | 0:158c61bb030f | 273 | |
mzta | 0:158c61bb030f | 274 | static size_t |
mzta | 0:158c61bb030f | 275 | get_irep_record_size(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 276 | { |
mzta | 0:158c61bb030f | 277 | size_t size = 0; |
mzta | 0:158c61bb030f | 278 | size_t irep_no; |
mzta | 0:158c61bb030f | 279 | |
mzta | 0:158c61bb030f | 280 | size = get_irep_record_size_1(mrb, irep); |
mzta | 0:158c61bb030f | 281 | for (irep_no = 0; irep_no < irep->rlen; irep_no++) { |
mzta | 0:158c61bb030f | 282 | size += get_irep_record_size(mrb, irep->reps[irep_no]); |
mzta | 0:158c61bb030f | 283 | } |
mzta | 0:158c61bb030f | 284 | return size; |
mzta | 0:158c61bb030f | 285 | } |
mzta | 0:158c61bb030f | 286 | |
mzta | 0:158c61bb030f | 287 | static int |
mzta | 0:158c61bb030f | 288 | write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *irep_record_size, uint8_t flags) |
mzta | 0:158c61bb030f | 289 | { |
mzta | 0:158c61bb030f | 290 | uint32_t i; |
mzta | 0:158c61bb030f | 291 | uint8_t *src = bin; |
mzta | 0:158c61bb030f | 292 | |
mzta | 0:158c61bb030f | 293 | if (irep == NULL) { |
mzta | 0:158c61bb030f | 294 | return MRB_DUMP_INVALID_IREP; |
mzta | 0:158c61bb030f | 295 | } |
mzta | 0:158c61bb030f | 296 | |
mzta | 0:158c61bb030f | 297 | *irep_record_size = get_irep_record_size_1(mrb, irep); |
mzta | 0:158c61bb030f | 298 | if (*irep_record_size == 0) { |
mzta | 0:158c61bb030f | 299 | return MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 300 | } |
mzta | 0:158c61bb030f | 301 | |
mzta | 0:158c61bb030f | 302 | bin += write_irep_header(mrb, irep, bin); |
mzta | 0:158c61bb030f | 303 | bin += write_iseq_block(mrb, irep, bin, flags); |
mzta | 0:158c61bb030f | 304 | bin += write_pool_block(mrb, irep, bin); |
mzta | 0:158c61bb030f | 305 | bin += write_syms_block(mrb, irep, bin); |
mzta | 0:158c61bb030f | 306 | |
mzta | 0:158c61bb030f | 307 | for (i = 0; i < irep->rlen; i++) { |
mzta | 0:158c61bb030f | 308 | int result; |
mzta | 0:158c61bb030f | 309 | size_t rsize; |
mzta | 0:158c61bb030f | 310 | |
mzta | 0:158c61bb030f | 311 | result = write_irep_record(mrb, irep->reps[i], bin, &rsize, flags); |
mzta | 0:158c61bb030f | 312 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 313 | return result; |
mzta | 0:158c61bb030f | 314 | } |
mzta | 0:158c61bb030f | 315 | bin += rsize; |
mzta | 0:158c61bb030f | 316 | } |
mzta | 0:158c61bb030f | 317 | *irep_record_size = bin - src; |
mzta | 0:158c61bb030f | 318 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 319 | } |
mzta | 0:158c61bb030f | 320 | |
mzta | 0:158c61bb030f | 321 | static uint32_t |
mzta | 0:158c61bb030f | 322 | write_footer(mrb_state *mrb, uint8_t *bin) |
mzta | 0:158c61bb030f | 323 | { |
mzta | 0:158c61bb030f | 324 | struct rite_binary_footer footer; |
mzta | 0:158c61bb030f | 325 | |
mzta | 0:158c61bb030f | 326 | memcpy(footer.section_identify, RITE_BINARY_EOF, sizeof(footer.section_identify)); |
mzta | 0:158c61bb030f | 327 | uint32_to_bin(sizeof(struct rite_binary_footer), footer.section_size); |
mzta | 0:158c61bb030f | 328 | memcpy(bin, &footer, sizeof(struct rite_binary_footer)); |
mzta | 0:158c61bb030f | 329 | |
mzta | 0:158c61bb030f | 330 | return sizeof(struct rite_binary_footer); |
mzta | 0:158c61bb030f | 331 | } |
mzta | 0:158c61bb030f | 332 | |
mzta | 0:158c61bb030f | 333 | |
mzta | 0:158c61bb030f | 334 | static int |
mzta | 0:158c61bb030f | 335 | write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin) |
mzta | 0:158c61bb030f | 336 | { |
mzta | 0:158c61bb030f | 337 | struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin; |
mzta | 0:158c61bb030f | 338 | |
mzta | 0:158c61bb030f | 339 | memcpy(header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(header->section_identify)); |
mzta | 0:158c61bb030f | 340 | |
mzta | 0:158c61bb030f | 341 | mrb_assert_int_fit(size_t, section_size, uint32_t, UINT32_MAX); |
mzta | 0:158c61bb030f | 342 | uint32_to_bin((uint32_t)section_size, header->section_size); |
mzta | 0:158c61bb030f | 343 | memcpy(header->rite_version, RITE_VM_VER, sizeof(header->rite_version)); |
mzta | 0:158c61bb030f | 344 | |
mzta | 0:158c61bb030f | 345 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 346 | } |
mzta | 0:158c61bb030f | 347 | |
mzta | 0:158c61bb030f | 348 | static int |
mzta | 0:158c61bb030f | 349 | write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *len_p, uint8_t flags) |
mzta | 0:158c61bb030f | 350 | { |
mzta | 0:158c61bb030f | 351 | int result; |
mzta | 0:158c61bb030f | 352 | size_t rsize = 0; |
mzta | 0:158c61bb030f | 353 | uint8_t *cur = bin; |
mzta | 0:158c61bb030f | 354 | |
mzta | 0:158c61bb030f | 355 | if (mrb == NULL || bin == NULL) { |
mzta | 0:158c61bb030f | 356 | return MRB_DUMP_INVALID_ARGUMENT; |
mzta | 0:158c61bb030f | 357 | } |
mzta | 0:158c61bb030f | 358 | |
mzta | 0:158c61bb030f | 359 | cur += sizeof(struct rite_section_irep_header); |
mzta | 0:158c61bb030f | 360 | |
mzta | 0:158c61bb030f | 361 | result = write_irep_record(mrb, irep, cur, &rsize, flags); |
mzta | 0:158c61bb030f | 362 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 363 | return result; |
mzta | 0:158c61bb030f | 364 | } |
mzta | 0:158c61bb030f | 365 | *len_p = cur - bin + rsize; |
mzta | 0:158c61bb030f | 366 | write_section_irep_header(mrb, *len_p, bin); |
mzta | 0:158c61bb030f | 367 | |
mzta | 0:158c61bb030f | 368 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 369 | } |
mzta | 0:158c61bb030f | 370 | |
mzta | 0:158c61bb030f | 371 | static int |
mzta | 0:158c61bb030f | 372 | write_section_lineno_header(mrb_state *mrb, size_t section_size, uint8_t *bin) |
mzta | 0:158c61bb030f | 373 | { |
mzta | 0:158c61bb030f | 374 | struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin; |
mzta | 0:158c61bb030f | 375 | |
mzta | 0:158c61bb030f | 376 | memcpy(header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(header->section_identify)); |
mzta | 0:158c61bb030f | 377 | uint32_to_bin((uint32_t)section_size, header->section_size); |
mzta | 0:158c61bb030f | 378 | |
mzta | 0:158c61bb030f | 379 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 380 | } |
mzta | 0:158c61bb030f | 381 | |
mzta | 0:158c61bb030f | 382 | static size_t |
mzta | 0:158c61bb030f | 383 | get_lineno_record_size(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 384 | { |
mzta | 0:158c61bb030f | 385 | size_t size = 0; |
mzta | 0:158c61bb030f | 386 | |
mzta | 0:158c61bb030f | 387 | size += sizeof(uint32_t); /* record size */ |
mzta | 0:158c61bb030f | 388 | size += sizeof(uint16_t); /* filename size */ |
mzta | 0:158c61bb030f | 389 | if (irep->filename) { |
mzta | 0:158c61bb030f | 390 | size += strlen(irep->filename); /* filename */ |
mzta | 0:158c61bb030f | 391 | } |
mzta | 0:158c61bb030f | 392 | size += sizeof(uint32_t); /* niseq */ |
mzta | 0:158c61bb030f | 393 | if (irep->lines) { |
mzta | 0:158c61bb030f | 394 | size += sizeof(uint16_t) * irep->ilen; /* lineno */ |
mzta | 0:158c61bb030f | 395 | } |
mzta | 0:158c61bb030f | 396 | |
mzta | 0:158c61bb030f | 397 | return size; |
mzta | 0:158c61bb030f | 398 | } |
mzta | 0:158c61bb030f | 399 | |
mzta | 0:158c61bb030f | 400 | static size_t |
mzta | 0:158c61bb030f | 401 | write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) |
mzta | 0:158c61bb030f | 402 | { |
mzta | 0:158c61bb030f | 403 | uint8_t *cur = bin; |
mzta | 0:158c61bb030f | 404 | size_t iseq_no; |
mzta | 0:158c61bb030f | 405 | size_t filename_len; |
mzta | 0:158c61bb030f | 406 | ptrdiff_t diff; |
mzta | 0:158c61bb030f | 407 | |
mzta | 0:158c61bb030f | 408 | cur += sizeof(uint32_t); /* record size */ |
mzta | 0:158c61bb030f | 409 | |
mzta | 0:158c61bb030f | 410 | if (irep->filename) { |
mzta | 0:158c61bb030f | 411 | filename_len = strlen(irep->filename); |
mzta | 0:158c61bb030f | 412 | } else { |
mzta | 0:158c61bb030f | 413 | filename_len = 0; |
mzta | 0:158c61bb030f | 414 | } |
mzta | 0:158c61bb030f | 415 | mrb_assert_int_fit(size_t, filename_len, uint16_t, UINT16_MAX); |
mzta | 0:158c61bb030f | 416 | cur += uint16_to_bin((uint16_t)filename_len, cur); /* filename size */ |
mzta | 0:158c61bb030f | 417 | |
mzta | 0:158c61bb030f | 418 | if (filename_len) { |
mzta | 0:158c61bb030f | 419 | memcpy(cur, irep->filename, filename_len); |
mzta | 0:158c61bb030f | 420 | cur += filename_len; /* filename */ |
mzta | 0:158c61bb030f | 421 | } |
mzta | 0:158c61bb030f | 422 | |
mzta | 0:158c61bb030f | 423 | if (irep->lines) { |
mzta | 0:158c61bb030f | 424 | mrb_assert_int_fit(size_t, irep->ilen, uint32_t, UINT32_MAX); |
mzta | 0:158c61bb030f | 425 | cur += uint32_to_bin((uint32_t)(irep->ilen), cur); /* niseq */ |
mzta | 0:158c61bb030f | 426 | for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { |
mzta | 0:158c61bb030f | 427 | cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */ |
mzta | 0:158c61bb030f | 428 | } |
mzta | 0:158c61bb030f | 429 | } |
mzta | 0:158c61bb030f | 430 | else { |
mzta | 0:158c61bb030f | 431 | cur += uint32_to_bin(0, cur); /* niseq */ |
mzta | 0:158c61bb030f | 432 | } |
mzta | 0:158c61bb030f | 433 | |
mzta | 0:158c61bb030f | 434 | diff = cur - bin; |
mzta | 0:158c61bb030f | 435 | mrb_assert_int_fit(ptrdiff_t, diff, uint32_t, UINT32_MAX); |
mzta | 0:158c61bb030f | 436 | |
mzta | 0:158c61bb030f | 437 | uint32_to_bin((uint32_t)diff, bin); /* record size */ |
mzta | 0:158c61bb030f | 438 | |
mzta | 0:158c61bb030f | 439 | mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 440 | return (size_t)diff; |
mzta | 0:158c61bb030f | 441 | } |
mzta | 0:158c61bb030f | 442 | |
mzta | 0:158c61bb030f | 443 | static size_t |
mzta | 0:158c61bb030f | 444 | write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin) |
mzta | 0:158c61bb030f | 445 | { |
mzta | 0:158c61bb030f | 446 | size_t i; |
mzta | 0:158c61bb030f | 447 | size_t rlen, size = 0; |
mzta | 0:158c61bb030f | 448 | |
mzta | 0:158c61bb030f | 449 | rlen = write_lineno_record_1(mrb, irep, bin); |
mzta | 0:158c61bb030f | 450 | bin += rlen; |
mzta | 0:158c61bb030f | 451 | size += rlen; |
mzta | 0:158c61bb030f | 452 | for (i=0; i<irep->rlen; i++) { |
mzta | 0:158c61bb030f | 453 | rlen = write_lineno_record(mrb, irep, bin); |
mzta | 0:158c61bb030f | 454 | bin += rlen; |
mzta | 0:158c61bb030f | 455 | size += rlen; |
mzta | 0:158c61bb030f | 456 | } |
mzta | 0:158c61bb030f | 457 | return size; |
mzta | 0:158c61bb030f | 458 | } |
mzta | 0:158c61bb030f | 459 | |
mzta | 0:158c61bb030f | 460 | static int |
mzta | 0:158c61bb030f | 461 | write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) |
mzta | 0:158c61bb030f | 462 | { |
mzta | 0:158c61bb030f | 463 | size_t section_size = 0; |
mzta | 0:158c61bb030f | 464 | size_t rlen = 0; /* size of irep record */ |
mzta | 0:158c61bb030f | 465 | uint8_t *cur = bin; |
mzta | 0:158c61bb030f | 466 | |
mzta | 0:158c61bb030f | 467 | if (mrb == NULL || bin == NULL) { |
mzta | 0:158c61bb030f | 468 | return MRB_DUMP_INVALID_ARGUMENT; |
mzta | 0:158c61bb030f | 469 | } |
mzta | 0:158c61bb030f | 470 | |
mzta | 0:158c61bb030f | 471 | cur += sizeof(struct rite_section_lineno_header); |
mzta | 0:158c61bb030f | 472 | section_size += sizeof(struct rite_section_lineno_header); |
mzta | 0:158c61bb030f | 473 | |
mzta | 0:158c61bb030f | 474 | rlen = write_lineno_record(mrb, irep, cur); |
mzta | 0:158c61bb030f | 475 | section_size += rlen; |
mzta | 0:158c61bb030f | 476 | |
mzta | 0:158c61bb030f | 477 | write_section_lineno_header(mrb, section_size, bin); |
mzta | 0:158c61bb030f | 478 | |
mzta | 0:158c61bb030f | 479 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 480 | } |
mzta | 0:158c61bb030f | 481 | |
mzta | 0:158c61bb030f | 482 | static size_t |
mzta | 0:158c61bb030f | 483 | get_debug_record_size(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 484 | { |
mzta | 0:158c61bb030f | 485 | size_t ret = 0; |
mzta | 0:158c61bb030f | 486 | uint16_t f_idx; |
mzta | 0:158c61bb030f | 487 | size_t i; |
mzta | 0:158c61bb030f | 488 | |
mzta | 0:158c61bb030f | 489 | ret += sizeof(uint32_t); /* record size */ |
mzta | 0:158c61bb030f | 490 | ret += sizeof(uint16_t); /* file count */ |
mzta | 0:158c61bb030f | 491 | |
mzta | 0:158c61bb030f | 492 | for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { |
mzta | 0:158c61bb030f | 493 | mrb_irep_debug_info_file const* file = irep->debug_info->files[f_idx]; |
mzta | 0:158c61bb030f | 494 | |
mzta | 0:158c61bb030f | 495 | ret += sizeof(uint32_t); /* position */ |
mzta | 0:158c61bb030f | 496 | ret += sizeof(uint16_t); /* filename index */ |
mzta | 0:158c61bb030f | 497 | |
mzta | 0:158c61bb030f | 498 | /* lines */ |
mzta | 0:158c61bb030f | 499 | ret += sizeof(uint32_t); /* entry count */ |
mzta | 0:158c61bb030f | 500 | ret += sizeof(uint8_t); /* line type */ |
mzta | 0:158c61bb030f | 501 | switch (file->line_type) { |
mzta | 0:158c61bb030f | 502 | case mrb_debug_line_ary: |
mzta | 0:158c61bb030f | 503 | ret += sizeof(uint16_t) * (size_t)(file->line_entry_count); |
mzta | 0:158c61bb030f | 504 | break; |
mzta | 0:158c61bb030f | 505 | |
mzta | 0:158c61bb030f | 506 | case mrb_debug_line_flat_map: |
mzta | 0:158c61bb030f | 507 | ret += (sizeof(uint32_t) + sizeof(uint16_t)) * (size_t)(file->line_entry_count); |
mzta | 0:158c61bb030f | 508 | break; |
mzta | 0:158c61bb030f | 509 | |
mzta | 0:158c61bb030f | 510 | default: mrb_assert(0); break; |
mzta | 0:158c61bb030f | 511 | } |
mzta | 0:158c61bb030f | 512 | } |
mzta | 0:158c61bb030f | 513 | for (i=0; i<irep->rlen; i++) { |
mzta | 0:158c61bb030f | 514 | ret += get_debug_record_size(mrb, irep->reps[i]); |
mzta | 0:158c61bb030f | 515 | } |
mzta | 0:158c61bb030f | 516 | |
mzta | 0:158c61bb030f | 517 | return ret; |
mzta | 0:158c61bb030f | 518 | } |
mzta | 0:158c61bb030f | 519 | |
mzta | 0:158c61bb030f | 520 | static int |
mzta | 0:158c61bb030f | 521 | find_filename_index(const mrb_sym *ary, int ary_len, mrb_sym s) |
mzta | 0:158c61bb030f | 522 | { |
mzta | 0:158c61bb030f | 523 | int i; |
mzta | 0:158c61bb030f | 524 | |
mzta | 0:158c61bb030f | 525 | for (i = 0; i < ary_len; ++i) { |
mzta | 0:158c61bb030f | 526 | if (ary[i] == s) { return i; } |
mzta | 0:158c61bb030f | 527 | } |
mzta | 0:158c61bb030f | 528 | return -1; |
mzta | 0:158c61bb030f | 529 | } |
mzta | 0:158c61bb030f | 530 | |
mzta | 0:158c61bb030f | 531 | static size_t |
mzta | 0:158c61bb030f | 532 | get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp) |
mzta | 0:158c61bb030f | 533 | { |
mzta | 0:158c61bb030f | 534 | mrb_sym *filenames = *fp; |
mzta | 0:158c61bb030f | 535 | size_t i, size = 0; |
mzta | 0:158c61bb030f | 536 | mrb_irep_debug_info *di = irep->debug_info; |
mzta | 0:158c61bb030f | 537 | |
mzta | 0:158c61bb030f | 538 | mrb_assert(lp); |
mzta | 0:158c61bb030f | 539 | for (i = 0; i < di->flen; ++i) { |
mzta | 0:158c61bb030f | 540 | mrb_irep_debug_info_file *file; |
mzta | 0:158c61bb030f | 541 | mrb_int filename_len; |
mzta | 0:158c61bb030f | 542 | |
mzta | 0:158c61bb030f | 543 | file = di->files[i]; |
mzta | 0:158c61bb030f | 544 | if (find_filename_index(filenames, *lp, file->filename_sym) == -1) { |
mzta | 0:158c61bb030f | 545 | /* register filename */ |
mzta | 0:158c61bb030f | 546 | *lp += 1; |
mzta | 0:158c61bb030f | 547 | *fp = filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp)); |
mzta | 0:158c61bb030f | 548 | filenames[*lp - 1] = file->filename_sym; |
mzta | 0:158c61bb030f | 549 | |
mzta | 0:158c61bb030f | 550 | /* filename */ |
mzta | 0:158c61bb030f | 551 | mrb_sym2name_len(mrb, file->filename_sym, &filename_len); |
mzta | 0:158c61bb030f | 552 | size += sizeof(uint16_t) + (size_t)filename_len; |
mzta | 0:158c61bb030f | 553 | } |
mzta | 0:158c61bb030f | 554 | } |
mzta | 0:158c61bb030f | 555 | for (i=0; i<irep->rlen; i++) { |
mzta | 0:158c61bb030f | 556 | size += get_filename_table_size(mrb, irep->reps[i], fp, lp); |
mzta | 0:158c61bb030f | 557 | } |
mzta | 0:158c61bb030f | 558 | return size; |
mzta | 0:158c61bb030f | 559 | } |
mzta | 0:158c61bb030f | 560 | |
mzta | 0:158c61bb030f | 561 | static size_t |
mzta | 0:158c61bb030f | 562 | write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) |
mzta | 0:158c61bb030f | 563 | { |
mzta | 0:158c61bb030f | 564 | uint8_t *cur; |
mzta | 0:158c61bb030f | 565 | uint16_t f_idx; |
mzta | 0:158c61bb030f | 566 | ptrdiff_t ret; |
mzta | 0:158c61bb030f | 567 | |
mzta | 0:158c61bb030f | 568 | cur = bin + sizeof(uint32_t); /* skip record size */ |
mzta | 0:158c61bb030f | 569 | cur += uint16_to_bin(irep->debug_info->flen, cur); /* file count */ |
mzta | 0:158c61bb030f | 570 | |
mzta | 0:158c61bb030f | 571 | for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { |
mzta | 0:158c61bb030f | 572 | int filename_idx; |
mzta | 0:158c61bb030f | 573 | const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx]; |
mzta | 0:158c61bb030f | 574 | |
mzta | 0:158c61bb030f | 575 | /* position */ |
mzta | 0:158c61bb030f | 576 | cur += uint32_to_bin(file->start_pos, cur); |
mzta | 0:158c61bb030f | 577 | |
mzta | 0:158c61bb030f | 578 | /* filename index */ |
mzta | 0:158c61bb030f | 579 | filename_idx = find_filename_index(filenames, filenames_len, |
mzta | 0:158c61bb030f | 580 | file->filename_sym); |
mzta | 0:158c61bb030f | 581 | mrb_assert_int_fit(int, filename_idx, uint16_t, UINT16_MAX); |
mzta | 0:158c61bb030f | 582 | cur += uint16_to_bin((uint16_t)filename_idx, cur); |
mzta | 0:158c61bb030f | 583 | |
mzta | 0:158c61bb030f | 584 | /* lines */ |
mzta | 0:158c61bb030f | 585 | cur += uint32_to_bin(file->line_entry_count, cur); |
mzta | 0:158c61bb030f | 586 | cur += uint8_to_bin(file->line_type, cur); |
mzta | 0:158c61bb030f | 587 | switch (file->line_type) { |
mzta | 0:158c61bb030f | 588 | case mrb_debug_line_ary: { |
mzta | 0:158c61bb030f | 589 | uint32_t l; |
mzta | 0:158c61bb030f | 590 | for (l = 0; l < file->line_entry_count; ++l) { |
mzta | 0:158c61bb030f | 591 | cur += uint16_to_bin(file->lines.ary[l], cur); |
mzta | 0:158c61bb030f | 592 | } |
mzta | 0:158c61bb030f | 593 | } break; |
mzta | 0:158c61bb030f | 594 | |
mzta | 0:158c61bb030f | 595 | case mrb_debug_line_flat_map: { |
mzta | 0:158c61bb030f | 596 | uint32_t line; |
mzta | 0:158c61bb030f | 597 | for (line = 0; line < file->line_entry_count; ++line) { |
mzta | 0:158c61bb030f | 598 | cur += uint32_to_bin(file->lines.flat_map[line].start_pos, cur); |
mzta | 0:158c61bb030f | 599 | cur += uint16_to_bin(file->lines.flat_map[line].line, cur); |
mzta | 0:158c61bb030f | 600 | } |
mzta | 0:158c61bb030f | 601 | } break; |
mzta | 0:158c61bb030f | 602 | |
mzta | 0:158c61bb030f | 603 | default: mrb_assert(0); break; |
mzta | 0:158c61bb030f | 604 | } |
mzta | 0:158c61bb030f | 605 | } |
mzta | 0:158c61bb030f | 606 | |
mzta | 0:158c61bb030f | 607 | ret = cur - bin; |
mzta | 0:158c61bb030f | 608 | mrb_assert_int_fit(ptrdiff_t, ret, uint32_t, UINT32_MAX); |
mzta | 0:158c61bb030f | 609 | uint32_to_bin(ret, bin); |
mzta | 0:158c61bb030f | 610 | |
mzta | 0:158c61bb030f | 611 | mrb_assert_int_fit(ptrdiff_t, ret, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 612 | return (size_t)ret; |
mzta | 0:158c61bb030f | 613 | } |
mzta | 0:158c61bb030f | 614 | |
mzta | 0:158c61bb030f | 615 | static size_t |
mzta | 0:158c61bb030f | 616 | write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len) |
mzta | 0:158c61bb030f | 617 | { |
mzta | 0:158c61bb030f | 618 | size_t size, len; |
mzta | 0:158c61bb030f | 619 | size_t irep_no; |
mzta | 0:158c61bb030f | 620 | |
mzta | 0:158c61bb030f | 621 | size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len); |
mzta | 0:158c61bb030f | 622 | bin += len; |
mzta | 0:158c61bb030f | 623 | for (irep_no = 0; irep_no < irep->rlen; irep_no++) { |
mzta | 0:158c61bb030f | 624 | len = write_debug_record(mrb, irep->reps[irep_no], bin, filenames, filenames_len); |
mzta | 0:158c61bb030f | 625 | bin += len; |
mzta | 0:158c61bb030f | 626 | size += len; |
mzta | 0:158c61bb030f | 627 | } |
mzta | 0:158c61bb030f | 628 | |
mzta | 0:158c61bb030f | 629 | mrb_assert(size == get_debug_record_size(mrb, irep)); |
mzta | 0:158c61bb030f | 630 | return size; |
mzta | 0:158c61bb030f | 631 | } |
mzta | 0:158c61bb030f | 632 | |
mzta | 0:158c61bb030f | 633 | static int |
mzta | 0:158c61bb030f | 634 | write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur, mrb_sym const *filenames, uint16_t filenames_len) |
mzta | 0:158c61bb030f | 635 | { |
mzta | 0:158c61bb030f | 636 | size_t section_size = 0; |
mzta | 0:158c61bb030f | 637 | const uint8_t *bin = cur; |
mzta | 0:158c61bb030f | 638 | struct rite_section_debug_header *header; |
mzta | 0:158c61bb030f | 639 | size_t dlen; |
mzta | 0:158c61bb030f | 640 | uint16_t i; |
mzta | 0:158c61bb030f | 641 | char const *sym; mrb_int sym_len; |
mzta | 0:158c61bb030f | 642 | |
mzta | 0:158c61bb030f | 643 | if (mrb == NULL || cur == NULL) { |
mzta | 0:158c61bb030f | 644 | return MRB_DUMP_INVALID_ARGUMENT; |
mzta | 0:158c61bb030f | 645 | } |
mzta | 0:158c61bb030f | 646 | |
mzta | 0:158c61bb030f | 647 | header = (struct rite_section_debug_header *)bin; |
mzta | 0:158c61bb030f | 648 | cur += sizeof(struct rite_section_debug_header); |
mzta | 0:158c61bb030f | 649 | section_size += sizeof(struct rite_section_debug_header); |
mzta | 0:158c61bb030f | 650 | |
mzta | 0:158c61bb030f | 651 | /* filename table */ |
mzta | 0:158c61bb030f | 652 | cur += uint16_to_bin(filenames_len, cur); |
mzta | 0:158c61bb030f | 653 | section_size += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 654 | for (i = 0; i < filenames_len; ++i) { |
mzta | 0:158c61bb030f | 655 | sym = mrb_sym2name_len(mrb, filenames[i], &sym_len); |
mzta | 0:158c61bb030f | 656 | mrb_assert(sym); |
mzta | 0:158c61bb030f | 657 | cur += uint16_to_bin(sym_len, cur); |
mzta | 0:158c61bb030f | 658 | memcpy(cur, sym, sym_len); |
mzta | 0:158c61bb030f | 659 | cur += sym_len; |
mzta | 0:158c61bb030f | 660 | section_size += sizeof(uint16_t) + sym_len; |
mzta | 0:158c61bb030f | 661 | } |
mzta | 0:158c61bb030f | 662 | |
mzta | 0:158c61bb030f | 663 | /* debug records */ |
mzta | 0:158c61bb030f | 664 | dlen = write_debug_record(mrb, irep, cur, filenames, filenames_len); |
mzta | 0:158c61bb030f | 665 | section_size += dlen; |
mzta | 0:158c61bb030f | 666 | |
mzta | 0:158c61bb030f | 667 | memcpy(header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(header->section_identify)); |
mzta | 0:158c61bb030f | 668 | mrb_assert(section_size <= INT32_MAX); |
mzta | 0:158c61bb030f | 669 | uint32_to_bin(section_size, header->section_size); |
mzta | 0:158c61bb030f | 670 | |
mzta | 0:158c61bb030f | 671 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 672 | } |
mzta | 0:158c61bb030f | 673 | |
mzta | 0:158c61bb030f | 674 | static void |
mzta | 0:158c61bb030f | 675 | create_lv_sym_table(mrb_state *mrb, const mrb_irep *irep, mrb_sym **syms, uint32_t *syms_len) |
mzta | 0:158c61bb030f | 676 | { |
mzta | 0:158c61bb030f | 677 | size_t i; |
mzta | 0:158c61bb030f | 678 | |
mzta | 0:158c61bb030f | 679 | if (*syms == NULL) { |
mzta | 0:158c61bb030f | 680 | *syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * 1); |
mzta | 0:158c61bb030f | 681 | } |
mzta | 0:158c61bb030f | 682 | |
mzta | 0:158c61bb030f | 683 | for (i = 0; i + 1 < irep->nlocals; ++i) { |
mzta | 0:158c61bb030f | 684 | mrb_sym const name = irep->lv[i].name; |
mzta | 0:158c61bb030f | 685 | if (name == 0) continue; |
mzta | 0:158c61bb030f | 686 | if (find_filename_index(*syms, *syms_len, name) != -1) continue; |
mzta | 0:158c61bb030f | 687 | |
mzta | 0:158c61bb030f | 688 | ++(*syms_len); |
mzta | 0:158c61bb030f | 689 | *syms = (mrb_sym*)mrb_realloc(mrb, *syms, sizeof(mrb_sym) * (*syms_len)); |
mzta | 0:158c61bb030f | 690 | (*syms)[*syms_len - 1] = name; |
mzta | 0:158c61bb030f | 691 | } |
mzta | 0:158c61bb030f | 692 | |
mzta | 0:158c61bb030f | 693 | for (i = 0; i < irep->rlen; ++i) { |
mzta | 0:158c61bb030f | 694 | create_lv_sym_table(mrb, irep->reps[i], syms, syms_len); |
mzta | 0:158c61bb030f | 695 | } |
mzta | 0:158c61bb030f | 696 | } |
mzta | 0:158c61bb030f | 697 | |
mzta | 0:158c61bb030f | 698 | static int |
mzta | 0:158c61bb030f | 699 | write_lv_sym_table(mrb_state *mrb, uint8_t **start, mrb_sym const *syms, uint32_t syms_len) |
mzta | 0:158c61bb030f | 700 | { |
mzta | 0:158c61bb030f | 701 | uint8_t *cur = *start; |
mzta | 0:158c61bb030f | 702 | uint32_t i; |
mzta | 0:158c61bb030f | 703 | const char *str; |
mzta | 0:158c61bb030f | 704 | mrb_int str_len; |
mzta | 0:158c61bb030f | 705 | |
mzta | 0:158c61bb030f | 706 | cur += uint32_to_bin(syms_len, cur); |
mzta | 0:158c61bb030f | 707 | |
mzta | 0:158c61bb030f | 708 | for (i = 0; i < syms_len; ++i) { |
mzta | 0:158c61bb030f | 709 | str = mrb_sym2name_len(mrb, syms[i], &str_len); |
mzta | 0:158c61bb030f | 710 | cur += uint16_to_bin(str_len, cur); |
mzta | 0:158c61bb030f | 711 | memcpy(cur, str, str_len); |
mzta | 0:158c61bb030f | 712 | cur += str_len; |
mzta | 0:158c61bb030f | 713 | } |
mzta | 0:158c61bb030f | 714 | |
mzta | 0:158c61bb030f | 715 | *start = cur; |
mzta | 0:158c61bb030f | 716 | |
mzta | 0:158c61bb030f | 717 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 718 | } |
mzta | 0:158c61bb030f | 719 | |
mzta | 0:158c61bb030f | 720 | static int |
mzta | 0:158c61bb030f | 721 | write_lv_record(mrb_state *mrb, const mrb_irep *irep, uint8_t **start, mrb_sym const *syms, uint32_t syms_len) |
mzta | 0:158c61bb030f | 722 | { |
mzta | 0:158c61bb030f | 723 | uint8_t *cur = *start; |
mzta | 0:158c61bb030f | 724 | size_t i; |
mzta | 0:158c61bb030f | 725 | |
mzta | 0:158c61bb030f | 726 | for (i = 0; i + 1 < irep->nlocals; ++i) { |
mzta | 0:158c61bb030f | 727 | if (irep->lv[i].name == 0) { |
mzta | 0:158c61bb030f | 728 | cur += uint16_to_bin(RITE_LV_NULL_MARK, cur); |
mzta | 0:158c61bb030f | 729 | cur += uint16_to_bin(0, cur); |
mzta | 0:158c61bb030f | 730 | } |
mzta | 0:158c61bb030f | 731 | else { |
mzta | 0:158c61bb030f | 732 | int const sym_idx = find_filename_index(syms, syms_len, irep->lv[i].name); |
mzta | 0:158c61bb030f | 733 | mrb_assert(sym_idx != -1); /* local variable name must be in syms */ |
mzta | 0:158c61bb030f | 734 | |
mzta | 0:158c61bb030f | 735 | cur += uint16_to_bin(sym_idx, cur); |
mzta | 0:158c61bb030f | 736 | cur += uint16_to_bin(irep->lv[i].r, cur); |
mzta | 0:158c61bb030f | 737 | } |
mzta | 0:158c61bb030f | 738 | } |
mzta | 0:158c61bb030f | 739 | |
mzta | 0:158c61bb030f | 740 | for (i = 0; i < irep->rlen; ++i) { |
mzta | 0:158c61bb030f | 741 | write_lv_record(mrb, irep->reps[i], &cur, syms, syms_len); |
mzta | 0:158c61bb030f | 742 | } |
mzta | 0:158c61bb030f | 743 | |
mzta | 0:158c61bb030f | 744 | *start = cur; |
mzta | 0:158c61bb030f | 745 | |
mzta | 0:158c61bb030f | 746 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 747 | } |
mzta | 0:158c61bb030f | 748 | |
mzta | 0:158c61bb030f | 749 | static size_t |
mzta | 0:158c61bb030f | 750 | get_lv_record_size(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 751 | { |
mzta | 0:158c61bb030f | 752 | size_t ret = 0, i; |
mzta | 0:158c61bb030f | 753 | |
mzta | 0:158c61bb030f | 754 | ret += (sizeof(uint16_t) + sizeof(uint16_t)) * (irep->nlocals - 1); |
mzta | 0:158c61bb030f | 755 | |
mzta | 0:158c61bb030f | 756 | for (i = 0; i < irep->rlen; ++i) { |
mzta | 0:158c61bb030f | 757 | ret += get_lv_record_size(mrb, irep->reps[i]); |
mzta | 0:158c61bb030f | 758 | } |
mzta | 0:158c61bb030f | 759 | |
mzta | 0:158c61bb030f | 760 | return ret; |
mzta | 0:158c61bb030f | 761 | } |
mzta | 0:158c61bb030f | 762 | |
mzta | 0:158c61bb030f | 763 | static size_t |
mzta | 0:158c61bb030f | 764 | get_lv_section_size(mrb_state *mrb, mrb_irep *irep, mrb_sym const *syms, uint32_t syms_len) |
mzta | 0:158c61bb030f | 765 | { |
mzta | 0:158c61bb030f | 766 | size_t ret = 0, i; |
mzta | 0:158c61bb030f | 767 | |
mzta | 0:158c61bb030f | 768 | ret += sizeof(uint32_t); /* syms_len */ |
mzta | 0:158c61bb030f | 769 | ret += sizeof(uint16_t) * syms_len; /* symbol name lengths */ |
mzta | 0:158c61bb030f | 770 | for (i = 0; i < syms_len; ++i) { |
mzta | 0:158c61bb030f | 771 | mrb_int str_len; |
mzta | 0:158c61bb030f | 772 | mrb_sym2name_len(mrb, syms[i], &str_len); |
mzta | 0:158c61bb030f | 773 | ret += str_len; |
mzta | 0:158c61bb030f | 774 | } |
mzta | 0:158c61bb030f | 775 | |
mzta | 0:158c61bb030f | 776 | ret += get_lv_record_size(mrb, irep); |
mzta | 0:158c61bb030f | 777 | |
mzta | 0:158c61bb030f | 778 | return ret; |
mzta | 0:158c61bb030f | 779 | } |
mzta | 0:158c61bb030f | 780 | |
mzta | 0:158c61bb030f | 781 | static int |
mzta | 0:158c61bb030f | 782 | write_section_lv(mrb_state *mrb, mrb_irep *irep, uint8_t *start, mrb_sym const *syms, uint32_t const syms_len) |
mzta | 0:158c61bb030f | 783 | { |
mzta | 0:158c61bb030f | 784 | uint8_t *cur = start; |
mzta | 0:158c61bb030f | 785 | struct rite_section_lv_header *header; |
mzta | 0:158c61bb030f | 786 | ptrdiff_t diff; |
mzta | 0:158c61bb030f | 787 | int result = MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 788 | |
mzta | 0:158c61bb030f | 789 | if (mrb == NULL || cur == NULL) { |
mzta | 0:158c61bb030f | 790 | return MRB_DUMP_INVALID_ARGUMENT; |
mzta | 0:158c61bb030f | 791 | } |
mzta | 0:158c61bb030f | 792 | |
mzta | 0:158c61bb030f | 793 | header = (struct rite_section_lv_header*)cur; |
mzta | 0:158c61bb030f | 794 | cur += sizeof(struct rite_section_lv_header); |
mzta | 0:158c61bb030f | 795 | |
mzta | 0:158c61bb030f | 796 | result = write_lv_sym_table(mrb, &cur, syms, syms_len); |
mzta | 0:158c61bb030f | 797 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 798 | goto lv_section_exit; |
mzta | 0:158c61bb030f | 799 | } |
mzta | 0:158c61bb030f | 800 | |
mzta | 0:158c61bb030f | 801 | result = write_lv_record(mrb, irep, &cur, syms, syms_len); |
mzta | 0:158c61bb030f | 802 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 803 | goto lv_section_exit; |
mzta | 0:158c61bb030f | 804 | } |
mzta | 0:158c61bb030f | 805 | |
mzta | 0:158c61bb030f | 806 | memcpy(header->section_identify, RITE_SECTION_LV_IDENTIFIER, sizeof(header->section_identify)); |
mzta | 0:158c61bb030f | 807 | |
mzta | 0:158c61bb030f | 808 | diff = cur - start; |
mzta | 0:158c61bb030f | 809 | mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 810 | uint32_to_bin(diff, header->section_size); |
mzta | 0:158c61bb030f | 811 | |
mzta | 0:158c61bb030f | 812 | lv_section_exit: |
mzta | 0:158c61bb030f | 813 | return result; |
mzta | 0:158c61bb030f | 814 | } |
mzta | 0:158c61bb030f | 815 | |
mzta | 0:158c61bb030f | 816 | static int |
mzta | 0:158c61bb030f | 817 | write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags) |
mzta | 0:158c61bb030f | 818 | { |
mzta | 0:158c61bb030f | 819 | struct rite_binary_header *header = (struct rite_binary_header *)bin; |
mzta | 0:158c61bb030f | 820 | uint16_t crc; |
mzta | 0:158c61bb030f | 821 | uint32_t offset; |
mzta | 0:158c61bb030f | 822 | |
mzta | 0:158c61bb030f | 823 | if (flags & FLAG_BYTEORDER_NATIVE) { |
mzta | 0:158c61bb030f | 824 | uint32_t ident = 0; |
mzta | 0:158c61bb030f | 825 | size_t i; |
mzta | 0:158c61bb030f | 826 | |
mzta | 0:158c61bb030f | 827 | for(i=0; i<sizeof(ident); i++) { |
mzta | 0:158c61bb030f | 828 | ident<<=8; |
mzta | 0:158c61bb030f | 829 | ident|=RITE_BINARY_IDENTIFIER[i]; |
mzta | 0:158c61bb030f | 830 | } |
mzta | 0:158c61bb030f | 831 | memcpy(header->binary_identify, (char*)&ident, sizeof(uint32_t)); |
mzta | 0:158c61bb030f | 832 | } |
mzta | 0:158c61bb030f | 833 | else { |
mzta | 0:158c61bb030f | 834 | memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)); |
mzta | 0:158c61bb030f | 835 | } |
mzta | 0:158c61bb030f | 836 | memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)); |
mzta | 0:158c61bb030f | 837 | memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name)); |
mzta | 0:158c61bb030f | 838 | memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version)); |
mzta | 0:158c61bb030f | 839 | mrb_assert(binary_size <= UINT32_MAX); |
mzta | 0:158c61bb030f | 840 | uint32_to_bin((uint32_t)binary_size, header->binary_size); |
mzta | 0:158c61bb030f | 841 | |
mzta | 0:158c61bb030f | 842 | offset = (&(header->binary_crc[0]) - bin) + sizeof(uint16_t); |
mzta | 0:158c61bb030f | 843 | crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0); |
mzta | 0:158c61bb030f | 844 | uint16_to_bin(crc, header->binary_crc); |
mzta | 0:158c61bb030f | 845 | |
mzta | 0:158c61bb030f | 846 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 847 | } |
mzta | 0:158c61bb030f | 848 | |
mzta | 0:158c61bb030f | 849 | static mrb_bool |
mzta | 0:158c61bb030f | 850 | is_debug_info_defined(mrb_irep *irep) |
mzta | 0:158c61bb030f | 851 | { |
mzta | 0:158c61bb030f | 852 | size_t i; |
mzta | 0:158c61bb030f | 853 | |
mzta | 0:158c61bb030f | 854 | if (!irep->debug_info) return FALSE; |
mzta | 0:158c61bb030f | 855 | for (i=0; i<irep->rlen; i++) { |
mzta | 0:158c61bb030f | 856 | if (!is_debug_info_defined(irep->reps[i])) return FALSE; |
mzta | 0:158c61bb030f | 857 | } |
mzta | 0:158c61bb030f | 858 | return TRUE; |
mzta | 0:158c61bb030f | 859 | } |
mzta | 0:158c61bb030f | 860 | |
mzta | 0:158c61bb030f | 861 | static mrb_bool |
mzta | 0:158c61bb030f | 862 | is_lv_defined(mrb_irep *irep) |
mzta | 0:158c61bb030f | 863 | { |
mzta | 0:158c61bb030f | 864 | size_t i; |
mzta | 0:158c61bb030f | 865 | |
mzta | 0:158c61bb030f | 866 | if (irep->lv) { return TRUE; } |
mzta | 0:158c61bb030f | 867 | |
mzta | 0:158c61bb030f | 868 | for (i = 0; i < irep->rlen; ++i) { |
mzta | 0:158c61bb030f | 869 | if (is_lv_defined(irep->reps[i])) { return TRUE; } |
mzta | 0:158c61bb030f | 870 | } |
mzta | 0:158c61bb030f | 871 | |
mzta | 0:158c61bb030f | 872 | return FALSE; |
mzta | 0:158c61bb030f | 873 | } |
mzta | 0:158c61bb030f | 874 | |
mzta | 0:158c61bb030f | 875 | static int |
mzta | 0:158c61bb030f | 876 | dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size, uint8_t flags) |
mzta | 0:158c61bb030f | 877 | { |
mzta | 0:158c61bb030f | 878 | int result = MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 879 | size_t malloc_size; |
mzta | 0:158c61bb030f | 880 | size_t section_irep_size; |
mzta | 0:158c61bb030f | 881 | size_t section_lineno_size = 0, section_lv_size = 0; |
mzta | 0:158c61bb030f | 882 | uint8_t *cur = NULL; |
mzta | 0:158c61bb030f | 883 | mrb_bool const debug_info_defined = is_debug_info_defined(irep), lv_defined = is_lv_defined(irep); |
mzta | 0:158c61bb030f | 884 | mrb_sym *lv_syms = NULL; uint32_t lv_syms_len = 0; |
mzta | 0:158c61bb030f | 885 | mrb_sym *filenames = NULL; uint16_t filenames_len = 0; |
mzta | 0:158c61bb030f | 886 | |
mzta | 0:158c61bb030f | 887 | if (mrb == NULL) { |
mzta | 0:158c61bb030f | 888 | *bin = NULL; |
mzta | 0:158c61bb030f | 889 | return MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 890 | } |
mzta | 0:158c61bb030f | 891 | |
mzta | 0:158c61bb030f | 892 | section_irep_size = sizeof(struct rite_section_irep_header); |
mzta | 0:158c61bb030f | 893 | section_irep_size += get_irep_record_size(mrb, irep); |
mzta | 0:158c61bb030f | 894 | |
mzta | 0:158c61bb030f | 895 | /* DEBUG section size */ |
mzta | 0:158c61bb030f | 896 | if (debug_info) { |
mzta | 0:158c61bb030f | 897 | if (debug_info_defined) { |
mzta | 0:158c61bb030f | 898 | section_lineno_size += sizeof(struct rite_section_debug_header); |
mzta | 0:158c61bb030f | 899 | /* filename table */ |
mzta | 0:158c61bb030f | 900 | filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) + 1); |
mzta | 0:158c61bb030f | 901 | |
mzta | 0:158c61bb030f | 902 | /* filename table size */ |
mzta | 0:158c61bb030f | 903 | section_lineno_size += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 904 | section_lineno_size += get_filename_table_size(mrb, irep, &filenames, &filenames_len); |
mzta | 0:158c61bb030f | 905 | |
mzta | 0:158c61bb030f | 906 | section_lineno_size += get_debug_record_size(mrb, irep); |
mzta | 0:158c61bb030f | 907 | } |
mzta | 0:158c61bb030f | 908 | else { |
mzta | 0:158c61bb030f | 909 | section_lineno_size += sizeof(struct rite_section_lineno_header); |
mzta | 0:158c61bb030f | 910 | section_lineno_size += get_lineno_record_size(mrb, irep); |
mzta | 0:158c61bb030f | 911 | } |
mzta | 0:158c61bb030f | 912 | } |
mzta | 0:158c61bb030f | 913 | |
mzta | 0:158c61bb030f | 914 | if (lv_defined) { |
mzta | 0:158c61bb030f | 915 | section_lv_size += sizeof(struct rite_section_lv_header); |
mzta | 0:158c61bb030f | 916 | create_lv_sym_table(mrb, irep, &lv_syms, &lv_syms_len); |
mzta | 0:158c61bb030f | 917 | section_lv_size += get_lv_section_size(mrb, irep, lv_syms, lv_syms_len); |
mzta | 0:158c61bb030f | 918 | } |
mzta | 0:158c61bb030f | 919 | |
mzta | 0:158c61bb030f | 920 | malloc_size = sizeof(struct rite_binary_header) + |
mzta | 0:158c61bb030f | 921 | section_irep_size + section_lineno_size + section_lv_size + |
mzta | 0:158c61bb030f | 922 | sizeof(struct rite_binary_footer); |
mzta | 0:158c61bb030f | 923 | cur = *bin = (uint8_t*)mrb_malloc(mrb, malloc_size); |
mzta | 0:158c61bb030f | 924 | cur += sizeof(struct rite_binary_header); |
mzta | 0:158c61bb030f | 925 | |
mzta | 0:158c61bb030f | 926 | result = write_section_irep(mrb, irep, cur, §ion_irep_size, flags); |
mzta | 0:158c61bb030f | 927 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 928 | goto error_exit; |
mzta | 0:158c61bb030f | 929 | } |
mzta | 0:158c61bb030f | 930 | cur += section_irep_size; |
mzta | 0:158c61bb030f | 931 | *bin_size = sizeof(struct rite_binary_header) + |
mzta | 0:158c61bb030f | 932 | section_irep_size + section_lineno_size + section_lv_size + |
mzta | 0:158c61bb030f | 933 | sizeof(struct rite_binary_footer); |
mzta | 0:158c61bb030f | 934 | |
mzta | 0:158c61bb030f | 935 | /* write DEBUG section */ |
mzta | 0:158c61bb030f | 936 | if (debug_info) { |
mzta | 0:158c61bb030f | 937 | if (debug_info_defined) { |
mzta | 0:158c61bb030f | 938 | result = write_section_debug(mrb, irep, cur, filenames, filenames_len); |
mzta | 0:158c61bb030f | 939 | } |
mzta | 0:158c61bb030f | 940 | else { |
mzta | 0:158c61bb030f | 941 | result = write_section_lineno(mrb, irep, cur); |
mzta | 0:158c61bb030f | 942 | } |
mzta | 0:158c61bb030f | 943 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 944 | goto error_exit; |
mzta | 0:158c61bb030f | 945 | } |
mzta | 0:158c61bb030f | 946 | cur += section_lineno_size; |
mzta | 0:158c61bb030f | 947 | } |
mzta | 0:158c61bb030f | 948 | |
mzta | 0:158c61bb030f | 949 | if (lv_defined) { |
mzta | 0:158c61bb030f | 950 | result = write_section_lv(mrb, irep, cur, lv_syms, lv_syms_len); |
mzta | 0:158c61bb030f | 951 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 952 | goto error_exit; |
mzta | 0:158c61bb030f | 953 | } |
mzta | 0:158c61bb030f | 954 | cur += section_lv_size; |
mzta | 0:158c61bb030f | 955 | } |
mzta | 0:158c61bb030f | 956 | |
mzta | 0:158c61bb030f | 957 | write_footer(mrb, cur); |
mzta | 0:158c61bb030f | 958 | write_rite_binary_header(mrb, *bin_size, *bin, flags); |
mzta | 0:158c61bb030f | 959 | |
mzta | 0:158c61bb030f | 960 | error_exit: |
mzta | 0:158c61bb030f | 961 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 962 | mrb_free(mrb, *bin); |
mzta | 0:158c61bb030f | 963 | *bin = NULL; |
mzta | 0:158c61bb030f | 964 | } |
mzta | 0:158c61bb030f | 965 | if (lv_syms) { |
mzta | 0:158c61bb030f | 966 | mrb_free(mrb, lv_syms); |
mzta | 0:158c61bb030f | 967 | } |
mzta | 0:158c61bb030f | 968 | if (filenames) { |
mzta | 0:158c61bb030f | 969 | mrb_free(mrb, filenames); |
mzta | 0:158c61bb030f | 970 | } |
mzta | 0:158c61bb030f | 971 | return result; |
mzta | 0:158c61bb030f | 972 | } |
mzta | 0:158c61bb030f | 973 | |
mzta | 0:158c61bb030f | 974 | int |
mzta | 0:158c61bb030f | 975 | mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size) |
mzta | 0:158c61bb030f | 976 | { |
mzta | 0:158c61bb030f | 977 | return dump_irep(mrb, irep, debug_info, bin, bin_size, FLAG_BYTEORDER_NONATIVE); |
mzta | 0:158c61bb030f | 978 | } |
mzta | 0:158c61bb030f | 979 | |
mzta | 0:158c61bb030f | 980 | int |
mzta | 0:158c61bb030f | 981 | mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp) |
mzta | 0:158c61bb030f | 982 | { |
mzta | 0:158c61bb030f | 983 | uint8_t *bin = NULL; |
mzta | 0:158c61bb030f | 984 | size_t bin_size = 0; |
mzta | 0:158c61bb030f | 985 | int result; |
mzta | 0:158c61bb030f | 986 | |
mzta | 0:158c61bb030f | 987 | if (fp == NULL) { |
mzta | 0:158c61bb030f | 988 | return MRB_DUMP_INVALID_ARGUMENT; |
mzta | 0:158c61bb030f | 989 | } |
mzta | 0:158c61bb030f | 990 | |
mzta | 0:158c61bb030f | 991 | result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NONATIVE); |
mzta | 0:158c61bb030f | 992 | if (result == MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 993 | if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) { |
mzta | 0:158c61bb030f | 994 | result = MRB_DUMP_WRITE_FAULT; |
mzta | 0:158c61bb030f | 995 | } |
mzta | 0:158c61bb030f | 996 | } |
mzta | 0:158c61bb030f | 997 | |
mzta | 0:158c61bb030f | 998 | mrb_free(mrb, bin); |
mzta | 0:158c61bb030f | 999 | return result; |
mzta | 0:158c61bb030f | 1000 | } |
mzta | 0:158c61bb030f | 1001 | |
mzta | 0:158c61bb030f | 1002 | static mrb_bool |
mzta | 0:158c61bb030f | 1003 | is_valid_c_symbol_name(const char *name) |
mzta | 0:158c61bb030f | 1004 | { |
mzta | 0:158c61bb030f | 1005 | const char *c = NULL; |
mzta | 0:158c61bb030f | 1006 | |
mzta | 0:158c61bb030f | 1007 | if (name == NULL || name[0] == '\0') return FALSE; |
mzta | 0:158c61bb030f | 1008 | if (!ISALPHA(name[0]) && name[0] != '_') return FALSE; |
mzta | 0:158c61bb030f | 1009 | |
mzta | 0:158c61bb030f | 1010 | c = &name[1]; |
mzta | 0:158c61bb030f | 1011 | for (; *c != '\0'; ++c) { |
mzta | 0:158c61bb030f | 1012 | if (!ISALNUM(*c) && *c != '_') return FALSE; |
mzta | 0:158c61bb030f | 1013 | } |
mzta | 0:158c61bb030f | 1014 | |
mzta | 0:158c61bb030f | 1015 | return TRUE; |
mzta | 0:158c61bb030f | 1016 | } |
mzta | 0:158c61bb030f | 1017 | |
mzta | 0:158c61bb030f | 1018 | int |
mzta | 0:158c61bb030f | 1019 | mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE *fp, const char *initname) |
mzta | 0:158c61bb030f | 1020 | { |
mzta | 0:158c61bb030f | 1021 | uint8_t *bin = NULL; |
mzta | 0:158c61bb030f | 1022 | size_t bin_size = 0, bin_idx = 0; |
mzta | 0:158c61bb030f | 1023 | int result; |
mzta | 0:158c61bb030f | 1024 | |
mzta | 0:158c61bb030f | 1025 | if (fp == NULL || initname == NULL || !is_valid_c_symbol_name(initname)) { |
mzta | 0:158c61bb030f | 1026 | return MRB_DUMP_INVALID_ARGUMENT; |
mzta | 0:158c61bb030f | 1027 | } |
mzta | 0:158c61bb030f | 1028 | |
mzta | 0:158c61bb030f | 1029 | result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NATIVE); |
mzta | 0:158c61bb030f | 1030 | if (result == MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 1031 | if (fprintf(fp, "#include <stdint.h>\n") < 0) { /* for uint8_t under at least Darwin */ |
mzta | 0:158c61bb030f | 1032 | mrb_free(mrb, bin); |
mzta | 0:158c61bb030f | 1033 | return MRB_DUMP_WRITE_FAULT; |
mzta | 0:158c61bb030f | 1034 | } |
mzta | 0:158c61bb030f | 1035 | if (fprintf(fp, |
mzta | 0:158c61bb030f | 1036 | "const uint8_t\n" |
mzta | 0:158c61bb030f | 1037 | "#if defined __GNUC__\n" |
mzta | 0:158c61bb030f | 1038 | "__attribute__((aligned(%u)))\n" |
mzta | 0:158c61bb030f | 1039 | "#elif defined _MSC_VER\n" |
mzta | 0:158c61bb030f | 1040 | "__declspec(align(%u))\n" |
mzta | 0:158c61bb030f | 1041 | "#endif\n" |
mzta | 0:158c61bb030f | 1042 | "%s[] = {", |
mzta | 0:158c61bb030f | 1043 | (uint16_t)MRB_DUMP_ALIGNMENT, (uint16_t)MRB_DUMP_ALIGNMENT, initname) < 0) { |
mzta | 0:158c61bb030f | 1044 | mrb_free(mrb, bin); |
mzta | 0:158c61bb030f | 1045 | return MRB_DUMP_WRITE_FAULT; |
mzta | 0:158c61bb030f | 1046 | } |
mzta | 0:158c61bb030f | 1047 | while (bin_idx < bin_size) { |
mzta | 0:158c61bb030f | 1048 | if (bin_idx % 16 == 0) { |
mzta | 0:158c61bb030f | 1049 | if (fputs("\n", fp) == EOF) { |
mzta | 0:158c61bb030f | 1050 | mrb_free(mrb, bin); |
mzta | 0:158c61bb030f | 1051 | return MRB_DUMP_WRITE_FAULT; |
mzta | 0:158c61bb030f | 1052 | } |
mzta | 0:158c61bb030f | 1053 | } |
mzta | 0:158c61bb030f | 1054 | if (fprintf(fp, "0x%02x,", bin[bin_idx++]) < 0) { |
mzta | 0:158c61bb030f | 1055 | mrb_free(mrb, bin); |
mzta | 0:158c61bb030f | 1056 | return MRB_DUMP_WRITE_FAULT; |
mzta | 0:158c61bb030f | 1057 | } |
mzta | 0:158c61bb030f | 1058 | } |
mzta | 0:158c61bb030f | 1059 | if (fputs("\n};\n", fp) == EOF) { |
mzta | 0:158c61bb030f | 1060 | mrb_free(mrb, bin); |
mzta | 0:158c61bb030f | 1061 | return MRB_DUMP_WRITE_FAULT; |
mzta | 0:158c61bb030f | 1062 | } |
mzta | 0:158c61bb030f | 1063 | } |
mzta | 0:158c61bb030f | 1064 | |
mzta | 0:158c61bb030f | 1065 | mrb_free(mrb, bin); |
mzta | 0:158c61bb030f | 1066 | return result; |
mzta | 0:158c61bb030f | 1067 | } |
mzta | 0:158c61bb030f | 1068 | |
mzta | 0:158c61bb030f | 1069 | #endif /* ENABLE_STDIO */ |
mzta | 0:158c61bb030f | 1070 |