[macruby-changes] [958] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 17 15:17:55 PDT 2009


Revision: 958
          http://trac.macosforge.org/projects/ruby/changeset/958
Author:   lsansonetti at apple.com
Date:     2009-03-17 15:17:55 -0700 (Tue, 17 Mar 2009)
Log Message:
-----------
fixed bad arity exception + fixed method missing exception + added some tests

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/test_roxor.rb

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-03-17 22:00:45 UTC (rev 957)
+++ MacRuby/branches/experimental/roxor.cpp	2009-03-17 22:17:55 UTC (rev 958)
@@ -35,6 +35,9 @@
 
 extern "C" const char *ruby_node_name(int node);
 
+#define DISPATCH_VCALL 1
+#define DISPATCH_SUPER 2
+
 static VALUE rb_cTopLevel = 0;
 
 struct RoxorFunction
@@ -406,7 +409,7 @@
 	int safe_level;
 	std::map<NODE *, rb_vm_block_t *> blocks;
 	std::map<double, struct rb_float_cache *> float_cache;
-	int method_missing_reason;
+	unsigned char method_missing_reason;
 
 	RoxorVM(void);
 
@@ -834,7 +837,8 @@
 RoxorCompiler::compile_dispatch_call(std::vector<Value *> &params)
 {
     if (dispatcherFunc == NULL) {
-	// VALUE rb_vm_dispatch(struct mcache *cache, VALUE self, SEL sel, void *block, unsigned char super, int argc, ...);
+	// VALUE rb_vm_dispatch(struct mcache *cache, VALUE self, SEL sel,
+	//		        void *block, unsigned char opt, int argc, ...);
 	std::vector<const Type *> types;
 	types.push_back(PtrTy);
 	types.push_back(RubyObjTy);
@@ -2887,7 +2891,12 @@
 		    blockVal = block_given ? compile_block_create() : compile_const_pointer(NULL);
 		}
 		params.push_back(blockVal);
-		params.push_back(ConstantInt::get(Type::Int8Ty, super_call ? 1 : 0));
+		const unsigned char call_opt = super_call 
+		    ? DISPATCH_SUPER
+		    : (nd_type(node) == NODE_VCALL)
+			? DISPATCH_VCALL
+			: 0;
+		params.push_back(ConstantInt::get(Type::Int8Ty, call_opt));
 
 		int argc = 0;
 		if (nd_type(node) == NODE_ZSUPER) {
@@ -4315,32 +4324,39 @@
         rb_raise(rb_eArgError, "no id given");
     }
 
-    const int last_call_status = GET_VM()->method_missing_reason;
-
+    const unsigned char last_call_status = GET_VM()->method_missing_reason;
+    const char *format = NULL;
     VALUE exc = rb_eNoMethodError;
-    const char *format = NULL;
 
-    if (last_call_status & NOEX_PRIVATE) {
-        format = "private method `%s' called for %s";
+    switch (last_call_status) {
+#if 0 // TODO
+	case NOEX_PRIVATE:
+	    format = "private method `%s' called for %s";
+	    break;
+
+	case NOEX_PROTECTED:
+	    format = "protected method `%s' called for %s";
+	    break;
+#endif
+
+	case DISPATCH_VCALL:
+	    format = "undefined local variable or method `%s' for %s";
+	    exc = rb_eNameError;
+	    break;
+
+	case DISPATCH_SUPER:
+	    format = "super: no superclass method `%s' for %s";
+	    break;
+
+	default:
+	    format = "undefined method `%s' for %s";
+	    break;
     }
-    else if (last_call_status & NOEX_PROTECTED) {
-        format = "protected method `%s' called for %s";
-    }
-    else if (last_call_status & NOEX_VCALL) {
-        format = "undefined local variable or method `%s' for %s";
-        exc = rb_eNameError;
-    }
-    else if (last_call_status & NOEX_SUPER) {
-        format = "super: no superclass method `%s' for %s";
-    }
-    else {
-        format = "undefined method `%s' for %s";
-    }
 
     int n = 0;
     VALUE args[3];
-    args[n++] = rb_funcall(rb_const_get(exc, rb_intern("message")), '!',
-	    3, rb_str_new2(format), obj, argv[0]);
+    VALUE message = rb_const_get(exc, rb_intern("message"));
+    args[n++] = rb_funcall(message, '!', 3, rb_str_new2(format), obj, argv[0]);
     args[n++] = argv[0];
     if (exc == rb_eNoMethodError) {
 	args[n++] = rb_ary_new4(argc - 1, argv + 1);
@@ -4353,7 +4369,7 @@
 }
 
 static VALUE
-method_missing(VALUE obj, SEL sel, int argc, const VALUE *argv, int call_status)
+method_missing(VALUE obj, SEL sel, int argc, const VALUE *argv, unsigned char call_status)
 {
     GET_VM()->method_missing_reason = call_status;
 
@@ -4380,7 +4396,7 @@
 
 static inline VALUE
 __rb_vm_dispatch(struct mcache *cache, VALUE self, Class klass, SEL sel, 
-		 bool super, int argc, const VALUE *argv)
+		 unsigned char opt, int argc, const VALUE *argv)
 {
     assert(cache != NULL);
 
@@ -4395,7 +4411,7 @@
     if (cache->flag == 0) {
 recache:
 	Method method;
-	if (super) {
+	if (opt == DISPATCH_SUPER) {
 	    method = rb_vm_super_lookup((VALUE)klass, sel, NULL);
 	}
 	else {
@@ -4427,7 +4443,7 @@
 	}
 	else {
 	    // TODO bridgesupport C call?
-	    return method_missing((VALUE)self, sel, argc, argv, super);
+	    return method_missing((VALUE)self, sel, argc, argv, opt);
 	}
     }
 
@@ -4439,9 +4455,7 @@
 	// TODO we should cache the arity
 	const node_arity arity = rb_vm_node_arity(cache->as.rcall.node);
 	if ((argc < arity.min) || ((arity.max != -1) && (argc > arity.max))) {
-	    // TODO this should be an exception
-	    printf("bad arity given %d expected %d\n", argc, arity.min);
-	    abort();
+	    rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, arity.min);
 	}
 
 #if ROXOR_DEBUG
@@ -4511,7 +4525,7 @@
 extern "C"
 VALUE
 rb_vm_dispatch(struct mcache *cache, VALUE self, SEL sel, void *block, 
-	       unsigned char super, int argc, ...)
+	       unsigned char opt, int argc, ...)
 {
 #define MAX_DISPATCH_ARGS 200
     VALUE argv[MAX_DISPATCH_ARGS];
@@ -4557,12 +4571,13 @@
 
     if (block != NULL) {
 	GET_VM()->push_block((rb_vm_block_t *)block);
-	VALUE retval = __rb_vm_dispatch(cache, self, NULL, sel, super, argc, argv);
+	VALUE retval = 
+	    __rb_vm_dispatch(cache, self, NULL, sel, opt, argc, argv);
 	GET_VM()->pop_block();
 	return retval;
     }
 
-    return __rb_vm_dispatch(cache, self, NULL, sel, super, argc, argv);
+    return __rb_vm_dispatch(cache, self, NULL, sel, opt, argc, argv);
 }
 
 extern "C"
@@ -4619,7 +4634,7 @@
 	rb_ary_push(obj, other);
 	return other;
     }
-    return __rb_vm_dispatch(cache, obj, NULL, selLTLT, false, 1, &other);
+    return __rb_vm_dispatch(cache, obj, NULL, selLTLT, 0, 1, &other);
 }
 
 extern "C"
@@ -4634,7 +4649,7 @@
 	extern VALUE rb_ary_aref(VALUE ary, SEL sel, int argc, VALUE *argv);
 	return rb_ary_aref(obj, 0, 1, &other);
     }
-    return __rb_vm_dispatch(cache, obj, NULL, selAREF, false, 1, &other);
+    return __rb_vm_dispatch(cache, obj, NULL, selAREF, 0, 1, &other);
 }
 
 extern "C"
@@ -4651,7 +4666,7 @@
     VALUE args[2];
     args[0] = other1;
     args[1] = other2;
-    return __rb_vm_dispatch(cache, obj, NULL, selASET, false, 2, args);
+    return __rb_vm_dispatch(cache, obj, NULL, selASET, 0, 2, args);
 }
 
 extern "C"
@@ -4704,7 +4719,8 @@
     if (super) {
 	struct mcache cache; 
 	cache.flag = 0;
-	VALUE retval = __rb_vm_dispatch(&cache, self, NULL, sel, true, argc, argv);
+	VALUE retval = __rb_vm_dispatch(&cache, self, NULL, sel, 
+					DISPATCH_SUPER, argc, argv);
 	if (cache.flag == MCACHE_OCALL) {
 	    free(cache.as.ocall.helper);
 	}
@@ -4712,7 +4728,7 @@
     }
     else {
 	struct mcache *cache = GET_VM()->method_cache_get(sel, false);
-	return __rb_vm_dispatch(cache, self, NULL, sel, false, argc, argv);
+	return __rb_vm_dispatch(cache, self, NULL, sel, 0, argc, argv);
     }
 }
 
@@ -4721,7 +4737,7 @@
 rb_vm_call_with_cache(void *cache, VALUE self, SEL sel, int argc, 
 		      const VALUE *argv)
 {
-    return __rb_vm_dispatch((struct mcache *)cache, self, NULL, sel, false,
+    return __rb_vm_dispatch((struct mcache *)cache, self, NULL, sel, 0,
 	    argc, argv);
 }
 
@@ -4731,7 +4747,7 @@
 		       const VALUE *argv)
 {
     return __rb_vm_dispatch((struct mcache *)cache, self, (Class)klass, sel,
-	    false, argc, argv);
+	    0, argc, argv);
 }
 
 extern "C"

Modified: MacRuby/branches/experimental/test_roxor.rb
===================================================================
--- MacRuby/branches/experimental/test_roxor.rb	2009-03-17 22:00:45 UTC (rev 957)
+++ MacRuby/branches/experimental/test_roxor.rb	2009-03-17 22:17:55 UTC (rev 958)
@@ -631,7 +631,13 @@
 
   assert ":ok", "def f(); end; begin f(1); rescue ArgumentError; p :ok; rescue; p :ko; end"
   assert ":ok", "def f(a); end; begin f; rescue ArgumentError; p :ok; rescue; p :ko; end"
+  assert ":ok", "def f(a); end; begin f(1, 2); rescue ArgumentError; p :ok; rescue; p :ko; end"
+  assert ':ok', "def f(a, b); end; begin; f; rescue ArgumentError; p :ok; rescue; p :ko; end"
+  assert ':ok', "def f(a, b); end; begin; f(1, 2, 3); rescue ArgumentError; p :ok; rescue; p :ko; end"
   
+  assert ':ok', "def f(a, b); end; begin; a=[1]; f(*a); rescue ArgumentError; p :ok; rescue; p :ko; end"
+  assert ':ok', "def f(a, b); end; begin; a=[1,2,3]; f(*a); rescue ArgumentError; p :ok; rescue; p :ko; end"
+
   assert ":ok", %{
     def func()
       1.times { |x| func() }
@@ -791,7 +797,7 @@
 
   assert ":ok", %q{
     begin
-      foo
+      self.foo
     rescue => e
       p :ok if e.is_a?(NoMethodError)
     end
@@ -799,6 +805,14 @@
 
   assert ":ok", %q{
     begin
+      self.foo
+    rescue => e
+      p :ok if e.is_a?(NameError)
+    end
+  }
+
+  assert ":ok", %q{
+    begin
       1.times { raise }
     rescue
       p :ok
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090317/fa852898/attachment-0001.html>


More information about the macruby-changes mailing list