diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java index 9aa2ad82c..7c348a323 100644 --- a/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java +++ b/src/main/java/org/eolang/jeo/representation/bytecode/BytecodeMethod.java @@ -425,7 +425,14 @@ DirectivesMethod directives() { * @return Max stack. */ private int computeStack() { - return new MaxStack( +// return new MaxStack( +// this.instructions, +// this.tryblocks.stream() +// .filter(BytecodeTryCatchBlock.class::isInstance) +// .map(BytecodeTryCatchBlock.class::cast) +// .collect(Collectors.toList()) +// ).value(); + return new MaxStackFlow( this.instructions, this.tryblocks.stream() .filter(BytecodeTryCatchBlock.class::isInstance) diff --git a/src/main/java/org/eolang/jeo/representation/bytecode/DataFlow.java b/src/main/java/org/eolang/jeo/representation/bytecode/DataFlow.java new file mode 100644 index 000000000..f4c899610 --- /dev/null +++ b/src/main/java/org/eolang/jeo/representation/bytecode/DataFlow.java @@ -0,0 +1,156 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2024 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang.jeo.representation.bytecode; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.objectweb.asm.Label; + +public final class DataFlow> { + private final InstructionsFlow instructions; + + private final List blocks; + + private final T initial; + + private final Function generate; + + public DataFlow( + final InstructionsFlow instructions, + final List blocks, + final T initial, + Function generator + ) { + this.instructions = instructions; + this.blocks = blocks; + this.initial = initial; + this.generate = generator; + } + + // this.blocks.stream() +// .map(BytecodeTryCatchBlock.class::cast) +// .map(BytecodeTryCatchBlock::handlerLabel) +// .map(this.instructions::index) +// .peek(ind -> visited.put(ind, 1)) +// .forEach(worklist::add); + + + public T max() { + final Map visited = new HashMap<>(0); + final Map worklist = new HashMap<>(0); + worklist.put(0, this.initial); + final int total = this.instructions.size(); + T current; + while (!worklist.isEmpty()) { + final Map.Entry curr = worklist.entrySet() + .stream() + .findFirst() + .orElseThrow(() -> new IllegalStateException("Cannot find first worklist element")); + int index = curr.getKey(); + current = curr.getValue(); + worklist.remove(index); + if (visited.get(index) != null) { + if (visited.get(index).compareTo(current) >= 0) { + continue; + } + } + while (index < total) { + final BytecodeEntry entry = this.instructions.get(index); + if (entry instanceof BytecodeInstruction) { + final BytecodeInstruction instruction = BytecodeInstruction.class.cast(entry); + current = current.add(this.generate.apply(instruction)); + final T updated = current; + if (instruction.isSwitch()) { + final List