Skip to content
This repository
Browse code

appropriately toggle the VM current class when #module_eval/#class_ev…

…al is called + fix metaclass outers

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/branches/experimental@1874 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
commit de8126fc4f6593a1097a2cb55d6a11d30deba1d5 1 parent 91eecd7
authored
2  class.c
@@ -374,7 +374,7 @@ rb_make_metaclass(VALUE obj, VALUE super)
374 374
 	    RCLASS_SET_VERSION(klass, v);
375 375
 	}
376 376
 	RCLASS_SET_VERSION_FLAG(klass, RCLASS_IS_SINGLETON);
377  
-	rb_vm_set_outer(klass, rb_cNSObject);
  377
+	rb_vm_set_outer(klass, rb_vm_get_outer(super));
378 378
 
379 379
 	rb_singleton_class_attached(klass, obj);
380 380
 
25  vm.cpp
@@ -774,6 +774,14 @@ rb_vm_set_outer(VALUE klass, VALUE under)
774 774
     GET_VM()->set_outer((Class)klass, (Class)under);
775 775
 }
776 776
 
  777
+extern "C"
  778
+VALUE
  779
+rb_vm_get_outer(VALUE klass)
  780
+{
  781
+    rb_vm_outer_t *o = GET_VM()->get_outer((Class)klass);
  782
+    return o == NULL ? Qundef : (VALUE)o->klass;
  783
+}
  784
+
777 785
 static inline void
778 786
 check_if_module(VALUE mod)
779 787
 {
@@ -1260,7 +1268,11 @@ void
1260 1268
 rb_vm_prepare_method(Class klass, SEL sel, Function *func, NODE *node)
1261 1269
 {
1262 1270
     if (GET_VM()->current_class != NULL) {
  1271
+	const bool meta = class_isMetaClass(klass);
1263 1272
 	klass = GET_VM()->current_class;
  1273
+	if (meta) {
  1274
+	    klass = *(Class *)klass;
  1275
+	}
1264 1276
     }
1265 1277
 
1266 1278
     const rb_vm_arity_t arity = rb_vm_node_arity(node);
@@ -3289,8 +3301,13 @@ rb_vm_yield_under(VALUE klass, VALUE self, int argc, const VALUE *argv)
3289 3301
 
3290 3302
     VALUE old_self = b->self;
3291 3303
     b->self = self;
3292  
-    //Class old_class = GET_VM()->current_class;
3293  
-    //GET_VM()->current_class = (Class)klass;
  3304
+    Class old_class = GET_VM()->current_class;
  3305
+    if (klass == self) {
  3306
+	// We only toggle the VM current klass in case #module_eval or
  3307
+	// #class_eval is used (where the given klass and self objects are 
  3308
+	// actually the same instances).
  3309
+	GET_VM()->current_class = (Class)klass;
  3310
+    }
3294 3311
 
3295 3312
     VALUE retval = Qnil;
3296 3313
     try {
@@ -3298,13 +3315,13 @@ rb_vm_yield_under(VALUE klass, VALUE self, int argc, const VALUE *argv)
3298 3315
     }
3299 3316
     catch (...) {
3300 3317
 	b->self = old_self;
3301  
-	//GET_VM()->current_class = old_class;
  3318
+	GET_VM()->current_class = old_class;
3302 3319
 	GET_VM()->add_current_block(b);
3303 3320
 	throw;
3304 3321
     }
3305 3322
 
3306 3323
     b->self = old_self;
3307  
-    //GET_VM()->current_class = old_class;
  3324
+    GET_VM()->current_class = old_class;
3308 3325
     GET_VM()->add_current_block(b);
3309 3326
 
3310 3327
     return retval;
1  vm.h
@@ -244,6 +244,7 @@ void rb_vm_push_methods(VALUE ary, VALUE mod, bool include_objc_methods,
244 244
 	int (*filter) (VALUE, ID, VALUE));
245 245
 int rb_vm_find_class_ivar_slot(VALUE klass, ID name);
246 246
 void rb_vm_set_outer(VALUE klass, VALUE under);
  247
+VALUE rb_vm_get_outer(VALUE klass);
247 248
 VALUE rb_vm_catch(VALUE tag);
248 249
 VALUE rb_vm_throw(VALUE tag, VALUE value);
249 250
 
2  vm_eval.c
@@ -498,7 +498,7 @@ rb_obj_instance_eval(VALUE self, SEL sel, int argc, VALUE *argv)
498 498
     VALUE klass;
499 499
 
500 500
     if (SPECIAL_CONST_P(self)) {
501  
-	klass = Qnil;
  501
+	klass = 0;
502 502
     }
503 503
     else {
504 504
 	klass = CLASS_OF(self);

0 notes on commit de8126f

Please sign in to comment.
Something went wrong with that request. Please try again.