mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
mbed-mruby
How to use
Class
src/load.c@0:158c61bb030f, 2015-03-25 (annotated)
- Committer:
- mzta
- Date:
- Wed Mar 25 17:36:16 2015 +0000
- Revision:
- 0:158c61bb030f
mirb_mbed initial commit;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mzta | 0:158c61bb030f | 1 | /* |
mzta | 0:158c61bb030f | 2 | ** load.c - mruby binary loader |
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 <limits.h> |
mzta | 0:158c61bb030f | 8 | #include <stdlib.h> |
mzta | 0:158c61bb030f | 9 | #include <string.h> |
mzta | 0:158c61bb030f | 10 | #include "mruby/dump.h" |
mzta | 0:158c61bb030f | 11 | #include "mruby/irep.h" |
mzta | 0:158c61bb030f | 12 | #include "mruby/proc.h" |
mzta | 0:158c61bb030f | 13 | #include "mruby/string.h" |
mzta | 0:158c61bb030f | 14 | #include "mruby/debug.h" |
mzta | 0:158c61bb030f | 15 | #include "mruby/error.h" |
mzta | 0:158c61bb030f | 16 | |
mzta | 0:158c61bb030f | 17 | #define FLAG_BYTEORDER_NATIVE 2 |
mzta | 0:158c61bb030f | 18 | #define FLAG_BYTEORDER_NONATIVE 0 |
mzta | 0:158c61bb030f | 19 | #define FLAG_SRC_MALLOC 1 |
mzta | 0:158c61bb030f | 20 | #define FLAG_SRC_STATIC 0 |
mzta | 0:158c61bb030f | 21 | |
mzta | 0:158c61bb030f | 22 | #if !defined(_WIN32) && SIZE_MAX < UINT32_MAX |
mzta | 0:158c61bb030f | 23 | # define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y)) |
mzta | 0:158c61bb030f | 24 | # define SIZE_ERROR(x) ((x) > SIZE_MAX) |
mzta | 0:158c61bb030f | 25 | #else |
mzta | 0:158c61bb030f | 26 | # define SIZE_ERROR_MUL(x, y) (0) |
mzta | 0:158c61bb030f | 27 | # define SIZE_ERROR(x) (0) |
mzta | 0:158c61bb030f | 28 | #endif |
mzta | 0:158c61bb030f | 29 | |
mzta | 0:158c61bb030f | 30 | #if UINT32_MAX > SIZE_MAX |
mzta | 0:158c61bb030f | 31 | # error This code cannot be built on your environment. |
mzta | 0:158c61bb030f | 32 | #endif |
mzta | 0:158c61bb030f | 33 | |
mzta | 0:158c61bb030f | 34 | static size_t |
mzta | 0:158c61bb030f | 35 | skip_padding(const uint8_t *buf) |
mzta | 0:158c61bb030f | 36 | { |
mzta | 0:158c61bb030f | 37 | const size_t align = MRB_DUMP_ALIGNMENT; |
mzta | 0:158c61bb030f | 38 | return -(intptr_t)buf & (align-1); |
mzta | 0:158c61bb030f | 39 | } |
mzta | 0:158c61bb030f | 40 | |
mzta | 0:158c61bb030f | 41 | static size_t |
mzta | 0:158c61bb030f | 42 | offset_crc_body(void) |
mzta | 0:158c61bb030f | 43 | { |
mzta | 0:158c61bb030f | 44 | struct rite_binary_header header; |
mzta | 0:158c61bb030f | 45 | return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc); |
mzta | 0:158c61bb030f | 46 | } |
mzta | 0:158c61bb030f | 47 | |
mzta | 0:158c61bb030f | 48 | static mrb_irep* |
mzta | 0:158c61bb030f | 49 | read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) |
mzta | 0:158c61bb030f | 50 | { |
mzta | 0:158c61bb030f | 51 | size_t i; |
mzta | 0:158c61bb030f | 52 | const uint8_t *src = bin; |
mzta | 0:158c61bb030f | 53 | ptrdiff_t diff; |
mzta | 0:158c61bb030f | 54 | uint16_t tt, pool_data_len, snl; |
mzta | 0:158c61bb030f | 55 | size_t plen; |
mzta | 0:158c61bb030f | 56 | int ai = mrb_gc_arena_save(mrb); |
mzta | 0:158c61bb030f | 57 | mrb_irep *irep = mrb_add_irep(mrb); |
mzta | 0:158c61bb030f | 58 | |
mzta | 0:158c61bb030f | 59 | /* skip record size */ |
mzta | 0:158c61bb030f | 60 | src += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 61 | |
mzta | 0:158c61bb030f | 62 | /* number of local variable */ |
mzta | 0:158c61bb030f | 63 | irep->nlocals = bin_to_uint16(src); |
mzta | 0:158c61bb030f | 64 | src += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 65 | |
mzta | 0:158c61bb030f | 66 | /* number of register variable */ |
mzta | 0:158c61bb030f | 67 | irep->nregs = bin_to_uint16(src); |
mzta | 0:158c61bb030f | 68 | src += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 69 | |
mzta | 0:158c61bb030f | 70 | /* number of child irep */ |
mzta | 0:158c61bb030f | 71 | irep->rlen = (size_t)bin_to_uint16(src); |
mzta | 0:158c61bb030f | 72 | src += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 73 | |
mzta | 0:158c61bb030f | 74 | /* Binary Data Section */ |
mzta | 0:158c61bb030f | 75 | /* ISEQ BLOCK */ |
mzta | 0:158c61bb030f | 76 | irep->ilen = (size_t)bin_to_uint32(src); |
mzta | 0:158c61bb030f | 77 | src += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 78 | src += skip_padding(src); |
mzta | 0:158c61bb030f | 79 | |
mzta | 0:158c61bb030f | 80 | if (irep->ilen > 0) { |
mzta | 0:158c61bb030f | 81 | if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) { |
mzta | 0:158c61bb030f | 82 | return NULL; |
mzta | 0:158c61bb030f | 83 | } |
mzta | 0:158c61bb030f | 84 | if ((flags & FLAG_SRC_MALLOC) == 0 && |
mzta | 0:158c61bb030f | 85 | (flags & FLAG_BYTEORDER_NATIVE)) { |
mzta | 0:158c61bb030f | 86 | irep->iseq = (mrb_code*)src; |
mzta | 0:158c61bb030f | 87 | src += sizeof(uint32_t) * irep->ilen; |
mzta | 0:158c61bb030f | 88 | irep->flags |= MRB_ISEQ_NO_FREE; |
mzta | 0:158c61bb030f | 89 | } |
mzta | 0:158c61bb030f | 90 | else { |
mzta | 0:158c61bb030f | 91 | irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); |
mzta | 0:158c61bb030f | 92 | if (flags & FLAG_BYTEORDER_NATIVE) { |
mzta | 0:158c61bb030f | 93 | memcpy(irep->iseq, src, sizeof(uint32_t) * irep->ilen); |
mzta | 0:158c61bb030f | 94 | src += sizeof(uint32_t) * irep->ilen; |
mzta | 0:158c61bb030f | 95 | } |
mzta | 0:158c61bb030f | 96 | else { |
mzta | 0:158c61bb030f | 97 | for (i = 0; i < irep->ilen; i++) { |
mzta | 0:158c61bb030f | 98 | irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */ |
mzta | 0:158c61bb030f | 99 | src += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 100 | } |
mzta | 0:158c61bb030f | 101 | } |
mzta | 0:158c61bb030f | 102 | } |
mzta | 0:158c61bb030f | 103 | } |
mzta | 0:158c61bb030f | 104 | |
mzta | 0:158c61bb030f | 105 | /* POOL BLOCK */ |
mzta | 0:158c61bb030f | 106 | plen = (size_t)bin_to_uint32(src); /* number of pool */ |
mzta | 0:158c61bb030f | 107 | src += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 108 | if (plen > 0) { |
mzta | 0:158c61bb030f | 109 | if (SIZE_ERROR_MUL(sizeof(mrb_value), plen)) { |
mzta | 0:158c61bb030f | 110 | return NULL; |
mzta | 0:158c61bb030f | 111 | } |
mzta | 0:158c61bb030f | 112 | irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * plen); |
mzta | 0:158c61bb030f | 113 | |
mzta | 0:158c61bb030f | 114 | for (i = 0; i < plen; i++) { |
mzta | 0:158c61bb030f | 115 | mrb_value s; |
mzta | 0:158c61bb030f | 116 | |
mzta | 0:158c61bb030f | 117 | tt = *src++; /* pool TT */ |
mzta | 0:158c61bb030f | 118 | pool_data_len = bin_to_uint16(src); /* pool data length */ |
mzta | 0:158c61bb030f | 119 | src += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 120 | if (flags & FLAG_SRC_MALLOC) { |
mzta | 0:158c61bb030f | 121 | s = mrb_str_new(mrb, (char *)src, pool_data_len); |
mzta | 0:158c61bb030f | 122 | } |
mzta | 0:158c61bb030f | 123 | else { |
mzta | 0:158c61bb030f | 124 | s = mrb_str_new_static(mrb, (char *)src, pool_data_len); |
mzta | 0:158c61bb030f | 125 | } |
mzta | 0:158c61bb030f | 126 | src += pool_data_len; |
mzta | 0:158c61bb030f | 127 | switch (tt) { /* pool data */ |
mzta | 0:158c61bb030f | 128 | case IREP_TT_FIXNUM: |
mzta | 0:158c61bb030f | 129 | irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE); |
mzta | 0:158c61bb030f | 130 | break; |
mzta | 0:158c61bb030f | 131 | |
mzta | 0:158c61bb030f | 132 | case IREP_TT_FLOAT: |
mzta | 0:158c61bb030f | 133 | irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE)); |
mzta | 0:158c61bb030f | 134 | break; |
mzta | 0:158c61bb030f | 135 | |
mzta | 0:158c61bb030f | 136 | case IREP_TT_STRING: |
mzta | 0:158c61bb030f | 137 | irep->pool[i] = mrb_str_pool(mrb, s); |
mzta | 0:158c61bb030f | 138 | break; |
mzta | 0:158c61bb030f | 139 | |
mzta | 0:158c61bb030f | 140 | default: |
mzta | 0:158c61bb030f | 141 | /* should not happen */ |
mzta | 0:158c61bb030f | 142 | irep->pool[i] = mrb_nil_value(); |
mzta | 0:158c61bb030f | 143 | break; |
mzta | 0:158c61bb030f | 144 | } |
mzta | 0:158c61bb030f | 145 | irep->plen++; |
mzta | 0:158c61bb030f | 146 | mrb_gc_arena_restore(mrb, ai); |
mzta | 0:158c61bb030f | 147 | } |
mzta | 0:158c61bb030f | 148 | } |
mzta | 0:158c61bb030f | 149 | |
mzta | 0:158c61bb030f | 150 | /* SYMS BLOCK */ |
mzta | 0:158c61bb030f | 151 | irep->slen = (size_t)bin_to_uint32(src); /* syms length */ |
mzta | 0:158c61bb030f | 152 | src += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 153 | if (irep->slen > 0) { |
mzta | 0:158c61bb030f | 154 | if (SIZE_ERROR_MUL(sizeof(mrb_sym), irep->slen)) { |
mzta | 0:158c61bb030f | 155 | return NULL; |
mzta | 0:158c61bb030f | 156 | } |
mzta | 0:158c61bb030f | 157 | irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen); |
mzta | 0:158c61bb030f | 158 | |
mzta | 0:158c61bb030f | 159 | for (i = 0; i < irep->slen; i++) { |
mzta | 0:158c61bb030f | 160 | snl = bin_to_uint16(src); /* symbol name length */ |
mzta | 0:158c61bb030f | 161 | src += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 162 | |
mzta | 0:158c61bb030f | 163 | if (snl == MRB_DUMP_NULL_SYM_LEN) { |
mzta | 0:158c61bb030f | 164 | irep->syms[i] = 0; |
mzta | 0:158c61bb030f | 165 | continue; |
mzta | 0:158c61bb030f | 166 | } |
mzta | 0:158c61bb030f | 167 | |
mzta | 0:158c61bb030f | 168 | if (flags & FLAG_SRC_MALLOC) { |
mzta | 0:158c61bb030f | 169 | irep->syms[i] = mrb_intern(mrb, (char *)src, snl); |
mzta | 0:158c61bb030f | 170 | } |
mzta | 0:158c61bb030f | 171 | else { |
mzta | 0:158c61bb030f | 172 | irep->syms[i] = mrb_intern_static(mrb, (char *)src, snl); |
mzta | 0:158c61bb030f | 173 | } |
mzta | 0:158c61bb030f | 174 | src += snl + 1; |
mzta | 0:158c61bb030f | 175 | |
mzta | 0:158c61bb030f | 176 | mrb_gc_arena_restore(mrb, ai); |
mzta | 0:158c61bb030f | 177 | } |
mzta | 0:158c61bb030f | 178 | } |
mzta | 0:158c61bb030f | 179 | |
mzta | 0:158c61bb030f | 180 | irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*irep->rlen); |
mzta | 0:158c61bb030f | 181 | |
mzta | 0:158c61bb030f | 182 | diff = src - bin; |
mzta | 0:158c61bb030f | 183 | mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 184 | *len = (size_t)diff; |
mzta | 0:158c61bb030f | 185 | |
mzta | 0:158c61bb030f | 186 | return irep; |
mzta | 0:158c61bb030f | 187 | } |
mzta | 0:158c61bb030f | 188 | |
mzta | 0:158c61bb030f | 189 | static mrb_irep* |
mzta | 0:158c61bb030f | 190 | read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) |
mzta | 0:158c61bb030f | 191 | { |
mzta | 0:158c61bb030f | 192 | mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags); |
mzta | 0:158c61bb030f | 193 | size_t i; |
mzta | 0:158c61bb030f | 194 | |
mzta | 0:158c61bb030f | 195 | if (irep == NULL) { |
mzta | 0:158c61bb030f | 196 | return NULL; |
mzta | 0:158c61bb030f | 197 | } |
mzta | 0:158c61bb030f | 198 | |
mzta | 0:158c61bb030f | 199 | bin += *len; |
mzta | 0:158c61bb030f | 200 | for (i=0; i<irep->rlen; i++) { |
mzta | 0:158c61bb030f | 201 | size_t rlen; |
mzta | 0:158c61bb030f | 202 | |
mzta | 0:158c61bb030f | 203 | irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags); |
mzta | 0:158c61bb030f | 204 | if (irep->reps[i] == NULL) { |
mzta | 0:158c61bb030f | 205 | return NULL; |
mzta | 0:158c61bb030f | 206 | } |
mzta | 0:158c61bb030f | 207 | bin += rlen; |
mzta | 0:158c61bb030f | 208 | *len += rlen; |
mzta | 0:158c61bb030f | 209 | } |
mzta | 0:158c61bb030f | 210 | return irep; |
mzta | 0:158c61bb030f | 211 | } |
mzta | 0:158c61bb030f | 212 | |
mzta | 0:158c61bb030f | 213 | static mrb_irep* |
mzta | 0:158c61bb030f | 214 | read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags) |
mzta | 0:158c61bb030f | 215 | { |
mzta | 0:158c61bb030f | 216 | size_t len; |
mzta | 0:158c61bb030f | 217 | |
mzta | 0:158c61bb030f | 218 | bin += sizeof(struct rite_section_irep_header); |
mzta | 0:158c61bb030f | 219 | return read_irep_record(mrb, bin, &len, flags); |
mzta | 0:158c61bb030f | 220 | } |
mzta | 0:158c61bb030f | 221 | |
mzta | 0:158c61bb030f | 222 | static int |
mzta | 0:158c61bb030f | 223 | read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len) |
mzta | 0:158c61bb030f | 224 | { |
mzta | 0:158c61bb030f | 225 | size_t i, fname_len, niseq; |
mzta | 0:158c61bb030f | 226 | char *fname; |
mzta | 0:158c61bb030f | 227 | uint16_t *lines; |
mzta | 0:158c61bb030f | 228 | |
mzta | 0:158c61bb030f | 229 | *len = 0; |
mzta | 0:158c61bb030f | 230 | bin += sizeof(uint32_t); /* record size */ |
mzta | 0:158c61bb030f | 231 | *len += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 232 | fname_len = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 233 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 234 | *len += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 235 | if (SIZE_ERROR(fname_len + 1)) { |
mzta | 0:158c61bb030f | 236 | return MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 237 | } |
mzta | 0:158c61bb030f | 238 | fname = (char *)mrb_malloc(mrb, fname_len + 1); |
mzta | 0:158c61bb030f | 239 | memcpy(fname, bin, fname_len); |
mzta | 0:158c61bb030f | 240 | fname[fname_len] = '\0'; |
mzta | 0:158c61bb030f | 241 | bin += fname_len; |
mzta | 0:158c61bb030f | 242 | *len += fname_len; |
mzta | 0:158c61bb030f | 243 | |
mzta | 0:158c61bb030f | 244 | niseq = (size_t)bin_to_uint32(bin); |
mzta | 0:158c61bb030f | 245 | bin += sizeof(uint32_t); /* niseq */ |
mzta | 0:158c61bb030f | 246 | *len += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 247 | |
mzta | 0:158c61bb030f | 248 | if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) { |
mzta | 0:158c61bb030f | 249 | return MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 250 | } |
mzta | 0:158c61bb030f | 251 | lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t)); |
mzta | 0:158c61bb030f | 252 | for (i = 0; i < niseq; i++) { |
mzta | 0:158c61bb030f | 253 | lines[i] = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 254 | bin += sizeof(uint16_t); /* niseq */ |
mzta | 0:158c61bb030f | 255 | *len += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 256 | } |
mzta | 0:158c61bb030f | 257 | |
mzta | 0:158c61bb030f | 258 | irep->filename = fname; |
mzta | 0:158c61bb030f | 259 | irep->lines = lines; |
mzta | 0:158c61bb030f | 260 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 261 | } |
mzta | 0:158c61bb030f | 262 | |
mzta | 0:158c61bb030f | 263 | static int |
mzta | 0:158c61bb030f | 264 | read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp) |
mzta | 0:158c61bb030f | 265 | { |
mzta | 0:158c61bb030f | 266 | int result = read_lineno_record_1(mrb, bin, irep, lenp); |
mzta | 0:158c61bb030f | 267 | size_t i; |
mzta | 0:158c61bb030f | 268 | |
mzta | 0:158c61bb030f | 269 | if (result != MRB_DUMP_OK) return result; |
mzta | 0:158c61bb030f | 270 | for (i = 0; i < irep->rlen; i++) { |
mzta | 0:158c61bb030f | 271 | size_t len; |
mzta | 0:158c61bb030f | 272 | |
mzta | 0:158c61bb030f | 273 | result = read_lineno_record(mrb, bin, irep->reps[i], &len); |
mzta | 0:158c61bb030f | 274 | if (result != MRB_DUMP_OK) break; |
mzta | 0:158c61bb030f | 275 | bin += len; |
mzta | 0:158c61bb030f | 276 | *lenp += len; |
mzta | 0:158c61bb030f | 277 | } |
mzta | 0:158c61bb030f | 278 | return result; |
mzta | 0:158c61bb030f | 279 | } |
mzta | 0:158c61bb030f | 280 | |
mzta | 0:158c61bb030f | 281 | static int |
mzta | 0:158c61bb030f | 282 | read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep) |
mzta | 0:158c61bb030f | 283 | { |
mzta | 0:158c61bb030f | 284 | size_t len; |
mzta | 0:158c61bb030f | 285 | |
mzta | 0:158c61bb030f | 286 | len = 0; |
mzta | 0:158c61bb030f | 287 | bin += sizeof(struct rite_section_lineno_header); |
mzta | 0:158c61bb030f | 288 | |
mzta | 0:158c61bb030f | 289 | /* Read Binary Data Section */ |
mzta | 0:158c61bb030f | 290 | return read_lineno_record(mrb, bin, irep, &len); |
mzta | 0:158c61bb030f | 291 | } |
mzta | 0:158c61bb030f | 292 | |
mzta | 0:158c61bb030f | 293 | static int |
mzta | 0:158c61bb030f | 294 | read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len) |
mzta | 0:158c61bb030f | 295 | { |
mzta | 0:158c61bb030f | 296 | const uint8_t *bin = start; |
mzta | 0:158c61bb030f | 297 | ptrdiff_t diff; |
mzta | 0:158c61bb030f | 298 | size_t record_size, i; |
mzta | 0:158c61bb030f | 299 | uint16_t f_idx; |
mzta | 0:158c61bb030f | 300 | |
mzta | 0:158c61bb030f | 301 | if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; } |
mzta | 0:158c61bb030f | 302 | |
mzta | 0:158c61bb030f | 303 | irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info)); |
mzta | 0:158c61bb030f | 304 | irep->debug_info->pc_count = irep->ilen; |
mzta | 0:158c61bb030f | 305 | |
mzta | 0:158c61bb030f | 306 | record_size = (size_t)bin_to_uint32(bin); |
mzta | 0:158c61bb030f | 307 | bin += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 308 | |
mzta | 0:158c61bb030f | 309 | irep->debug_info->flen = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 310 | irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen); |
mzta | 0:158c61bb030f | 311 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 312 | |
mzta | 0:158c61bb030f | 313 | for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) { |
mzta | 0:158c61bb030f | 314 | mrb_irep_debug_info_file *file; |
mzta | 0:158c61bb030f | 315 | uint16_t filename_idx; |
mzta | 0:158c61bb030f | 316 | mrb_int len; |
mzta | 0:158c61bb030f | 317 | |
mzta | 0:158c61bb030f | 318 | file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file)); |
mzta | 0:158c61bb030f | 319 | irep->debug_info->files[f_idx] = file; |
mzta | 0:158c61bb030f | 320 | |
mzta | 0:158c61bb030f | 321 | file->start_pos = bin_to_uint32(bin); |
mzta | 0:158c61bb030f | 322 | bin += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 323 | |
mzta | 0:158c61bb030f | 324 | /* filename */ |
mzta | 0:158c61bb030f | 325 | filename_idx = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 326 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 327 | mrb_assert(filename_idx < filenames_len); |
mzta | 0:158c61bb030f | 328 | file->filename_sym = filenames[filename_idx]; |
mzta | 0:158c61bb030f | 329 | len = 0; |
mzta | 0:158c61bb030f | 330 | file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len); |
mzta | 0:158c61bb030f | 331 | |
mzta | 0:158c61bb030f | 332 | file->line_entry_count = bin_to_uint32(bin); |
mzta | 0:158c61bb030f | 333 | bin += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 334 | file->line_type = (mrb_debug_line_type)bin_to_uint8(bin); |
mzta | 0:158c61bb030f | 335 | bin += sizeof(uint8_t); |
mzta | 0:158c61bb030f | 336 | switch (file->line_type) { |
mzta | 0:158c61bb030f | 337 | case mrb_debug_line_ary: { |
mzta | 0:158c61bb030f | 338 | uint32_t l; |
mzta | 0:158c61bb030f | 339 | |
mzta | 0:158c61bb030f | 340 | file->lines.ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count)); |
mzta | 0:158c61bb030f | 341 | for (l = 0; l < file->line_entry_count; ++l) { |
mzta | 0:158c61bb030f | 342 | file->lines.ary[l] = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 343 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 344 | } |
mzta | 0:158c61bb030f | 345 | } break; |
mzta | 0:158c61bb030f | 346 | |
mzta | 0:158c61bb030f | 347 | case mrb_debug_line_flat_map: { |
mzta | 0:158c61bb030f | 348 | uint32_t l; |
mzta | 0:158c61bb030f | 349 | |
mzta | 0:158c61bb030f | 350 | file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc( |
mzta | 0:158c61bb030f | 351 | mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count)); |
mzta | 0:158c61bb030f | 352 | for (l = 0; l < file->line_entry_count; ++l) { |
mzta | 0:158c61bb030f | 353 | file->lines.flat_map[l].start_pos = bin_to_uint32(bin); |
mzta | 0:158c61bb030f | 354 | bin += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 355 | file->lines.flat_map[l].line = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 356 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 357 | } |
mzta | 0:158c61bb030f | 358 | } break; |
mzta | 0:158c61bb030f | 359 | |
mzta | 0:158c61bb030f | 360 | default: return MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 361 | } |
mzta | 0:158c61bb030f | 362 | } |
mzta | 0:158c61bb030f | 363 | |
mzta | 0:158c61bb030f | 364 | diff = bin - start; |
mzta | 0:158c61bb030f | 365 | mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 366 | |
mzta | 0:158c61bb030f | 367 | if (record_size != (size_t)diff) { |
mzta | 0:158c61bb030f | 368 | return MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 369 | } |
mzta | 0:158c61bb030f | 370 | |
mzta | 0:158c61bb030f | 371 | for (i = 0; i < irep->rlen; i++) { |
mzta | 0:158c61bb030f | 372 | size_t len; |
mzta | 0:158c61bb030f | 373 | int ret; |
mzta | 0:158c61bb030f | 374 | |
mzta | 0:158c61bb030f | 375 | ret = read_debug_record(mrb, bin, irep->reps[i], &len, filenames, filenames_len); |
mzta | 0:158c61bb030f | 376 | if (ret != MRB_DUMP_OK) return ret; |
mzta | 0:158c61bb030f | 377 | bin += len; |
mzta | 0:158c61bb030f | 378 | } |
mzta | 0:158c61bb030f | 379 | |
mzta | 0:158c61bb030f | 380 | diff = bin - start; |
mzta | 0:158c61bb030f | 381 | mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 382 | *record_len = (size_t)diff; |
mzta | 0:158c61bb030f | 383 | |
mzta | 0:158c61bb030f | 384 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 385 | } |
mzta | 0:158c61bb030f | 386 | |
mzta | 0:158c61bb030f | 387 | static int |
mzta | 0:158c61bb030f | 388 | read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) |
mzta | 0:158c61bb030f | 389 | { |
mzta | 0:158c61bb030f | 390 | const uint8_t *bin; |
mzta | 0:158c61bb030f | 391 | ptrdiff_t diff; |
mzta | 0:158c61bb030f | 392 | struct rite_section_debug_header *header; |
mzta | 0:158c61bb030f | 393 | uint16_t i; |
mzta | 0:158c61bb030f | 394 | size_t len = 0; |
mzta | 0:158c61bb030f | 395 | int result; |
mzta | 0:158c61bb030f | 396 | uint16_t filenames_len; |
mzta | 0:158c61bb030f | 397 | mrb_sym *filenames; |
mzta | 0:158c61bb030f | 398 | |
mzta | 0:158c61bb030f | 399 | bin = start; |
mzta | 0:158c61bb030f | 400 | header = (struct rite_section_debug_header *)bin; |
mzta | 0:158c61bb030f | 401 | bin += sizeof(struct rite_section_debug_header); |
mzta | 0:158c61bb030f | 402 | |
mzta | 0:158c61bb030f | 403 | filenames_len = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 404 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 405 | filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len); |
mzta | 0:158c61bb030f | 406 | for (i = 0; i < filenames_len; ++i) { |
mzta | 0:158c61bb030f | 407 | uint16_t f_len = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 408 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 409 | if (flags & FLAG_SRC_MALLOC) { |
mzta | 0:158c61bb030f | 410 | filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); |
mzta | 0:158c61bb030f | 411 | } |
mzta | 0:158c61bb030f | 412 | else { |
mzta | 0:158c61bb030f | 413 | filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len); |
mzta | 0:158c61bb030f | 414 | } |
mzta | 0:158c61bb030f | 415 | bin += f_len; |
mzta | 0:158c61bb030f | 416 | } |
mzta | 0:158c61bb030f | 417 | |
mzta | 0:158c61bb030f | 418 | result = read_debug_record(mrb, bin, irep, &len, filenames, filenames_len); |
mzta | 0:158c61bb030f | 419 | if (result != MRB_DUMP_OK) goto debug_exit; |
mzta | 0:158c61bb030f | 420 | |
mzta | 0:158c61bb030f | 421 | bin += len; |
mzta | 0:158c61bb030f | 422 | diff = bin - start; |
mzta | 0:158c61bb030f | 423 | mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 424 | if ((uint32_t)diff != bin_to_uint32(header->section_size)) { |
mzta | 0:158c61bb030f | 425 | result = MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 426 | } |
mzta | 0:158c61bb030f | 427 | |
mzta | 0:158c61bb030f | 428 | debug_exit: |
mzta | 0:158c61bb030f | 429 | mrb_free(mrb, filenames); |
mzta | 0:158c61bb030f | 430 | return result; |
mzta | 0:158c61bb030f | 431 | } |
mzta | 0:158c61bb030f | 432 | |
mzta | 0:158c61bb030f | 433 | static int |
mzta | 0:158c61bb030f | 434 | read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *record_len, mrb_sym const *syms, uint32_t syms_len) |
mzta | 0:158c61bb030f | 435 | { |
mzta | 0:158c61bb030f | 436 | const uint8_t *bin = start; |
mzta | 0:158c61bb030f | 437 | size_t i; |
mzta | 0:158c61bb030f | 438 | ptrdiff_t diff; |
mzta | 0:158c61bb030f | 439 | |
mzta | 0:158c61bb030f | 440 | irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (irep->nlocals - 1)); |
mzta | 0:158c61bb030f | 441 | |
mzta | 0:158c61bb030f | 442 | for (i = 0; i + 1< irep->nlocals; ++i) { |
mzta | 0:158c61bb030f | 443 | uint16_t const sym_idx = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 444 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 445 | if (sym_idx == RITE_LV_NULL_MARK) { |
mzta | 0:158c61bb030f | 446 | irep->lv[i].name = 0; |
mzta | 0:158c61bb030f | 447 | irep->lv[i].r = 0; |
mzta | 0:158c61bb030f | 448 | } |
mzta | 0:158c61bb030f | 449 | else { |
mzta | 0:158c61bb030f | 450 | if (sym_idx >= syms_len) { |
mzta | 0:158c61bb030f | 451 | return MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 452 | } |
mzta | 0:158c61bb030f | 453 | irep->lv[i].name = syms[sym_idx]; |
mzta | 0:158c61bb030f | 454 | |
mzta | 0:158c61bb030f | 455 | irep->lv[i].r = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 456 | } |
mzta | 0:158c61bb030f | 457 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 458 | } |
mzta | 0:158c61bb030f | 459 | |
mzta | 0:158c61bb030f | 460 | for (i = 0; i < irep->rlen; ++i) { |
mzta | 0:158c61bb030f | 461 | size_t len; |
mzta | 0:158c61bb030f | 462 | int ret; |
mzta | 0:158c61bb030f | 463 | |
mzta | 0:158c61bb030f | 464 | ret = read_lv_record(mrb, bin, irep->reps[i], &len, syms, syms_len); |
mzta | 0:158c61bb030f | 465 | if (ret != MRB_DUMP_OK) return ret; |
mzta | 0:158c61bb030f | 466 | bin += len; |
mzta | 0:158c61bb030f | 467 | } |
mzta | 0:158c61bb030f | 468 | |
mzta | 0:158c61bb030f | 469 | diff = bin - start; |
mzta | 0:158c61bb030f | 470 | mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 471 | *record_len = (size_t)diff; |
mzta | 0:158c61bb030f | 472 | |
mzta | 0:158c61bb030f | 473 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 474 | } |
mzta | 0:158c61bb030f | 475 | |
mzta | 0:158c61bb030f | 476 | static int |
mzta | 0:158c61bb030f | 477 | read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) |
mzta | 0:158c61bb030f | 478 | { |
mzta | 0:158c61bb030f | 479 | const uint8_t *bin; |
mzta | 0:158c61bb030f | 480 | ptrdiff_t diff; |
mzta | 0:158c61bb030f | 481 | struct rite_section_lv_header const *header; |
mzta | 0:158c61bb030f | 482 | uint32_t i; |
mzta | 0:158c61bb030f | 483 | size_t len = 0; |
mzta | 0:158c61bb030f | 484 | int result; |
mzta | 0:158c61bb030f | 485 | uint32_t syms_len; |
mzta | 0:158c61bb030f | 486 | mrb_sym *syms; |
mzta | 0:158c61bb030f | 487 | mrb_sym (*intern_func)(mrb_state*, const char*, size_t) = |
mzta | 0:158c61bb030f | 488 | (flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static; |
mzta | 0:158c61bb030f | 489 | |
mzta | 0:158c61bb030f | 490 | bin = start; |
mzta | 0:158c61bb030f | 491 | header = (struct rite_section_lv_header const*)bin; |
mzta | 0:158c61bb030f | 492 | bin += sizeof(struct rite_section_lv_header); |
mzta | 0:158c61bb030f | 493 | |
mzta | 0:158c61bb030f | 494 | syms_len = bin_to_uint32(bin); |
mzta | 0:158c61bb030f | 495 | bin += sizeof(uint32_t); |
mzta | 0:158c61bb030f | 496 | syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)syms_len); |
mzta | 0:158c61bb030f | 497 | for (i = 0; i < syms_len; ++i) { |
mzta | 0:158c61bb030f | 498 | uint16_t const str_len = bin_to_uint16(bin); |
mzta | 0:158c61bb030f | 499 | bin += sizeof(uint16_t); |
mzta | 0:158c61bb030f | 500 | |
mzta | 0:158c61bb030f | 501 | syms[i] = intern_func(mrb, (const char*)bin, str_len); |
mzta | 0:158c61bb030f | 502 | bin += str_len; |
mzta | 0:158c61bb030f | 503 | } |
mzta | 0:158c61bb030f | 504 | |
mzta | 0:158c61bb030f | 505 | result = read_lv_record(mrb, bin, irep, &len, syms, syms_len); |
mzta | 0:158c61bb030f | 506 | if (result != MRB_DUMP_OK) goto lv_exit; |
mzta | 0:158c61bb030f | 507 | |
mzta | 0:158c61bb030f | 508 | bin += len; |
mzta | 0:158c61bb030f | 509 | diff = bin - start; |
mzta | 0:158c61bb030f | 510 | mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX); |
mzta | 0:158c61bb030f | 511 | if ((uint32_t)diff != bin_to_uint32(header->section_size)) { |
mzta | 0:158c61bb030f | 512 | result = MRB_DUMP_GENERAL_FAILURE; |
mzta | 0:158c61bb030f | 513 | } |
mzta | 0:158c61bb030f | 514 | |
mzta | 0:158c61bb030f | 515 | lv_exit: |
mzta | 0:158c61bb030f | 516 | mrb_free(mrb, syms); |
mzta | 0:158c61bb030f | 517 | return result; |
mzta | 0:158c61bb030f | 518 | } |
mzta | 0:158c61bb030f | 519 | |
mzta | 0:158c61bb030f | 520 | static int |
mzta | 0:158c61bb030f | 521 | read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t *flags) |
mzta | 0:158c61bb030f | 522 | { |
mzta | 0:158c61bb030f | 523 | const struct rite_binary_header *header = (const struct rite_binary_header *)bin; |
mzta | 0:158c61bb030f | 524 | uint32_t ident = 0; |
mzta | 0:158c61bb030f | 525 | size_t i; |
mzta | 0:158c61bb030f | 526 | |
mzta | 0:158c61bb030f | 527 | /* create native byteorder version of RITE_BINARY_IDENTIFIER */ |
mzta | 0:158c61bb030f | 528 | for(i=0; i<sizeof(ident); i++) { |
mzta | 0:158c61bb030f | 529 | ident<<=8; |
mzta | 0:158c61bb030f | 530 | ident|=RITE_BINARY_IDENTIFIER[i]; |
mzta | 0:158c61bb030f | 531 | } |
mzta | 0:158c61bb030f | 532 | if (memcmp(header->binary_identify, &ident, sizeof(header->binary_identify)) == 0) { |
mzta | 0:158c61bb030f | 533 | *flags |= FLAG_BYTEORDER_NATIVE; |
mzta | 0:158c61bb030f | 534 | } |
mzta | 0:158c61bb030f | 535 | else if (memcmp(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)) != 0) { |
mzta | 0:158c61bb030f | 536 | return MRB_DUMP_INVALID_FILE_HEADER; |
mzta | 0:158c61bb030f | 537 | } |
mzta | 0:158c61bb030f | 538 | |
mzta | 0:158c61bb030f | 539 | if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) { |
mzta | 0:158c61bb030f | 540 | return MRB_DUMP_INVALID_FILE_HEADER; |
mzta | 0:158c61bb030f | 541 | } |
mzta | 0:158c61bb030f | 542 | |
mzta | 0:158c61bb030f | 543 | if (crc) { |
mzta | 0:158c61bb030f | 544 | *crc = bin_to_uint16(header->binary_crc); |
mzta | 0:158c61bb030f | 545 | } |
mzta | 0:158c61bb030f | 546 | *bin_size = (size_t)bin_to_uint32(header->binary_size); |
mzta | 0:158c61bb030f | 547 | |
mzta | 0:158c61bb030f | 548 | return MRB_DUMP_OK; |
mzta | 0:158c61bb030f | 549 | } |
mzta | 0:158c61bb030f | 550 | |
mzta | 0:158c61bb030f | 551 | MRB_API mrb_irep* |
mzta | 0:158c61bb030f | 552 | read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags) |
mzta | 0:158c61bb030f | 553 | { |
mzta | 0:158c61bb030f | 554 | int result; |
mzta | 0:158c61bb030f | 555 | mrb_irep *irep = NULL; |
mzta | 0:158c61bb030f | 556 | const struct rite_section_header *section_header; |
mzta | 0:158c61bb030f | 557 | uint16_t crc; |
mzta | 0:158c61bb030f | 558 | size_t bin_size = 0; |
mzta | 0:158c61bb030f | 559 | size_t n; |
mzta | 0:158c61bb030f | 560 | |
mzta | 0:158c61bb030f | 561 | if ((mrb == NULL) || (bin == NULL)) { |
mzta | 0:158c61bb030f | 562 | return NULL; |
mzta | 0:158c61bb030f | 563 | } |
mzta | 0:158c61bb030f | 564 | |
mzta | 0:158c61bb030f | 565 | result = read_binary_header(bin, &bin_size, &crc, &flags); |
mzta | 0:158c61bb030f | 566 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 567 | return NULL; |
mzta | 0:158c61bb030f | 568 | } |
mzta | 0:158c61bb030f | 569 | |
mzta | 0:158c61bb030f | 570 | n = offset_crc_body(); |
mzta | 0:158c61bb030f | 571 | if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) { |
mzta | 0:158c61bb030f | 572 | return NULL; |
mzta | 0:158c61bb030f | 573 | } |
mzta | 0:158c61bb030f | 574 | |
mzta | 0:158c61bb030f | 575 | bin += sizeof(struct rite_binary_header); |
mzta | 0:158c61bb030f | 576 | do { |
mzta | 0:158c61bb030f | 577 | section_header = (const struct rite_section_header *)bin; |
mzta | 0:158c61bb030f | 578 | if (memcmp(section_header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { |
mzta | 0:158c61bb030f | 579 | irep = read_section_irep(mrb, bin, flags); |
mzta | 0:158c61bb030f | 580 | if (!irep) return NULL; |
mzta | 0:158c61bb030f | 581 | } |
mzta | 0:158c61bb030f | 582 | else if (memcmp(section_header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { |
mzta | 0:158c61bb030f | 583 | if (!irep) return NULL; /* corrupted data */ |
mzta | 0:158c61bb030f | 584 | result = read_section_lineno(mrb, bin, irep); |
mzta | 0:158c61bb030f | 585 | if (result < MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 586 | return NULL; |
mzta | 0:158c61bb030f | 587 | } |
mzta | 0:158c61bb030f | 588 | } |
mzta | 0:158c61bb030f | 589 | else if (memcmp(section_header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { |
mzta | 0:158c61bb030f | 590 | if (!irep) return NULL; /* corrupted data */ |
mzta | 0:158c61bb030f | 591 | result = read_section_debug(mrb, bin, irep, flags); |
mzta | 0:158c61bb030f | 592 | if (result < MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 593 | return NULL; |
mzta | 0:158c61bb030f | 594 | } |
mzta | 0:158c61bb030f | 595 | } |
mzta | 0:158c61bb030f | 596 | else if (memcmp(section_header->section_identify, RITE_SECTION_LV_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { |
mzta | 0:158c61bb030f | 597 | if (!irep) return NULL; |
mzta | 0:158c61bb030f | 598 | result = read_section_lv(mrb, bin, irep, flags); |
mzta | 0:158c61bb030f | 599 | if (result < MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 600 | return NULL; |
mzta | 0:158c61bb030f | 601 | } |
mzta | 0:158c61bb030f | 602 | } |
mzta | 0:158c61bb030f | 603 | bin += bin_to_uint32(section_header->section_size); |
mzta | 0:158c61bb030f | 604 | } while (memcmp(section_header->section_identify, RITE_BINARY_EOF, sizeof(section_header->section_identify)) != 0); |
mzta | 0:158c61bb030f | 605 | |
mzta | 0:158c61bb030f | 606 | return irep; |
mzta | 0:158c61bb030f | 607 | } |
mzta | 0:158c61bb030f | 608 | |
mzta | 0:158c61bb030f | 609 | MRB_API mrb_irep* |
mzta | 0:158c61bb030f | 610 | mrb_read_irep(mrb_state *mrb, const uint8_t *bin) |
mzta | 0:158c61bb030f | 611 | { |
mzta | 0:158c61bb030f | 612 | #ifdef MRB_USE_ETEXT_EDATA |
mzta | 0:158c61bb030f | 613 | uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC; |
mzta | 0:158c61bb030f | 614 | #else |
mzta | 0:158c61bb030f | 615 | uint8_t flags = FLAG_SRC_STATIC; |
mzta | 0:158c61bb030f | 616 | #endif |
mzta | 0:158c61bb030f | 617 | |
mzta | 0:158c61bb030f | 618 | return read_irep(mrb, bin, flags); |
mzta | 0:158c61bb030f | 619 | } |
mzta | 0:158c61bb030f | 620 | |
mzta | 0:158c61bb030f | 621 | static void |
mzta | 0:158c61bb030f | 622 | irep_error(mrb_state *mrb) |
mzta | 0:158c61bb030f | 623 | { |
mzta | 0:158c61bb030f | 624 | mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error")); |
mzta | 0:158c61bb030f | 625 | } |
mzta | 0:158c61bb030f | 626 | |
mzta | 0:158c61bb030f | 627 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 628 | mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c) |
mzta | 0:158c61bb030f | 629 | { |
mzta | 0:158c61bb030f | 630 | mrb_irep *irep = mrb_read_irep(mrb, bin); |
mzta | 0:158c61bb030f | 631 | struct RProc *proc; |
mzta | 0:158c61bb030f | 632 | |
mzta | 0:158c61bb030f | 633 | if (!irep) { |
mzta | 0:158c61bb030f | 634 | irep_error(mrb); |
mzta | 0:158c61bb030f | 635 | return mrb_nil_value(); |
mzta | 0:158c61bb030f | 636 | } |
mzta | 0:158c61bb030f | 637 | proc = mrb_proc_new(mrb, irep); |
mzta | 0:158c61bb030f | 638 | mrb_irep_decref(mrb, irep); |
mzta | 0:158c61bb030f | 639 | if (c && c->no_exec) return mrb_obj_value(proc); |
mzta | 0:158c61bb030f | 640 | return mrb_toplevel_run(mrb, proc); |
mzta | 0:158c61bb030f | 641 | } |
mzta | 0:158c61bb030f | 642 | |
mzta | 0:158c61bb030f | 643 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 644 | mrb_load_irep(mrb_state *mrb, const uint8_t *bin) |
mzta | 0:158c61bb030f | 645 | { |
mzta | 0:158c61bb030f | 646 | return mrb_load_irep_cxt(mrb, bin, NULL); |
mzta | 0:158c61bb030f | 647 | } |
mzta | 0:158c61bb030f | 648 | |
mzta | 0:158c61bb030f | 649 | #ifdef ENABLE_STDIO |
mzta | 0:158c61bb030f | 650 | |
mzta | 0:158c61bb030f | 651 | MRB_API mrb_irep* |
mzta | 0:158c61bb030f | 652 | mrb_read_irep_file(mrb_state *mrb, FILE* fp) |
mzta | 0:158c61bb030f | 653 | { |
mzta | 0:158c61bb030f | 654 | mrb_irep *irep = NULL; |
mzta | 0:158c61bb030f | 655 | uint8_t *buf; |
mzta | 0:158c61bb030f | 656 | const size_t header_size = sizeof(struct rite_binary_header); |
mzta | 0:158c61bb030f | 657 | size_t buf_size = 0; |
mzta | 0:158c61bb030f | 658 | uint8_t flags; |
mzta | 0:158c61bb030f | 659 | int result; |
mzta | 0:158c61bb030f | 660 | |
mzta | 0:158c61bb030f | 661 | if ((mrb == NULL) || (fp == NULL)) { |
mzta | 0:158c61bb030f | 662 | return NULL; |
mzta | 0:158c61bb030f | 663 | } |
mzta | 0:158c61bb030f | 664 | |
mzta | 0:158c61bb030f | 665 | /* You don't need use SIZE_ERROR as buf_size is enough small. */ |
mzta | 0:158c61bb030f | 666 | buf = (uint8_t*)mrb_malloc(mrb, header_size); |
mzta | 0:158c61bb030f | 667 | if (fread(buf, header_size, 1, fp) == 0) { |
mzta | 0:158c61bb030f | 668 | mrb_free(mrb, buf); |
mzta | 0:158c61bb030f | 669 | return NULL; |
mzta | 0:158c61bb030f | 670 | } |
mzta | 0:158c61bb030f | 671 | result = read_binary_header(buf, &buf_size, NULL, &flags); |
mzta | 0:158c61bb030f | 672 | if (result != MRB_DUMP_OK) { |
mzta | 0:158c61bb030f | 673 | mrb_free(mrb, buf); |
mzta | 0:158c61bb030f | 674 | return NULL; |
mzta | 0:158c61bb030f | 675 | } |
mzta | 0:158c61bb030f | 676 | |
mzta | 0:158c61bb030f | 677 | buf = (uint8_t*)mrb_realloc(mrb, buf, buf_size); |
mzta | 0:158c61bb030f | 678 | if (fread(buf+header_size, buf_size-header_size, 1, fp) == 0) { |
mzta | 0:158c61bb030f | 679 | mrb_free(mrb, buf); |
mzta | 0:158c61bb030f | 680 | return NULL; |
mzta | 0:158c61bb030f | 681 | } |
mzta | 0:158c61bb030f | 682 | irep = read_irep(mrb, buf, FLAG_SRC_MALLOC); |
mzta | 0:158c61bb030f | 683 | mrb_free(mrb, buf); |
mzta | 0:158c61bb030f | 684 | |
mzta | 0:158c61bb030f | 685 | return irep; |
mzta | 0:158c61bb030f | 686 | } |
mzta | 0:158c61bb030f | 687 | |
mzta | 0:158c61bb030f | 688 | void mrb_codedump_all(mrb_state*, struct RProc*); |
mzta | 0:158c61bb030f | 689 | |
mzta | 0:158c61bb030f | 690 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 691 | mrb_load_irep_file_cxt(mrb_state *mrb, FILE* fp, mrbc_context *c) |
mzta | 0:158c61bb030f | 692 | { |
mzta | 0:158c61bb030f | 693 | mrb_irep *irep = mrb_read_irep_file(mrb, fp); |
mzta | 0:158c61bb030f | 694 | mrb_value val; |
mzta | 0:158c61bb030f | 695 | struct RProc *proc; |
mzta | 0:158c61bb030f | 696 | |
mzta | 0:158c61bb030f | 697 | if (!irep) { |
mzta | 0:158c61bb030f | 698 | irep_error(mrb); |
mzta | 0:158c61bb030f | 699 | return mrb_nil_value(); |
mzta | 0:158c61bb030f | 700 | } |
mzta | 0:158c61bb030f | 701 | proc = mrb_proc_new(mrb, irep); |
mzta | 0:158c61bb030f | 702 | mrb_irep_decref(mrb, irep); |
mzta | 0:158c61bb030f | 703 | if (c && c->dump_result) mrb_codedump_all(mrb, proc); |
mzta | 0:158c61bb030f | 704 | if (c && c->no_exec) return mrb_obj_value(proc); |
mzta | 0:158c61bb030f | 705 | val = mrb_toplevel_run(mrb, proc); |
mzta | 0:158c61bb030f | 706 | return val; |
mzta | 0:158c61bb030f | 707 | } |
mzta | 0:158c61bb030f | 708 | |
mzta | 0:158c61bb030f | 709 | MRB_API mrb_value |
mzta | 0:158c61bb030f | 710 | mrb_load_irep_file(mrb_state *mrb, FILE* fp) |
mzta | 0:158c61bb030f | 711 | { |
mzta | 0:158c61bb030f | 712 | return mrb_load_irep_file_cxt(mrb, fp, NULL); |
mzta | 0:158c61bb030f | 713 | } |
mzta | 0:158c61bb030f | 714 | #endif /* ENABLE_STDIO */ |
mzta | 0:158c61bb030f | 715 |