https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17097754782016-02-21T04:53:11ZRuby Issue Tracking SystemRuby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=570662016-02-21T04:53:11Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Project</strong> changed from <i>14</i> to <i>Ruby master</i></li></ul> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=570742016-02-22T08:06:24Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Depending on the context, an identifier may be a local variable or a method call.<br>
I think that <code>RubyVM::InstructionSequence#compile</code> would need the binding, instead of <code>#eval</code>.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=572502016-03-03T05:10:32Zshyouhei (Shyouhei Urabe)shyouhei@ruby-lang.org
<ul></ul><p>"ISeq#compile's need of binding" means a template engine cannot cache compiled ISeqs for later invocation, right? I doubt the benfit of compile's taking bindings.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=572852016-03-04T14:44:06Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Do you mean same template with different contexts, a name is a variable one time, but a method call next time?<br>
I doubt that it is a common use case.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=607142016-09-29T05:41:48Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>I discovered an old <a href="https://github.com/ruby/ruby/compare/trunk...nobu:feature/12093-iseq-eval_with" class="external">patch</a> for this issue.<br>
This enables the following code, but doesn't seem useful to me.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">obj</span> <span class="o">=</span> <span class="no">Struct</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:a</span><span class="p">,</span> <span class="ss">:b</span><span class="p">).</span><span class="nf">new</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="n">bind</span> <span class="o">=</span> <span class="n">obj</span><span class="p">.</span><span class="nf">instance_eval</span> <span class="p">{</span><span class="nb">binding</span><span class="p">}</span>
<span class="no">RubyVM</span><span class="o">::</span><span class="no">InstructionSequence</span><span class="p">.</span><span class="nf">compile</span><span class="p">(</span><span class="s2">"a + b"</span><span class="p">).</span><span class="nf">eval_with</span><span class="p">(</span><span class="n">bind</span><span class="p">)</span> <span class="c1">#=> 3</span>
</code></pre> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=798032019-07-22T16:51:32Zdalehamel (Dale Hamel)
<ul></ul><p>Howdy,</p>
<p>Sorry to ping a 3 year old issue, i Just wanted to add my 2 cents here.</p>
<p>I came across this issue when googling for a way to evaluate an instruction sequence with a particular binding. I'm working on an experimental gem that would inject "breakpoints" in arbitrary lines in ruby methods, with the idea that eBPF / bpftrace can be used to read values from these overridden methods.</p>
<p>Right now i'm using a block to 'handle' the original source code in its original binding, but i have to use ruby's 'eval' method to do this.</p>
<p>I'd ideally like to precompile the original source code sequence, and evaluate this with the original binding.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=798412019-07-23T04:35:27Zdalehamel (Dale Hamel)
<ul><li><strong>File</strong> <a href="/attachments/7912">0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/7912/0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch">0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch</a> added</li><li><strong>File</strong> <a href="/attachments/7913">0001-RubyVM-InstructionSequence-eval_with.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/7913/0001-RubyVM-InstructionSequence-eval_with.patch">0001-RubyVM-InstructionSequence-eval_with.patch</a> added</li></ul><p>Here's the current draft of the patch set, which I intend to submit a github pull request for as well.</p>
<p>I've retained Nobu's patch, and built on it.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=798622019-07-23T15:01:40Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><p>Nobu recently added it for the next developer meeting (in August; see<br>
<a href="https://bugs.ruby-lang.org/issues/15996" class="external">https://bugs.ruby-lang.org/issues/15996</a>) so stay tuned. :)</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=798782019-07-23T15:14:44Zdalehamel (Dale Hamel)
<ul></ul><p>Awesome I just saw that - thanks for the update!</p>
<p>The latest patch is now at <a href="https://github.com/ruby/ruby/pull/2298" class="external">https://github.com/ruby/ruby/pull/2298</a> and so that's where the review should go.</p>
<p>I'll stay-tuned and watch for updates from that meeting, thanks Robert!</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=807932019-08-16T02:01:01Zko1 (Koichi Sasada)
<ul></ul><p>What the last line should output?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">a</span><span class="p">;</span> <span class="ss">:m_a</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">b</span><span class="p">;</span> <span class="ss">:m_b</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">bind</span>
<span class="n">a</span> <span class="o">=</span> <span class="ss">:l_a</span>
<span class="n">b</span> <span class="o">=</span> <span class="ss">:l_b</span>
<span class="nb">binding</span>
<span class="k">end</span>
<span class="nb">eval</span><span class="p">(</span><span class="s1">'p [a, b]'</span><span class="p">,</span> <span class="n">bind</span><span class="p">())</span>
<span class="c1">#=> [:l_a, :l_b]</span>
<span class="no">RubyVM</span><span class="o">::</span><span class="no">InstructionSequence</span><span class="p">.</span><span class="nf">compile</span><span class="p">(</span><span class="s2">"p [a, b]"</span><span class="p">).</span><span class="nf">eval</span>
<span class="c1">#=> [:m_a, :m_b]</span>
<span class="no">RubyVM</span><span class="o">::</span><span class="no">InstructionSequence</span><span class="p">.</span><span class="nf">compile</span><span class="p">(</span><span class="s2">"p [a, b]"</span><span class="p">).</span><span class="nf">eval</span><span class="p">(</span><span class="n">bind</span><span class="p">())</span>
<span class="c1">#=> ???</span>
</code></pre>
<p>I believe we shouldn't introduce <code>binding</code> option to <code>ISeq#eval</code>.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=807992019-08-16T12:36:08Zdalehamel (Dale Hamel)
<ul></ul><p>Yes when I test out Koichi's sample, the iseq look like:</p>
<pre><code>disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(1,6)> (catch: FALSE)
0000 putself ( 1)[Li]
0001 opt_send_without_block <callinfo!mid:a, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache>
0004 putself
0005 opt_send_without_block <callinfo!mid:b, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache>
0008 newarray 2
0010 leave
</code></pre>
<p>So there is no way for the local variables from the binding to be evaluated, as the original instruction sequence expects a method call. I hadn't realized that when compiling the iseq string, methods calls are found in this way.</p>
<p>This indicates that yeah, Nobu's comment above appears correct, you must have the binding available when the iseq is compiled. It appears to do so implicitly based on the current binding.</p>
<p>It looks works with the struct example because the values for <code>a</code> and <code>b</code> have method calls that can receive and respond instead of these local variables, avoiding the problem. This seems inconsistent with <code>Kernel#eval</code> and <code>binding#eval</code>, which is counterproductive.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=808002019-08-16T12:53:24Zko1 (Koichi Sasada)
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>Ok. I reject this ticket, and pls remake your proposal if you find a good way.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=808042019-08-16T14:39:39Zdalehamel (Dale Hamel)
<ul></ul><p>Understood, I’ve closed the pull request.</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=808262019-08-17T23:49:43Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>Indeed <code>eval</code> with an arbitrary <code>Binding</code> doesn't make a sense.<br>
How about <code>eval</code> on a given object?<br>
Currently, iseqs eval always on the top-level object without any argument, and I've needed code like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">RubyVM</span><span class="o">::</span><span class="no">InstructionSequence</span><span class="p">.</span><span class="nf">compile</span><span class="p">(</span><span class="s2">"proc {...}"</span><span class="p">).</span><span class="nf">eval</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="n">obj</span><span class="p">).</span><span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
</code></pre>
<p>I think it should be simpler.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">RubyVM</span><span class="o">::</span><span class="no">InstructionSequence</span><span class="p">.</span><span class="nf">compile</span><span class="p">(</span><span class="s2">"proc {...}"</span><span class="p">).</span><span class="nf">bind</span><span class="p">(</span><span class="n">obj</span><span class="p">).</span><span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="c1"># or</span>
<span class="no">RubyVM</span><span class="o">::</span><span class="no">InstructionSequence</span><span class="p">.</span><span class="nf">compile</span><span class="p">(</span><span class="s2">"proc {...}"</span><span class="p">,</span> <span class="ss">receiver: </span><span class="n">obj</span><span class="p">).</span><span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
</code></pre>
<p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/25855">@dalehamel (Dale Hamel)</a>, does this suffice your use case?</p> Ruby master - Feature #12093: Eval InstructionSequence with bindinghttps://redmine.ruby-lang.org/issues/12093?journal_id=809652019-08-24T05:10:46Zdalehamel (Dale Hamel)
<ul></ul><blockquote>
<p>does this suffice your use case?</p>
</blockquote>
<p>Interesting, I'll need to investigate this - it certainly has potential.</p>
<p>My use case is for experimental tracing work, and I basically want to be<br>
able to pre-compile original source with added instructions, and execute them<br>
within the context they were originally intended to be executed within.</p>
<p>This is why I had a use for being able to execute within arbitrary bindings, but<br>
if I can target right receiver / bind to the right object, this could work.</p>
<p>I will try a prototype be seeing which receiving I am presently binding to, and<br>
look into modifying the patch to support the prototype you suggest to see if<br>
it can fit my use case by passing this receiver rather than the binding.</p>
<p>Thank you for response and feedback Nobu.</p>