Class StatementWriter
- Direct Known Subclasses:
OptimizingStatementWriter,StaticTypesStatementWriter
WriterController.
Handles control flow (loops, branches, try/catch), synchronization, assertions,
and expression statements.-
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final WriterControllerThe controller coordinating all bytecode writers for the current class. -
Constructor Summary
ConstructorsConstructorDescriptionStatementWriter(WriterController controller) Creates a statement writer backed by the given controller. -
Method Summary
Modifier and TypeMethodDescriptionprotected final BytecodeVariabledefineLoopIndexVariable(ForStatement statement) protected final voidincrementForLoopIndexVariable(BytecodeVariable indexVariable) Increments the for-in index variable by one.protected final voidstoreForLoopVariable(BytecodeVariable variable) Stores the top-of-stack value into a for-in loop variable slot.voidwriteAssert(AssertStatement statement) Generates bytecode for an assert statement.voidGenerates bytecode for a block statement by visiting each contained statement.voidwriteBreak(BreakStatement statement) Generates bytecode for a break statement, applying any intervening finally blocks before the jump.voidwriteContinue(ContinueStatement statement) Generates bytecode for a continue statement, applying any intervening finally blocks before the jump.voidwriteDoWhileLoop(DoWhileStatement statement) Generates bytecode for a do-while loop.voidwriteExpressionStatement(ExpressionStatement statement) Generates bytecode for an expression statement.protected voidwriteForInLoop(ForStatement statement) Generates bytecode for a for-in loop by callingiterator()on the collection expression and delegating loop control towriteForInLoopControlAndBlock(org.codehaus.groovy.ast.stmt.ForStatement).protected voidwriteForInLoopControlAndBlock(ForStatement statement) Emits the loop-control structure and body for a for-in loop.protected voidwriteForLoopWithClosureList(ForStatement statement) Generates bytecode for a C-stylefor(init; cond; incr)loop.voidwriteForStatement(ForStatement statement) Generates bytecode for a for statement.voidwriteIfElse(IfStatement statement) Generates bytecode for an if/else statement.protected voidwriteIteratorHasNext(org.objectweb.asm.MethodVisitor mv) Emits theIterator.hasNext()call via the given visitor.protected voidwriteIteratorNext(org.objectweb.asm.MethodVisitor mv) Emits theIterator.next()call via the given visitor.protected final voidwriteLoopBackEdge(org.objectweb.asm.Label continueLabel, boolean bodyMayReachContinue) voidwriteReturn(ReturnStatement statement) Generates bytecode for a return statement.protected voidwriteStatementLabel(Statement statement) Emits bytecode labels for any statement labels attached tostatement.voidwriteSwitch(SwitchStatement statement) Generates bytecode for a switch statement.voidwriteSynchronized(SynchronizedStatement statement) Generates bytecode for a synchronized statement.voidwriteThrow(ThrowStatement statement) Generates bytecode for a throw statement.voidwriteTryCatchFinally(TryCatchStatement statement) Generates bytecode for a try/catch/finally statement.voidwriteWhileLoop(WhileStatement statement) Generates bytecode for a while loop.
-
Field Details
-
controller
The controller coordinating all bytecode writers for the current class.
-
-
Constructor Details
-
StatementWriter
Creates a statement writer backed by the given controller.- Parameters:
controller- the writer controller for the current compilation
-
-
Method Details
-
writeStatementLabel
Emits bytecode labels for any statement labels attached tostatement. Called before emitting the body of every statement so that named labels (break foo/continue foo) resolve correctly.- Parameters:
statement- the statement whose labels should be emitted
-
writeBlockStatement
Generates bytecode for a block statement by visiting each contained statement. Pushes the block's variable scope, emits the statements, and pops afterward. Named labels on the block create a breakable region so thatbreak labelwithin the block jumps to the end of it.- Parameters:
block- the block statement to compile
-
writeForStatement
Generates bytecode for a for statement. Delegates towriteForLoopWithClosureList(org.codehaus.groovy.ast.stmt.ForStatement)for C-style loops (using aClosureListExpression), or towriteForInLoop(org.codehaus.groovy.ast.stmt.ForStatement)for for-in loops.- Parameters:
statement- the for statement to compile
-
writeForInLoop
Generates bytecode for a for-in loop by callingiterator()on the collection expression and delegating loop control towriteForInLoopControlAndBlock(org.codehaus.groovy.ast.stmt.ForStatement).- Parameters:
statement- the for-in statement to compile
-
writeForInLoopControlAndBlock
Emits the loop-control structure and body for a for-in loop. Assumes the iterator object is already on the operand stack. Declares loop variables, emits thehasNext/nextcheck-and-advance, generates the loop body, and handles index-variable increment when present.- Parameters:
statement- the for-in statement whose control and body should be emitted
-
storeForLoopVariable
Stores the top-of-stack value into a for-in loop variable slot.Applies the for-in per-iteration capture policy (
WriterController.isForInPerIterationCaptureEnabled(), GROOVY-11792): when enabled, a shared (holder) loop variable receives a freshReferenceso deferred closures, lambdas, and anonymous inner classes observe this iteration's value. When disabled, the historical in-placeReference#setpath is used. Non-holder variables always take the plain store path.Bytecode emission is delegated to
CompileStack.storeVar(BytecodeVariable, boolean).- Parameters:
variable- the for-in value (or similarly stored) loop variable
-
incrementForLoopIndexVariable
Increments the for-in index variable by one.Plain (non-shared) indexes use
IINC. Shared indexes are loaded from theirReference, unboxed, incremented, then stored viastoreForLoopVariable(BytecodeVariable)so the same per-iteration capture policy applies as for value variables (GROOVY-11751, GROOVY-11792).- Parameters:
indexVariable- the for-in index variable; must not benull
-
defineLoopIndexVariable
-
writeLoopBackEdge
protected final void writeLoopBackEdge(org.objectweb.asm.Label continueLabel, boolean bodyMayReachContinue) -
writeIteratorHasNext
protected void writeIteratorHasNext(org.objectweb.asm.MethodVisitor mv) Emits theIterator.hasNext()call via the given visitor. Overrideable so subclasses can substitute a specialized or inlined variant.- Parameters:
mv- the method visitor to write to
-
writeIteratorNext
protected void writeIteratorNext(org.objectweb.asm.MethodVisitor mv) Emits theIterator.next()call via the given visitor. Overrideable so subclasses can substitute a specialized or inlined variant.- Parameters:
mv- the method visitor to write to
-
writeForLoopWithClosureList
Generates bytecode for a C-stylefor(init; cond; incr)loop. The collection expression is aClosureListExpressionwhose middle element is the boolean condition, lower elements are initializers, and upper elements are incrementors.- Parameters:
statement- the for statement with aClosureListExpressioncollection
-
writeWhileLoop
Generates bytecode for a while loop.- Parameters:
statement- the while statement to compile
-
writeDoWhileLoop
Generates bytecode for a do-while loop.- Parameters:
statement- the do-while statement to compile
-
writeIfElse
Generates bytecode for an if/else statement.- Parameters:
statement- the if statement to compile
-
writeTryCatchFinally
Generates bytecode for a try/catch/finally statement.A
CompileStack.BlockRecorderis always registered for the try (and catch) regions so that:- a non-empty finally is inlined on every abrupt exit
(
return/break/continue); - exception-table ranges are closed before any enclosing finally is inlined (required when an inner try/catch without its own finally sits inside an outer try/finally — see GROOVY-8229);
- GROOVY-9805 stack-map casts remain active for assignments in the
region (
CompileStack.hasBlockRecorder()).
try/catch), the catch-all identity rethrow and the empty shared-finally block are omitted so the shape matches javac more closely and stays more JIT-friendly.- Parameters:
statement- the try/catch/finally statement to compile
- a non-empty finally is inlined on every abrupt exit
(
-
writeSwitch
Generates bytecode for a switch statement. Eachcaseexpression is compared using Groovy'sisCaseoperator, so non-integer switch expressions are supported.- Parameters:
statement- the switch statement to compile
-
writeBreak
Generates bytecode for a break statement, applying any intervening finally blocks before the jump.- Parameters:
statement- the break statement to compile
-
writeContinue
Generates bytecode for a continue statement, applying any intervening finally blocks before the jump.- Parameters:
statement- the continue statement to compile
-
writeSynchronized
Generates bytecode for a synchronized statement. Stores the monitor object in a local variable, emitsMONITORENTER/MONITOREXITguards, and registers a catch-all exception handler that exits the monitor before rethrowing.- Parameters:
statement- the synchronized statement to compile
-
writeAssert
Generates bytecode for an assert statement.- Parameters:
statement- the assert statement to compile
-
writeThrow
Generates bytecode for a throw statement. Casts the expression toThrowableand emitsATHROW.- Parameters:
statement- the throw statement to compile
-
writeReturn
Generates bytecode for a return statement. For void methods emitsRETURNafter applying any finally blocks. For value-returning methods evaluates the expression, casts it to the declared return type, and emits the appropriate typed return instruction.- Parameters:
statement- the return statement to compile
-
writeExpressionStatement
Generates bytecode for an expression statement. Evaluates the expression and discards any value left on the operand stack. Marks method-call and binary expressions so that unused return values are elided rather than boxed.- Parameters:
statement- the expression statement to compile
-