OLD | NEW |
1 /* | 1 /* |
2 * YASM assembler virtual line mapping handling (for parse stage) | 2 * YASM assembler virtual line mapping handling (for parse stage) |
3 * | 3 * |
4 * Copyright (C) 2002-2007 Peter Johnson | 4 * Copyright (C) 2002-2007 Peter Johnson |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
14 * | 14 * |
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' | 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' |
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * POSSIBILITY OF SUCH DAMAGE. | 25 * POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 #include "util.h" | 27 #include "util.h" |
28 /*@unused@*/ RCSID("$Id: linemap.c 1896 2007-07-15 21:54:11Z peter $"); | 28 /*@unused@*/ RCSID("$Id: linemap.c 2259 2010-01-03 01:58:23Z peter $"); |
29 | 29 |
30 #include "coretype.h" | 30 #include "coretype.h" |
31 #include "hamt.h" | 31 #include "hamt.h" |
32 | 32 |
33 #include "errwarn.h" | 33 #include "errwarn.h" |
34 #include "linemap.h" | 34 #include "linemap.h" |
35 | 35 |
36 | 36 |
37 typedef struct line_mapping { | 37 typedef struct line_mapping { |
38 /* monotonically increasing virtual line */ | 38 /* monotonically increasing virtual line */ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 }; | 73 }; |
74 | 74 |
75 static void | 75 static void |
76 filename_delete_one(/*@only@*/ void *d) | 76 filename_delete_one(/*@only@*/ void *d) |
77 { | 77 { |
78 yasm_xfree(d); | 78 yasm_xfree(d); |
79 } | 79 } |
80 | 80 |
81 void | 81 void |
82 yasm_linemap_set(yasm_linemap *linemap, const char *filename, | 82 yasm_linemap_set(yasm_linemap *linemap, const char *filename, |
83 unsigned long file_line, unsigned long line_inc) | 83 unsigned long virtual_line, unsigned long file_line, |
| 84 unsigned long line_inc) |
84 { | 85 { |
85 char *copy; | 86 char *copy; |
| 87 unsigned long i; |
86 int replace = 0; | 88 int replace = 0; |
87 line_mapping *mapping; | 89 line_mapping *mapping = NULL; |
88 | 90 |
89 /* Create a new mapping in the map */ | 91 if (virtual_line == 0) { |
90 if (linemap->map_size >= linemap->map_allocated) { | 92 virtual_line = linemap->current; |
91 /* allocate another size bins when full for 2x space */ | |
92 linemap->map_vector = | |
93 yasm_xrealloc(linemap->map_vector, 2*linemap->map_allocated | |
94 *sizeof(line_mapping)); | |
95 linemap->map_allocated *= 2; | |
96 } | 93 } |
97 mapping = &linemap->map_vector[linemap->map_size]; | 94 |
98 linemap->map_size++; | 95 /* Replace all existing mappings that have line numbers >= this one. */ |
| 96 for (i = linemap->map_size; i > 0; i--) { |
| 97 if (linemap->map_vector[i-1].line < virtual_line) { |
| 98 if (i < linemap->map_size) { |
| 99 mapping = &linemap->map_vector[i]; |
| 100 linemap->map_size = i + 1; |
| 101 } |
| 102 break; |
| 103 } |
| 104 } |
| 105 |
| 106 if (mapping == NULL) { |
| 107 /* Create a new mapping in the map */ |
| 108 if (linemap->map_size >= linemap->map_allocated) { |
| 109 /* allocate another size bins when full for 2x space */ |
| 110 linemap->map_vector = yasm_xrealloc(linemap->map_vector, |
| 111 2*linemap->map_allocated*sizeof(line_mapping)); |
| 112 linemap->map_allocated *= 2; |
| 113 } |
| 114 mapping = &linemap->map_vector[linemap->map_size]; |
| 115 linemap->map_size++; |
| 116 } |
99 | 117 |
100 /* Fill it */ | 118 /* Fill it */ |
101 | 119 |
102 if (!filename) { | 120 if (!filename) { |
103 if (linemap->map_size >= 2) | 121 if (linemap->map_size >= 2) |
104 mapping->filename = | 122 mapping->filename = |
105 linemap->map_vector[linemap->map_size-2].filename; | 123 linemap->map_vector[linemap->map_size-2].filename; |
106 else | 124 else |
107 filename = "unknown"; | 125 filename = "unknown"; |
108 } | 126 } |
109 if (filename) { | 127 if (filename) { |
110 /* Copy the filename (via shared storage) */ | 128 /* Copy the filename (via shared storage) */ |
111 copy = yasm__xstrdup(filename); | 129 copy = yasm__xstrdup(filename); |
112 /*@-aliasunique@*/ | 130 /*@-aliasunique@*/ |
113 mapping->filename = HAMT_insert(linemap->filenames, copy, copy, | 131 mapping->filename = HAMT_insert(linemap->filenames, copy, copy, |
114 &replace, filename_delete_one); | 132 &replace, filename_delete_one); |
115 /*@=aliasunique@*/ | 133 /*@=aliasunique@*/ |
116 } | 134 } |
117 | 135 |
118 mapping->line = linemap->current; | 136 mapping->line = virtual_line; |
119 mapping->file_line = file_line; | 137 mapping->file_line = file_line; |
120 mapping->line_inc = line_inc; | 138 mapping->line_inc = line_inc; |
121 } | 139 } |
122 | 140 |
123 unsigned long | 141 unsigned long |
124 yasm_linemap_poke(yasm_linemap *linemap, const char *filename, | 142 yasm_linemap_poke(yasm_linemap *linemap, const char *filename, |
125 unsigned long file_line) | 143 unsigned long file_line) |
126 { | 144 { |
127 unsigned long line; | 145 unsigned long line; |
128 line_mapping *mapping; | 146 line_mapping *mapping; |
129 | 147 |
130 linemap->current++; | 148 linemap->current++; |
131 yasm_linemap_set(linemap, filename, file_line, 0); | 149 yasm_linemap_set(linemap, filename, 0, file_line, 0); |
132 | 150 |
133 mapping = &linemap->map_vector[linemap->map_size-1]; | 151 mapping = &linemap->map_vector[linemap->map_size-1]; |
134 | 152 |
135 line = linemap->current; | 153 line = linemap->current; |
136 | 154 |
137 linemap->current++; | 155 linemap->current++; |
138 yasm_linemap_set(linemap, mapping->filename, | 156 yasm_linemap_set(linemap, mapping->filename, 0, |
139 mapping->file_line + | 157 mapping->file_line + |
140 mapping->line_inc*(linemap->current-2-mapping->line), | 158 mapping->line_inc*(linemap->current-2-mapping->line), |
141 mapping->line_inc); | 159 mapping->line_inc); |
142 | 160 |
143 return line; | 161 return line; |
144 } | 162 } |
145 | 163 |
146 yasm_linemap * | 164 yasm_linemap * |
147 yasm_linemap_create(void) | 165 yasm_linemap_create(void) |
148 { | 166 { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 step*=2; | 260 step*=2; |
243 while (step>0) { | 261 while (step>0) { |
244 if (vindex+step < linemap->map_size | 262 if (vindex+step < linemap->map_size |
245 && linemap->map_vector[vindex+step].line <= line) | 263 && linemap->map_vector[vindex+step].line <= line) |
246 vindex += step; | 264 vindex += step; |
247 step /= 2; | 265 step /= 2; |
248 } | 266 } |
249 mapping = &linemap->map_vector[vindex]; | 267 mapping = &linemap->map_vector[vindex]; |
250 | 268 |
251 *filename = mapping->filename; | 269 *filename = mapping->filename; |
252 *file_line = mapping->file_line + mapping->line_inc*(line-mapping->line); | 270 *file_line = (line ? mapping->file_line + mapping->line_inc*(line-mapping->l
ine) : 0); |
253 } | 271 } |
254 | 272 |
255 int | 273 int |
256 yasm_linemap_traverse_filenames(yasm_linemap *linemap, /*@null@*/ void *d, | 274 yasm_linemap_traverse_filenames(yasm_linemap *linemap, /*@null@*/ void *d, |
257 int (*func) (const char *filename, void *d)) | 275 int (*func) (const char *filename, void *d)) |
258 { | 276 { |
259 return HAMT_traverse(linemap->filenames, d, (int (*) (void *, void *))func); | 277 return HAMT_traverse(linemap->filenames, d, (int (*) (void *, void *))func); |
260 } | 278 } |
261 | 279 |
262 int | 280 int |
263 yasm_linemap_get_source(yasm_linemap *linemap, unsigned long line, | 281 yasm_linemap_get_source(yasm_linemap *linemap, unsigned long line, |
264 yasm_bytecode **bcp, const char **sourcep) | 282 yasm_bytecode **bcp, const char **sourcep) |
265 { | 283 { |
266 if (line > linemap->source_info_size) { | 284 if (line > linemap->source_info_size) { |
267 *bcp = NULL; | 285 *bcp = NULL; |
268 *sourcep = NULL; | 286 *sourcep = NULL; |
269 return 1; | 287 return 1; |
270 } | 288 } |
271 | 289 |
272 *bcp = linemap->source_info[line-1].bc; | 290 *bcp = linemap->source_info[line-1].bc; |
273 *sourcep = linemap->source_info[line-1].source; | 291 *sourcep = linemap->source_info[line-1].source; |
274 | 292 |
275 return (!(*sourcep)); | 293 return (!(*sourcep)); |
276 } | 294 } |
OLD | NEW |