MCPcopy Index your code
hub / github.com/compiler-explorer/compiler-explorer / parseAsmForClass

Method parseAsmForClass

lib/compilers/java.ts:340–457  ·  view source on GitHub ↗
(javapOut: string)

Source from the content-addressed store, hash-verified

338 }
339
340 parseAsmForClass(javapOut: string) {
341 const textsBeforeMethod: string[] = [];
342 const methods: {instructions: any[]; startLine?: number}[] = [];
343 // javap output puts ` Code:` after every signature. (Line will not be shown to user)
344 // We use this to find the individual methods.
345 // Before the first `Code:` occurrence, there is the method signature as well as the name of the class.
346 // Subsequent matches are always followed by lists of assembly instructions as well as line info mappings
347
348 // Regex idea: make sure `Code:` is the only thing on the line. Also consume trailing line ending!
349 const [classNameAndFirstMethodSignature, ...codeAndLineNumberTables] = javapOut.split(/^\s+Code:\s*$\r?\n/m);
350 textsBeforeMethod.push(classNameAndFirstMethodSignature.trimEnd()); // possible trailing \r on windows
351
352 for (const codeAndLineNumberTable of codeAndLineNumberTables) {
353 const method = {
354 instructions: [],
355 } as (typeof methods)[0];
356 methods.push(method);
357
358 for (const codeLineCandidate of utils.splitLines(codeAndLineNumberTable)) {
359 // Match
360 // 1: invokespecial #1 // Method java/lang/Object."<init>":()V
361 // Or match lines inside inside a lookupswitch instruction like:
362 // 8: <code>
363 // -1: <code>
364 // default: <code>
365 const match = codeLineCandidate.match(/\s+([\d-]+|default): (.*)/);
366 if (match) {
367 const instrOffset = Number.parseInt(match[1], 10);
368 method.instructions.push({
369 instrOffset: instrOffset,
370 // Should an instruction ever not be followed by a line number table,
371 // it might contain a trailing \r on Windows -> trim it, otherwise this would not be necessary
372 text: codeLineCandidate.trimEnd(),
373 });
374 } else {
375 // Attempt to match the closing } of a lookupswitch. If we don't include the closing bracket, then
376 // the brackets will be misaligned, and it may be confusing to read.
377 const isClosingCurlyBrace = codeLineCandidate.match(/\s+}/);
378 if (isClosingCurlyBrace) {
379 // Put closing curly brace in asm output
380 method.instructions.push({
381 text: codeLineCandidate.trimEnd(),
382 });
383 continue;
384 }
385 break;
386 }
387 }
388
389 const lineRegex = /line\s*(\d+):\s*(\d+)/g;
390 let m;
391 let currentInstr = 0;
392 let currentSourceLine = -1;
393 let lastIndex = -1;
394 do {
395 m = lineRegex.exec(codeAndLineNumberTable);
396 if (m) {
397 // If exec doesn't find a match anymore, lineRegex.lastIndex will be reset to 0

Callers 1

processAsmMethod · 0.95

Calls 4

pushMethod · 0.80
splitLinesMethod · 0.80
matchMethod · 0.80
execMethod · 0.45

Tested by

no test coverage detected