mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
mbed-mruby
How to use
Class
src/debug.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 | #include <string.h> |
mzta | 0:158c61bb030f | 2 | #include "mruby.h" |
mzta | 0:158c61bb030f | 3 | #include "mruby/irep.h" |
mzta | 0:158c61bb030f | 4 | #include "mruby/debug.h" |
mzta | 0:158c61bb030f | 5 | |
mzta | 0:158c61bb030f | 6 | static mrb_irep_debug_info_file * |
mzta | 0:158c61bb030f | 7 | get_file(mrb_irep_debug_info *info, uint32_t pc) |
mzta | 0:158c61bb030f | 8 | { |
mzta | 0:158c61bb030f | 9 | mrb_irep_debug_info_file **ret; |
mzta | 0:158c61bb030f | 10 | int32_t count; |
mzta | 0:158c61bb030f | 11 | |
mzta | 0:158c61bb030f | 12 | if (pc >= info->pc_count) { return NULL; } |
mzta | 0:158c61bb030f | 13 | /* get upper bound */ |
mzta | 0:158c61bb030f | 14 | ret = info->files; |
mzta | 0:158c61bb030f | 15 | count = info->flen; |
mzta | 0:158c61bb030f | 16 | while (count > 0) { |
mzta | 0:158c61bb030f | 17 | int32_t step = count / 2; |
mzta | 0:158c61bb030f | 18 | mrb_irep_debug_info_file **it = ret + step; |
mzta | 0:158c61bb030f | 19 | if (!(pc < (*it)->start_pos)) { |
mzta | 0:158c61bb030f | 20 | ret = it + 1; |
mzta | 0:158c61bb030f | 21 | count -= step + 1; |
mzta | 0:158c61bb030f | 22 | } else { count = step; } |
mzta | 0:158c61bb030f | 23 | } |
mzta | 0:158c61bb030f | 24 | |
mzta | 0:158c61bb030f | 25 | --ret; |
mzta | 0:158c61bb030f | 26 | |
mzta | 0:158c61bb030f | 27 | /* check returning file exists inside debug info */ |
mzta | 0:158c61bb030f | 28 | mrb_assert(info->files <= ret && ret < (info->files + info->flen)); |
mzta | 0:158c61bb030f | 29 | /* check pc is within the range of returning file */ |
mzta | 0:158c61bb030f | 30 | mrb_assert((*ret)->start_pos <= pc && |
mzta | 0:158c61bb030f | 31 | pc < (((ret + 1 - info->files) < info->flen) |
mzta | 0:158c61bb030f | 32 | ? (*(ret+1))->start_pos : info->pc_count)); |
mzta | 0:158c61bb030f | 33 | |
mzta | 0:158c61bb030f | 34 | return *ret; |
mzta | 0:158c61bb030f | 35 | } |
mzta | 0:158c61bb030f | 36 | |
mzta | 0:158c61bb030f | 37 | static mrb_debug_line_type |
mzta | 0:158c61bb030f | 38 | select_line_type(const uint16_t *lines, size_t lines_len) |
mzta | 0:158c61bb030f | 39 | { |
mzta | 0:158c61bb030f | 40 | size_t line_count = 0; |
mzta | 0:158c61bb030f | 41 | int prev_line = -1; |
mzta | 0:158c61bb030f | 42 | size_t i; |
mzta | 0:158c61bb030f | 43 | for (i = 0; i < lines_len; ++i) { |
mzta | 0:158c61bb030f | 44 | if (lines[i] != prev_line) { |
mzta | 0:158c61bb030f | 45 | ++line_count; |
mzta | 0:158c61bb030f | 46 | } |
mzta | 0:158c61bb030f | 47 | } |
mzta | 0:158c61bb030f | 48 | return (sizeof(uint16_t) * lines_len) <= (sizeof(mrb_irep_debug_info_line) * line_count) |
mzta | 0:158c61bb030f | 49 | ? mrb_debug_line_ary : mrb_debug_line_flat_map; |
mzta | 0:158c61bb030f | 50 | } |
mzta | 0:158c61bb030f | 51 | |
mzta | 0:158c61bb030f | 52 | MRB_API char const* |
mzta | 0:158c61bb030f | 53 | mrb_debug_get_filename(mrb_irep *irep, uint32_t pc) |
mzta | 0:158c61bb030f | 54 | { |
mzta | 0:158c61bb030f | 55 | if (irep && pc < irep->ilen) { |
mzta | 0:158c61bb030f | 56 | mrb_irep_debug_info_file* f = NULL; |
mzta | 0:158c61bb030f | 57 | if (!irep->debug_info) { return irep->filename; } |
mzta | 0:158c61bb030f | 58 | else if ((f = get_file(irep->debug_info, pc))) { |
mzta | 0:158c61bb030f | 59 | return f->filename; |
mzta | 0:158c61bb030f | 60 | } |
mzta | 0:158c61bb030f | 61 | } |
mzta | 0:158c61bb030f | 62 | return NULL; |
mzta | 0:158c61bb030f | 63 | } |
mzta | 0:158c61bb030f | 64 | |
mzta | 0:158c61bb030f | 65 | MRB_API int32_t |
mzta | 0:158c61bb030f | 66 | mrb_debug_get_line(mrb_irep *irep, uint32_t pc) |
mzta | 0:158c61bb030f | 67 | { |
mzta | 0:158c61bb030f | 68 | if (irep && pc < irep->ilen) { |
mzta | 0:158c61bb030f | 69 | mrb_irep_debug_info_file* f = NULL; |
mzta | 0:158c61bb030f | 70 | if (!irep->debug_info) { |
mzta | 0:158c61bb030f | 71 | return irep->lines? irep->lines[pc] : -1; |
mzta | 0:158c61bb030f | 72 | } |
mzta | 0:158c61bb030f | 73 | else if ((f = get_file(irep->debug_info, pc))) { |
mzta | 0:158c61bb030f | 74 | switch (f->line_type) { |
mzta | 0:158c61bb030f | 75 | case mrb_debug_line_ary: |
mzta | 0:158c61bb030f | 76 | mrb_assert(f->start_pos <= pc && pc < (f->start_pos + f->line_entry_count)); |
mzta | 0:158c61bb030f | 77 | return f->lines.ary[pc - f->start_pos]; |
mzta | 0:158c61bb030f | 78 | |
mzta | 0:158c61bb030f | 79 | case mrb_debug_line_flat_map: { |
mzta | 0:158c61bb030f | 80 | /* get upper bound */ |
mzta | 0:158c61bb030f | 81 | mrb_irep_debug_info_line *ret = f->lines.flat_map; |
mzta | 0:158c61bb030f | 82 | uint32_t count = f->line_entry_count; |
mzta | 0:158c61bb030f | 83 | while (count > 0) { |
mzta | 0:158c61bb030f | 84 | int32_t step = count / 2; |
mzta | 0:158c61bb030f | 85 | mrb_irep_debug_info_line *it = ret + step; |
mzta | 0:158c61bb030f | 86 | if (!(pc < it->start_pos)) { |
mzta | 0:158c61bb030f | 87 | ret = it + 1; |
mzta | 0:158c61bb030f | 88 | count -= step + 1; |
mzta | 0:158c61bb030f | 89 | } else { count = step; } |
mzta | 0:158c61bb030f | 90 | } |
mzta | 0:158c61bb030f | 91 | |
mzta | 0:158c61bb030f | 92 | --ret; |
mzta | 0:158c61bb030f | 93 | |
mzta | 0:158c61bb030f | 94 | /* check line entry pointer range */ |
mzta | 0:158c61bb030f | 95 | mrb_assert(f->lines.flat_map <= ret && ret < (f->lines.flat_map + f->line_entry_count)); |
mzta | 0:158c61bb030f | 96 | /* check pc range */ |
mzta | 0:158c61bb030f | 97 | mrb_assert(ret->start_pos <= pc && |
mzta | 0:158c61bb030f | 98 | pc < (((uint32_t)(ret + 1 - f->lines.flat_map) < f->line_entry_count) |
mzta | 0:158c61bb030f | 99 | ? (ret+1)->start_pos : irep->debug_info->pc_count)); |
mzta | 0:158c61bb030f | 100 | |
mzta | 0:158c61bb030f | 101 | return ret->line; |
mzta | 0:158c61bb030f | 102 | } |
mzta | 0:158c61bb030f | 103 | } |
mzta | 0:158c61bb030f | 104 | } |
mzta | 0:158c61bb030f | 105 | } |
mzta | 0:158c61bb030f | 106 | return -1; |
mzta | 0:158c61bb030f | 107 | } |
mzta | 0:158c61bb030f | 108 | |
mzta | 0:158c61bb030f | 109 | MRB_API mrb_irep_debug_info * |
mzta | 0:158c61bb030f | 110 | mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep) |
mzta | 0:158c61bb030f | 111 | { |
mzta | 0:158c61bb030f | 112 | static const mrb_irep_debug_info initial = { 0, 0, NULL }; |
mzta | 0:158c61bb030f | 113 | mrb_irep_debug_info *ret; |
mzta | 0:158c61bb030f | 114 | |
mzta | 0:158c61bb030f | 115 | mrb_assert(!irep->debug_info); |
mzta | 0:158c61bb030f | 116 | ret = (mrb_irep_debug_info *)mrb_malloc(mrb, sizeof(*ret)); |
mzta | 0:158c61bb030f | 117 | *ret = initial; |
mzta | 0:158c61bb030f | 118 | irep->debug_info = ret; |
mzta | 0:158c61bb030f | 119 | return ret; |
mzta | 0:158c61bb030f | 120 | } |
mzta | 0:158c61bb030f | 121 | |
mzta | 0:158c61bb030f | 122 | MRB_API mrb_irep_debug_info_file * |
mzta | 0:158c61bb030f | 123 | mrb_debug_info_append_file(mrb_state *mrb, mrb_irep *irep, |
mzta | 0:158c61bb030f | 124 | uint32_t start_pos, uint32_t end_pos) |
mzta | 0:158c61bb030f | 125 | { |
mzta | 0:158c61bb030f | 126 | mrb_irep_debug_info *info; |
mzta | 0:158c61bb030f | 127 | mrb_irep_debug_info_file *ret; |
mzta | 0:158c61bb030f | 128 | uint32_t file_pc_count; |
mzta | 0:158c61bb030f | 129 | size_t fn_len; |
mzta | 0:158c61bb030f | 130 | mrb_int len; |
mzta | 0:158c61bb030f | 131 | uint32_t i; |
mzta | 0:158c61bb030f | 132 | |
mzta | 0:158c61bb030f | 133 | if (!irep->debug_info) { return NULL; } |
mzta | 0:158c61bb030f | 134 | |
mzta | 0:158c61bb030f | 135 | mrb_assert(irep->filename); |
mzta | 0:158c61bb030f | 136 | mrb_assert(irep->lines); |
mzta | 0:158c61bb030f | 137 | |
mzta | 0:158c61bb030f | 138 | info = irep->debug_info; |
mzta | 0:158c61bb030f | 139 | |
mzta | 0:158c61bb030f | 140 | if (info->flen > 0 && strcmp(irep->filename, info->files[info->flen - 1]->filename) == 0) { |
mzta | 0:158c61bb030f | 141 | return NULL; |
mzta | 0:158c61bb030f | 142 | } |
mzta | 0:158c61bb030f | 143 | |
mzta | 0:158c61bb030f | 144 | ret = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*ret)); |
mzta | 0:158c61bb030f | 145 | info->files = |
mzta | 0:158c61bb030f | 146 | (mrb_irep_debug_info_file**)( |
mzta | 0:158c61bb030f | 147 | info->files |
mzta | 0:158c61bb030f | 148 | ? mrb_realloc(mrb, info->files, sizeof(mrb_irep_debug_info_file*) * (info->flen + 1)) |
mzta | 0:158c61bb030f | 149 | : mrb_malloc(mrb, sizeof(mrb_irep_debug_info_file*))); |
mzta | 0:158c61bb030f | 150 | info->files[info->flen++] = ret; |
mzta | 0:158c61bb030f | 151 | |
mzta | 0:158c61bb030f | 152 | file_pc_count = end_pos - start_pos; |
mzta | 0:158c61bb030f | 153 | |
mzta | 0:158c61bb030f | 154 | ret->start_pos = start_pos; |
mzta | 0:158c61bb030f | 155 | info->pc_count = end_pos; |
mzta | 0:158c61bb030f | 156 | |
mzta | 0:158c61bb030f | 157 | fn_len = strlen(irep->filename); |
mzta | 0:158c61bb030f | 158 | ret->filename_sym = mrb_intern(mrb, irep->filename, fn_len); |
mzta | 0:158c61bb030f | 159 | len = 0; |
mzta | 0:158c61bb030f | 160 | ret->filename = mrb_sym2name_len(mrb, ret->filename_sym, &len); |
mzta | 0:158c61bb030f | 161 | |
mzta | 0:158c61bb030f | 162 | ret->line_type = select_line_type(irep->lines + start_pos, end_pos - start_pos); |
mzta | 0:158c61bb030f | 163 | ret->lines.ptr = NULL; |
mzta | 0:158c61bb030f | 164 | |
mzta | 0:158c61bb030f | 165 | switch (ret->line_type) { |
mzta | 0:158c61bb030f | 166 | case mrb_debug_line_ary: |
mzta | 0:158c61bb030f | 167 | ret->line_entry_count = file_pc_count; |
mzta | 0:158c61bb030f | 168 | ret->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count); |
mzta | 0:158c61bb030f | 169 | for (i = 0; i < file_pc_count; ++i) { |
mzta | 0:158c61bb030f | 170 | ret->lines.ary[i] = irep->lines[start_pos + i]; |
mzta | 0:158c61bb030f | 171 | } |
mzta | 0:158c61bb030f | 172 | break; |
mzta | 0:158c61bb030f | 173 | |
mzta | 0:158c61bb030f | 174 | case mrb_debug_line_flat_map: { |
mzta | 0:158c61bb030f | 175 | uint16_t prev_line = 0; |
mzta | 0:158c61bb030f | 176 | mrb_irep_debug_info_line m; |
mzta | 0:158c61bb030f | 177 | ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1); |
mzta | 0:158c61bb030f | 178 | ret->line_entry_count = 0; |
mzta | 0:158c61bb030f | 179 | for (i = 0; i < file_pc_count; ++i) { |
mzta | 0:158c61bb030f | 180 | if (irep->lines[start_pos + i] == prev_line) { continue; } |
mzta | 0:158c61bb030f | 181 | |
mzta | 0:158c61bb030f | 182 | ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc( |
mzta | 0:158c61bb030f | 183 | mrb, ret->lines.flat_map, |
mzta | 0:158c61bb030f | 184 | sizeof(mrb_irep_debug_info_line) * (ret->line_entry_count + 1)); |
mzta | 0:158c61bb030f | 185 | m.start_pos = start_pos + i; |
mzta | 0:158c61bb030f | 186 | m.line = irep->lines[start_pos + i]; |
mzta | 0:158c61bb030f | 187 | ret->lines.flat_map[ret->line_entry_count] = m; |
mzta | 0:158c61bb030f | 188 | |
mzta | 0:158c61bb030f | 189 | /* update */ |
mzta | 0:158c61bb030f | 190 | ++ret->line_entry_count; |
mzta | 0:158c61bb030f | 191 | prev_line = irep->lines[start_pos + i]; |
mzta | 0:158c61bb030f | 192 | } |
mzta | 0:158c61bb030f | 193 | } break; |
mzta | 0:158c61bb030f | 194 | |
mzta | 0:158c61bb030f | 195 | default: mrb_assert(0); break; |
mzta | 0:158c61bb030f | 196 | } |
mzta | 0:158c61bb030f | 197 | |
mzta | 0:158c61bb030f | 198 | return ret; |
mzta | 0:158c61bb030f | 199 | } |
mzta | 0:158c61bb030f | 200 | |
mzta | 0:158c61bb030f | 201 | MRB_API void |
mzta | 0:158c61bb030f | 202 | mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d) |
mzta | 0:158c61bb030f | 203 | { |
mzta | 0:158c61bb030f | 204 | uint32_t i; |
mzta | 0:158c61bb030f | 205 | |
mzta | 0:158c61bb030f | 206 | if (!d) { return; } |
mzta | 0:158c61bb030f | 207 | |
mzta | 0:158c61bb030f | 208 | for (i = 0; i < d->flen; ++i) { |
mzta | 0:158c61bb030f | 209 | mrb_assert(d->files[i]); |
mzta | 0:158c61bb030f | 210 | mrb_free(mrb, d->files[i]->lines.ptr); |
mzta | 0:158c61bb030f | 211 | mrb_free(mrb, d->files[i]); |
mzta | 0:158c61bb030f | 212 | } |
mzta | 0:158c61bb030f | 213 | mrb_free(mrb, d->files); |
mzta | 0:158c61bb030f | 214 | mrb_free(mrb, d); |
mzta | 0:158c61bb030f | 215 | } |
mzta | 0:158c61bb030f | 216 |