Skip to content

Commit ad846a0

Browse files
committed
fix: resolve issues with incorrect labels and metadata
1 parent 2692263 commit ad846a0

File tree

11 files changed

+116
-67
lines changed

11 files changed

+116
-67
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ node_modules/
3333

3434
**/.DS_Store
3535

36-
cliff.toml
36+
cliff.toml

raung-asm/src/main/java/io/github/skylot/raung/asm/impl/utils/ValidateAsmArgs.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static void process(RaungAsmBuilder args) {
3030
}
3131

3232
public static void processOptions(RaungAsmBuilder args) {
33-
LOG.debug("Effective args: {}", args);
33+
LOG.trace("Effective args: {}", args);
3434
}
3535

3636
private static Path getOutDirFromInputs(List<Path> inputs) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.github.skylot.raung.disasm.impl.utils;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
7+
import org.jetbrains.annotations.Nullable;
8+
9+
public class ListUtils {
10+
11+
public static <T> List<T> fromNullable(@Nullable List<T> list) {
12+
return list == null ? Collections.emptyList() : list;
13+
}
14+
15+
public static <T> List<T> addToNullable(@Nullable List<T> list, T obj) {
16+
List<T> result = list == null ? new ArrayList<>() : list;
17+
result.add(obj);
18+
return result;
19+
}
20+
}

raung-disasm/src/main/java/io/github/skylot/raung/disasm/impl/utils/RaungWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
@SuppressWarnings("UnusedReturnValue")
66
public class RaungWriter {
7-
public static final String NL = System.getProperty("line.separator");
7+
public static final String NL = System.lineSeparator();
88
public static final String INDENT_STR = " ";
99

1010
private final StringBuilder sb = new StringBuilder();

raung-disasm/src/main/java/io/github/skylot/raung/disasm/impl/utils/ValidateDisasmArgs.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ public static void processOptions(RaungDisasmBuilder args) {
2727
if (args.isAutoFrames()) {
2828
args.autoMax(true);
2929
}
30-
LOG.debug("Effective args: {}", args);
30+
LOG.trace("Effective args: {}", args);
3131
}
3232
}

raung-disasm/src/main/java/io/github/skylot/raung/disasm/impl/visitors/RaungClassVisitor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor,
159159
if (signature != null) {
160160
writer.startLine(Directive.SIGNATURE).add(signature);
161161
}
162-
return new RaungMethodVisitor(this);
162+
return new RaungMethodVisitor(this, name + descriptor);
163163
}
164164

165165
@Override
@@ -186,4 +186,9 @@ public String getClsFullName() {
186186
public String getResult() {
187187
return writer.getCode();
188188
}
189+
190+
@Override
191+
public String toString() {
192+
return clsFullName;
193+
}
189194
}

raung-disasm/src/main/java/io/github/skylot/raung/disasm/impl/visitors/RaungMethodVisitor.java

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.util.IdentityHashMap;
66
import java.util.List;
77
import java.util.Map;
8-
import java.util.stream.Collectors;
98

109
import org.objectweb.asm.AnnotationVisitor;
1110
import org.objectweb.asm.Attribute;
@@ -30,6 +29,7 @@
3029
public class RaungMethodVisitor extends MethodVisitor {
3130
private final RaungClassVisitor classVisitor;
3231
private final RaungWriter writer;
32+
private final String mthShortId;
3333

3434
private final RaungWriter tempWriter = new RaungWriter();
3535

@@ -39,10 +39,11 @@ public class RaungMethodVisitor extends MethodVisitor {
3939

4040
private int catchCount;
4141

42-
public RaungMethodVisitor(RaungClassVisitor classVisitor) {
42+
public RaungMethodVisitor(RaungClassVisitor classVisitor, String mthShortId) {
4343
super(classVisitor.getApi());
4444
this.classVisitor = classVisitor;
4545
this.writer = classVisitor.getWriter();
46+
this.mthShortId = mthShortId;
4647
}
4748

4849
@Override
@@ -69,11 +70,13 @@ public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, Str
6970

7071
@Override
7172
public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String descriptor, boolean visible) {
72-
RaungWriter rw = new RaungWriter().setIndent(writer.getIndent());
73-
RaungAnnotationVisitor av = RaungAnnotationVisitor.buildInsnAnnotation(classVisitor, rw, typeRef, typePath, descriptor, visible);
7473
// attach annotation to last instruction
75-
insnAttachments.put(insns.size() - 1, rw);
76-
return av;
74+
int insn = insns.size() - 1;
75+
if (insn < 0) {
76+
throw new RaungDisasmException("No instructions to attach annotation");
77+
}
78+
RaungWriter rw = insnAttachments.computeIfAbsent(insn, i -> new RaungWriter().setIndent(writer.getIndent()));
79+
return RaungAnnotationVisitor.buildInsnAnnotation(classVisitor, rw, typeRef, typePath, descriptor, visible);
7780
}
7881

7982
@Override
@@ -312,14 +315,16 @@ public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath type
312315
@Override
313316
public void visitLineNumber(int line, Label start) {
314317
if (addDebugInfo()) {
315-
insns.add(".line " + line);
318+
LabelData ld = getLabelData(start);
319+
ld.setLine(line);
316320
}
317321
}
318322

319323
@Override
320324
public void visitLabel(Label label) {
321325
LabelData ld = getLabelData(label);
322-
ld.setInsnRef(insns.size());
326+
ld.setInsnRef(insns.size()); // for next insn
327+
// System.out.println("DISASM visit label: " + ld);
323328
}
324329

325330
@Override
@@ -334,23 +339,31 @@ public void visitMaxs(int maxStack, int maxLocals) {
334339

335340
@Override
336341
public void visitEnd() {
337-
Map<Integer, LabelData> labelsMap = labels.values().stream()
338-
.filter(LabelData::isUsed)
339-
.collect(Collectors.toMap(LabelData::getInsnRef, ld -> ld));
340-
int insnsCount = insns.size();
341-
for (int i = 0; i < insnsCount; i++) {
342-
LabelData labelData = labelsMap.get(i);
343-
if (labelData != null) {
344-
handleLabelDataBeforeInsn(labelData);
342+
try {
343+
Map<Integer, LabelData> labelsMap = new HashMap<>();
344+
for (LabelData ld : labels.values()) {
345+
LabelData prevLabel = labelsMap.put(ld.getInsnRef(), ld);
346+
if (prevLabel != null) {
347+
throw new RaungDisasmException("Duplicate label, " + ld + ", prev: " + prevLabel);
348+
}
345349
}
346-
addInsnAttachments(i);
347-
writer.startLine(insns.get(i));
348-
if (labelData != null) {
349-
handleLabelDataAfterInsn(labelData, i == insnsCount - 1);
350+
int insnsCount = insns.size();
351+
for (int i = 0; i < insnsCount; i++) {
352+
LabelData labelData = labelsMap.get(i);
353+
if (labelData != null) {
354+
handleLabelDataBeforeInsn(labelData);
355+
}
356+
addInsnAttachments(i);
357+
writer.startLine(insns.get(i));
358+
if (labelData != null) {
359+
handleLabelDataAfterInsn(labelData, i == insnsCount - 1);
360+
}
350361
}
362+
writer.setIndent(0);
363+
writer.startLine(".end method");
364+
} catch (Exception e) {
365+
throw new RaungDisasmException("Failed to process method: " + this, e);
351366
}
352-
writer.setIndent(0);
353-
writer.startLine(".end method");
354367
}
355368

356369
private void addInsnAttachments(int insnOffset) {
@@ -375,19 +388,20 @@ private void handleLabelDataBeforeInsn(LabelData labelData) {
375388
writer.space().add(startVar.getSignature());
376389
}
377390
}
378-
if (!labelData.getCatches().isEmpty()) {
379-
for (TryCatchBlock catchBlock : labelData.getCatches()) {
380-
String type = catchBlock.getType();
381-
writer.startLine(Directive.CATCH);
382-
if (classVisitor.getArgs().isSaveCatchNumber()) {
383-
writer.add('@').add(catchBlock.getId()).space();
384-
}
385-
writer.add(type == null ? "all" : type)
386-
.space().add(catchBlock.getStart().getName())
387-
.space().add("..")
388-
.space().add(catchBlock.getEnd().getName())
389-
.space().add("goto").space().add(catchBlock.getHandler().getName());
391+
for (TryCatchBlock catchBlock : labelData.getCatches()) {
392+
String type = catchBlock.getType();
393+
writer.startLine(Directive.CATCH);
394+
if (classVisitor.getArgs().isSaveCatchNumber()) {
395+
writer.add('@').add(catchBlock.getId()).space();
390396
}
397+
writer.add(type == null ? "all" : type)
398+
.space().add(catchBlock.getStart().getName())
399+
.space().add("..")
400+
.space().add(catchBlock.getEnd().getName())
401+
.space().add("goto").space().add(catchBlock.getHandler().getName());
402+
}
403+
for (Integer line : labelData.getLines()) {
404+
writer.startLine(".line ").add(line);
391405
}
392406
}
393407

@@ -414,4 +428,9 @@ private RaungWriter formatInsn(int opcode) {
414428
private boolean addDebugInfo() {
415429
return !classVisitor.getArgs().isIgnoreDebugInfo();
416430
}
431+
432+
@Override
433+
public String toString() {
434+
return classVisitor + "->" + mthShortId;
435+
}
417436
}
Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
package io.github.skylot.raung.disasm.impl.visitors.data;
22

3-
import java.util.ArrayList;
4-
import java.util.Collections;
53
import java.util.List;
64

5+
import org.jetbrains.annotations.Nullable;
76
import org.objectweb.asm.Label;
87

8+
import io.github.skylot.raung.disasm.impl.utils.ListUtils;
9+
910
public class LabelData {
1011
private final Label label;
1112
private final String name;
1213
private int insnRef;
1314
private int useCount;
14-
private List<LocalVar> startVars;
15-
private List<LocalVar> endVars;
16-
private List<TryCatchBlock> catches;
15+
private @Nullable List<LocalVar> startVars;
16+
private @Nullable List<LocalVar> endVars;
17+
private @Nullable List<TryCatchBlock> catches;
18+
private @Nullable List<Integer> lines;
1719

1820
public LabelData(Label label, String name) {
1921
this.label = label;
@@ -46,42 +48,39 @@ public LabelData addUse() {
4648
}
4749

4850
public List<LocalVar> getStartVars() {
49-
return startVars == null ? Collections.emptyList() : startVars;
51+
return ListUtils.fromNullable(startVars);
5052
}
5153

5254
public void addStartVars(LocalVar var) {
53-
if (startVars == null) {
54-
startVars = new ArrayList<>();
55-
}
56-
startVars.add(var);
55+
this.startVars = ListUtils.addToNullable(startVars, var);
5756
}
5857

5958
public List<LocalVar> getEndVars() {
60-
return endVars == null ? Collections.emptyList() : endVars;
59+
return ListUtils.fromNullable(endVars);
6160
}
6261

6362
public void addEndVar(LocalVar var) {
64-
if (endVars == null) {
65-
endVars = new ArrayList<>();
66-
}
67-
endVars.add(var);
63+
this.endVars = ListUtils.addToNullable(endVars, var);
6864
}
6965

7066
public List<TryCatchBlock> getCatches() {
71-
return catches == null ? Collections.emptyList() : catches;
67+
return ListUtils.fromNullable(catches);
7268
}
7369

7470
public void addCatch(TryCatchBlock block) {
75-
if (catches == null) {
76-
catches = new ArrayList<>();
77-
}
78-
catches.add(block);
71+
this.catches = ListUtils.addToNullable(catches, block);
72+
}
73+
74+
public List<Integer> getLines() {
75+
return ListUtils.fromNullable(lines);
76+
}
77+
78+
public void setLine(int line) {
79+
this.lines = ListUtils.addToNullable(lines, line);
7980
}
8081

81-
public boolean isUsed() {
82-
return getUseCount() != 0
83-
|| !getStartVars().isEmpty()
84-
|| !getEndVars().isEmpty()
85-
|| !getCatches().isEmpty();
82+
@Override
83+
public String toString() {
84+
return name + " at " + insnRef;
8685
}
8786
}

raung-disasm/src/main/java/io/github/skylot/raung/disasm/impl/visitors/data/LocalVar.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@ public String getType() {
2828
public String getSignature() {
2929
return signature;
3030
}
31+
32+
@Override
33+
public String toString() {
34+
return name + " : " + type;
35+
}
3136
}

raung-tests/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ dependencies {
77
testImplementation(project(":raung-disasm"))
88

99
testCompileOnly("org.jetbrains:annotations:24.1.0")
10+
testImplementation("commons-io:commons-io:2.15.1")
1011
}

0 commit comments

Comments
 (0)