compile.c, vm_insnhelper.c: flip-flop without hidden string key
* 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/trunk@38292 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2ffc29e864
commit
c9b4b78085
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
Mon Dec 10 15:11:06 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.
|
||||||
|
|
||||||
Mon Dec 10 10:36:12 2012 Narihiro Nakamura <authornari@gmail.com>
|
Mon Dec 10 10:36:12 2012 Narihiro Nakamura <authornari@gmail.com>
|
||||||
|
|
||||||
* lib/irb/magic-file.rb: set a encoding, which is detected from
|
* lib/irb/magic-file.rb: set a encoding, which is detected from
|
||||||
|
12
compile.c
12
compile.c
@ -4977,12 +4977,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
LABEL *lend = NEW_LABEL(nd_line(node));
|
LABEL *lend = NEW_LABEL(nd_line(node));
|
||||||
LABEL *lfin = NEW_LABEL(nd_line(node));
|
LABEL *lfin = NEW_LABEL(nd_line(node));
|
||||||
LABEL *ltrue = NEW_LABEL(nd_line(node));
|
LABEL *ltrue = NEW_LABEL(nd_line(node));
|
||||||
VALUE key = rb_sprintf("flipflag/%s-%p-%d",
|
struct iseq_compile_data *data = iseq->local_iseq->compile_data;
|
||||||
RSTRING_PTR(iseq->location.label), (void *)iseq,
|
rb_num_t cnt;
|
||||||
iseq->compile_data->flip_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_INSN2(ret, nd_line(node), getspecial, key, INT2FIX(0));
|
||||||
ADD_INSNL(ret, nd_line(node), branchif, lend);
|
ADD_INSNL(ret, nd_line(node), branchif, lend);
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ setlocal
|
|||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
getspecial
|
getspecial
|
||||||
(VALUE key, rb_num_t type)
|
(rb_num_t key, rb_num_t type)
|
||||||
()
|
()
|
||||||
(VALUE val)
|
(VALUE val)
|
||||||
{
|
{
|
||||||
@ -109,7 +109,7 @@ getspecial
|
|||||||
*/
|
*/
|
||||||
DEFINE_INSN
|
DEFINE_INSN
|
||||||
setspecial
|
setspecial
|
||||||
(VALUE key)
|
(rb_num_t key)
|
||||||
(VALUE obj)
|
(VALUE obj)
|
||||||
()
|
()
|
||||||
{
|
{
|
||||||
|
4
iseq.c
4
iseq.c
@ -231,6 +231,10 @@ set_relation(rb_iseq_t *iseq, const VALUE parent)
|
|||||||
GetISeqPtr(parent, piseq);
|
GetISeqPtr(parent, piseq);
|
||||||
iseq->parent_iseq = piseq;
|
iseq->parent_iseq = piseq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == ISEQ_TYPE_MAIN) {
|
||||||
|
iseq->local_iseq = iseq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
2
iseq.h
2
iseq.h
@ -131,6 +131,8 @@ enum defined_type {
|
|||||||
|
|
||||||
VALUE rb_iseq_defined_string(enum defined_type type);
|
VALUE rb_iseq_defined_string(enum defined_type type);
|
||||||
|
|
||||||
|
#define DEFAULT_SPECIAL_VAR_COUNT 2
|
||||||
|
|
||||||
#if defined __GNUC__ && __GNUC__ >= 4
|
#if defined __GNUC__ && __GNUC__ >= 4
|
||||||
#pragma GCC visibility pop
|
#pragma GCC visibility pop
|
||||||
#endif
|
#endif
|
||||||
|
13
test/ruby/test_flip.rb
Normal file
13
test/ruby/test_flip.rb
Normal file
@ -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
|
@ -180,7 +180,7 @@ lep_svar_place(rb_thread_t *th, VALUE *lep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
lep_svar_get(rb_thread_t *th, VALUE *lep, VALUE key)
|
lep_svar_get(rb_thread_t *th, VALUE *lep, rb_num_t key)
|
||||||
{
|
{
|
||||||
NODE *svar = lep_svar_place(th, lep);
|
NODE *svar = lep_svar_place(th, lep);
|
||||||
|
|
||||||
@ -190,20 +190,20 @@ lep_svar_get(rb_thread_t *th, VALUE *lep, VALUE key)
|
|||||||
case 1:
|
case 1:
|
||||||
return svar->u2.value;
|
return svar->u2.value;
|
||||||
default: {
|
default: {
|
||||||
const VALUE hash = svar->u3.value;
|
const VALUE ary = svar->u3.value;
|
||||||
|
|
||||||
if (hash == Qnil) {
|
if (NIL_P(ary)) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return rb_hash_lookup(hash, key);
|
return rb_ary_entry(ary, key - DEFAULT_SPECIAL_VAR_COUNT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
lep_svar_set(rb_thread_t *th, VALUE *lep, VALUE key, VALUE val)
|
lep_svar_set(rb_thread_t *th, VALUE *lep, rb_num_t key, VALUE val)
|
||||||
{
|
{
|
||||||
NODE *svar = lep_svar_place(th, lep);
|
NODE *svar = lep_svar_place(th, lep);
|
||||||
|
|
||||||
@ -215,27 +215,23 @@ lep_svar_set(rb_thread_t *th, VALUE *lep, VALUE key, VALUE val)
|
|||||||
svar->u2.value = val;
|
svar->u2.value = val;
|
||||||
return;
|
return;
|
||||||
default: {
|
default: {
|
||||||
VALUE hash = svar->u3.value;
|
VALUE ary = svar->u3.value;
|
||||||
|
|
||||||
if (hash == Qnil) {
|
if (NIL_P(ary)) {
|
||||||
svar->u3.value = hash = rb_hash_new();
|
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
|
static inline VALUE
|
||||||
vm_getspecial(rb_thread_t *th, VALUE *lep, VALUE key, rb_num_t type)
|
vm_getspecial(rb_thread_t *th, VALUE *lep, rb_num_t key, rb_num_t type)
|
||||||
{
|
{
|
||||||
VALUE val;
|
VALUE val;
|
||||||
|
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
VALUE k = key;
|
val = lep_svar_get(th, lep, key);
|
||||||
if (FIXNUM_P(key)) {
|
|
||||||
k = FIX2INT(key);
|
|
||||||
}
|
|
||||||
val = lep_svar_get(th, lep, k);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE backref = lep_svar_get(th, lep, 1);
|
VALUE backref = lep_svar_get(th, lep, 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user