From e575070f2f513051d2937bf2f6031e400eb6a82e Mon Sep 17 00:00:00 2001 From: shirosaki Date: Mon, 5 Nov 2012 15:24:07 +0000 Subject: [PATCH] Expose whether two arrays are shared * array.c (rb_ary_shared_with_p): new function. Expose whether two arrays are shared (read-only, C only). * include/ruby/intern.h (rb_ary_shared_with_p): declare. Patch by Greg Price. [ruby-core:47970] [Bug #7158] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37478 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 9 +++++++++ array.c | 16 ++++++++++++++++ include/ruby/intern.h | 1 + load.c | 2 +- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a6c57f4205..da540779a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Mon Nov 5 23:23:51 2012 Greg Price + + * array.c (rb_ary_shared_with_p): new function. + Expose whether two arrays are shared (read-only, C only). + + * include/ruby/intern.h (rb_ary_shared_with_p): declare. + Patch by Greg Price. + [ruby-core:47970] [Bug #7158] + Mon Nov 5 23:21:14 2012 Greg Price * load.c (loaded_feature_path): clarify and briefly comment diff --git a/array.c b/array.c index 1d526644c7..4442e20c04 100644 --- a/array.c +++ b/array.c @@ -305,6 +305,22 @@ rb_ary_frozen_p(VALUE ary) return Qfalse; } +/* This can be used to take a snapshot of an array (with + e.g. rb_ary_replace) and check later whether the array has been + modified from the snapshot. The snapshot is cheap, though if + something does modify the array it will pay the cost of copying + it. */ +VALUE +rb_ary_shared_with_p(VALUE ary1, VALUE ary2) +{ + if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) + && !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) + && RARRAY(ary1)->as.heap.aux.shared == RARRAY(ary2)->as.heap.aux.shared) { + return Qtrue; + } + return Qfalse; +} + static VALUE ary_alloc(VALUE klass) { diff --git a/include/ruby/intern.h b/include/ruby/intern.h index f954232b48..1b3179fbc6 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -56,6 +56,7 @@ VALUE rb_ary_tmp_new(long); void rb_ary_free(VALUE); void rb_ary_modify(VALUE); VALUE rb_ary_freeze(VALUE); +VALUE rb_ary_shared_with_p(VALUE, VALUE); VALUE rb_ary_aref(int, VALUE*, VALUE); VALUE rb_ary_subseq(VALUE, long, long); void rb_ary_store(VALUE, long, VALUE); diff --git a/load.c b/load.c index a2e36861e8..54629983e8 100644 --- a/load.c +++ b/load.c @@ -88,7 +88,7 @@ loaded_feature_path(const char *name, long vlen, const char *feature, long len, long plen; const char *e; - if (vlen < len+1) return 0 + if (vlen < len+1) return 0; if (!strncmp(name+(vlen-len), feature, len)) { plen = vlen - len - 1; }