[macruby-changes] [1152] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Wed Mar 25 17:55:06 PDT 2009
Revision: 1152
http://trac.macosforge.org/projects/ruby/changeset/1152
Author: lsansonetti at apple.com
Date: 2009-03-25 17:55:06 -0700 (Wed, 25 Mar 2009)
Log Message:
-----------
fixed bugs in const lookup
Modified Paths:
--------------
MacRuby/branches/experimental/class.c
MacRuby/branches/experimental/roxor.cpp
MacRuby/branches/experimental/roxor.h
MacRuby/branches/experimental/test_roxor.rb
MacRuby/branches/experimental/variable.c
Modified: MacRuby/branches/experimental/class.c
===================================================================
--- MacRuby/branches/experimental/class.c 2009-03-26 00:54:43 UTC (rev 1151)
+++ MacRuby/branches/experimental/class.c 2009-03-26 00:55:06 UTC (rev 1152)
@@ -372,6 +372,7 @@
RCLASS_SET_VERSION(klass, v);
}
RCLASS_SET_VERSION_FLAG(klass, RCLASS_IS_SINGLETON);
+ rb_vm_set_outer(klass, rb_cNSObject);
rb_singleton_class_attached(klass, obj);
Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp 2009-03-26 00:54:43 UTC (rev 1151)
+++ MacRuby/branches/experimental/roxor.cpp 2009-03-26 00:55:06 UTC (rev 1152)
@@ -370,6 +370,11 @@
}
};
+struct rb_vm_outer {
+ Class klass;
+ struct rb_vm_outer *outer;
+};
+
class RoxorVM
{
private:
@@ -384,6 +389,7 @@
std::map<ID, struct ccache *> ccache;
std::map<Class, std::map<ID, int> *> ivar_slots;
std::map<SEL, GlobalVariable *> redefined_ops_gvars;
+ std::map<Class, struct rb_vm_outer *> outers;
public:
static RoxorVM *current;
@@ -482,6 +488,21 @@
}
int find_ivar_slot(VALUE klass, ID name, bool create);
bool class_can_have_ivar_slots(VALUE klass);
+
+ struct rb_vm_outer *get_outer(Class klass) {
+ std::map<Class, struct rb_vm_outer *>::iterator iter =
+ outers.find(klass);
+ return iter == outers.end() ? NULL : iter->second;
+ }
+
+ void set_outer(Class klass, Class mod) {
+ struct rb_vm_outer *mod_outer = get_outer(mod);
+ struct rb_vm_outer *class_outer = (struct rb_vm_outer *)
+ malloc(sizeof(struct rb_vm_outer));
+ class_outer->klass = klass;
+ class_outer->outer = mod_outer;
+ outers[klass] = class_outer;
+ }
};
RoxorVM *RoxorVM::current = NULL;
@@ -991,16 +1012,25 @@
Value *
RoxorCompiler::compile_const(ID id, Value *outer)
{
+ bool outer_given = true;
+ if (outer == NULL) {
+ outer = compile_current_class();
+ outer_given = false;
+ }
+
if (getConstFunc == NULL) {
- // VALUE rb_vm_get_const(VALUE mod, struct ccache *cache, ID id);
- getConstFunc = cast<Function>(module->getOrInsertFunction("rb_vm_get_const",
- RubyObjTy, RubyObjTy, PtrTy, IntTy, NULL));
+ // VALUE rb_vm_get_const(VALUE mod, unsigned char lexical_lookup,
+ // struct ccache *cache, ID id);
+ getConstFunc = cast<Function>(module->getOrInsertFunction(
+ "rb_vm_get_const",
+ RubyObjTy, RubyObjTy, Type::Int8Ty, PtrTy, IntTy, NULL));
}
std::vector<Value *> params;
struct ccache *cache = GET_VM()->constant_cache_get(id);
params.push_back(outer);
+ params.push_back(ConstantInt::get(Type::Int8Ty, outer_given ? 0 : 1));
params.push_back(compile_const_pointer(cache));
params.push_back(ConstantInt::get(IntTy, id));
@@ -1027,8 +1057,9 @@
#define DEFINED_GVAR 2
#define DEFINED_CVAR 3
#define DEFINED_CONST 4
-#define DEFINED_SUPER 5
-#define DEFINED_METHOD 6
+#define DEFINED_LCONST 5
+#define DEFINED_SUPER 6
+#define DEFINED_METHOD 7
Value *
RoxorCompiler::compile_defined_expression(NODE *node)
@@ -1116,8 +1147,9 @@
break;
case NODE_CONST:
- type = DEFINED_CONST;
+ type = DEFINED_LCONST;
what1 = (VALUE)node->nd_vid;
+ what2 = compile_current_class();
break;
case NODE_SUPER:
@@ -3236,7 +3268,7 @@
case NODE_CONST:
assert(node->nd_vid > 0);
- return compile_const(node->nd_vid, compile_current_class());
+ return compile_const(node->nd_vid, NULL);
case NODE_CDECL:
{
@@ -4114,27 +4146,84 @@
GET_VM()->const_defined(id);
}
+static inline VALUE
+rb_const_get_direct(VALUE klass, ID id)
+{
+ CFDictionaryRef iv_dict = rb_class_ivar_dict(klass);
+ if (iv_dict != NULL) {
+ VALUE value;
+ if (CFDictionaryGetValueIfPresent(iv_dict, (const void *)id,
+ (const void **)&value)) {
+ return value;
+ }
+ }
+ VALUE mods = rb_attr_get(klass, idIncludedModules);
+ if (mods != Qnil) {
+ int i, count = RARRAY_LEN(mods);
+ for (i = 0; i < count; i++) {
+ VALUE val = rb_const_get_direct(RARRAY_AT(mods, i), id);
+ if (val != Qundef) {
+ return val;
+ }
+ }
+ }
+ return Qundef;
+}
+
+static VALUE
+rb_vm_const_lookup(VALUE outer, ID path, bool lexical, bool defined)
+{
+ if (lexical) {
+ struct rb_vm_outer *o = GET_VM()->get_outer((Class)outer);
+ while (o != NULL && o->klass != (Class)rb_cNSObject) {
+ VALUE val = rb_const_get_direct((VALUE)o->klass, path);
+ if (val != Qundef) {
+ return defined ? Qtrue : val;
+ }
+ o = o->outer;
+ }
+ }
+
+ return defined ? rb_const_defined(outer, path) : rb_const_get(outer, path);
+}
+
extern "C"
VALUE
-rb_vm_get_const(VALUE outer, struct ccache *cache, ID path)
+rb_vm_get_const(VALUE outer, unsigned char lexical_lookup,
+ struct ccache *cache, ID path)
{
- // TODO if called within module_eval, we should update outer
+ if (GET_VM()->current_class != NULL && lexical_lookup) {
+ outer = (VALUE)GET_VM()->current_class;
+ }
+
assert(cache != NULL);
if (cache->outer == outer && cache->val != Qundef) {
return cache->val;
}
+
+ VALUE val = rb_vm_const_lookup(outer, path, lexical_lookup, false);
+
cache->outer = outer;
- return cache->val = rb_const_get(outer, path);
+ cache->val = val;
+
+ return val;
}
extern "C"
void
-rb_vm_const_defined(ID path)
+rb_vm_const_is_defined(ID path)
{
GET_VM()->const_defined(path);
}
extern "C"
+void
+rb_vm_set_outer(VALUE klass, VALUE under)
+{
+ GET_VM()->set_outer((Class)klass, (Class)under);
+}
+
+extern "C"
VALUE
rb_vm_define_class(ID path, VALUE outer, VALUE super, unsigned char is_module)
{
@@ -4340,12 +4429,10 @@
break;
case DEFINED_CONST:
+ case DEFINED_LCONST:
{
- VALUE outer = what2;
- if (NIL_P(outer)) {
- outer = CLASS_OF(self);
- }
- if (rb_const_defined(outer, (ID)what)) {
+ if (rb_vm_const_lookup(what2, (ID)what,
+ type == DEFINED_LCONST, true)) {
str = "constant";
}
}
Modified: MacRuby/branches/experimental/roxor.h
===================================================================
--- MacRuby/branches/experimental/roxor.h 2009-03-26 00:54:43 UTC (rev 1151)
+++ MacRuby/branches/experimental/roxor.h 2009-03-26 00:55:06 UTC (rev 1152)
@@ -18,7 +18,7 @@
int rb_vm_safe_level(void);
void rb_vm_set_safe_level(int level);
VALUE rb_vm_top_self(void);
-void rb_vm_const_defined(ID path);
+void rb_vm_const_is_defined(ID path);
bool rb_vm_lookup_method(Class klass, SEL sel, IMP *pimp, NODE **pnode);
bool rb_vm_lookup_method2(Class klass, ID mid, SEL *psel, IMP *pimp, NODE **pnode);
void rb_vm_define_method(Class klass, SEL sel, IMP imp, NODE *node);
@@ -33,6 +33,7 @@
bool rb_vm_respond_to(VALUE obj, SEL sel, bool priv);
VALUE rb_vm_method_missing(VALUE obj, int argc, const VALUE *argv);
int rb_vm_find_class_ivar_slot(VALUE klass, ID name);
+void rb_vm_set_outer(VALUE klass, VALUE under);
static inline void
rb_vm_regrow_robject_slots(struct RObject *obj, unsigned int new_num_slot)
Modified: MacRuby/branches/experimental/test_roxor.rb
===================================================================
--- MacRuby/branches/experimental/test_roxor.rb 2009-03-26 00:54:43 UTC (rev 1151)
+++ MacRuby/branches/experimental/test_roxor.rb 2009-03-26 00:55:06 UTC (rev 1152)
@@ -435,6 +435,21 @@
assert 'true', 'p ::String == String'
+ assert '42', %q{
+ o = Object.new
+ class << o
+ module Foo
+ Bar = 42
+ end
+ class Baz; include Foo; end
+ class Baz;
+ def self.bar; Bar; end
+ end
+ def baz; Baz; end
+ end
+ p o.baz.bar
+ }
+
end
test "ranges" do
Modified: MacRuby/branches/experimental/variable.c
===================================================================
--- MacRuby/branches/experimental/variable.c 2009-03-26 00:54:43 UTC (rev 1151)
+++ MacRuby/branches/experimental/variable.c 2009-03-26 00:55:06 UTC (rev 1152)
@@ -273,6 +273,8 @@
}
OBJ_FREEZE(str);
rb_ivar_set(klass, classpath, str);
+
+ rb_vm_set_outer(klass, under);
}
VALUE
@@ -1831,7 +1833,7 @@
DLOG("CONS", "%s::%s <- %p", class_getName((Class)klass), rb_id2name(id), (void *)val);
CFDictionarySetValue(iv_dict, (const void *)id, (const void *)val);
- rb_vm_const_defined(id);
+ rb_vm_const_is_defined(id);
}
void
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090325/cb8d6cf1/attachment-0001.html>
More information about the macruby-changes
mailing list