Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1e70f9827cdf
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 6580094c06af
Choose a head ref
  • 4 commits
  • 5 files changed
  • 2 contributors

Commits on Sep 28, 2014

  1. Implement rb_funcall_with_block

    This commit adds `rb_funcall_with_block` (which is available in MRI) to the C
    API.
    seanchas116 committed Sep 28, 2014
    Copy the full SHA
    d597807 View commit details
  2. Add specs for rb_funcall_with_block

    This commit adds specs for `rb_funcall_with_block`.
    seanchas116 committed Sep 28, 2014
    Copy the full SHA
    f652673 View commit details

Commits on Oct 2, 2014

  1. Copy the full SHA
    8072237 View commit details

Commits on Oct 3, 2014

  1. Merge pull request #3144 from seanchas116/add-rb-funcall-with-block

    Add rb_funcall_with_block
    Yorick Peterse committed Oct 3, 2014
    Copy the full SHA
    6580094 View commit details
Showing with 50 additions and 3 deletions.
  1. +10 −0 spec/ruby/optional/capi/ext/kernel_spec.c
  2. +1 −0 spec/ruby/optional/capi/ext/rubyspec.h
  3. +19 −0 spec/ruby/optional/capi/kernel_spec.rb
  4. +15 −3 vm/capi/capi.cpp
  5. +5 −0 vm/include/capi/ruby/ruby.h
10 changes: 10 additions & 0 deletions spec/ruby/optional/capi/ext/kernel_spec.c
Original file line number Diff line number Diff line change
@@ -283,6 +283,12 @@ static VALUE kernel_spec_rb_funcall3(VALUE self, VALUE obj, VALUE method) {
}
#endif

#ifdef HAVE_RB_FUNCALL_WITH_BLOCK
static VALUE kernel_spec_rb_funcall_with_block(VALUE self, VALUE obj, VALUE method, VALUE block) {
return rb_funcall_with_block(obj, SYM2ID(method), 0, NULL, block);
}
#endif

void Init_kernel_spec() {
VALUE cls;
cls = rb_define_class("CApiKernelSpecs", rb_cObject);
@@ -390,6 +396,10 @@ void Init_kernel_spec() {
#ifdef HAVE_RB_FUNCALL3
rb_define_method(cls, "rb_funcall3", kernel_spec_rb_funcall3, 2);
#endif

#ifdef HAVE_RB_FUNCALL_WITH_BLOCK
rb_define_method(cls, "rb_funcall_with_block", kernel_spec_rb_funcall_with_block, 3);
#endif
}

#ifdef __cplusplus
1 change: 1 addition & 0 deletions spec/ruby/optional/capi/ext/rubyspec.h
Original file line number Diff line number Diff line change
@@ -392,6 +392,7 @@
#define HAVE_RB_YIELD_SPLAT 1
#define HAVE_RB_YIELD_VALUES 1
#define HAVE_RB_FUNCALL3 1
#define HAVE_RB_FUNCALL_WITH_BLOCK 1

/* GC */
#define HAVE_RB_GC_REGISTER_ADDRESS 1
19 changes: 19 additions & 0 deletions spec/ruby/optional/capi/kernel_spec.rb
Original file line number Diff line number Diff line change
@@ -434,4 +434,23 @@ def method_private; :method_private end
lambda { @s.rb_funcall3(@obj, :method_private) }.should raise_error(NoMethodError, /private/)
end
end

describe 'rb_funcall_with_block' do
before :each do
@obj = Object.new
class << @obj
def method_public; yield end
def method_private; yield end
private :method_private
end
end

it "calls a method with block" do
@s.rb_funcall_with_block(@obj, :method_public, proc { :result }).should == :result
end

it "does not call a private method" do
lambda { @s.rb_funcall_with_block(@obj, :method_private, proc { :result }) }.should raise_error(NoMethodError, /private/)
end
end
end
18 changes: 15 additions & 3 deletions vm/capi/capi.cpp
Original file line number Diff line number Diff line change
@@ -519,8 +519,8 @@ extern "C" {
arg_count, args, blk, false);
}

VALUE rb_funcall2b(VALUE receiver, ID method_name, int arg_count,
const VALUE* v_args, VALUE block)
static VALUE call_function_with_block(VALUE receiver, ID method_name, int arg_count,
const VALUE* v_args, VALUE block, bool allow_private)
{
NativeMethodEnvironment* env = NativeMethodEnvironment::get();

@@ -533,7 +533,19 @@ extern "C" {
return capi_funcall_backend_native(env, "", 0,
env->get_object(receiver),
reinterpret_cast<Symbol*>(method_name),
arg_count, args, env->get_object(block), true);
arg_count, args, env->get_object(block), allow_private);
}

VALUE rb_funcall2b(VALUE receiver, ID method_name, int arg_count,
const VALUE* v_args, VALUE block)
{
return call_function_with_block(receiver, method_name, arg_count, v_args, block, true);
}

VALUE rb_funcall_with_block(VALUE receiver, ID method_name, int arg_count,
const VALUE* v_args, VALUE block)
{
return call_function_with_block(receiver, method_name, arg_count, v_args, block, false);
}

VALUE rb_yield(VALUE argument_handle) {
5 changes: 5 additions & 0 deletions vm/include/capi/ruby/ruby.h
Original file line number Diff line number Diff line change
@@ -1296,6 +1296,11 @@ struct RTypedData {
VALUE rb_funcall2b(VALUE receiver, ID method_name, int arg_count,
const VALUE* v_args, VALUE block);

/** Call the method with args provided in a C array and block.
* Does not call private methods. */
VALUE rb_funcall_with_block(VALUE receiver, ID method_name, int arg_count,
const VALUE* v_args, VALUE block);

/** Return name of the function being called */
ID rb_frame_last_func();