private void compileCatchStatements(
      MethodVisitor mv,
      Label tryStart,
      Label tryEnd,
      Label tryCatchEnd,
      List<IRCatchClause> catchStmts) {
    for (int i = 0; i < catchStmts.size(); i++) {
      IRCatchClause catchStmt = catchStmts.get(i);
      _context.pushScope(); // scope for the exception param
      try {
        IRType type = catchStmt.getIdentifier().getType();
        Label catchStart =
            new NamedLabel("CatchStart for " + (type == null ? "(no type)" : type.getName()));
        _context.visitLabel(catchStart);

        declareCatchExtents(mv, tryStart, tryEnd, catchStart, type);

        assignExceptionParam(mv, catchStmt.getIdentifier());
        IRBytecodeCompiler.compileIRStatement(catchStmt.getBody(), _context);

        inlineLocalFinallyStmt(catchStmt.getBody(), tryCatchEnd);
      } finally {
        _context.popScope();
      }
    }
  }
 private void insertTryCatchBlock(
     MethodVisitor mv, Label handlerStart, IRType type, Label start, Label end) {
   if (start.getOffset() > end.getOffset()) {
     throw new IllegalStateException("start label must precede the end label");
   } else if (start.getOffset()
       != end
           .getOffset()) { // If start == end, then we want to ignore it and not generate any
                           // exception table entry
     mv.visitTryCatchBlock(start, end, handlerStart, type.getSlashName());
   }
 }