[macruby-changes] [4960] MacRuby/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue Nov 30 18:25:24 PST 2010
Revision: 4960
http://trac.macosforge.org/projects/ruby/changeset/4960
Author: lsansonetti at apple.com
Date: 2010-11-30 18:25:20 -0800 (Tue, 30 Nov 2010)
Log Message:
-----------
no longer register all objc classes as constants upon #framework (which had the side effect of waking them up, calling +initialize), instead we now always use the dynamic resolver
Modified Paths:
--------------
MacRuby/trunk/class.c
MacRuby/trunk/objc.m
MacRuby/trunk/variable.c
MacRuby/trunk/vm.cpp
Modified: MacRuby/trunk/class.c
===================================================================
--- MacRuby/trunk/class.c 2010-12-01 00:34:02 UTC (rev 4959)
+++ MacRuby/trunk/class.c 2010-12-01 02:25:20 UTC (rev 4960)
@@ -471,10 +471,14 @@
if (TYPE(klass) != T_CLASS) {
rb_raise(rb_eTypeError, "%s is not a class", name);
}
- if (rb_class_real(RCLASS_SUPER(klass), true) != super) {
- rb_name_error(id, "%s is already defined", name);
+ if (RCLASS_RUBY(klass)) {
+ // Only for pure Ruby classes, as Objective-C classes
+ // might be returned from the dynamic resolver.
+ if (rb_class_real(RCLASS_SUPER(klass), true) != super) {
+ rb_name_error(id, "%s is already defined", name);
+ }
+ return klass;
}
- return klass;
}
if (!super) {
rb_warn("no super class for `%s::%s', Object assumed",
Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m 2010-12-01 00:34:02 UTC (rev 4959)
+++ MacRuby/trunk/objc.m 2010-12-01 02:25:20 UTC (rev 4960)
@@ -215,37 +215,6 @@
}
#endif
-static void
-reload_class_constants(void)
-{
- static int class_count = 0;
-
- const int count = objc_getClassList(NULL, 0);
- if (count == class_count) {
- return;
- }
-
- Class *buf = (Class *)malloc(sizeof(Class) * count);
- objc_getClassList(buf, count);
-
- for (int i = 0; i < count; i++) {
- Class k = buf[i];
- if (!RCLASS_RUBY(k)) {
- const char *name = class_getName(k);
- if (name[0] != '_') {
- ID name_id = rb_intern(name);
- if (!rb_const_defined(rb_cObject, name_id)) {
- rb_const_set(rb_cObject, name_id, (VALUE)k);
- }
- }
- }
- }
-
- class_count = count;
-
- free(buf);
-}
-
bool rb_objc_enable_ivar_set_kvo_notifications = false;
VALUE
@@ -360,7 +329,6 @@
}
rb_objc_search_and_load_bridge_support(cstr);
- reload_class_constants();
rb_objc_enable_ivar_set_kvo_notifications = true;
@@ -782,8 +750,6 @@
assert(m != NULL);
old_imp_isaForAutonotifying = method_getImplementation(m);
method_setImplementation(m, (IMP)rb_obj_imp_isaForAutonotifying);
-
- reload_class_constants();
}
@interface Protocol
Modified: MacRuby/trunk/variable.c
===================================================================
--- MacRuby/trunk/variable.c 2010-12-01 00:34:02 UTC (rev 4959)
+++ MacRuby/trunk/variable.c 2010-12-01 02:25:20 UTC (rev 4960)
@@ -1466,19 +1466,19 @@
static VALUE
retrieve_dynamic_objc_class(VALUE klass, ID name)
{
- // Classes are typically pre-loaded by Kernel#framework but it is still
- // useful to keep the dynamic import facility, because someone in the
- // Objective-C world may dynamically define classes at runtime (like
- // ScriptingBridge.framework).
- if (klass == rb_cObject) {
- VALUE k = (VALUE)objc_getClass(rb_id2name(name));
- if (k != 0 && !RCLASS_RUBY(k)) {
- // Set the constant. Only if the returned class is a pure
- // Objective-C class, to avoid namespace conflicts in Ruby land.
- rb_objc_force_class_initialize((Class)k);
- rb_const_set(klass, name, k);
- return k;
+ // The Objective-C class dynamic resolver. By default, MacRuby doesn't
+ // know about native classes. They will be resolved and added into the
+ // NSObject dictionary on demand.
+ Class k = (Class)objc_getClass(rb_id2name(name));
+ if (k != NULL && !RCLASS_RUBY(k)) {
+ // Skip classes that aren't pure Objective-C, to avoid namespace
+ // conflicts in Ruby land.
+ CFMutableDictionaryRef dict = rb_class_ivar_dict_or_create(rb_cObject);
+ if (!CFDictionaryContainsKey(dict, (const void *)name)) {
+ CFDictionarySetValue(dict, (const void *)name, (const void *)k);
+ rb_objc_force_class_initialize(k);
}
+ return (VALUE)k;
}
return Qnil;
}
@@ -1540,7 +1540,6 @@
if (k != Qnil) {
return k;
}
-
return const_missing(klass, id);
}
@@ -1773,7 +1772,7 @@
const char *dest = isconst ? "constant" : "class variable";
if (!OBJ_TAINTED(klass) && rb_safe_level() >= 4) {
- rb_raise(rb_eSecurityError, "Insecure: can't set %s", dest);
+ rb_raise(rb_eSecurityError, "Insecure: can't set %s", dest);
}
if (OBJ_FROZEN(klass)) {
if (BUILTIN_TYPE(klass) == T_MODULE) {
Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp 2010-12-01 00:34:02 UTC (rev 4959)
+++ MacRuby/trunk/vm.cpp 2010-12-01 02:25:20 UTC (rev 4960)
@@ -1321,17 +1321,25 @@
static VALUE
get_klass_const(VALUE outer, ID path, bool lexical)
{
+ VALUE klass = Qundef;
if (lexical) {
if (rb_vm_const_lookup(outer, path, true, true) == Qtrue) {
- return rb_vm_const_lookup(outer, path, true, false);
+ klass = rb_vm_const_lookup(outer, path, true, false);
}
}
else {
if (rb_const_defined_at(outer, path)) {
- return rb_const_get_at(outer, path);
+ klass = rb_const_get_at(outer, path);
}
}
- return Qundef;
+ if (klass != Qundef) {
+ rb_vm_check_if_module(klass);
+ if (outer != rb_cObject && !RCLASS_RUBY(klass)) {
+ // Ignore classes retrived by the dynamic resolver.
+ klass = Qundef;
+ }
+ }
+ return klass;
}
extern "C"
@@ -1352,7 +1360,6 @@
VALUE klass = get_klass_const(outer, path, dynamic_class);
if (klass != Qundef) {
// Constant is already defined.
- rb_vm_check_if_module(klass);
if (!(flags & DEFINE_MODULE) && super != 0) {
if (rb_class_real(RCLASS_SUPER(klass), true) != super) {
rb_raise(rb_eTypeError, "superclass mismatch for class %s",
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20101130/8c872909/attachment-0001.html>
More information about the macruby-changes
mailing list