author | cl |
Thu, 21 Nov 2013 09:23:03 -0800 | |
changeset 21741 | 8cd632761233 |
parent 19610 | 2073a59a2787 |
child 23010 | 6dadb192ad81 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
5506 | 2 |
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
#include <setjmp.h> |
|
27 |
||
28 |
#include "util.h" |
|
29 |
#include "SDE.h" |
|
30 |
||
19610
2073a59a2787
8023786: (jdk) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
5506
diff
changeset
|
31 |
#ifdef __APPLE__ |
2073a59a2787
8023786: (jdk) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
5506
diff
changeset
|
32 |
/* use setjmp/longjmp versions that do not save/restore the signal mask */ |
2073a59a2787
8023786: (jdk) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
5506
diff
changeset
|
33 |
#define setjmp _setjmp |
2073a59a2787
8023786: (jdk) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
5506
diff
changeset
|
34 |
#define longjmp _longjmp |
2073a59a2787
8023786: (jdk) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
5506
diff
changeset
|
35 |
#endif |
2073a59a2787
8023786: (jdk) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
5506
diff
changeset
|
36 |
|
2 | 37 |
/** |
38 |
* This SourceDebugExtension code does not |
|
39 |
* allow concurrent translation - due to caching method. |
|
40 |
* A separate thread setting the default stratum ID |
|
41 |
* is, however, fine. |
|
42 |
*/ |
|
43 |
||
44 |
#define INIT_SIZE_FILE 10 |
|
45 |
#define INIT_SIZE_LINE 100 |
|
46 |
#define INIT_SIZE_STRATUM 3 |
|
47 |
||
48 |
#define BASE_STRATUM_NAME "Java" |
|
49 |
||
50 |
#define null NULL |
|
51 |
#define true JNI_TRUE |
|
52 |
#define false JNI_FALSE |
|
53 |
#define String char * |
|
54 |
#define private static |
|
55 |
||
56 |
typedef struct { |
|
57 |
int fileId; |
|
58 |
String sourceName; |
|
59 |
String sourcePath; // do not read - use accessor |
|
60 |
int isConverted; |
|
61 |
} FileTableRecord; |
|
62 |
||
63 |
typedef struct { |
|
64 |
int jplsStart; |
|
65 |
int jplsEnd; |
|
66 |
int jplsLineInc; |
|
67 |
int njplsStart; |
|
68 |
int njplsEnd; |
|
69 |
int fileId; |
|
70 |
} LineTableRecord; |
|
71 |
||
72 |
typedef struct { |
|
73 |
String id; |
|
74 |
int fileIndex; |
|
75 |
int lineIndex; |
|
76 |
} StratumTableRecord; |
|
77 |
||
78 |
/* back-end wide value for default stratum */ |
|
79 |
private String globalDefaultStratumId = null; |
|
80 |
||
81 |
/* reference type default */ |
|
82 |
private String defaultStratumId = null; |
|
83 |
||
84 |
private jclass cachedClass = NULL; |
|
85 |
||
86 |
private FileTableRecord* fileTable; |
|
87 |
private LineTableRecord* lineTable; |
|
88 |
private StratumTableRecord* stratumTable; |
|
89 |
||
90 |
private int fileTableSize; |
|
91 |
private int lineTableSize; |
|
92 |
private int stratumTableSize; |
|
93 |
||
94 |
private int fileIndex; |
|
95 |
private int lineIndex; |
|
96 |
private int stratumIndex = 0; |
|
97 |
private int currentFileId; |
|
98 |
||
99 |
private int defaultStratumIndex; |
|
100 |
private int baseStratumIndex; |
|
101 |
private char* sdePos; |
|
102 |
||
103 |
private char* jplsFilename = null; |
|
104 |
private char* NullString = null; |
|
105 |
||
106 |
/* mangled in parse, cannot be parsed. Must be kept. */ |
|
107 |
private String sourceDebugExtension; |
|
108 |
||
109 |
private jboolean sourceMapIsValid; |
|
110 |
||
111 |
private jmp_buf jmp_buf_env; |
|
112 |
||
113 |
private int stratumTableIndex(String stratumId); |
|
114 |
private int stiLineTableIndex(int sti, int jplsLine); |
|
115 |
private int stiLineNumber(int sti, int lti, int jplsLine); |
|
116 |
private void decode(void); |
|
117 |
private void ignoreWhite(void); |
|
118 |
private jboolean isValid(void); |
|
119 |
||
120 |
private void |
|
121 |
loadDebugInfo(JNIEnv *env, jclass clazz) { |
|
122 |
||
123 |
if (!isSameObject(env, clazz, cachedClass)) { |
|
124 |
/* Not the same - swap out the info */ |
|
125 |
||
126 |
/* Delete existing info */ |
|
127 |
if ( cachedClass != null ) { |
|
128 |
tossGlobalRef(env, &cachedClass); |
|
129 |
cachedClass = null; |
|
130 |
} |
|
131 |
if ( sourceDebugExtension!=null ) { |
|
132 |
jvmtiDeallocate(sourceDebugExtension); |
|
133 |
} |
|
134 |
sourceDebugExtension = null; |
|
135 |
||
136 |
/* Init info */ |
|
137 |
lineTable = null; |
|
138 |
fileTable = null; |
|
139 |
stratumTable = null; |
|
140 |
lineTableSize = 0; |
|
141 |
fileTableSize = 0; |
|
142 |
stratumTableSize = 0; |
|
143 |
fileIndex = 0; |
|
144 |
lineIndex = 0; |
|
145 |
stratumIndex = 0; |
|
146 |
currentFileId = 0; |
|
147 |
defaultStratumId = null; |
|
148 |
defaultStratumIndex = -1; |
|
149 |
baseStratumIndex = -2; /* so as not to match -1 above */ |
|
150 |
sourceMapIsValid = false; |
|
151 |
||
152 |
if (getSourceDebugExtension(clazz, &sourceDebugExtension) == |
|
153 |
JVMTI_ERROR_NONE) { |
|
154 |
sdePos = sourceDebugExtension; |
|
155 |
if (setjmp(jmp_buf_env) == 0) { |
|
156 |
/* this is the initial (non-error) case, do parse */ |
|
157 |
decode(); |
|
158 |
} |
|
159 |
} |
|
160 |
||
161 |
cachedClass = null; |
|
162 |
saveGlobalRef(env, clazz, &cachedClass); |
|
163 |
} |
|
164 |
} |
|
165 |
||
166 |
/* Return 1 if match, 0 if no match */ |
|
167 |
private int |
|
168 |
patternMatch(char *classname, const char *pattern) { |
|
169 |
int pattLen; |
|
170 |
int compLen; |
|
171 |
char *start; |
|
172 |
int offset; |
|
173 |
||
174 |
if (pattern == NULL || classname == NULL) { |
|
175 |
return 0; |
|
176 |
} |
|
177 |
pattLen = (int)strlen(pattern); |
|
178 |
||
179 |
if ((pattern[0] != '*') && (pattern[pattLen-1] != '*')) { |
|
180 |
return strcmp(pattern, classname) == 0; |
|
181 |
} |
|
182 |
||
183 |
compLen = pattLen - 1; |
|
184 |
offset = (int)strlen(classname) - compLen; |
|
185 |
if (offset < 0) { |
|
186 |
return 0; |
|
187 |
} |
|
188 |
if (pattern[0] == '*') { |
|
189 |
pattern++; |
|
190 |
start = classname + offset; |
|
191 |
} else { |
|
192 |
start = classname; |
|
193 |
} |
|
194 |
return strncmp(pattern, start, compLen) == 0; |
|
195 |
} |
|
196 |
||
197 |
/** |
|
198 |
* Return 1 if p1 is a SourceName for stratum sti, |
|
199 |
* else, return 0. |
|
200 |
*/ |
|
201 |
private int |
|
202 |
searchOneSourceName(int sti, char *p1) { |
|
203 |
int fileIndexStart = stratumTable[sti].fileIndex; |
|
204 |
/* one past end */ |
|
205 |
int fileIndexEnd = stratumTable[sti+1].fileIndex; |
|
206 |
int ii; |
|
207 |
for (ii = fileIndexStart; ii < fileIndexEnd; ++ii) { |
|
208 |
if (patternMatch(fileTable[ii].sourceName, p1)) { |
|
209 |
return 1; |
|
210 |
} |
|
211 |
} |
|
212 |
return 0; |
|
213 |
} |
|
214 |
||
215 |
/** |
|
216 |
* Return 1 if p1 is a SourceName for any stratum |
|
217 |
* else, return 0. |
|
218 |
*/ |
|
219 |
int searchAllSourceNames(JNIEnv *env, |
|
220 |
jclass clazz, |
|
221 |
char *p1) { |
|
222 |
int ii; |
|
223 |
loadDebugInfo(env, clazz); |
|
224 |
if (!isValid()) { |
|
225 |
return 0; /* no SDE or not SourceMap */ |
|
226 |
} |
|
227 |
||
228 |
for (ii = 0; ii < stratumIndex - 1; ++ii) { |
|
229 |
if (searchOneSourceName(ii, p1) == 1) { |
|
230 |
return 1; |
|
231 |
} |
|
232 |
} |
|
233 |
return 0; |
|
234 |
} |
|
235 |
||
236 |
/** |
|
237 |
* Convert a line number table, as returned by the JVMTI |
|
238 |
* function GetLineNumberTable, to one for another stratum. |
|
239 |
* Conversion is by overwrite. |
|
240 |
* Actual line numbers are not returned - just a unique |
|
241 |
* number (file ID in top 16 bits, line number in |
|
242 |
* bottom 16 bits) - this is all stepping needs. |
|
243 |
*/ |
|
244 |
void |
|
245 |
convertLineNumberTable(JNIEnv *env, jclass clazz, |
|
246 |
jint *entryCountPtr, |
|
247 |
jvmtiLineNumberEntry **tablePtr) { |
|
248 |
jvmtiLineNumberEntry *fromEntry = *tablePtr; |
|
249 |
jvmtiLineNumberEntry *toEntry = *tablePtr; |
|
250 |
int cnt = *entryCountPtr; |
|
251 |
int lastLn = 0; |
|
252 |
int sti; |
|
253 |
||
254 |
loadDebugInfo(env, clazz); |
|
255 |
if (!isValid()) { |
|
256 |
return; /* no SDE or not SourceMap - return unchanged */ |
|
257 |
} |
|
258 |
sti = stratumTableIndex(globalDefaultStratumId); |
|
259 |
if (sti == baseStratumIndex) { |
|
260 |
return; /* Java stratum - return unchanged */ |
|
261 |
} |
|
262 |
LOG_MISC(("SDE is re-ordering the line table")); |
|
263 |
for (; cnt-->0; ++fromEntry) { |
|
264 |
int jplsLine = fromEntry->line_number; |
|
265 |
int lti = stiLineTableIndex(sti, jplsLine); |
|
266 |
if (lti >= 0) { |
|
267 |
int fileId = lineTable[lti].fileId; |
|
268 |
int ln = stiLineNumber(sti, lti, jplsLine); |
|
269 |
ln += (fileId << 16); /* create line hash */ |
|
270 |
if (ln != lastLn) { |
|
271 |
lastLn = ln; |
|
272 |
toEntry->start_location = fromEntry->start_location; |
|
273 |
toEntry->line_number = ln; |
|
274 |
++toEntry; |
|
275 |
} |
|
276 |
} |
|
277 |
} |
|
278 |
/*LINTED*/ |
|
279 |
*entryCountPtr = (int)(toEntry - *tablePtr); |
|
280 |
} |
|
281 |
||
282 |
/** |
|
283 |
* Set back-end wide default stratum ID . |
|
284 |
*/ |
|
285 |
void |
|
286 |
setGlobalStratumId(char *id) { |
|
287 |
globalDefaultStratumId = id; |
|
288 |
} |
|
289 |
||
290 |
||
291 |
private void syntax(String msg) { |
|
292 |
char buf[200]; |
|
293 |
(void)snprintf(buf, sizeof(buf), |
|
294 |
"bad SourceDebugExtension syntax - position %d - %s\n", |
|
295 |
/*LINTED*/ |
|
296 |
(int)(sdePos-sourceDebugExtension), |
|
297 |
msg); |
|
298 |
JDI_ASSERT_FAILED(buf); |
|
299 |
||
300 |
longjmp(jmp_buf_env, 1); /* abort parse */ |
|
301 |
} |
|
302 |
||
303 |
private char sdePeek(void) { |
|
304 |
if (*sdePos == 0) { |
|
305 |
syntax("unexpected EOF"); |
|
306 |
} |
|
307 |
return *sdePos; |
|
308 |
} |
|
309 |
||
310 |
private char sdeRead(void) { |
|
311 |
if (*sdePos == 0) { |
|
312 |
syntax("unexpected EOF"); |
|
313 |
} |
|
314 |
return *sdePos++; |
|
315 |
} |
|
316 |
||
317 |
private void sdeAdvance(void) { |
|
318 |
sdePos++; |
|
319 |
} |
|
320 |
||
321 |
private void assureLineTableSize(void) { |
|
322 |
if (lineIndex >= lineTableSize) { |
|
323 |
size_t allocSize; |
|
324 |
LineTableRecord* new_lineTable; |
|
325 |
int new_lineTableSize; |
|
326 |
||
327 |
new_lineTableSize = lineTableSize == 0? |
|
328 |
INIT_SIZE_LINE : |
|
329 |
lineTableSize * 2; |
|
330 |
allocSize = new_lineTableSize * (int)sizeof(LineTableRecord); |
|
331 |
new_lineTable = jvmtiAllocate((jint)allocSize); |
|
332 |
if ( new_lineTable == NULL ) { |
|
333 |
EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE line table"); |
|
334 |
} |
|
335 |
if ( lineTable!=NULL ) { |
|
336 |
(void)memcpy(new_lineTable, lineTable, |
|
337 |
lineTableSize * (int)sizeof(LineTableRecord)); |
|
338 |
jvmtiDeallocate(lineTable); |
|
339 |
} |
|
340 |
lineTable = new_lineTable; |
|
341 |
lineTableSize = new_lineTableSize; |
|
342 |
} |
|
343 |
} |
|
344 |
||
345 |
private void assureFileTableSize(void) { |
|
346 |
if (fileIndex >= fileTableSize) { |
|
347 |
size_t allocSize; |
|
348 |
FileTableRecord* new_fileTable; |
|
349 |
int new_fileTableSize; |
|
350 |
||
351 |
new_fileTableSize = fileTableSize == 0? |
|
352 |
INIT_SIZE_FILE : |
|
353 |
fileTableSize * 2; |
|
354 |
allocSize = new_fileTableSize * (int)sizeof(FileTableRecord); |
|
355 |
new_fileTable = jvmtiAllocate((jint)allocSize); |
|
356 |
if ( new_fileTable == NULL ) { |
|
357 |
EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE file table"); |
|
358 |
} |
|
359 |
if ( fileTable!=NULL ) { |
|
360 |
(void)memcpy(new_fileTable, fileTable, |
|
361 |
fileTableSize * (int)sizeof(FileTableRecord)); |
|
362 |
jvmtiDeallocate(fileTable); |
|
363 |
} |
|
364 |
fileTable = new_fileTable; |
|
365 |
fileTableSize = new_fileTableSize; |
|
366 |
} |
|
367 |
} |
|
368 |
||
369 |
private void assureStratumTableSize(void) { |
|
370 |
if (stratumIndex >= stratumTableSize) { |
|
371 |
size_t allocSize; |
|
372 |
StratumTableRecord* new_stratumTable; |
|
373 |
int new_stratumTableSize; |
|
374 |
||
375 |
new_stratumTableSize = stratumTableSize == 0? |
|
376 |
INIT_SIZE_STRATUM : |
|
377 |
stratumTableSize * 2; |
|
378 |
allocSize = new_stratumTableSize * (int)sizeof(StratumTableRecord); |
|
379 |
new_stratumTable = jvmtiAllocate((jint)allocSize); |
|
380 |
if ( new_stratumTable == NULL ) { |
|
381 |
EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE stratum table"); |
|
382 |
} |
|
383 |
if ( stratumTable!=NULL ) { |
|
384 |
(void)memcpy(new_stratumTable, stratumTable, |
|
385 |
stratumTableSize * (int)sizeof(StratumTableRecord)); |
|
386 |
jvmtiDeallocate(stratumTable); |
|
387 |
} |
|
388 |
stratumTable = new_stratumTable; |
|
389 |
stratumTableSize = new_stratumTableSize; |
|
390 |
} |
|
391 |
} |
|
392 |
||
393 |
private String readLine(void) { |
|
394 |
char *initialPos; |
|
395 |
char ch; |
|
396 |
||
397 |
ignoreWhite(); |
|
398 |
initialPos = sdePos; |
|
399 |
while (((ch = *sdePos) != '\n') && (ch != '\r')) { |
|
400 |
if (ch == 0) { |
|
401 |
syntax("unexpected EOF"); |
|
402 |
} |
|
403 |
++sdePos; |
|
404 |
} |
|
405 |
*sdePos++ = 0; /* null terminate string - mangles SDE */ |
|
406 |
||
407 |
/* check for CR LF */ |
|
408 |
if ((ch == '\r') && (*sdePos == '\n')) { |
|
409 |
++sdePos; |
|
410 |
} |
|
411 |
ignoreWhite(); /* leading white */ |
|
412 |
return initialPos; |
|
413 |
} |
|
414 |
||
415 |
private int defaultStratumTableIndex(void) { |
|
416 |
if ((defaultStratumIndex == -1) && (defaultStratumId != null)) { |
|
417 |
defaultStratumIndex = |
|
418 |
stratumTableIndex(defaultStratumId); |
|
419 |
} |
|
420 |
return defaultStratumIndex; |
|
421 |
} |
|
422 |
||
423 |
private int stratumTableIndex(String stratumId) { |
|
424 |
int i; |
|
425 |
||
426 |
if (stratumId == null) { |
|
427 |
return defaultStratumTableIndex(); |
|
428 |
} |
|
429 |
for (i = 0; i < (stratumIndex-1); ++i) { |
|
430 |
if (strcmp(stratumTable[i].id, stratumId) == 0) { |
|
431 |
return i; |
|
432 |
} |
|
433 |
} |
|
434 |
return defaultStratumTableIndex(); |
|
435 |
} |
|
436 |
||
437 |
||
438 |
/***************************** |
|
439 |
* below functions/methods are written to compile under either Java or C |
|
440 |
* |
|
441 |
* Needed support functions: |
|
442 |
* sdePeek() |
|
443 |
* sdeRead() |
|
444 |
* sdeAdvance() |
|
445 |
* readLine() |
|
446 |
* assureLineTableSize() |
|
447 |
* assureFileTableSize() |
|
448 |
* assureStratumTableSize() |
|
449 |
* syntax(String) |
|
450 |
* |
|
451 |
* stratumTableIndex(String) |
|
452 |
* |
|
453 |
* Needed support variables: |
|
454 |
* lineTable |
|
455 |
* lineIndex |
|
456 |
* fileTable |
|
457 |
* fileIndex |
|
458 |
* currentFileId |
|
459 |
* |
|
460 |
* Needed types: |
|
461 |
* String |
|
462 |
* |
|
463 |
* Needed constants: |
|
464 |
* NullString |
|
465 |
*/ |
|
466 |
||
467 |
private void ignoreWhite(void) { |
|
468 |
char ch; |
|
469 |
||
470 |
while (((ch = sdePeek()) == ' ') || (ch == '\t')) { |
|
471 |
sdeAdvance(); |
|
472 |
} |
|
473 |
} |
|
474 |
||
475 |
private void ignoreLine(void) { |
|
476 |
char ch; |
|
477 |
||
478 |
do { |
|
479 |
ch = sdeRead(); |
|
480 |
} while ((ch != '\n') && (ch != '\r')); |
|
481 |
||
482 |
/* check for CR LF */ |
|
483 |
if ((ch == '\r') && (sdePeek() == '\n')) { |
|
484 |
sdeAdvance(); |
|
485 |
} |
|
486 |
ignoreWhite(); /* leading white */ |
|
487 |
} |
|
488 |
||
489 |
private int readNumber(void) { |
|
490 |
int value = 0; |
|
491 |
char ch; |
|
492 |
||
493 |
ignoreWhite(); |
|
494 |
while (((ch = sdePeek()) >= '0') && (ch <= '9')) { |
|
495 |
sdeAdvance(); |
|
496 |
value = (value * 10) + ch - '0'; |
|
497 |
} |
|
498 |
ignoreWhite(); |
|
499 |
return value; |
|
500 |
} |
|
501 |
||
502 |
private void storeFile(int fileId, String sourceName, String sourcePath) { |
|
503 |
assureFileTableSize(); |
|
504 |
fileTable[fileIndex].fileId = fileId; |
|
505 |
fileTable[fileIndex].sourceName = sourceName; |
|
506 |
fileTable[fileIndex].sourcePath = sourcePath; |
|
507 |
++fileIndex; |
|
508 |
} |
|
509 |
||
510 |
private void fileLine(void) { |
|
511 |
int hasAbsolute = 0; /* acts as boolean */ |
|
512 |
int fileId; |
|
513 |
String sourceName; |
|
514 |
String sourcePath = null; |
|
515 |
||
516 |
/* is there an absolute filename? */ |
|
517 |
if (sdePeek() == '+') { |
|
518 |
sdeAdvance(); |
|
519 |
hasAbsolute = 1; |
|
520 |
} |
|
521 |
fileId = readNumber(); |
|
522 |
sourceName = readLine(); |
|
523 |
if (hasAbsolute == 1) { |
|
524 |
sourcePath = readLine(); |
|
525 |
} |
|
526 |
storeFile(fileId, sourceName, sourcePath); |
|
527 |
} |
|
528 |
||
529 |
private void storeLine(int jplsStart, int jplsEnd, int jplsLineInc, |
|
530 |
int njplsStart, int njplsEnd, int fileId) { |
|
531 |
assureLineTableSize(); |
|
532 |
lineTable[lineIndex].jplsStart = jplsStart; |
|
533 |
lineTable[lineIndex].jplsEnd = jplsEnd; |
|
534 |
lineTable[lineIndex].jplsLineInc = jplsLineInc; |
|
535 |
lineTable[lineIndex].njplsStart = njplsStart; |
|
536 |
lineTable[lineIndex].njplsEnd = njplsEnd; |
|
537 |
lineTable[lineIndex].fileId = fileId; |
|
538 |
++lineIndex; |
|
539 |
} |
|
540 |
||
541 |
/** |
|
542 |
* Parse line translation info. Syntax is |
|
543 |
* <NJ-start-line> [ # <file-id> ] [ , <line-count> ] : |
|
544 |
* <J-start-line> [ , <line-increment> ] CR |
|
545 |
*/ |
|
546 |
private void lineLine(void) { |
|
547 |
int lineCount = 1; |
|
548 |
int lineIncrement = 1; |
|
549 |
int njplsStart; |
|
550 |
int jplsStart; |
|
551 |
||
552 |
njplsStart = readNumber(); |
|
553 |
||
554 |
/* is there a fileID? */ |
|
555 |
if (sdePeek() == '#') { |
|
556 |
sdeAdvance(); |
|
557 |
currentFileId = readNumber(); |
|
558 |
} |
|
559 |
||
560 |
/* is there a line count? */ |
|
561 |
if (sdePeek() == ',') { |
|
562 |
sdeAdvance(); |
|
563 |
lineCount = readNumber(); |
|
564 |
} |
|
565 |
||
566 |
if (sdeRead() != ':') { |
|
567 |
syntax("expected ':'"); |
|
568 |
} |
|
569 |
jplsStart = readNumber(); |
|
570 |
if (sdePeek() == ',') { |
|
571 |
sdeAdvance(); |
|
572 |
lineIncrement = readNumber(); |
|
573 |
} |
|
574 |
ignoreLine(); /* flush the rest */ |
|
575 |
||
576 |
storeLine(jplsStart, |
|
577 |
jplsStart + (lineCount * lineIncrement) -1, |
|
578 |
lineIncrement, |
|
579 |
njplsStart, |
|
580 |
njplsStart + lineCount -1, |
|
581 |
currentFileId); |
|
582 |
} |
|
583 |
||
584 |
/** |
|
585 |
* Until the next stratum section, everything after this |
|
586 |
* is in stratumId - so, store the current indicies. |
|
587 |
*/ |
|
588 |
private void storeStratum(String stratumId) { |
|
589 |
/* remove redundant strata */ |
|
590 |
if (stratumIndex > 0) { |
|
591 |
if ((stratumTable[stratumIndex-1].fileIndex |
|
592 |
== fileIndex) && |
|
593 |
(stratumTable[stratumIndex-1].lineIndex |
|
594 |
== lineIndex)) { |
|
595 |
/* nothing changed overwrite it */ |
|
596 |
--stratumIndex; |
|
597 |
} |
|
598 |
} |
|
599 |
/* store the results */ |
|
600 |
assureStratumTableSize(); |
|
601 |
stratumTable[stratumIndex].id = stratumId; |
|
602 |
stratumTable[stratumIndex].fileIndex = fileIndex; |
|
603 |
stratumTable[stratumIndex].lineIndex = lineIndex; |
|
604 |
++stratumIndex; |
|
605 |
currentFileId = 0; |
|
606 |
} |
|
607 |
||
608 |
/** |
|
609 |
* The beginning of a stratum's info |
|
610 |
*/ |
|
611 |
private void stratumSection(void) { |
|
612 |
storeStratum(readLine()); |
|
613 |
} |
|
614 |
||
615 |
private void fileSection(void) { |
|
616 |
ignoreLine(); |
|
617 |
while (sdePeek() != '*') { |
|
618 |
fileLine(); |
|
619 |
} |
|
620 |
} |
|
621 |
||
622 |
private void lineSection(void) { |
|
623 |
ignoreLine(); |
|
624 |
while (sdePeek() != '*') { |
|
625 |
lineLine(); |
|
626 |
} |
|
627 |
} |
|
628 |
||
629 |
/** |
|
630 |
* Ignore a section we don't know about. |
|
631 |
*/ |
|
632 |
private void ignoreSection(void) { |
|
633 |
ignoreLine(); |
|
634 |
while (sdePeek() != '*') { |
|
635 |
ignoreLine(); |
|
636 |
} |
|
637 |
} |
|
638 |
||
639 |
/** |
|
640 |
* A base "Java" stratum is always available, though |
|
641 |
* it is not in the SourceDebugExtension. |
|
642 |
* Create the base stratum. |
|
643 |
*/ |
|
644 |
private void createJavaStratum(void) { |
|
645 |
baseStratumIndex = stratumIndex; |
|
646 |
storeStratum(BASE_STRATUM_NAME); |
|
647 |
storeFile(1, jplsFilename, NullString); |
|
648 |
/* JPL line numbers cannot exceed 65535 */ |
|
649 |
storeLine(1, 65536, 1, 1, 65536, 1); |
|
650 |
storeStratum("Aux"); /* in case they don't declare */ |
|
651 |
} |
|
652 |
||
653 |
/** |
|
654 |
* Decode a SourceDebugExtension which is in SourceMap format. |
|
655 |
* This is the entry point into the recursive descent parser. |
|
656 |
*/ |
|
657 |
private void decode(void) { |
|
658 |
/* check for "SMAP" - allow EOF if not ours */ |
|
659 |
if (strlen(sourceDebugExtension) <= 4 || |
|
660 |
(sdeRead() != 'S') || |
|
661 |
(sdeRead() != 'M') || |
|
662 |
(sdeRead() != 'A') || |
|
663 |
(sdeRead() != 'P')) { |
|
664 |
return; /* not our info */ |
|
665 |
} |
|
666 |
ignoreLine(); /* flush the rest */ |
|
667 |
jplsFilename = readLine(); |
|
668 |
defaultStratumId = readLine(); |
|
669 |
createJavaStratum(); |
|
670 |
while (true) { |
|
671 |
if (sdeRead() != '*') { |
|
672 |
syntax("expected '*'"); |
|
673 |
} |
|
674 |
switch (sdeRead()) { |
|
675 |
case 'S': |
|
676 |
stratumSection(); |
|
677 |
break; |
|
678 |
case 'F': |
|
679 |
fileSection(); |
|
680 |
break; |
|
681 |
case 'L': |
|
682 |
lineSection(); |
|
683 |
break; |
|
684 |
case 'E': |
|
685 |
/* set end points */ |
|
686 |
storeStratum("*terminator*"); |
|
687 |
sourceMapIsValid = true; |
|
688 |
return; |
|
689 |
default: |
|
690 |
ignoreSection(); |
|
691 |
} |
|
692 |
} |
|
693 |
} |
|
694 |
||
695 |
/***************** query functions ***********************/ |
|
696 |
||
697 |
private int stiLineTableIndex(int sti, int jplsLine) { |
|
698 |
int i; |
|
699 |
int lineIndexStart; |
|
700 |
int lineIndexEnd; |
|
701 |
||
702 |
lineIndexStart = stratumTable[sti].lineIndex; |
|
703 |
/* one past end */ |
|
704 |
lineIndexEnd = stratumTable[sti+1].lineIndex; |
|
705 |
for (i = lineIndexStart; i < lineIndexEnd; ++i) { |
|
706 |
if ((jplsLine >= lineTable[i].jplsStart) && |
|
707 |
(jplsLine <= lineTable[i].jplsEnd)) { |
|
708 |
return i; |
|
709 |
} |
|
710 |
} |
|
711 |
return -1; |
|
712 |
} |
|
713 |
||
714 |
private int stiLineNumber(int sti, int lti, int jplsLine) { |
|
715 |
return lineTable[lti].njplsStart + |
|
716 |
(((jplsLine - lineTable[lti].jplsStart) / |
|
717 |
lineTable[lti].jplsLineInc)); |
|
718 |
} |
|
719 |
||
720 |
private int fileTableIndex(int sti, int fileId) { |
|
721 |
int i; |
|
722 |
int fileIndexStart = stratumTable[sti].fileIndex; |
|
723 |
/* one past end */ |
|
724 |
int fileIndexEnd = stratumTable[sti+1].fileIndex; |
|
725 |
for (i = fileIndexStart; i < fileIndexEnd; ++i) { |
|
726 |
if (fileTable[i].fileId == fileId) { |
|
727 |
return i; |
|
728 |
} |
|
729 |
} |
|
730 |
return -1; |
|
731 |
} |
|
732 |
||
733 |
private int stiFileTableIndex(int sti, int lti) { |
|
734 |
return fileTableIndex(sti, lineTable[lti].fileId); |
|
735 |
} |
|
736 |
||
737 |
private jboolean isValid(void) { |
|
738 |
return sourceMapIsValid; |
|
739 |
} |