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: 8370899cb87c
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7f7782183655
Choose a head ref
  • 4 commits
  • 10 files changed
  • 1 contributor

Commits on Feb 4, 2016

  1. Fixed Module#define_method.

    brixen committed Feb 4, 2016
    Copy the full SHA
    b5d2f64 View commit details
  2. Moved CodeDB to core/.

    brixen committed Feb 4, 2016
    Copy the full SHA
    d35d915 View commit details
  3. Copy the full SHA
    689db82 View commit details
  4. Copy the full SHA
    7f77821 View commit details
Showing with 109 additions and 87 deletions.
  1. +2 −2 core/alpha.rb
  2. +0 −4 core/{delta → }/code_db.rb
  3. +1 −0 core/load_order.txt
  4. +12 −4 core/module.rb
  5. +54 −4 core/rubinius.rb
  6. +13 −14 core/thread.rb
  7. +6 −59 core/zed.rb
  8. +13 −0 spec/ruby/core/module/define_method_spec.rb
  9. +5 −0 vm/builtin/thread.cpp
  10. +3 −0 vm/builtin/thread.hpp
4 changes: 2 additions & 2 deletions core/alpha.rb
Original file line number Diff line number Diff line change
@@ -610,7 +610,7 @@ def alias_method(new_name, current_name)
# If we're aliasing a method we contain, just reference it directly, no
# need for the alias wrapper
if entry = @method_table.lookup(current_name)
@method_table.store new_name, entry.method_id, entry.method,
@method_table.store new_name, entry.method_id, entry.get_method,
entry.scope, entry.serial, entry.visibility
else
mod = direct_superclass()
@@ -625,7 +625,7 @@ def alias_method(new_name, current_name)
end

@method_table.alias new_name, entry.visibility, current_name,
entry.method, mod
entry.get_method, mod
end

Rubinius::VM.reset_method_cache self, new_name
4 changes: 0 additions & 4 deletions core/delta/code_db.rb → core/code_db.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
module Rubinius
class CodeDB
class << self
undef :new
end

def self.open(path)
Rubinius.primitive :code_db_open
raise PrimitiveFailure, "Rubinius::CodeDB.open primitive failed"
1 change: 1 addition & 0 deletions core/load_order.txt
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ capi.rb
channel.rb
character.rb
class.rb
code_db.rb
code_loader.rb
compact_lookup_table.rb
comparable.rb
16 changes: 12 additions & 4 deletions core/module.rb
Original file line number Diff line number Diff line change
@@ -465,23 +465,31 @@ def define_method(name, meth = undefined, &prc)
# level always.
if exec.kind_of? Rubinius::DelegatedMethod
code = exec
scope = nil
else
code = Rubinius::DelegatedMethod.new(name, :call_on_instance, meth.unbind, true)
if exec.kind_of? Rubinius::CompiledCode
scope = exec.scope
else
scope = nil
end
end

scope = exec.scope
when UnboundMethod
Rubinius::Type.bindable_method? meth.defined_in, self.class

exec = meth.executable
# Same reasoning as above.
if exec.kind_of? Rubinius::DelegatedMethod
code = exec
scope = nil
else
code = Rubinius::DelegatedMethod.new(name, :call_on_instance, meth, true)
if exec.kind_of? Rubinius::CompiledCode
scope = exec.scope
else
scope = nil
end
end

scope = exec.scope
else
raise TypeError, "wrong argument type #{meth.class} (expected Proc/Method)"
end
58 changes: 54 additions & 4 deletions core/rubinius.rb
Original file line number Diff line number Diff line change
@@ -70,13 +70,63 @@ def self.mri_backtrace(skip)
raise PrimitiveFailure, "Rubinius.mri_backtrace primitive failed"
end

def self.add_method(name, executable, mod, serial, vis)
if executable.kind_of? String
mod.method_table.store name, executable, nil, serial, :public
def self.add_method(name, executable, mod, scope, serial, vis)
vis ||= :public

# Don't change the visibility for methods added to singleton
# classes
if Type.singleton_class_object(mod)
visibility = vis
elsif vis == :module or privatized_method?(name)
visibility = :private
else
mod.method_table.store name, nil, executable, serial, :public
visibility = vis
end

if Type.object_kind_of? executable, String
mod.method_table.store name, executable, nil, scope, serial, visibility
else
mod.method_table.store name, nil, executable, scope, serial, visibility
end
Rubinius::VM.reset_method_cache mod, name

Rubinius.privately do
mod.module_function name if vis == :module
end

# Have to use Rubinius::Type.object_respond_to? rather than #respond_to?
# because code will redefine #respond_to? itself, which is added
# via #add_method, and then we'll call this new #respond_to?, which
# commonly can't run yet because it requires methods that haven't been
# added yet. (ActionMailer does this)

if obj = Type.singleton_class_object(mod)
if Type.object_kind_of? obj, Numeric

# Such a weird protocol. If :singleton_method_added exists, allow this.
# le sigh.
unless obj.respond_to? :singleton_method_added
raise TypeError, "Unable to define singleton methods on Numerics"
end
end

Rubinius.privately do
obj.singleton_method_added(name)
end
else
case executable
when CompiledCode, AccessVariable
mod.add_ivars(executable)
end

Rubinius.privately do
mod.method_added(name)
end
end

@add_method_hook.trigger! mod, name, executable

return executable
end

def self.mathn_loaded?
27 changes: 13 additions & 14 deletions core/thread.rb
Original file line number Diff line number Diff line change
@@ -105,6 +105,11 @@ def current_exception
Kernel.raise PrimitiveFailure, "Thread#current_exception primitive failed"
end

def set_exception(exception)
Rubinius.primitive :thread_set_exception
Kernel.raise PrimitiveFailure, "Thread#set_exception primitive failed"
end

@abort_on_exception = false

def self.abort_on_exception
@@ -353,7 +358,6 @@ def self.kill(thread)
# Called by Thread#fork in the new thread
#
def __run__
exception = nil
begin
begin
Rubinius.unlock(self)
@@ -384,26 +388,21 @@ def __run__
end
end
rescue Exception => e
exception = e
ensure
unless exception && (abort_on_exception || Thread.abort_on_exception)
@exception = exception
if $DEBUG
STDERR.puts "Exception in thread: #{@exception.message} (#{@exception.class})"
end
end
set_exception e

STDERR.puts "Exception in thread: #{e.message} (#{e.class})" if $DEBUG

if abort_on_exception or Thread.abort_on_exception
Thread.main.raise e
end
ensure
Rubinius::Mirror.reflect(@group).remove self

if Rubinius.thread_state[0] == :thread_kill
@killed = true
end
@alive = false
Rubinius.unlock(self)
end

unless @exception
Thread.main.raise exception
Rubinius.unlock(self)
end
end

65 changes: 6 additions & 59 deletions core/zed.rb
Original file line number Diff line number Diff line change
@@ -470,65 +470,6 @@ def self.add_defn_method(name, executable, constant_scope, vis)
name
end

def self.add_method(name, executable, mod, scope, serial, vis)
vis ||= :public

# Don't change the visibility for methods added to singleton
# classes
if Type.singleton_class_object(mod)
visibility = vis
elsif vis == :module or privatized_method?(name)
visibility = :private
else
visibility = vis
end

if Type.object_kind_of? executable, String
mod.method_table.store name, executable, nil, scope, serial, visibility
else
mod.method_table.store name, nil, executable, scope, serial, visibility
end
Rubinius::VM.reset_method_cache mod, name

Rubinius.privately do
mod.module_function name if vis == :module
end

# Have to use Rubinius::Type.object_respond_to? rather than #respond_to?
# because code will redefine #respond_to? itself, which is added
# via #add_method, and then we'll call this new #respond_to?, which
# commonly can't run yet because it requires methods that haven't been
# added yet. (ActionMailer does this)

if obj = Type.singleton_class_object(mod)
if Type.object_kind_of? obj, Numeric

# Such a weird protocol. If :singleton_method_added exists, allow this.
# le sigh.
unless obj.respond_to? :singleton_method_added
raise TypeError, "Unable to define singleton methods on Numerics"
end
end

Rubinius.privately do
obj.singleton_method_added(name)
end
else
case executable
when CompiledCode, AccessVariable
mod.add_ivars(executable)
end

Rubinius.privately do
mod.method_added(name)
end
end

@add_method_hook.trigger! mod, name, executable

return executable
end

# Must be AFTER add_method, because otherwise we'll run this attach_method to add
# add_method itself and fail.
def self.attach_method(name, executable, constant_scope, recv)
@@ -1858,6 +1799,12 @@ class Time
end

module Rubinius
class CodeDB
class << self
undef :new
end
end

module FFI
module Library
# Once the core library is loaded, we want to raise an error if
13 changes: 13 additions & 0 deletions spec/ruby/core/module/define_method_spec.rb
Original file line number Diff line number Diff line change
@@ -213,6 +213,19 @@ class DefineMethodSpecClass
end
end

it "allows a Method from a parent class to be defined on a child class" do
class DefineMethodSpecClass::ParentDefineMethod
def parent_define_method; end
end

DefineMethodSpecClass::ChildDefineMethod = Class.new do
define_method :child_define_method,
DefineMethodSpecClass::ParentDefineMethod.new.method(:parent_define_method)
end

DefineMethodSpecClass::ChildDefineMethod.new.should respond_to(:child_define_method)
end

it "allows an UnboundMethod from a module to be defined on a class" do
DestinationClass = Class.new {
define_method :bar, ModuleSpecs::UnboundMethodTest.instance_method(:foo)
5 changes: 5 additions & 0 deletions vm/builtin/thread.cpp
Original file line number Diff line number Diff line change
@@ -457,6 +457,11 @@ namespace rubinius {
return exc;
}

Object* Thread::set_exception(STATE, Exception* exc) {
exception(state, exc);
return exc;
}

Object* Thread::current_exception(STATE) {
utilities::thread::SpinLock::LockGuard lg(init_lock_);
return vm_->thread_state()->current_exception();
3 changes: 3 additions & 0 deletions vm/builtin/thread.hpp
Original file line number Diff line number Diff line change
@@ -176,6 +176,9 @@ namespace rubinius {
// Rubinius.primitive :thread_raise
Object* raise(STATE, GCToken gct, Exception* exc, CallFrame* calling_environment);

// Rubinius.primitive :thread_set_exception
Object* set_exception(STATE, Exception* exc);

/**
* Returns current exception
*/