Index: error.c
===================================================================
--- error.c	(revision 26674)
+++ error.c	(working copy)
@@ -402,4 +402,6 @@ VALUE rb_eSyntaxError;
 VALUE rb_eLoadError;
 
+VALUE rb_eNoConstantError;
+
 VALUE rb_eSystemCallError;
 VALUE rb_mErrno;
@@ -1143,4 +1145,5 @@ Init_Exception(void)
     rb_define_method(rb_eNoMethodError, "initialize", nometh_err_initialize, -1);
     rb_define_method(rb_eNoMethodError, "args", nometh_err_args, 0);
+    rb_eNoConstantError = rb_define_class("NoConstantError", rb_eNameError);
 
     rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
Index: variable.c
===================================================================
--- variable.c	(revision 26674)
+++ variable.c	(working copy)
@@ -1355,9 +1355,31 @@
 }
 
 static VALUE
+const_missing_call(VALUE arg)
+{
+    VALUE *args = (VALUE *)arg;
+    ID const_missing_id;
+    CONST_ID(const_missing_id, "const_missing");
+    return rb_check_funcall(args[0], const_missing_id, 1, &args[1]);
+}
+
+static VALUE
+const_missing_rescue(VALUE arg, VALUE errinfo)
+{
+    return arg;
+}
+
+extern VALUE rb_eNoConstantError;
+
+static VALUE
 const_missing(VALUE klass, ID id)
 {
-    return rb_funcall(klass, rb_intern("const_missing"), 1, ID2SYM(id));
+    VALUE args[2];
+    args[0] = klass;
+    args[1] = ID2SYM(id);
+    return rb_rescue2(const_missing_call, (VALUE)args,
+		      const_missing_rescue, (VALUE)Qundef,
+		      rb_eNoConstantError, (VALUE)0);
 }
 
 
@@ -1392,8 +1414,7 @@
 VALUE
 rb_mod_const_missing(VALUE klass, VALUE name)
 {
-    rb_frame_pop(); /* pop frame for "const_missing" */
-    uninitialized_constant(klass, rb_to_id(name));
+    rb_raise(rb_eNoConstantError, "uninitialized constant");
     return Qnil;		/* not reached */
 }
 
@@ -1596,8 +1617,26 @@
 	tmp = rb_cObject;
 	goto retry;
     }
+    
+    tmp = klass;
+    if ((value = const_missing(tmp, id)) == Qundef) {
+	NODE *rb_vm_cref(void);
+	NODE *cref = rb_vm_cref();
+        cref = cref->nd_next;
+        while (cref && cref->nd_next &&
+               ((cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) ||
+             NIL_P(tmp = cref->nd_clss) ||
+             (value = const_missing(tmp, id)) == Qundef)) {
+            cref = cref->nd_next;
+        }
+	if (value == Qundef) {
+	    if (!exclude && (BUILTIN_TYPE(klass) == T_MODULE || BUILTIN_TYPE(klass) == T_CLASS) &&
+		(value = const_missing(rb_cObject, id)) == Qundef) {
+		uninitialized_constant(klass, id);
+	    }
+	}
+    }
 
-    value = const_missing(klass, id);
     rb_vm_inc_const_missing_count();
     return value;
 }
