ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:73901] [CommonRuby Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
@ 2016-02-20 12:00 ` pavel.evst
  2016-02-21  4:53 ` [ruby-core:73906] [Ruby trunk " nobu
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: pavel.evst @ 2016-02-20 12:00 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been reported by Pavel Evstigneev.

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093

* Author: Pavel Evstigneev
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:73906] [Ruby trunk Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
  2016-02-20 12:00 ` [ruby-core:73901] [CommonRuby Feature#12093] Eval InstructionSequence with binding pavel.evst
@ 2016-02-21  4:53 ` nobu
  2016-02-22  8:06 ` [ruby-core:73918] " nobu
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: nobu @ 2016-02-21  4:53 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by Nobuyoshi Nakada.

Project changed from CommonRuby to Ruby trunk

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-57066

* Author: Pavel Evstigneev
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:73918] [Ruby trunk Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
  2016-02-20 12:00 ` [ruby-core:73901] [CommonRuby Feature#12093] Eval InstructionSequence with binding pavel.evst
  2016-02-21  4:53 ` [ruby-core:73906] [Ruby trunk " nobu
@ 2016-02-22  8:06 ` nobu
  2016-03-03  5:10 ` [ruby-core:74103] " shyouhei
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: nobu @ 2016-02-22  8:06 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by Nobuyoshi Nakada.


Depending on the context, an identifier may be a local variable or a method call.
I think that `RubyVM::InstructionSequence#compile` would need the binding, instead of `#eval`.

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-57074

* Author: Pavel Evstigneev
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:74103] [Ruby trunk Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2016-02-22  8:06 ` [ruby-core:73918] " nobu
@ 2016-03-03  5:10 ` shyouhei
  2016-03-04 14:44 ` [ruby-core:74140] " nobu
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: shyouhei @ 2016-03-03  5:10 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by Shyouhei Urabe.


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

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-57250

* Author: Pavel Evstigneev
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:74140] [Ruby trunk Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2016-03-03  5:10 ` [ruby-core:74103] " shyouhei
@ 2016-03-04 14:44 ` nobu
  2016-09-29  5:41 ` [ruby-core:77452] " nobu
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: nobu @ 2016-03-04 14:44 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by Nobuyoshi Nakada.


Do you mean same template with different contexts, a name is a variable one time, but a method call next time?
I doubt that it is a common use case.

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-57285

* Author: Pavel Evstigneev
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:77452] [Ruby trunk Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2016-03-04 14:44 ` [ruby-core:74140] " nobu
@ 2016-09-29  5:41 ` nobu
  2019-07-22 16:51 ` [ruby-core:93868] [Ruby master " dale.hamel
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: nobu @ 2016-09-29  5:41 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by Nobuyoshi Nakada.


I discovered an old [patch] for this issue.
This enables the following code, but doesn't seem useful to me.

```ruby
obj = Struct.new(:a, :b).new(1, 2)
bind = obj.instance_eval {binding}
RubyVM::InstructionSequence.compile("a + b").eval_with(bind) #=> 3
```

[patch]: https://github.com/ruby/ruby/compare/trunk...nobu:feature/12093-iseq-eval_with

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-60714

* Author: Pavel Evstigneev
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:93868] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (5 preceding siblings ...)
  2016-09-29  5:41 ` [ruby-core:77452] " nobu
@ 2019-07-22 16:51 ` dale.hamel
  2019-07-23  4:35 ` [ruby-core:93877] " dale.hamel
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: dale.hamel @ 2019-07-22 16:51 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by dalehamel (Dale Hamel).


Howdy,

Sorry to ping a 3 year old issue, i Just wanted to add my 2 cents here.

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. I've written up my early approach to this at https://bpf.sh/production-breakpoints-doc/index.html

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.

I'd ideally like to precompile the original source code sequence, and evaluate this with the original binding.


> This enables the following code, but doesn't seem useful to me.


So in my case, this would be *exactly* what I want and extremely useful.

Say I have the original method:

```ruby
 def some_method
       a = 1
       sleep 0.5
       b = a + 1
 end
```

Then it currenly is transformed into:

```ruby
 def some_method
 local_bind=binding; ProductionBreakpoints.installed_breakpoints[:test_breakpoint_install].handle(local_bind) do
 <<-EOS
       a = 1
       sleep 0.5
       b = a + 1
 EOS
 end
  ProductionBreakpoints.installed_breakpoints[:test_breakpoint_install].finish(local_bind) do
 <<-EOS
 EOS
 end
     end
```

where those strings are just passed to `eval` with that original method binding. I think I could improve the performance of this if i could just precompile that source when I'm redefining the method, so that i don't have to take the overhead of eval each time this code is executed.

Nobu's patch looks like it would allow me to do this, eg by compiling the source and storing it on my "breakpoint" object to just be evaluated in the context of the caller's binding.

There may be other ways to do this, just wanted to add my 2 cents to this issue as it seemed most relevant.

I know this is a bit of an esoteric metaprogramming case, but it seems like the patch is pretty small and simple. I wonder if it still applies relatively easily (3 years later - sorry!)?

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-79803

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:93877] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (6 preceding siblings ...)
  2019-07-22 16:51 ` [ruby-core:93868] [Ruby master " dale.hamel
@ 2019-07-23  4:35 ` dale.hamel
  2019-07-23 15:01 ` [ruby-core:93885] " shevegen
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: dale.hamel @ 2019-07-23  4:35 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by dalehamel (Dale Hamel).

File 0001-RubyVM-InstructionSequence-eval_with.patch added
File 0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch added

Here's the current draft of the patch set, which I intend to submit a github pull request for as well.

I've retained Nobu's patch, and built on it.

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-79841

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:93885] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (7 preceding siblings ...)
  2019-07-23  4:35 ` [ruby-core:93877] " dale.hamel
@ 2019-07-23 15:01 ` shevegen
  2019-07-23 15:14 ` [ruby-core:93889] " dale.hamel
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: shevegen @ 2019-07-23 15:01 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by shevegen (Robert A. Heiler).


Nobu recently added it for the next developer meeting (in August; see
https://bugs.ruby-lang.org/issues/15996) so stay tuned. :)

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-79862

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:93889] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (8 preceding siblings ...)
  2019-07-23 15:01 ` [ruby-core:93885] " shevegen
@ 2019-07-23 15:14 ` dale.hamel
  2019-08-16  2:01 ` [ruby-core:94378] " ko1
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: dale.hamel @ 2019-07-23 15:14 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by dalehamel (Dale Hamel).


Awesome I just saw that - thanks for the update!

The latest patch is now at https://github.com/ruby/ruby/pull/2298 and so that's where the review should go.

I'll stay-tuned and watch for updates from that meeting, thanks Robert!

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-79878

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:94378] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (9 preceding siblings ...)
  2019-07-23 15:14 ` [ruby-core:93889] " dale.hamel
@ 2019-08-16  2:01 ` ko1
  2019-08-16 12:36 ` [ruby-core:94384] " dale.hamel
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: ko1 @ 2019-08-16  2:01 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by ko1 (Koichi Sasada).


What the last line should output?

```
def a; :m_a end
def b; :m_b end
def bind
  a = :l_a
  b = :l_b
  binding
end

eval('p [a, b]', bind())
#=> [:l_a, :l_b]

RubyVM::InstructionSequence.compile("p [a, b]").eval
#=> [:m_a, :m_b]

RubyVM::InstructionSequence.compile("p [a, b]").eval(bind())
#=> ???
```

I believe we shouldn't introduce `binding` option to `ISeq#eval`.

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-80793

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:94384] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (10 preceding siblings ...)
  2019-08-16  2:01 ` [ruby-core:94378] " ko1
@ 2019-08-16 12:36 ` dale.hamel
  2019-08-16 12:53 ` [ruby-core:94385] " ko1
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: dale.hamel @ 2019-08-16 12:36 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by dalehamel (Dale Hamel).


Yes when I test out Koichi's sample, the iseq look like:

```
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
```

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.

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.



----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-80799

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:94385] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (11 preceding siblings ...)
  2019-08-16 12:36 ` [ruby-core:94384] " dale.hamel
@ 2019-08-16 12:53 ` ko1
  2019-08-16 14:39 ` [ruby-core:94389] " dale.hamel
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 16+ messages in thread
From: ko1 @ 2019-08-16 12:53 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by ko1 (Koichi Sasada).

Status changed from Open to Rejected

Ok. I reject this ticket, and pls remake your proposal if you find a good way.

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-80800

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Rejected
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:94389] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (12 preceding siblings ...)
  2019-08-16 12:53 ` [ruby-core:94385] " ko1
@ 2019-08-16 14:39 ` dale.hamel
  2019-08-17 23:49 ` [ruby-core:94406] " nobu
  2019-08-24  5:10 ` [ruby-core:94524] " dale.hamel
  15 siblings, 0 replies; 16+ messages in thread
From: dale.hamel @ 2019-08-16 14:39 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by dalehamel (Dale Hamel).


Understood, I’ve closed the pull request.

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-80804

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Rejected
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:94406] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (13 preceding siblings ...)
  2019-08-16 14:39 ` [ruby-core:94389] " dale.hamel
@ 2019-08-17 23:49 ` nobu
  2019-08-24  5:10 ` [ruby-core:94524] " dale.hamel
  15 siblings, 0 replies; 16+ messages in thread
From: nobu @ 2019-08-17 23:49 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by nobu (Nobuyoshi Nakada).


Indeed `eval` with an arbitrary `Binding` doesn't make a sense.
How about `eval` on a given object?
Currently, iseqs eval always on the top-level object without any argument, and I've needed code like:

```ruby
RubyVM::InstructionSequence.compile("proc {...}").eval.call(obj).call(*args)
```

I think it should be simpler.

```ruby
RubyVM::InstructionSequence.compile("proc {...}").bind(obj).call(*args)
# or
RubyVM::InstructionSequence.compile("proc {...}", receiver: obj).call(*args)
```

@dalehamel, does this suffice your use case?

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-80826

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Rejected
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [ruby-core:94524] [Ruby master Feature#12093] Eval InstructionSequence with binding
       [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
                   ` (14 preceding siblings ...)
  2019-08-17 23:49 ` [ruby-core:94406] " nobu
@ 2019-08-24  5:10 ` dale.hamel
  15 siblings, 0 replies; 16+ messages in thread
From: dale.hamel @ 2019-08-24  5:10 UTC (permalink / raw)
  To: ruby-core

Issue #12093 has been updated by dalehamel (Dale Hamel).


> does this suffice your use case?

Interesting, I'll need to investigate this - it certainly has potential.

My use case is for experimental tracing work, and I basically want to be
able to pre-compile original source with added instructions, and execute them
within the context they were originally intended to be executed within.

This is why I had a use for being able to execute within arbitrary bindings, but
if I can target right receiver / bind to the right object, this could work.

I will try a prototype be seeing which receiving I am presently binding to, and
look into modifying the patch to support the prototype you suggest to see if
it can fit my use case by passing this receiver rather than the binding.

Thank you for response and feedback Nobu.

----------------------------------------
Feature #12093: Eval InstructionSequence with binding
https://bugs.ruby-lang.org/issues/12093#change-80965

* Author: pavel.evstigneev (Pavel Evstigneev)
* Status: Rejected
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Implementing this feature can boost template engine performance

Currently Kernel#eval can accept binding argument, so code running with eval will have access to local variables and current instance. This feature used by template languages

ERB: https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L887
Erubis: Can't find code on github, but it uses instance_eval or Kernel#eval
Haml: https://github.com/haml/haml/blob/master/lib/haml/engine.rb#L115

My proposal is to make RubyVM::InstructionSequence#eval to recieve binding argument. So it can be used for caching templates. As I see from ERB and Haml, cached template is stored as ruby code string, every time when we render template that string (ruby code) is evaluated, internally ruby will parse it into RubyVM::InstructionSequence and then evaluate.

Before I try to implement it myself in ruby, but could not. Lack of experience with C https://github.com/Paxa/ruby/commit/f5b602b6d9eada9675a4c002c9a5a79129df73a6 (not working)

---Files--------------------------------
0002-Update-iseq.eval-to-accept-optional-binding-FIXES-Bu.patch (4.83 KB)
0001-RubyVM-InstructionSequence-eval_with.patch (2.91 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2019-08-24  5:10 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-12093.20160220120020@ruby-lang.org>
2016-02-20 12:00 ` [ruby-core:73901] [CommonRuby Feature#12093] Eval InstructionSequence with binding pavel.evst
2016-02-21  4:53 ` [ruby-core:73906] [Ruby trunk " nobu
2016-02-22  8:06 ` [ruby-core:73918] " nobu
2016-03-03  5:10 ` [ruby-core:74103] " shyouhei
2016-03-04 14:44 ` [ruby-core:74140] " nobu
2016-09-29  5:41 ` [ruby-core:77452] " nobu
2019-07-22 16:51 ` [ruby-core:93868] [Ruby master " dale.hamel
2019-07-23  4:35 ` [ruby-core:93877] " dale.hamel
2019-07-23 15:01 ` [ruby-core:93885] " shevegen
2019-07-23 15:14 ` [ruby-core:93889] " dale.hamel
2019-08-16  2:01 ` [ruby-core:94378] " ko1
2019-08-16 12:36 ` [ruby-core:94384] " dale.hamel
2019-08-16 12:53 ` [ruby-core:94385] " ko1
2019-08-16 14:39 ` [ruby-core:94389] " dale.hamel
2019-08-17 23:49 ` [ruby-core:94406] " nobu
2019-08-24  5:10 ` [ruby-core:94524] " dale.hamel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).