Skip to content

Commit

Permalink
feat(objectionary#509): implement disassembling of the rest instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
volodya-lombrozo committed Mar 15, 2024
1 parent ffc3c18 commit 219fa87
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/main/java/org/eolang/jeo/representation/DataType.java
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,14 @@ private static byte[] hexClass(final String name) {
private static DataType from(final Object data) {
return Arrays.stream(DataType.values()).filter(type -> type.clazz.isInstance(data))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unknown data type"));
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"Unknown data type of %s, class is %s",
data,
data.getClass().getName()
)
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
package org.eolang.jeo.representation.directives;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.xembly.Directive;
Expand Down Expand Up @@ -60,6 +61,13 @@ public final class DirectivesMethod implements Iterable<Directive> {
*/
private final boolean counting;

/**
* Constructor.
*/
public DirectivesMethod() {
this("testMethod");
}

/**
* Constructor.
* @param name Method name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
*/
package org.eolang.jeo.representation.directives;

import java.util.Arrays;
import java.util.Iterator;
import java.util.stream.Stream;
import org.eolang.jeo.representation.DefaultVersion;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
Expand Down Expand Up @@ -58,6 +61,10 @@ public final class DirectivesMethodVisitor extends MethodVisitor implements Iter
*/
private final DirectivesMethod method;

DirectivesMethodVisitor(final DirectivesMethod method) {
this(method, new DummyMethodVisitor());
}

/**
* Constructor.
* @param method Method
Expand Down Expand Up @@ -143,6 +150,7 @@ public void visitInvokeDynamicInsn(
final Handle handler,
final Object... arguments
) {
this.opcode(Opcodes.INVOKEDYNAMIC, name, descriptor, handler, arguments);
super.visitInvokeDynamicInsn(
name,
descriptor,
Expand All @@ -151,6 +159,47 @@ public void visitInvokeDynamicInsn(
);
}

@Override
public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
this.opcode(Opcodes.MULTIANEWARRAY, descriptor, numDimensions);
super.visitMultiANewArrayInsn(descriptor, numDimensions);
}

@Override
public void visitIincInsn(final int varIndex, final int increment) {
this.opcode(Opcodes.IINC, varIndex, increment);
super.visitIincInsn(varIndex, increment);
}

@Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
this.method.opcode(
Opcodes.LOOKUPSWITCH,
Stream.concat(
Stream.of(dflt),
Stream.concat(
Arrays.stream(keys).boxed(),
Stream.of(labels)
)
).toArray(Object[]::new)
);
super.visitLookupSwitchInsn(dflt, keys, labels);
}

@Override
public void visitTableSwitchInsn(
final int min, final int max, final Label dflt, final Label... labels
) {
this.opcode(
Opcodes.TABLESWITCH,
Stream.concat(
Stream.of(min, max, dflt),
Arrays.stream(labels)
).toArray(Object[]::new)
);
super.visitTableSwitchInsn(min, max, dflt, labels);
}

@Override
public void visitTryCatchBlock(
final Label start,
Expand All @@ -175,4 +224,19 @@ public Iterator<Directive> iterator() {
private void opcode(final int opcode, final Object... operands) {
this.method.opcode(opcode, operands);
}

/**
* Dummy method visitor.
* This method visitor does nothing.
* It is used in tests.
* @since 0.3
*/
private static class DummyMethodVisitor extends MethodVisitor {
/**
* Constructor.
*/
DummyMethodVisitor() {
super(new DefaultVersion().api());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,70 @@ void doesNotContainTryCatchBlock() {
Matchers.not(Matchers.containsString("trycatchblocks"))
);
}

@Test
void visitsMultiArrayInstructionSuccessfully() throws ImpossibleModificationException {
final DirectivesMethod method = new DirectivesMethod();
new DirectivesMethodVisitor(method).visitMultiANewArrayInsn("java/lang/String", 2);
MatcherAssert.assertThat(
"MultiArray instruction wasn't visited successfully.",
new Xembler(method).xml(),
Matchers.allOf(
Matchers.containsString("MULTIANEWARRAY"),
Matchers.containsString("2")
)
);
}

@Test
void visitsIisncInstructionSuccessfully() throws ImpossibleModificationException {
final DirectivesMethod method = new DirectivesMethod();
new DirectivesMethodVisitor(method).visitIincInsn(1, 2);
MatcherAssert.assertThat(
"Iinc instruction wasn't visited successfully.",
new Xembler(method).xml(),
Matchers.allOf(
Matchers.containsString("IINC"),
Matchers.containsString("1"),
Matchers.containsString("2")
)
);
}

@Test
void visitsLookupSwitchInstructionSuccessfully() throws ImpossibleModificationException {
final DirectivesMethod method = new DirectivesMethod();
new DirectivesMethodVisitor(method).visitLookupSwitchInsn(
new Label(), new int[]{1, 2, 3}, new Label[]{new Label(), new Label(), new Label()}
);
MatcherAssert.assertThat(
"LookupSwitch instruction wasn't visited successfully.",
new Xembler(method).xml(),
Matchers.allOf(
Matchers.containsString("LOOKUPSWITCH"),
Matchers.containsString("1"),
Matchers.containsString("2"),
Matchers.containsString("3"),
Matchers.containsString("label")
)
);
}

@Test
void visitsTableSwitchInstructionSuccessfully() throws ImpossibleModificationException {
final DirectivesMethod method = new DirectivesMethod();
new DirectivesMethodVisitor(method).visitTableSwitchInsn(
1, 3, new Label(), new Label[]{new Label(), new Label(), new Label()}
);
MatcherAssert.assertThat(
"TableSwitch instruction wasn't visited successfully.",
new Xembler(method).xml(),
Matchers.allOf(
Matchers.containsString("TABLESWITCH"),
Matchers.containsString("1"),
Matchers.containsString("3"),
Matchers.containsString("label")
)
);
}
}

0 comments on commit 219fa87

Please sign in to comment.