Skip to content

Commit

Permalink
feat(objectionary#750): add utility methods
Browse files Browse the repository at this point in the history
  • Loading branch information
volodya-lombrozo committed Nov 6, 2024
1 parent d17c7c9 commit f24b5be
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.eolang.jeo.representation.directives.DirectivesFrame;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.LabelNode;
import org.xembly.Directive;

Expand Down Expand Up @@ -176,14 +177,102 @@ public List<Label> jumps() {

@Override
public String view() {
final String name;
switch (this.type) {
case Opcodes.F_NEW:
name = "NEW";
break;
case Opcodes.F_FULL:
name = "FULL";
break;
case Opcodes.F_APPEND:
name = "APPEND";
break;
case Opcodes.F_CHOP:
name = "CHOP";
break;
case Opcodes.F_SAME:
name = "SAME";
break;
case Opcodes.F_SAME1:
name = "SAME1";
break;
default:
name = "UNKNOWN";
}
return String.format(
"Frame %d locals %d stack %d",
this.type,
"Frame %s locals %d stack %d",
name,
this.nlocal,
this.nstack
);
}

public int stackDiff(final BytecodeFrame other) {
return this.nstack - other.nstack;
}


public boolean stackOneElement() {
return this.nstack == 1;
}

public boolean stackEmpty() {
return this.nstack == 0;
}

public BytecodeFrame withType(final int type) {
return new BytecodeFrame(
type,
this.nlocal,
this.locals,
this.nstack,
this.stack
);
}

public BytecodeFrame substract(final BytecodeFrame other) {
final int length = this.nlocal - other.nlocal;
final Object[] locals;
if (length <= 0) {
locals = new Object[0];
} else {
locals = new Object[length];
System.arraycopy(this.locals, length - 1, locals, 0, length);
}
final int stackLength = this.nstack - other.nstack;
final Object[] stack = new Object[stackLength];
System.arraycopy(this.stack, 0, stack, 0, stackLength);
return new BytecodeFrame(
this.type,
length,
locals,
stackLength,
stack
);
}

public int localsDiff(final BytecodeFrame previous) {
return this.nlocal - previous.nlocal;
}

/**
* Check if the frame has the same locals.
* @param frame Frame to compare.
* @return True if the frame has the same locals.
*/
public boolean sameLocals(final BytecodeFrame frame) {
final boolean size = this.nlocal == frame.nlocal;
final Object[] current = this.locals;
final Object[] other = frame.locals;
for (int index = 0; index < this.nlocal; ++index) {
if (!current[index].equals(other[index])) {
return false;
}
}
return size;
}

/**
* Convert a list to array.
* @param list List of objects.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,50 @@ public int localIndex() {
return this.varIndex();
}

public Object localType() {
return 1;
/**
* // Standard stack map frame element types.
*
* Integer TOP = Frame.ITEM_TOP;
* Integer INTEGER = Frame.ITEM_INTEGER;
* Integer FLOAT = Frame.ITEM_FLOAT;
* Integer DOUBLE = Frame.ITEM_DOUBLE;
* Integer LONG = Frame.ITEM_LONG;
* Integer NULL = Frame.ITEM_NULL;
* Integer UNINITIALIZED_THIS = Frame.ITEM_UNINITIALIZED_THIS;
* @return
*/
public Object elementType() {
final Object result;
switch (this.opcode) {
case Opcodes.ILOAD:
case Opcodes.ISTORE:
result = Opcodes.INTEGER;
break;
case Opcodes.LLOAD:
case Opcodes.LSTORE:
result = Opcodes.LONG;
break;
case Opcodes.FLOAD:
case Opcodes.FSTORE:
result = Opcodes.FLOAT;
break;
case Opcodes.DLOAD:
case Opcodes.DSTORE:
result = Opcodes.DOUBLE;
break;
case Opcodes.ALOAD:
case Opcodes.ASTORE:
result = Opcodes.NULL;
break;
default:
throw new IllegalStateException(
String.format(
"Unexpected opcode for local variable instruction: %s",
new OpcodeName(this.opcode).simplified()
)
);
}
return result;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ BytecodeMaxs currentMaxs() {
*/
List<BytecodeFrame> computeFrames() {
return new StackMapFrames(
this.properties,
this.instructions,
this.tryblocks.stream()
.filter(BytecodeTryCatchBlock.class::isInstance)
Expand Down
Loading

0 comments on commit f24b5be

Please sign in to comment.