Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make iseq eval consistent with Kernel eval #2298

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Next

RubyVM::InstructionSequence#eval_with

* iseq.c (iseq_eval_with): RubyVM::InstructionSequence#eval_with.
  [Feature #12093]

* vm.c (rb_iseq_eval_in_scope): evaluate an iseq in the given
  scope.
  • Loading branch information...
nobu authored and dalehamel committed Feb 22, 2016
commit 5d0c8c83d8fdea16c403abbc80c160ddddb92ef8
18 iseq.c
@@ -1345,6 +1345,23 @@ iseqw_eval(VALUE self)
return rb_iseq_eval(iseqw_check(self));
}

/*
* call-seq:
* iseq.eval_with(binding) -> obj
*
* Evaluates the instruction sequence and returns the result.
*
* obj = Struct.new(:a, :b).new(1, 2)
* bind = obj.instance_eval {binding}
* RubyVM::InstructionSequence.compile("a + b").eval_with(bind) #=> 3
*/
static VALUE
iseq_eval_with(VALUE self, VALUE scope)
{
rb_secure(1);
return rb_iseq_eval_in_scope(iseqw_check(self), scope);
}

/*
* Returns a human-readable string representation of this instruction
* sequence, including the #label and #path.
@@ -3483,6 +3500,7 @@ Init_ISeq(void)
rb_define_method(rb_cISeq, "disassemble", iseqw_disasm, 0);
rb_define_method(rb_cISeq, "to_a", iseqw_to_a, 0);
rb_define_method(rb_cISeq, "eval", iseqw_eval, 0);
rb_define_method(rb_cISeq, "eval_with", iseq_eval_with, 1);

rb_define_method(rb_cISeq, "to_binary", iseqw_to_binary, -1);
rb_define_singleton_method(rb_cISeq, "load_from_binary", iseqw_s_load_from_binary, 1);
19 vm.c
@@ -2138,6 +2138,25 @@ rb_iseq_eval(const rb_iseq_t *iseq)
return val;
}

VALUE
rb_iseq_eval_in_scope(const rb_iseq_t *iseq, VALUE scope)
{
rb_thread_t *th = GET_THREAD();
rb_binding_t *bind = rb_check_typeddata(scope, &ruby_binding_data_type);
struct rb_block *base_block = &bind->block;

if (iseq->body->local_table_size > 0) {
vm_bind_update_env(bind, vm_make_env_object(th, th->cfp));
}
#if 0
iseq_set_parent_block(iseq, base_block);
iseq_set_local_table(iseq, rb_vm_cref()->nd_tbl);
#endif
vm_set_eval_stack(th, iseq, 0, base_block);

return vm_exec(th);
}

VALUE
rb_iseq_eval_main(const rb_iseq_t *iseq)
{
@@ -1616,6 +1616,7 @@ NORETURN(void rb_bug_context(const void *, const char *fmt, ...));
/* functions about thread/vm execution */
RUBY_SYMBOL_EXPORT_BEGIN
VALUE rb_iseq_eval(const rb_iseq_t *iseq);
VALUE rb_iseq_eval_in_scope(const rb_iseq_t *iseq, VALUE scope);
VALUE rb_iseq_eval_main(const rb_iseq_t *iseq);
VALUE rb_iseq_path(const rb_iseq_t *iseq);
VALUE rb_iseq_realpath(const rb_iseq_t *iseq);
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.