Interface Misc


public interface Misc
Miscellaneous utilities
  • Method Details

    • cast1

      static <T1 extends Types.BNonVoid, N1 extends Emitter.Next, N0 extends Emitter.Ent<N1, T1>> Emitter<Emitter.Ent<N1,T1>> cast1(Emitter<N0> em)
      Fix the top of the stack, so it doesn't "extend" Emitter.Ent, but just is Emitter.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 stack
      N1 - the tail of the stack
      N0 - 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 block

      This places a label to mark the start of the try block. 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., using Lbl#placeDead(Emitter, Lbl).

      Type Parameters:
      T - the type caught by the block
      N - the stack contents at the bounds of the try block
      Parameters:
      em - the emitter
      end - the end label, often just Lbl.create().
      handler - the handler label, often just Lbl.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

      static <N extends Emitter.Next> Emitter<N> lineNumber(Emitter<N> em, int number)
      Place a line number
      Type Parameters:
      N - any live stack
      Parameters:
      em - the emitter
      number - the (non zero) line number
      Returns:
      the emitter
    • finish

      static Void finish(Emitter<Emitter.Dead> em)
      Finish emitting bytecode

      This is where we invoke MethodVisitor.visitMaxs(int, int). Frameworks that require bytecode generation can try to enforce this by requiring bytecode generation methods to return Void. 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 finish missing. Provided the generation method returns Void, this pattern should compile.

      Parameters:
      em - the emittter
      Returns:
      null