summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--array.c12
-rw-r--r--internal.h16
-rw-r--r--vm_insnhelper.c7
3 files changed, 23 insertions, 12 deletions
diff --git a/array.c b/array.c
index 7ce72f9fa9..2789acd56f 100644
--- a/array.c
+++ b/array.c
@@ -1209,17 +1209,7 @@ rb_ary_elt(VALUE ary, long offset)
VALUE
rb_ary_entry(VALUE ary, long offset)
{
- long len = RARRAY_LEN(ary);
- const VALUE *ptr = RARRAY_CONST_PTR(ary);
- if (len == 0) return Qnil;
- if (offset < 0) {
- offset += len;
- if (offset < 0) return Qnil;
- }
- else if (len <= offset) {
- return Qnil;
- }
- return ptr[offset];
+ return rb_ary_entry_internal(ary, offset);
}
VALUE
diff --git a/internal.h b/internal.h
index 88a1f9210e..3ca1352505 100644
--- a/internal.h
+++ b/internal.h
@@ -1093,6 +1093,22 @@ VALUE rb_check_to_array(VALUE ary);
})
#endif
+static inline VALUE
+rb_ary_entry_internal(VALUE ary, long offset)
+{
+ long len = RARRAY_LEN(ary);
+ const VALUE *ptr = RARRAY_CONST_PTR(ary);
+ if (len == 0) return Qnil;
+ if (offset < 0) {
+ offset += len;
+ if (offset < 0) return Qnil;
+ }
+ else if (len <= offset) {
+ return Qnil;
+ }
+ return ptr[offset];
+}
+
/* bignum.c */
extern const char ruby_digitmap[];
double rb_big_fdiv_double(VALUE x, VALUE y);
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index a0f63dfbc4..415070f852 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -3647,7 +3647,12 @@ vm_opt_aref(VALUE recv, VALUE obj)
}
else if (RBASIC_CLASS(recv) == rb_cArray &&
BASIC_OP_UNREDEFINED_P(BOP_AREF, ARRAY_REDEFINED_OP_FLAG)) {
- return rb_ary_aref1(recv, obj);
+ if (FIXNUM_P(obj)) {
+ return rb_ary_entry_internal(recv, FIX2LONG(obj));
+ }
+ else {
+ return rb_ary_aref1(recv, obj);
+ }
}
else if (RBASIC_CLASS(recv) == rb_cHash &&
BASIC_OP_UNREDEFINED_P(BOP_AREF, HASH_REDEFINED_OP_FLAG)) {