Class StatementRecoverer
- java.lang.Object
-
- com.tonic.analysis.source.recovery.StatementRecoverer
-
- All Implemented Interfaces:
RegionRecoveryBridge
public class StatementRecoverer extends Object implements RegionRecoveryBridge
Recovers Statement AST nodes from IR blocks, offering each region to the reaching-condition structurer first and falling back to the legacy walk for shapes it declines.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classStatementRecoverer.RetiredSchemaRecoveryExceptionSignals a region classification whose schema recoverer is retired and which no engine route owned.
-
Constructor Summary
Constructors Constructor Description StatementRecoverer(ControlFlowContext context, StructuralAnalyzer analyzer, ExpressionRecoverer exprRecoverer)Creates a recoverer and pre-declares the method parameters so stores to them recover as assignments rather than declarations.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description booleanconditionInlinesSideEffect(IRBlock block)True when recoveringblock's branch condition would inline an allocation or call - a side effect a shared-tail guard must not duplicate by re-emitting the condition.SwitchDescriptordecodeSwitch(IRBlock switchBlock)DecodesswitchBlockinto a structuring-readySwitchDescriptor- selector, merge, ordered cases and labels - without recovering case bodies or marking any block, so the reaching-condition engine can structure the cases itself.TryNodeDescriptordecodeTryNode(IRBlock block, Set<IRBlock> regionStops)Statically decodes the try starting atblockinto an opaqueTryNodeDescriptor- the blocks the try/catch recovery will consume and the single join it continues at - without recovering or marking anything.SourceTypegetLocalSlotUnifiedType(String slotName)Looks up the type unified across every value stored into a local slot.booleanguardAtomExceptionFree(IRBlock block)True when recoveringblock's branch condition inlines no operation that can throw.booleanhasDroppedOperations(BlockStmt body)Completeness invariant.booleanisDuplicationSafe(IRBlock block)True whenblockmay be duplicated - re-recovered once per reaching edge - without changing semantics or perturbing the round trip.booleanisRegionBlockProcessed(IRBlock block)True onceblockhas been emitted.booleanisRetiredHandlerBlock(IRBlock block)Whetherblockis the entry of an exception handler the surrounding recovery has already consumed - a retired copy-side guard catch or a de-duplicated finally's scaffolding.List<Statement>lowerInductionPhiInitsOnEdge(IRBlock pred, IRBlock succ)AslowerPhisOnEdge(com.tonic.analysis.ssa.cfg.IRBlock, com.tonic.analysis.ssa.cfg.IRBlock), but only for the loop's for-induction counter phis - the onesemitPhiDeclaration(com.tonic.analysis.ssa.ir.PhiInstruction, java.util.List<com.tonic.analysis.source.ast.stmt.Statement>, java.util.Set<java.lang.String>, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>)deliberately does not declare.List<Statement>lowerPhisOnEdge(IRBlock pred, IRBlock succ)SSA destruction on a CFG edge.voidmarkRegionBlockProcessed(IRBlock block, List<Statement> statements)Recordsblock's recovered statements and marks it emitted so nothing re-emits it.List<Statement>processedReturnStatements(IRBlock block)The statements of a processed RETURN block, for idempotent re-emission - a trailing return two paths share is recovered once by the first path's pass.List<Statement>recoverBlockSequence(IRBlock startBlock, Set<IRBlock> stopBlocks)Recovers the statements of one region as a hand-off, preserving the surrounding recovery's processed marks.List<Statement>recoverBoundaryTail(IRBlock tail)Recovers a straight terminal tail (single-successor blocks chaining into a return/throw) as fresh statements, without marking the blocks processed.ExpressionrecoverCondition(IRBlock block, boolean negate)The branch condition ofblock, negated whennegateis set.booleanrecoveredTryTerminates(Statement recovered)Whether a statement recovered byRegionRecoveryBridge.recoverTryNode(com.tonic.analysis.ssa.cfg.IRBlock, com.tonic.analysis.source.recovery.rcs.TryNodeDescriptor, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>)leaves no normal fall-through.BlockStmtrecoverMethod()Recovers the whole method body, routing through try-with-resources or general exception handling when the method declares handlers.BlockStmtrecoverMethodAsDispatch()Recovers the whole method as a structured dispatch loop.List<Statement>recoverSimpleBlock(IRBlock block)The straight-line statements ofblock(its terminator branch is not emitted here).List<Statement>recoverSwitchHeaderStatements(IRBlock header)The switch header's own statements for emission before theswitch.StatementrecoverTryNode(IRBlock block, TryNodeDescriptor node, Set<IRBlock> stopBlocks, Set<IRBlock> alreadyEmitted)Recovers the try node starting atblockas one statement via the host's try/catch machinery, marking its handler and blocks consumed.List<Statement>recoverUnconsumedForLoopInits(IRBlock header)The still-unconsumed for-induction inits ofheader's preheader.booleanregionContainsUnprocessedHandler(Set<IRBlock> region)True when some block inregionstarts an exception handler the surrounding recovery has not yet consumed - a nested try the engine must decline so the try/catch scaffolding recovers it.voidsetEnumClassPool(ClassPool pool)Sets the pool enum constants resolve from for switches that dispatch on ordinal() directly.List<Statement>stackPhiCopiesOnEdge(IRBlock pred, IRBlock succ)Copies forsucc's operand-stack merge phis whose incoming on this edge no instruction inpredproduces.booleanstartsUnprocessedHandler(IRBlock block)True whenblockstarts the protected range of an exception handler no recovery has consumed.booleantryCollapseTernaryDiamond(IRBlock branch)Collapses a value-producing ternary diamond headed bybranchto a cached ternary expression, returning true when it applies.voidunrecoveredTryNode(IRBlock block)Signals that the host's try recovery produced nothing for a try node the engine had decoded - a routing gap, since every region structures through the engine.
-
-
-
Constructor Detail
-
StatementRecoverer
public StatementRecoverer(ControlFlowContext context, StructuralAnalyzer analyzer, ExpressionRecoverer exprRecoverer)
Creates a recoverer and pre-declares the method parameters so stores to them recover as assignments rather than declarations.- Parameters:
context- the per-method recovery stateanalyzer- supplies the structural analysis of the control flowexprRecoverer- recovers the expressions inside the statements
-
-
Method Detail
-
setEnumClassPool
public void setEnumClassPool(ClassPool pool)
Sets the pool enum constants resolve from for switches that dispatch on ordinal() directly.- Parameters:
pool- the class pool, or null to resolve nothing
-
markRegionBlockProcessed
public void markRegionBlockProcessed(IRBlock block, List<Statement> statements)
Description copied from interface:RegionRecoveryBridgeRecordsblock's recovered statements and marks it emitted so nothing re-emits it.- Specified by:
markRegionBlockProcessedin interfaceRegionRecoveryBridge- Parameters:
block- the block being consumedstatements- the statements recovered for it
-
processedReturnStatements
public List<Statement> processedReturnStatements(IRBlock block)
Description copied from interface:RegionRecoveryBridgeThe statements of a processed RETURN block, for idempotent re-emission - a trailing return two paths share is recovered once by the first path's pass.- Specified by:
processedReturnStatementsin interfaceRegionRecoveryBridge- Parameters:
block- the shared trailing block- Returns:
- its recovered return statements, empty when it is not a bare processed return
-
isRegionBlockProcessed
public boolean isRegionBlockProcessed(IRBlock block)
Description copied from interface:RegionRecoveryBridgeTrue onceblockhas been emitted.- Specified by:
isRegionBlockProcessedin interfaceRegionRecoveryBridge- Parameters:
block- the block to test- Returns:
- true when it has already been emitted
-
tryCollapseTernaryDiamond
public boolean tryCollapseTernaryDiamond(IRBlock branch)
Description copied from interface:RegionRecoveryBridgeCollapses a value-producing ternary diamond headed bybranchto a cached ternary expression, returning true when it applies.- Specified by:
tryCollapseTernaryDiamondin interfaceRegionRecoveryBridge- Parameters:
branch- the candidate diamond head- Returns:
- true when the diamond was collapsed and its arms marked emitted
-
decodeSwitch
public SwitchDescriptor decodeSwitch(IRBlock switchBlock)
Description copied from interface:RegionRecoveryBridgeDecodesswitchBlockinto a structuring-readySwitchDescriptor- selector, merge, ordered cases and labels - without recovering case bodies or marking any block, so the reaching-condition engine can structure the cases itself.- Specified by:
decodeSwitchin interfaceRegionRecoveryBridge- Parameters:
switchBlock- the block terminated by the switch- Returns:
- the decoded descriptor, or null for a shape the engine does not own natively
-
recoverSwitchHeaderStatements
public List<Statement> recoverSwitchHeaderStatements(IRBlock header)
Description copied from interface:RegionRecoveryBridgeThe switch header's own statements for emission before theswitch.- Specified by:
recoverSwitchHeaderStatementsin interfaceRegionRecoveryBridge- Parameters:
header- the switch header block- Returns:
- the statements to emit before the switch
-
recoverMethod
public BlockStmt recoverMethod()
Recovers the whole method body, routing through try-with-resources or general exception handling when the method declares handlers.- Returns:
- the recovered body, or an empty block when the method has no entry
-
getLocalSlotUnifiedType
public SourceType getLocalSlotUnifiedType(String slotName)
Looks up the type unified across every value stored into a local slot.- Parameters:
slotName- the recovered variable name of the slot- Returns:
- the unified type, or null if none was computed for the slot
-
recoverBlockSequence
public List<Statement> recoverBlockSequence(IRBlock startBlock, Set<IRBlock> stopBlocks)
Recovers the statements of one region as a hand-off, preserving the surrounding recovery's processed marks.- Parameters:
startBlock- the block the region starts atstopBlocks- blocks that bound the region and are not recovered into it- Returns:
- the recovered statements
-
startsUnprocessedHandler
public boolean startsUnprocessedHandler(IRBlock block)
Description copied from interface:RegionRecoveryBridgeTrue whenblockstarts the protected range of an exception handler no recovery has consumed.- Specified by:
startsUnprocessedHandlerin interfaceRegionRecoveryBridge- Parameters:
block- the candidate protected-range start- Returns:
- true when an unconsumed handler protects a range starting there
-
isRetiredHandlerBlock
public boolean isRetiredHandlerBlock(IRBlock block)
Description copied from interface:RegionRecoveryBridgeWhetherblockis the entry of an exception handler the surrounding recovery has already consumed - a retired copy-side guard catch or a de-duplicated finally's scaffolding.- Specified by:
isRetiredHandlerBlockin interfaceRegionRecoveryBridge- Parameters:
block- the candidate handler entry- Returns:
- true when it is a retired handler entry
-
decodeTryNode
public TryNodeDescriptor decodeTryNode(IRBlock block, Set<IRBlock> regionStops)
Description copied from interface:RegionRecoveryBridgeStatically decodes the try starting atblockinto an opaqueTryNodeDescriptor- the blocks the try/catch recovery will consume and the single join it continues at - without recovering or marking anything.- Specified by:
decodeTryNodein interfaceRegionRecoveryBridge- Parameters:
block- the candidate try entryregionStops- blocks that bound the enclosing region's walk- Returns:
- the decoded node, or null for a shape the node model does not own
-
recoverBoundaryTail
public List<Statement> recoverBoundaryTail(IRBlock tail)
Description copied from interface:RegionRecoveryBridgeRecovers a straight terminal tail (single-successor blocks chaining into a return/throw) as fresh statements, without marking the blocks processed.- Specified by:
recoverBoundaryTailin interfaceRegionRecoveryBridge- Parameters:
tail- the first block of the candidate tail chain- Returns:
- the tail's statements, or null when the shape is not a straight terminal tail
-
recoverTryNode
public Statement recoverTryNode(IRBlock block, TryNodeDescriptor node, Set<IRBlock> stopBlocks, Set<IRBlock> alreadyEmitted)
Description copied from interface:RegionRecoveryBridgeRecovers the try node starting atblockas one statement via the host's try/catch machinery, marking its handler and blocks consumed.- Specified by:
recoverTryNodein interfaceRegionRecoveryBridge- Parameters:
block- the try entrynode- the descriptor decoded byRegionRecoveryBridge.decodeTryNode(com.tonic.analysis.ssa.cfg.IRBlock, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>)stopBlocks- blocks the try's walk must not cross intoalreadyEmitted- region blocks recovered before the node- Returns:
- the try statement, or null when the shape cannot be recovered
-
recoveredTryTerminates
public boolean recoveredTryTerminates(Statement recovered)
Description copied from interface:RegionRecoveryBridgeWhether a statement recovered byRegionRecoveryBridge.recoverTryNode(com.tonic.analysis.ssa.cfg.IRBlock, com.tonic.analysis.source.recovery.rcs.TryNodeDescriptor, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>)leaves no normal fall-through.- Specified by:
recoveredTryTerminatesin interfaceRegionRecoveryBridge- Parameters:
recovered- a statement produced byRegionRecoveryBridge.recoverTryNode(com.tonic.analysis.ssa.cfg.IRBlock, com.tonic.analysis.source.recovery.rcs.TryNodeDescriptor, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>)- Returns:
- true when every path out of it returns or throws
-
unrecoveredTryNode
public void unrecoveredTryNode(IRBlock block)
Description copied from interface:RegionRecoveryBridgeSignals that the host's try recovery produced nothing for a try node the engine had decoded - a routing gap, since every region structures through the engine.- Specified by:
unrecoveredTryNodein interfaceRegionRecoveryBridge- Parameters:
block- the try entry whose recovery produced nothing
-
recoverSimpleBlock
public List<Statement> recoverSimpleBlock(IRBlock block)
Description copied from interface:RegionRecoveryBridgeThe straight-line statements ofblock(its terminator branch is not emitted here).- Specified by:
recoverSimpleBlockin interfaceRegionRecoveryBridge- Parameters:
block- the block to recover- Returns:
- its straight-line statements
-
hasDroppedOperations
public boolean hasDroppedOperations(BlockStmt body)
Completeness invariant.- Parameters:
body- the recovered method body to audit- Returns:
- true if a reachable call is missing from the body
-
recoverMethodAsDispatch
public BlockStmt recoverMethodAsDispatch()
Recovers the whole method as a structured dispatch loop.- Returns:
- the method body as a dispatch loop, or an empty block when the method has no entry
-
lowerPhisOnEdge
public List<Statement> lowerPhisOnEdge(IRBlock pred, IRBlock succ)
SSA destruction on a CFG edge.- Specified by:
lowerPhisOnEdgein interfaceRegionRecoveryBridge- Parameters:
pred- the source block of the edgesucc- the target block whose phis are lowered- Returns:
- the copies for that edge
-
lowerInductionPhiInitsOnEdge
public List<Statement> lowerInductionPhiInitsOnEdge(IRBlock pred, IRBlock succ)
AslowerPhisOnEdge(com.tonic.analysis.ssa.cfg.IRBlock, com.tonic.analysis.ssa.cfg.IRBlock), but only for the loop's for-induction counter phis - the onesemitPhiDeclaration(com.tonic.analysis.ssa.ir.PhiInstruction, java.util.List<com.tonic.analysis.source.ast.stmt.Statement>, java.util.Set<java.lang.String>, java.util.Set<com.tonic.analysis.ssa.cfg.IRBlock>)deliberately does not declare.- Specified by:
lowerInductionPhiInitsOnEdgein interfaceRegionRecoveryBridge
-
recoverUnconsumedForLoopInits
public List<Statement> recoverUnconsumedForLoopInits(IRBlock header)
Description copied from interface:RegionRecoveryBridgeThe still-unconsumed for-induction inits ofheader's preheader.- Specified by:
recoverUnconsumedForLoopInitsin interfaceRegionRecoveryBridge- Parameters:
header- the loop header whose preheader holds the inits- Returns:
- the init declarations, empty when none remain
-
stackPhiCopiesOnEdge
public List<Statement> stackPhiCopiesOnEdge(IRBlock pred, IRBlock succ)
Copies forsucc's operand-stack merge phis whose incoming on this edge no instruction inpredproduces.- Specified by:
stackPhiCopiesOnEdgein interfaceRegionRecoveryBridge- Parameters:
pred- the source block of the edgesucc- the merge block whose stack phis are lowered- Returns:
- the copies that arm owes the merge, empty when the arm already produced them
-
recoverCondition
public Expression recoverCondition(IRBlock block, boolean negate)
Description copied from interface:RegionRecoveryBridgeThe branch condition ofblock, negated whennegateis set.- Specified by:
recoverConditionin interfaceRegionRecoveryBridge- Parameters:
block- the block terminated by the branchnegate- whether to recover the complement- Returns:
- the condition expression
-
conditionInlinesSideEffect
public boolean conditionInlinesSideEffect(IRBlock block)
Description copied from interface:RegionRecoveryBridgeTrue when recoveringblock's branch condition would inline an allocation or call - a side effect a shared-tail guard must not duplicate by re-emitting the condition.- Specified by:
conditionInlinesSideEffectin interfaceRegionRecoveryBridge- Parameters:
block- the block whose branch condition is inspected- Returns:
- true when re-emitting the condition would repeat a side effect
-
guardAtomExceptionFree
public boolean guardAtomExceptionFree(IRBlock block)
Description copied from interface:RegionRecoveryBridgeTrue when recoveringblock's branch condition inlines no operation that can throw.- Specified by:
guardAtomExceptionFreein interfaceRegionRecoveryBridge- Parameters:
block- the block whose branch condition is inspected- Returns:
- true when the condition inlines nothing that can throw
-
isDuplicationSafe
public boolean isDuplicationSafe(IRBlock block)
Description copied from interface:RegionRecoveryBridgeTrue whenblockmay be duplicated - re-recovered once per reaching edge - without changing semantics or perturbing the round trip.- Specified by:
isDuplicationSafein interfaceRegionRecoveryBridge- Parameters:
block- the block a region would re-recover per reaching edge- Returns:
- true when duplicating it is safe
-
regionContainsUnprocessedHandler
public boolean regionContainsUnprocessedHandler(Set<IRBlock> region)
Description copied from interface:RegionRecoveryBridgeTrue when some block inregionstarts an exception handler the surrounding recovery has not yet consumed - a nested try the engine must decline so the try/catch scaffolding recovers it.- Specified by:
regionContainsUnprocessedHandlerin interfaceRegionRecoveryBridge- Parameters:
region- the blocks under consideration- Returns:
- true when one of them starts an unconsumed handler
-
-