Interface Misc
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic final recordMisc.TryCatchBlock<T extends Throwable,N extends Emitter.Next> A handle to an (incomplete)try-catchblock -
Method Summary
Static MethodsModifier and TypeMethodDescriptionstatic <T1 extends Types.BNonVoid,N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, T1>>
Emitter<Emitter.Ent<N1, T1>> Fix the top of the stack, so it doesn't "extend"Emitter.Ent, but just isEmitter.Ent.static Voidfinish(Emitter<Emitter.Dead> em) Finish emitting bytecodestatic <N extends Emitter.Next>
Emitter<N> lineNumber(Emitter<N> em, int number) Place a line numberstatic <T extends Throwable,N extends Emitter.Next>
Misc.TryCatchBlock<T, N> tryCatch(Emitter<N> em, Lbl<N> end, Lbl<Emitter.Ent<N, Types.TRef<T>>> handler, Types.TRef<T> type) Start a try-catch block
-
Method Details
-
cast1
static <T1 extends Types.BNonVoid,N1 extends Emitter.Next, Emitter<Emitter.Ent<N1,N0 extends Emitter.Ent<N1, T1>> T1>> cast1(Emitter<N0> em) Fix the top of the stack, so it doesn't "extend"Emitter.Ent, but just isEmitter.Ent.This may be necessary when a code generating method is typed to pop then push something of the same type, but in some conditions actually just leaves the stack as is.
- Type Parameters:
T1- the type at the top of the stackN1- the tail of the stackN0- the full stack- Parameters:
em- the emitter- Returns:
- the same emitter
-
tryCatch
static <T extends Throwable,N extends Emitter.Next> Misc.TryCatchBlock<T,N> tryCatch(Emitter<N> em, Lbl<N> end, Lbl<Emitter.Ent<N, Types.TRef<T>>> handler, Types.TRef<T> type) Start a try-catch blockThis places a label to mark the start of the
tryblock. The user must provide labels for the end and the handler. Note that the stack contents at the handler must be the same as at the bounds, but with the exception type pushed. While this can check that the labels are correctly placed, it cannot check if placement is altogether forgotten. Ideally, the handler label is placed where code is otherwise unreachable, i.e., usingLbl#placeDead(Emitter, Lbl).- Type Parameters:
T- the type caught by the blockN- the stack contents at the bounds of thetryblock- Parameters:
em- the emitterend- the end label, often justLbl.create().handler- the handler label, often justLbl.create()type- the exception type. If multiple types are caught, this must be the join of those types, and the user must emit code to distinguish each, possibly re-throwing if the join is larger than the union.- Returns:
- a handle to the block.
-
lineNumber
Place a line number- Type Parameters:
N- any live stack- Parameters:
em- the emitternumber- the (non zero) line number- Returns:
- the emitter
-
finish
Finish emitting bytecodeThis is where we invoke
MethodVisitor.visitMaxs(int, int). Frameworks that require bytecode generation can try to enforce this by requiring bytecode generation methods to returnVoid. Sure, a user can just return null, but this will at least remind them that they should call this method, as convention is to use a pattern like:return em .emit(Op::ldc__i, 0) .emit(Op::ireturn, retReq) .emit(Misc::finish);A user of this pattern would be reminded were
finishmissing. Provided the generation method returnsVoid, this pattern should compile.- Parameters:
em- the emittter- Returns:
- null
-