Skip to content

Commit

Permalink
Make Object constants invisible from BasicObject
Browse files Browse the repository at this point in the history
  • Loading branch information
ryoqun committed Jul 5, 2012
1 parent 7ea1598 commit 2a20dde
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 27 deletions.
6 changes: 3 additions & 3 deletions kernel/bootstrap/basicobject.rb
Expand Up @@ -8,7 +8,7 @@ def initialize

def equal?(other)
Rubinius.primitive :object_equal
raise PrimitiveFailure, "BasicObject#equal? primitive failed"
raise ::PrimitiveFailure, "BasicObject#equal? primitive failed"
end

alias_method :==, :equal?
Expand All @@ -31,11 +31,11 @@ def !=(other)
#
def __send__(message, *args)
Rubinius.primitive :object_send
raise PrimitiveFailure, "#__send__ primitive failed"
raise ::PrimitiveFailure, "#__send__ primitive failed"
end

def __id__
Rubinius.primitive :object_id
raise PrimitiveFailure, "#__id__ primitive failed"
raise ::PrimitiveFailure, "#__id__ primitive failed"
end
end
2 changes: 1 addition & 1 deletion kernel/bootstrap/weakref.rb
Expand Up @@ -2,7 +2,7 @@

class WeakRef

class RefError < RuntimeError; end
class RefError < ::RuntimeError; end

def self.new
Rubinius.primitive :weakref_new
Expand Down
2 changes: 1 addition & 1 deletion kernel/common/basicobject.rb
Expand Up @@ -2,7 +2,7 @@

class BasicObject
def method_missing(meth, *args)
Kernel.raise NoMethodError, "Unable to send '#{meth}' on instance of BasicObject"
::Kernel.raise ::NoMethodError, "Unable to send '#{meth}' on instance of BasicObject"
end
private :method_missing

Expand Down
30 changes: 15 additions & 15 deletions kernel/common/eval19.rb
Expand Up @@ -23,15 +23,15 @@ class BasicObject
# k.instance_eval { @secret } #=> 99

def instance_eval(string=nil, filename="(eval)", line=1, &prc)
if ImmediateValue === self
if ::ImmediateValue === self
sc = nil
else
sc = Rubinius::Type.object_singleton_class(self)
sc = ::Rubinius::Type.object_singleton_class(self)
end

if prc
if string
raise ArgumentError, 'cannot pass both a block and a string to evaluate'
raise ::ArgumentError, 'cannot pass both a block and a string to evaluate'
end
# Return a copy of the BlockEnvironment with the receiver set to self
env = prc.block
Expand All @@ -46,24 +46,24 @@ def instance_eval(string=nil, filename="(eval)", line=1, &prc)
elsif string
string = StringValue(string)

constant_scope = Rubinius::ConstantScope.of_sender
constant_scope = ::Rubinius::ConstantScope.of_sender

if sc
constant_scope = Rubinius::ConstantScope.new(sc, constant_scope)
constant_scope = ::Rubinius::ConstantScope.new(sc, constant_scope)
else
constant_scope = constant_scope.using_disabled_scope
end

binding = Binding.setup(Rubinius::VariableScope.of_sender,
Rubinius::CompiledMethod.of_sender,
constant_scope)
binding = ::Binding.setup(::Rubinius::VariableScope.of_sender,
::Rubinius::CompiledMethod.of_sender,
constant_scope)

be = Rubinius::Compiler.construct_block string, binding,
filename, line
be = ::Rubinius::Compiler.construct_block string, binding,
filename, line

be.call_on_instance(self)
else
raise ArgumentError, 'block not supplied'
raise ::ArgumentError, 'block not supplied'
end
end

Expand All @@ -87,18 +87,18 @@ def instance_eval(string=nil, filename="(eval)", line=1, &prc)
# k.instance_exec(5) { |x| @secret+x } #=> 104

def instance_exec(*args, &prc)
raise LocalJumpError, "Missing block" unless block_given?
raise ::LocalJumpError, "Missing block" unless block_given?
env = prc.block

if prc.kind_of? Proc::Method
if prc.kind_of? ::Proc::Method
return prc.bound_method.call(*args)
end

constant_scope = env.constant_scope
if ImmediateValue === self
if ::ImmediateValue === self
constant_scope = constant_scope.using_disabled_scope
else
sc = Rubinius::Type.object_singleton_class(self)
sc = ::Rubinius::Type.object_singleton_class(self)
constant_scope = constant_scope.using_current_as(sc)
end

Expand Down
34 changes: 27 additions & 7 deletions vm/helpers.cpp
Expand Up @@ -61,9 +61,11 @@ namespace rubinius {
// Ok, this has to be explained or it will be considered black magic.
// The scope chain always ends with an entry at the top that contains
// a parent of nil, and a module of Object. This entry is put in
// regardless of lexical scoping, it's the default scope.
// regardless of lexical scoping, it's the fallback scope (the default
// scope). This is not case when deriving from BasicObject, which is
// explained later.
//
// When looking up a constant, we don't want to consider the default
// When looking up a constant, we don't want to consider the fallback
// scope (ie, Object) initially because we need to lookup up
// the superclass chain first, because falling back on the default.
//
Expand All @@ -88,6 +90,12 @@ namespace rubinius {
//
// So, in this case, foo would print "1", not "2".
//
// As indicated above, the fallback scope isn't used when the superclass
// chain directly rooted from BasicObject. To determine this is the
// case, we record whether Object is seen when looking up the superclass
// chain. If Object isn't seen, this means we are directly deriving from
// BasicObject.

cur = call_frame->constant_scope();
while(!cur->nil_p()) {
// Detect the toplevel scope (the default) and get outta dodge.
Expand All @@ -103,10 +111,20 @@ namespace rubinius {
}

// Now look up the superclass chain.
Module *fallback = G(object);
bool object_seen = false;

cur = call_frame->constant_scope();
if(!cur->nil_p()) {
Module* mod = cur->module();
while(!mod->nil_p()) {
if(mod == G(object)) {
object_seen = true;
}
if(!object_seen && mod == G(basicobject)) {
fallback = NULL;
}

result = mod->get_const(state, name, found);
if(*found) {
if(result != filter) return result;
Expand All @@ -117,11 +135,13 @@ namespace rubinius {
}
}

// Lastly, check Object specifically
result = G(object)->get_const(state, name, found, true);
if(*found) {
if(result != filter) return result;
*found = false;
// Lastly, check the fallback scope (=Object) specifically if needed
if(fallback) {
result = fallback->get_const(state, name, found, true);
if(*found) {
if(result != filter) return result;
*found = false;
}
}

return cNil;
Expand Down

0 comments on commit 2a20dde

Please sign in to comment.