Backport #6899

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

Added by Matthias Schwarze over 1 year ago. Updated over 1 year 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 irbbinding'
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 38317
Added by Usaku NAKAMURA over 1 year 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 1 year 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 @@ iseqcompileeach(rbiseqt *iseq, LINKANCHOR *ret, NODE * node, int poped)
RSTRING
PTR(iseq->location.label), (void *)iseq,
iseq->compiledata->flipcnt++);

  • hide_obj(key);
  • rbobjfreeze(key); iseqaddmarkobjectcompiletime(iseq, key); ADDINSN2(ret, ndline(node), getspecial, key, INT2FIX(0)); ADDINSNL(ret, nd_line(node), branchif, lend);

Yusuke Endoh mame@tsg.ne.jp

#2 Updated by Bohuslav Kabrda over 1 year ago

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

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

The above patch fixes the issue.

#3 Updated by Nobuyoshi Nakada over 1 year ago

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

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 (iseqcompileeach): count flip-flop state in local iseq not in each iseqs, so that the keys can be other than hidden strings. [Bug #6899]
  • vminsnhelper.c (lepsvarget, lepsvarset, vmgetspecial): 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 1 year ago

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

#5 Updated by Usaku NAKAMURA over 1 year 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