diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstruction.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstruction.java index 05b75b9a2..b585fe80c 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstruction.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeInstruction.java @@ -174,7 +174,7 @@ public Object elementType() { break; case Opcodes.ALOAD: case Opcodes.ASTORE: - result = Opcodes.NULL; + result = Opcodes.TOP; break; default: throw new IllegalStateException( diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeTryCatchBlock.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeTryCatchBlock.java index 0e2e19a55..7edd898aa 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeTryCatchBlock.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeTryCatchBlock.java @@ -181,4 +181,12 @@ Label handlerLabel() { return this.handler; } + /** + * Exception type. + * @return Type. + */ + String descriptor() { + return this.type; + } + } diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/StackMapFrames.java b/src/main/java/org/eolang/jeo/representation/bytecode/StackMapFrames.java index 814d8d4a5..099b23a83 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/StackMapFrames.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/StackMapFrames.java @@ -25,6 +25,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Comparator; import java.util.Deque; import java.util.LinkedHashMap; import java.util.List; @@ -78,14 +79,12 @@ final class StackMapFrames { * @return The list of frames. */ List frames() { - // Initialization final Deque worklist = new ArrayDeque<>(0); final Map res = new LinkedHashMap<>(0); final int size = this.entries.size(); - //Work final Entry initial = this.initial(); -// res.put(0, initial); worklist.push(initial); + this.blocks.stream().map(this::block).forEach(worklist::push); while (!worklist.isEmpty()) { Entry current = worklist.pop(); for (int index = current.indx(); index < size; ++index) { @@ -124,6 +123,7 @@ List frames() { res.values() .stream() .filter(Entry::joined) + .sorted(Comparator.comparingInt(Entry::indx)) .collect(Collectors.toList()) ); } @@ -141,12 +141,20 @@ private void logEntires(final Map res) { } } + private Entry block(final BytecodeTryCatchBlock block) { + final int index = this.index(block.handlerLabel()); + final Entry initial = this.initial(); + final LinkedHashMap stack = new LinkedHashMap<>(0); + stack.put(0, block.descriptor()); + return initial.withStack(stack).join(index); + } + private Entry initial() { final String descriptor = this.props.descriptor(); final boolean stat = this.props.isStatic(); final Type[] types = Type.getArgumentTypes(descriptor); int indx = stat ? 0 : 1; - LinkedHashMap locals = new LinkedHashMap<>(0); + final LinkedHashMap locals = new LinkedHashMap<>(0); if (!stat) { locals.put(0, Opcodes.TOP); } @@ -298,6 +306,10 @@ Entry copy(final int indx) { return new Entry(indx, this.locals, this.stack, false); } + Entry withStack(final LinkedHashMap stack) { + return new Entry(this.indx, this.locals, stack, this.join); + } + Entry append(final Entry next) { final int max = Math.max( this.locals.keySet().stream().mapToInt(Integer::intValue).max().orElse(0),