docs: @JRubyMethod(optional = 1, frame = true)
      public static IRubyObject emit(IRubyObject self, IRubyObject[] _oid, Block proc) {
          Ruby runtime = self.getRuntime();
          int level = RubyNumeric.fix2int((IRubyObject)((RubyObject)self).fastGetInstanceVariable("@level")) + 1;
          ((RubyObject)self).fastSetInstanceVariable("@level", runtime.newFixnum(level));
          ThreadContext ctx = runtime.getCurrentContext();
          Emitter emitter = (Emitter)self.dataGetStructChecked();
          Extra bonus = (Extra)emitter.bonus;
  
          IRubyObject oid = _oid.length == 0 ? runtime.getNil() : _oid[0];
              
          bonus.oid = oid;
          IRubyObject symple;
          if(!oid.isNil() && bonus.data.callMethod(ctx, "has_key?", oid).isTrue()) {
              symple = ((RubyHash)bonus.data).op_aref(ctx, oid);
          } else {
              symple = proc.yield(ctx, (IRubyObject)((RubyObject)self).fastGetInstanceVariable("@out"));
          }
          emitter.markNode(symple);
  
          level--;
          ((RubyObject)self).fastSetInstanceVariable("@level", runtime.newFixnum(level));
          if(level == 0) {
              emitter.emit(symple);
              emitter.flush(0);
              return bonus.port;
          }
          return symple;
      }