Backport #6899

Flip flop operator broken in IRB (1.9.3, win/osx)

Added by Matthias Schwarze almost 3 years ago. Updated over 2 years ago.

[ruby-core:47253]
Status:Closed
Priority:Normal
Assignee:Usaku NAKAMURA

Description

IRB sometimes fails with "NotImplementedError: method `eql?' called on hidden T_STRING object"

When running this code in IRB, you either get the correct bunch of "345..." or you get the error message above:

2000.times do 20.times do |x| print x if x==3..x==5 end end

You may have to repeat the command several times to get the error!
This does not seem to happen when running this as a script with ruby - just with IRB!

Fresh install of ruby 1.9.3p194 (windows 7: OneClickInstaller / OSX: RVM)
No gems installed or loaded!

Full stack trace:
NotImplementedError: method eql?' called on hidden T_STRING object (0x007f9fd18f2460 flags=0x2805 klass=0x0)
from (irb):46:in
block (2 levels) in irb_binding'
from (irb):46:in times'
from (irb):46:in
block in irb_binding'
from (irb):46:in times'
from (irb):46
from /Users/schwarze/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in
'

Associated revisions

Revision 38292
Added by Nobuyoshi Nakada over 2 years ago

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. [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.

Revision 38317
Added by Usaku NAKAMURA over 2 years ago

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.   [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.

History

#1 Updated by Yusuke Endoh over 2 years ago

  • Status changed from Open to Assigned
  • Assignee set to Nobuyoshi Nakada
  • Target version set to 2.0.0

Confirmed. Good catch! A simplified example:

$ ruby -e 'eval("x = 1; " + "if x==1..x==2;end;" * 1000000)'
-e:1:in eval': methodeql?' called on hidden T_STRING object (0x000000210d9488 flags=0x2805 klass=0x0) (NotImplementedError)
from -e:1:in eval'
from -e:1:in
'

I guess that this is caused by the "hidden string" for flipflop's internal variable name.
The following patch stops the exception, though it makes the string visible for ObjectSpace.
Nobu, what do you think?

diff --git a/compile.c b/compile.c
index 16bfcef..3924948 100644
--- a/compile.c
+++ b/compile.c
@@ -4965,7 +4965,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
RSTRING_PTR(iseq->location.label), (void *)iseq,
iseq->compile_data->flip_cnt++);

  • hide_obj(key);
  • rb_obj_freeze(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);

Yusuke Endoh mame@tsg.ne.jp

#2 Updated by Anonymous over 2 years ago

I'm experiencing this issue on ruby-1.9.3p327 during test suite run on armv7:

31) Failure:
test_literal_in_conditional(TestParse) [/builddir/build/BUILD/ruby-1.9.3-p327/test/ruby/test_parse.rb:787]:
Exception raised:
<#>.

The above patch fixes the issue.

#3 Updated by Nobuyoshi Nakada over 2 years ago

  • % Done changed from 0 to 100
  • Status changed from Assigned to Closed

This issue was solved with changeset r38292.
Matthias, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


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. [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.

#4 Updated by Nobuyoshi Nakada over 2 years ago

  • Project changed from Ruby trunk to Backport193
  • Status changed from Closed to Assigned
  • Assignee changed from Nobuyoshi Nakada to Usaku NAKAMURA
  • Target version deleted (2.0.0)
  • Tracker changed from Bug to Backport

#5 Updated by Usaku NAKAMURA over 2 years ago

  • Status changed from Assigned to Closed

This issue was solved with changeset r38317.
Matthias, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


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.   [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.

Also available in: Atom PDF