summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-11 09:51:43 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-11 09:51:43 +0000
commit35f2714452975d567a966b3e8614a203eac8f099 (patch)
tree556975cb00ac4b40ac198fd128cfa85e2c1bf6cd
parent985a8067cda379847bab32b36c3fd8c54740b42e (diff)
merge revision(s) 38292: [Backport #6899]
* compile.c (iseq_compile_each): count flip-flop state in local iseq not in each iseqs, so that the keys can be other than hidden strings. [ruby-core:47253] [Bug #6899] * vm_insnhelper.c (lep_svar_get, lep_svar_set, vm_getspecial): store flip-flop states in an array instead of a hash. * iseq.c (set_relation): main iseq also can has local scope. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@38317 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog11
-rw-r--r--compile.c12
-rw-r--r--insns.def4
-rw-r--r--iseq.c4
-rw-r--r--iseq.h2
-rw-r--r--test/ruby/test_flip.rb13
-rw-r--r--version.h2
-rw-r--r--vm_insnhelper.c26
8 files changed, 51 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index d5eea36e9b..fd97290b2e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Tue Dec 11 17:53:55 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * compile.c (iseq_compile_each): count flip-flop state in local iseq
+ not in each iseqs, so that the keys can be other than hidden
+ strings. [ruby-core:47253] [Bug #6899]
+
+ * vm_insnhelper.c (lep_svar_get, lep_svar_set, vm_getspecial): store
+ flip-flop states in an array instead of a hash.
+
+ * iseq.c (set_relation): main iseq also can has local scope.
+
Tue Dec 11 17:52:30 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
* include/ruby/backward/rubysig.h: fix visibility. [Bug #6607]
diff --git a/compile.c b/compile.c
index f4211ed860..74c9ef98f5 100644
--- a/compile.c
+++ b/compile.c
@@ -4844,12 +4844,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
LABEL *lend = NEW_LABEL(nd_line(node));
LABEL *lfin = NEW_LABEL(nd_line(node));
LABEL *ltrue = NEW_LABEL(nd_line(node));
- VALUE key = rb_sprintf("flipflag/%s-%p-%d",
- RSTRING_PTR(iseq->name), (void *)iseq,
- iseq->compile_data->flip_cnt++);
+ struct iseq_compile_data *data = iseq->local_iseq->compile_data;
+ rb_num_t cnt;
+ VALUE key;
+
+ if (!data) data = iseq->compile_data;
+ cnt = data->flip_cnt++ + DEFAULT_SPECIAL_VAR_COUNT;
+ key = INT2FIX(cnt);
- hide_obj(key);
- iseq_add_mark_object_compile_time(iseq, key);
ADD_INSN2(ret, nd_line(node), getspecial, key, INT2FIX(0));
ADD_INSNL(ret, nd_line(node), branchif, lend);
diff --git a/insns.def b/insns.def
index 49faec5d09..feeb74bc7d 100644
--- a/insns.def
+++ b/insns.def
@@ -79,7 +79,7 @@ setlocal
*/
DEFINE_INSN
getspecial
-(VALUE key, rb_num_t type)
+(rb_num_t key, rb_num_t type)
()
(VALUE val)
{
@@ -93,7 +93,7 @@ getspecial
*/
DEFINE_INSN
setspecial
-(VALUE key)
+(rb_num_t key)
(VALUE obj)
()
{
diff --git a/iseq.c b/iseq.c
index 73806630b5..721277a7d3 100644
--- a/iseq.c
+++ b/iseq.c
@@ -216,6 +216,10 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
GetISeqPtr(parent, piseq);
iseq->parent_iseq = piseq;
}
+
+ if (type == ISEQ_TYPE_MAIN) {
+ iseq->local_iseq = iseq;
+ }
}
static VALUE
diff --git a/iseq.h b/iseq.h
index beeacbb236..85336d93d8 100644
--- a/iseq.h
+++ b/iseq.h
@@ -118,6 +118,8 @@ enum defined_type {
DEFINED_FUNC
};
+#define DEFAULT_SPECIAL_VAR_COUNT 2
+
#if defined __GNUC__ && __GNUC__ >= 4
#pragma GCC visibility pop
#endif
diff --git a/test/ruby/test_flip.rb b/test/ruby/test_flip.rb
new file mode 100644
index 0000000000..8d7cdd03ad
--- /dev/null
+++ b/test/ruby/test_flip.rb
@@ -0,0 +1,13 @@
+require 'test/unit'
+require_relative 'envutil'
+
+class TestFlip < Test::Unit::TestCase
+ def test_hidden_key
+ bug6899 = '[ruby-core:47253]'
+ foo = "foor"
+ bar = "bar"
+ assert_nothing_raised(NotImplementedError, bug6899) do
+ 2000.times {eval %[(foo..bar) ? 1 : 2]}
+ end
+ end
+end
diff --git a/version.h b/version.h
index 333ae4d7e6..177923131c 100644
--- a/version.h
+++ b/version.h
@@ -1,5 +1,5 @@
#define RUBY_VERSION "1.9.3"
-#define RUBY_PATCHLEVEL 335
+#define RUBY_PATCHLEVEL 336
#define RUBY_RELEASE_DATE "2012-12-11"
#define RUBY_RELEASE_YEAR 2012
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 55152df2d9..4f709e6291 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -981,7 +981,7 @@ lfp_svar_place(rb_thread_t *th, VALUE *lfp)
}
static VALUE
-lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key)
+lfp_svar_get(rb_thread_t *th, VALUE *lfp, rb_num_t key)
{
NODE *svar = lfp_svar_place(th, lfp);
@@ -991,20 +991,20 @@ lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key)
case 1:
return svar->u2.value;
default: {
- const VALUE hash = svar->u3.value;
+ const VALUE ary = svar->u3.value;
- if (hash == Qnil) {
+ if (NIL_P(ary)) {
return Qnil;
}
else {
- return rb_hash_lookup(hash, key);
+ return rb_ary_entry(ary, key - DEFAULT_SPECIAL_VAR_COUNT);
}
}
}
}
static void
-lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val)
+lfp_svar_set(rb_thread_t *th, VALUE *lfp, rb_num_t key, VALUE val)
{
NODE *svar = lfp_svar_place(th, lfp);
@@ -1016,27 +1016,23 @@ lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val)
svar->u2.value = val;
return;
default: {
- VALUE hash = svar->u3.value;
+ VALUE ary = svar->u3.value;
- if (hash == Qnil) {
- svar->u3.value = hash = rb_hash_new();
+ if (NIL_P(ary)) {
+ svar->u3.value = ary = rb_ary_new();
}
- rb_hash_aset(hash, key, val);
+ rb_ary_store(ary, key - DEFAULT_SPECIAL_VAR_COUNT, val);
}
}
}
static inline VALUE
-vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type)
+vm_getspecial(rb_thread_t *th, VALUE *lfp, rb_num_t key, rb_num_t type)
{
VALUE val;
if (type == 0) {
- VALUE k = key;
- if (FIXNUM_P(key)) {
- k = FIX2INT(key);
- }
- val = lfp_svar_get(th, lfp, k);
+ val = lfp_svar_get(th, lfp, key);
}
else {
VALUE backref = lfp_svar_get(th, lfp, 1);