string.c:888
static VALUE
rb_str_index_m(argc, argv, str)
    int argc;
    VALUE *argv;
    VALUE str;
{
    VALUE sub;
    VALUE initpos;
    long pos;

    if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) {
	pos = NUM2LONG(initpos);
    }
    else {
	pos = 0;
    }
    if (pos < 0) {
	pos += RSTRING(str)->len;
	if (pos < 0) {
	    if (TYPE(sub) == T_REGEXP) {
		rb_backref_set(Qnil);
	    }
	    return Qnil;
	}
    }

    switch (TYPE(sub)) {
      case T_REGEXP:
	pos = rb_reg_adjust_startpos(sub, str, pos, 0);
	pos = rb_reg_search(sub, str, pos, 0);
	break;

      case T_FIXNUM:
      {
	  int c = FIX2INT(sub);
	  long len = RSTRING(str)->len;
	  char *p = RSTRING(str)->ptr;

	  for (;pos<len;pos++) {
	      if (p[pos] == c) return LONG2NUM(pos);
	  }
	  return Qnil;
      }

      default: {
	  VALUE tmp;

	  tmp = rb_check_string_type(sub);
	  if (NIL_P(tmp)) {
	      rb_raise(rb_eTypeError, "type mismatch: %s given",
		       rb_obj_classname(sub));
	  }
	  sub = tmp;
      }
	/* fall through */
      case T_STRING:
	pos = rb_str_index(str, sub, pos);
	break;
    }

    if (pos == -1) return Qnil;
    return LONG2NUM(pos);
}
