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