[macruby-changes] [2519] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Sep 8 19:25:01 PDT 2009


Revision: 2519
          http://trac.macosforge.org/projects/ruby/changeset/2519
Author:   lsansonetti at apple.com
Date:     2009-09-08 19:25:01 -0700 (Tue, 08 Sep 2009)
Log Message:
-----------
Object#instance_variables: added support for slot-based ivars

Modified Paths:
--------------
    MacRuby/trunk/variable.c
    MacRuby/trunk/vm.cpp
    MacRuby/trunk/vm.h

Modified: MacRuby/trunk/variable.c
===================================================================
--- MacRuby/trunk/variable.c	2009-09-09 02:24:25 UTC (rev 2518)
+++ MacRuby/trunk/variable.c	2009-09-09 02:25:01 UTC (rev 2519)
@@ -1201,17 +1201,12 @@
     return Qfalse;
 }
 
-struct obj_ivar_tag {
-    VALUE obj;
-    int (*func)(ID key, VALUE val, st_data_t arg);
-    st_data_t arg;
-};
-
-void rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
+void
+rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
 {
     switch (TYPE(obj)) {
       case T_OBJECT:
-	  // TODO support slots
+	  rb_vm_each_ivar_slot(obj, func, (void *)arg);
 	  if (ROBJECT(obj)->tbl != NULL) {
 	      CFDictionaryApplyFunction(ROBJECT(obj)->tbl, 
 		      (CFDictionaryApplierFunction)func, (void *)arg);
@@ -1222,8 +1217,9 @@
       case T_MODULE:
 	  {
 	      CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(obj);
-	      if (iv_dict != NULL)
+	      if (iv_dict != NULL) {
 		  ivar_dict_foreach((VALUE)iv_dict, func, arg);
+	      }
 	  }
 	  return;
 

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2009-09-09 02:24:25 UTC (rev 2518)
+++ MacRuby/trunk/vm.cpp	2009-09-09 02:25:01 UTC (rev 2519)
@@ -786,6 +786,30 @@
     }
 }
 
+void
+RoxorCore::each_ivar_slot(VALUE obj, int (*func)(ANYARGS),
+	void *ctx)
+{
+    VALUE k = *(VALUE *)obj;
+
+    while (k != 0) {
+	std::map <ID, int> *slots = get_ivar_slots((Class)k, false);
+	if (slots != NULL) {
+	    for (std::map <ID, int>::iterator iter = slots->begin();
+		 iter != slots->end();
+		 ++iter) {
+		ID name = iter->first;
+		int slot = iter->second;
+		VALUE value = rb_vm_get_ivar_from_slot(obj, slot);
+		if (value != Qundef) {
+		    func(name, value, ctx);
+		}
+	    }
+	}
+	k = RCLASS_SUPER(k);
+    }
+}
+
 inline bool
 RoxorCore::class_can_have_ivar_slots(VALUE klass)
 {
@@ -1322,6 +1346,15 @@
     return -1;
 }
 
+extern "C"
+void
+rb_vm_each_ivar_slot(VALUE obj, int (*func)(ANYARGS), void *ctx)
+{
+    if (GET_CORE()->class_can_have_ivar_slots(CLASS_OF(obj))) {
+	GET_CORE()->each_ivar_slot(obj, func, ctx);	
+    } 
+}
+
 static inline void 
 resolve_method_type(char *buf, const size_t buflen, Class klass, Method m,
 	SEL sel, const unsigned int oc_arity)

Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h	2009-09-09 02:24:25 UTC (rev 2518)
+++ MacRuby/trunk/vm.h	2009-09-09 02:25:01 UTC (rev 2519)
@@ -294,6 +294,7 @@
 void rb_vm_push_methods(VALUE ary, VALUE mod, bool include_objc_methods,
 	int (*filter) (VALUE, ID, VALUE));
 int rb_vm_find_class_ivar_slot(VALUE klass, ID name);
+void rb_vm_each_ivar_slot(VALUE obj, int (*func)(ANYARGS), void *ctx);
 void rb_vm_set_outer(VALUE klass, VALUE under);
 VALUE rb_vm_get_outer(VALUE klass);
 VALUE rb_vm_catch(VALUE tag);
@@ -698,17 +699,23 @@
 	struct ccache *constant_cache_get(ID path);
 	void const_defined(ID path);
 	
-	std::map<ID, int> *get_ivar_slots(Class klass) {
+	std::map<ID, int> *get_ivar_slots(Class klass, bool create=true) {
 	    std::map<Class, std::map<ID, int> *>::iterator iter = 
 		ivar_slots.find(klass);
 	    if (iter == ivar_slots.end()) {
-		std::map<ID, int> *map = new std::map<ID, int>;
-		ivar_slots[klass] = map;
-		return map;
+		if (create) {
+		    std::map<ID, int> *map = new std::map<ID, int>;
+		    ivar_slots[klass] = map;
+		    return map;
+		}
+		else {
+		    return NULL;
+		}
 	    }
 	    return iter->second;
 	}
 	int find_ivar_slot(VALUE klass, ID name, bool create);
+	void each_ivar_slot(VALUE obj, int (*func)(ANYARGS), void *ctx);
 	bool class_can_have_ivar_slots(VALUE klass);
 
 	struct rb_vm_outer *get_outer(Class klass) {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090908/70837f5b/attachment-0001.html>


More information about the macruby-changes mailing list