changeset 15909:b8bff84022d6 classdef

Use strong reference between objects and their class. * libinterp/octave-value/ov-classdef.h (cdef_object_rep::cname): Remove member. (cdef_object_rep::cdef_object_rep (void), cdef_object_rep::cdef_object_rep (cdef_object_rep)): Do not initialize it. (cdef_object_rep::cdef_object_rep (std::string)): Remove constructor. (cdef_object_rep::set_class_name): Remove method. (cdef_object_rep::grip_invalid_object): New private method. (cdef_object_rep::set_class, cdef_object_rep::is_class, cdef_object_rep::is_property, cdef_object_rep::is_method, cdef_object_rep::is_package): New methods. (cdef_object_rep::map, cdef_object_rep::ctor_list): Move members to cdef_object_scalar. (cdef_object_rep::put, cdef_object_rep::get, cdef_object_rep::subsref, cdef_object_rep::subsasgn, cdef_object_rep::mark_for_construction, cdef_object_rep::is_constructed_for, cdef_object_rep::mark_as_constructed, cdef_object_rep::is_partially_constructed_for, cdef_object_rep::is_constructed): Move implementation to cdef_object_scalar. (cdef_object_rep::is_constructed_for, cdef_object_rep::mark_as_constructed, cdef_object_rep::is_partially_constructed_for): Change signature, use cdef_class argument instead of std::string. (cdef_object_rep::class_name): Use get_class () and move inline definition after cdef_class declaration. (cdef_object::set_class_name): Remove method. (cdef_object::is_class, cdef_object::is_property, cdef_object::is_method, cdef_object::is_package): New methods. (cdef_object::is_constructed_for, cdef_object::mark_as_constructed, cdef_object::is_partially_constructed_for): Change signature, use cdef_class instead of std::string. (class cdef_object_base, class cdef_object_scalar): New classes. (class handle_cdef_object, class value_cdef_object): Inherits from cdef_object_scalar. (handle_cdef_object::handle_cdef_object (std::string)): Remove constructor. (value_cdef_object::value_cdef_object (std::string)): Likewise. (value_cdef_object::value_cdef_object (value_cdef_object)): Implement copy constructor. (value_cdef_object::clone): Use it. (cdef_class::cdef_class_rep::cdef_class_rep): Remove first string argument. (cdef_class::cdef_class_rep::is_class, cdef_class::cdef_class_rep::set_name, cdef_class::cdef_class_rep::wrap): New methods. (cdef_class::cdef_class_rep::implicit_ctor_list): Change type to std::list<cdef_class>. (cdef_class::cdef_class (std::string): Remove constructor. (cdef_class::cdef_class (std::list<cdef_class>)): Use string argument as the class name. (cdef_class::cdef_class (cdef_object), cdef_class::operator= (cdef_object)): Use is_class method. (cdef_class::_meta_class, cdef_class::_meta_property, cdef_class::_meta_method, cdef_class::_meta_package): New static members. (cdef_class::meta_class, cdef_class::meta_property, cdef_class::meta_method, cdef_class::meta_package): New static methods. (operator< (cdef_cass, cdef_class)): New function. (cdef_property::cdef_property_rep::cdef_property_rep): Remove first argument string. (cdef_property::cdef_property_rep::is_property, cdef_property::cdef_property_rep::get_name, cdef_property::cdef_property_rep::set_name, cdef_property::cdef_property_rep::is_constant): New methods. (cdef_property::get_name, cdef_property::is_constant): Use them. (cdef_property::cdef_property (std::string)): Use string argument as property name. (cdef_property::cdef_property (cdef_object)): Use is_property method. (cdef_method::cdef_method_rep::cdef_method_rep): Remove first argument string. (cdef_method::cdef_method_rep::is_method, cdef_method::cdef_method_rep::get_name, cdef_method::cdef_method_rep::set_name, cdef_method::cdef_method_rep::is_static): New methods. (cdef_method::get_name, cdef_method::is_static): Use them. (cdef_method::cdef_method (std::string)): Use string argument as method name. (cdef_method::cdef_method (cdef_object)): Use is_method method. (cdef_package::cdef_package_rep::cdef_package_rep): Remove first argument string. (cdef_package::cdef_package_rep::is_package, cdef_package::cdef_package_rep::get_name, cdef_package::cdef_package_rep::set_name): New methods. (cdef_package::get_name): Likewise. (cdef_package::cdef_package (std::string)): Use string argument as package name. (cdef_package::cdef_package (cdef_object)): Use is_package method. (cdef_package::_meta): New static member. (cdef_package::meta): New static method. * libinterp/octave-value/ov-classdef.cc (lookup_class (cdef_class), lookup_class (octave_value)): New static function overloads. (lookup_classes): Change argument name to reflect the fact we're using now a list of cdef_class objects, not a list of names. (make_class, make_property, make_method, make_package): Use name as constructor argument. Set object class. (cdef_object_rep::get_class): Move implementation to header. (cdef_object_rep::subsref, cdef_object_rep::subsasgn, cdef_object_rep::mark_for_construction): Move implementation to cdef_object_scalar. (cdef_object_scalar::is_constructed_for, cdef_object_scalar::is_partially_constructed_for): Moved from cdef_object_rep. (handle_cdef_object::~handle_cdef_object, value_cdef_object::~value_cdef_object): Do not use cname. (cdef_class::cdef_class_rep::cdef_class_rep (std::list<cdef_class>)): Remove first string argument. Keep strong references to cdef_class superclass objects. (cdef_class::cdef_class_rep::find_method, cdef_class::cdef_class_rep::find_methods, cdef_class::cdef_class_rep::find_property, cdef_class::cdef_class_rep::find_properties, cdef_class::cdef_class_rep::find_names, cdef_class::cdef_class_rep::delete_object): Superclasses are now strong references for cdef_class objects. (ctor_analyzer::available_ctor_list): Remove member. (ctor_analyzer::ctor_analyzer): Do not use it. (ctor_analyzer::ctor_list): Change type to std::list<cdef_class>. (ctor_analyzer::visit_funcall): Use it. Do not produce any error. (cdef_class::cdef_class_rep::install_method): Use strong references to cdef_class superclass objects. (cdef_class::cdef_class_rep::run_constructor): Likewise. (cdef_class::cdef_class_rep::construct): Use strong reference to cdef_class object. (cdef_property::cdef_property_rep::get_value, cdef_property::cdef_property_rep::set_value): Likewise. (cdef_class::_meta_class, cdef_class::_meta_property, cdef_class::_meta_method, cdef_class::_meta_package): Initialize static members. (cdef_package::_meta): Likewise. (install_classdef): Bootstrap meta classes with strong references to cdef_class. Assign cdef_class and cdef_package static members.
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 06 Jan 2013 12:19:16 -0500
parents a413c6fe1726
children dfd0dc594c4f
files libinterp/octave-value/ov-classdef.cc libinterp/octave-value/ov-classdef.h
diffstat 2 files changed, 430 insertions(+), 207 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-classdef.cc	Fri Jan 04 14:29:13 2013 -0500
+++ b/libinterp/octave-value/ov-classdef.cc	Sun Jan 06 12:19:16 2013 -0500
@@ -179,14 +179,39 @@
   return cdef_class ();
 }
 
+static cdef_class
+lookup_class (const cdef_class& cls)
+{
+  // FIXME: placeholder for the time being, the purpose
+  //        is to centralized any class update activity here.
+
+  return cls;
+}
+
+static cdef_class
+lookup_class (const octave_value& ov)
+{
+  if (ov.is_string())
+    return lookup_class (ov.string_value ());
+  else
+    {
+      cdef_class cls (to_cdef (ov));
+
+      if (! error_state)
+        return lookup_class (cls);
+    }
+
+  return cdef_class ();
+}
+
 static std::list<cdef_class>
-lookup_classes (const Cell& cls_names)
+lookup_classes (const Cell& cls_list)
 {
   std::list<cdef_class> retval;
 
-  for (int i = 0; i < cls_names.numel (); i++)
+  for (int i = 0; i < cls_list.numel (); i++)
     {
-      cdef_class c = lookup_class (cls_names(i).string_value ());
+      cdef_class c = lookup_class (cls_list(i));
 
       if (! error_state)
         retval.push_back (c);
@@ -227,7 +252,7 @@
 
       for (int i = 0; ! error_state && ! retval && i < c.numel (); i++)
 	{
-	  cdef_class cls = lookup_class (c(i).string_value ());
+	  cdef_class cls = lookup_class (c(i));
 
 	  if (! error_state)
 	    retval = is_superclass (clsa, cls, true,
@@ -583,8 +608,9 @@
 make_class (const std::string& name,
             const std::list<cdef_class>& super_list = std::list<cdef_class> ())
 {
-  cdef_class cls ("meta.class", super_list);
-
+  cdef_class cls (name, super_list);
+
+  cls.set_class (cdef_class::meta_class ());
   cls.put ("ConstructOnLoad", false);
   cls.put ("ContainingPackage", Matrix ());
   cls.put ("Description", std::string ());
@@ -593,7 +619,6 @@
   cls.put ("Hidden", false);
   cls.put ("InferiorClasses", Cell ());
   cls.put ("Methods", Cell ());
-  cls.put ("Name", name);
   cls.put ("Properties", Cell ());
   cls.put ("Sealed", false);
 
@@ -652,9 +677,9 @@
 {
   // FIXME: what about default value?
 
-  cdef_property prop ("meta.property");
-
-  prop.put ("Name", name);
+  cdef_property prop (name);
+
+  prop.set_class (cdef_class::meta_property ());
   prop.put ("Description", std::string ());
   prop.put ("DetailedDescription", std::string ());
   prop.put ("Abstract", false);
@@ -693,15 +718,15 @@
              const octave_value& fcn,const std::string& m_access = "public",
              bool is_static = false)
 {
-  cdef_method meth ("meta.method");
-
+  cdef_method meth (name);
+
+  meth.set_class (cdef_class::meta_method ());
   meth.put ("Abstract", false);
   meth.put ("Access", m_access);
   meth.put ("DefiningClass", to_ov (cls));
   meth.put ("Description", std::string ());
   meth.put ("DetailedDescription", std::string ());
   meth.put ("Hidden", false);
-  meth.put ("Name", name);
   meth.put ("Sealed", true);
   meth.put ("Static", is_static);
 
@@ -728,10 +753,12 @@
 {
   cdef_package pack ("meta.package");
 
-  all_packages[nm] = pack;
+  pack.set_class (cdef_class::meta_package ());
   pack.put ("Name", nm);
   pack.put ("ContainingPackage", to_ov (all_packages[parent]));
 
+  all_packages[nm] = pack;
+
   return pack;
 }
 
@@ -981,14 +1008,6 @@
 
 //----------------------------------------------------------------------------
 
-cdef_class
-cdef_object_rep::get_class (void) const
-{
-  cdef_class cls = lookup_class (class_name ());
-
-  return cls;
-}
-
 string_vector
 cdef_object_rep::map_keys (void) const
 {
@@ -1001,10 +1020,10 @@
 }
 
 octave_value_list
-cdef_object_rep::subsref (const std::string& type,
-                          const std::list<octave_value_list>& idx,
-                          int nargout, size_t& skip,
-                          const cdef_class& context)
+cdef_object_scalar::subsref (const std::string& type,
+                             const std::list<octave_value_list>& idx,
+                             int nargout, size_t& skip,
+                             const cdef_class& context)
 {
   skip = 0;
 
@@ -1084,9 +1103,9 @@
 }
 
 octave_value
-cdef_object_rep::subsasgn (const std::string& type,
-                           const std::list<octave_value_list>& idx,
-                           const octave_value& rhs)
+cdef_object_scalar::subsasgn (const std::string& type,
+                              const std::list<octave_value_list>& idx,
+                              const octave_value& rhs)
 {
   octave_value retval;
 
@@ -1143,7 +1162,7 @@
 }
 
 void
-cdef_object_rep::mark_for_construction (const cdef_class& cls)
+cdef_object_scalar::mark_for_construction (const cdef_class& cls)
 {
   std::string cls_name = cls.get_name ();
 
@@ -1151,35 +1170,54 @@
 
   if (! error_state)
     {
-      std::list<std::string> supcls_names;
-
-      for (int i = 0; ! error_state && i < supcls.numel (); i++)
-        supcls_names.push_back (supcls(i).string_value ());
+      std::list<cdef_class> supcls_list = lookup_classes (supcls);
 
       if (! error_state)
-        ctor_list[cls_name] = supcls_names;
+        ctor_list[cls] = supcls_list;
     }
 }
+  
+bool cdef_object_scalar::is_constructed_for (const cdef_class& cls) const
+{
+  return (is_constructed ()
+          || ctor_list.find (cls) == ctor_list.end ());
+}
+
+bool cdef_object_scalar::is_partially_constructed_for (const cdef_class& cls) const
+{
+  std::map< cdef_class, std::list<cdef_class> >::const_iterator it;
+
+  if (is_constructed ())
+    return true;
+  else if ((it = ctor_list.find (cls)) == ctor_list.end ()
+           || it->second.empty ())
+    return true;
+
+  for (std::list<cdef_class>::const_iterator lit = it->second.begin ();
+       lit != it->second.end (); ++lit)
+    if (! is_constructed_for (*lit))
+      return false;
+
+  return true;
+}
 
 handle_cdef_object::~handle_cdef_object (void)
 {
-  gnulib::printf ("deleting %s object (handle)\n", cname.c_str ());
+  gnulib::printf ("deleting %s object (handle)\n",
+                  get_class ().get_name ().c_str ());
 }
 
 value_cdef_object::~value_cdef_object (void)
 {
-  gnulib::printf ("deleting %s object (value)\n", cname.c_str ());
+  gnulib::printf ("deleting %s object (value)\n",
+                  get_class ().get_name ().c_str ());
 }
 
-cdef_class::cdef_class_rep::cdef_class_rep (const std::string& nm,
-                                            const std::list<cdef_class>& superclasses)
-     : handle_cdef_object (nm), handle_class (false)
+cdef_class::cdef_class_rep::cdef_class_rep (const std::list<cdef_class>& superclasses)
+     : handle_cdef_object (), handle_class (false)
 {
-  for (std::list<cdef_class>::const_iterator it = superclasses.begin ();
-       it != superclasses.end (); ++it)
-    implicit_ctor_list.push_back (it->get_name ());
-
-  put ("SuperClasses", Cell (implicit_ctor_list));
+  put ("SuperClasses", to_ov (superclasses));
+  implicit_ctor_list = superclasses;
 }
 
 cdef_method
@@ -1209,7 +1247,7 @@
 
       for (int i = 0; i < super_classes.numel (); i++)
         {
-          cdef_class cls = lookup_class (super_classes(i).string_value ());
+          cdef_class cls = lookup_class (super_classes(i));
 
           if (! error_state)
             {
@@ -1227,9 +1265,8 @@
 class ctor_analyzer : public tree_walker
 {
 public:
-  ctor_analyzer (const std::string& ctor, const std::string& obj,
-                 const std::list<std::string>& l)
-    : tree_walker (), who (ctor), obj_name (obj), available_ctor_list (l) { }
+  ctor_analyzer (const std::string& ctor, const std::string& obj)
+    : tree_walker (), who (ctor), obj_name (obj) { }
 
   void visit_statement_list (tree_statement_list& t)
     {
@@ -1282,24 +1319,17 @@
                                                ? class_name
                                                : package_name + "." + class_name);
 
-                      if (std::find (available_ctor_list.begin (),
-                                     available_ctor_list.end (), ctor_name)
-                          == available_ctor_list.end ())
-                        ::error ("`%s' is not a direct superclass of `%s'",
-                                 ctor_name.c_str (), who.c_str ());
-                      else if (std::find (ctor_list.begin (), ctor_list.end (),
-                                          ctor_name) != ctor_list.end ())
-                        ::error ("calling constructor `%s' more than once",
-                                 ctor_name.c_str ());
-
-                      ctor_list.push_back (ctor_name);
+                      cdef_class cls = lookup_class (ctor_name, false);
+
+                      if (cls.ok ())
+                        ctor_list.push_back (cls);
                     }
                 }
             }
         }
     }
 
-  std::list<std::string> get_constructor_list (void) const
+  std::list<cdef_class> get_constructor_list (void) const
     { return ctor_list; }
 
   // NO-OP
@@ -1348,10 +1378,7 @@
   std::string obj_name;
 
   /* The list of superclass constructors that are explicitly called */
-  std::list<std::string> ctor_list;
-
-  /* The list of possible superclass constructors */
-  std::list<std::string> available_ctor_list;
+  std::list<cdef_class> ctor_list;
 };
 
 void
@@ -1378,20 +1405,19 @@
               if (ret_list && ret_list->size () == 1)
                 {
                   std::string obj_name = ret_list->front ()->name ();
-                  ctor_analyzer a (meth.get_name (), obj_name,
-                                   implicit_ctor_list);
+                  ctor_analyzer a (meth.get_name (), obj_name);
 
                   body->accept (a);
                   if (! error_state)
                     {
-                      std::list<std::string> explicit_ctor_list
+                      std::list<cdef_class> explicit_ctor_list
                         = a.get_constructor_list ();
 
-                      for (std::list<std::string>::const_iterator it = explicit_ctor_list.begin ();
+                      for (std::list<cdef_class>::const_iterator it = explicit_ctor_list.begin ();
                            ! error_state && it != explicit_ctor_list.end (); ++it)
                         {
                           gnulib::printf ("explicit superclass constructor: %s\n",
-                                  it->c_str ());
+                                          it->get_name ().c_str ());
                           implicit_ctor_list.remove (*it);
                         }
                     }
@@ -1471,7 +1497,7 @@
 
   for (int i = 0; i < super_classes.numel (); i++)
     {
-      cdef_class cls = lookup_class (super_classes(i).string_value ());
+      cdef_class cls = lookup_class (super_classes(i));
 
       if (! error_state)
 	cls.get_rep ()->find_methods (meths, true);
@@ -1499,7 +1525,7 @@
 
   for (int i = 0; i < super_classes.numel (); i++)
     {
-      cdef_class cls = lookup_class (super_classes(i).string_value ());
+      cdef_class cls = lookup_class (super_classes(i));
 
       if (! error_state)
 	{
@@ -1574,7 +1600,7 @@
 
   for (int i = 0; ! error_state && i < super_classes.numel (); i++)
     {
-      cdef_class cls = lookup_class (super_classes(i).string_value ());
+      cdef_class cls = lookup_class (super_classes(i));
 
       if (! error_state)
 	cls.get_rep ()->find_properties (props, true);
@@ -1634,7 +1660,7 @@
 
   for (int i = 0; ! error_state && i < super_classes.numel (); i++)
     {
-      cdef_class cls = lookup_class (super_classes(i).string_value ());
+      cdef_class cls = lookup_class (super_classes(i));
 
       if (! error_state)
 	cls.get_rep ()->find_names (names, all);
@@ -1672,13 +1698,13 @@
 
   if (it != method_map.end ())
     {
-      std::string cls_name = obj.class_name ();
-
-      obj.set_class_name (get ("Name").string_value ());
+      cdef_class cls = obj.get_class ();
+
+      obj.set_class (wrap ());
 
       it->second.execute (obj, octave_value_list (), 0);
 
-      obj.set_class_name (cls_name);
+      obj.set_class (cls);
     }
 
   // FIXME: should we destroy corresponding properties here?
@@ -1689,7 +1715,7 @@
 
   for (int i = 0; i < super_classes.numel (); i++)
     {
-      cdef_class cls = lookup_class (super_classes(i).string_value ());
+      cdef_class cls = lookup_class (super_classes(i));
 
       if (!error_state)
 	cls.delete_object (obj);
@@ -1769,7 +1795,7 @@
 {
   octave_value_list empty_args;
 
-  for (std::list<std::string>::const_iterator it = implicit_ctor_list.begin ();
+  for (std::list<cdef_class>::const_iterator it = implicit_ctor_list.begin ();
        ! error_state && it != implicit_ctor_list.end (); ++it)
     {
       cdef_class supcls = lookup_class (*it);
@@ -1807,7 +1833,7 @@
         }
     }
 
-  obj.mark_as_constructed (cls_name);
+  obj.mark_as_constructed (wrap ());
 }
 
 octave_value
@@ -1816,9 +1842,10 @@
   cdef_object_rep *r;
 
   if (is_handle_class ())
-    r = new handle_cdef_object (get_name ());
+    r = new handle_cdef_object ();
   else
-    r = new value_cdef_object (get_name ());
+    r = new value_cdef_object ();
+  r->set_class (wrap ());
 
   cdef_object obj (r);
 
@@ -2071,7 +2098,7 @@
     {
       cdef_class cls (to_cdef (get ("DefiningClass")));
 
-      if (! obj.is_partially_constructed_for (cls.get_name ()))
+      if (! obj.is_partially_constructed_for (cls))
         {
           ::error ("cannot reference properties of class `%s' for non-constructed object",
                    cls.get_name ().c_str ());
@@ -2115,7 +2142,7 @@
     {
       cdef_class cls (to_cdef (get ("DefiningClass")));
 
-      if (! obj.is_partially_constructed_for (cls.get_name ()))
+      if (! obj.is_partially_constructed_for (cls))
         {
           ::error ("cannot reference properties of class `%s' for non-constructed object",
                    cls.get_name ().c_str ());
@@ -2389,26 +2416,38 @@
 cdef_package::cdef_package_rep::get_packages (void) const
 { return map2Cell (package_map); }
 
+cdef_class cdef_class::_meta_class = cdef_class ();
+cdef_class cdef_class::_meta_property = cdef_class ();
+cdef_class cdef_class::_meta_method = cdef_class ();
+cdef_class cdef_class::_meta_package = cdef_class ();
+
+cdef_package cdef_package::_meta = cdef_package ();
+
 void
 install_classdef (void)
 {
   octave_classdef::register_type ();
 
-  /* meta classes */
+  /* bootstrap */
   cdef_class handle = make_class ("handle");
-  cdef_class meta_class = make_class ("meta.class", handle);
-  cdef_class meta_property = make_class ("meta.property", handle);
-  cdef_class meta_method = make_class ("meta.method", handle);
+  cdef_class meta_class = cdef_class::_meta_class = make_class ("meta.class", handle);
+  handle.set_class (meta_class);
+  meta_class.set_class (meta_class);
+
+  /* meta classes */
+  cdef_class meta_property = cdef_class::_meta_property = make_class ("meta.property", handle);
+  cdef_class meta_method = cdef_class::_meta_method = make_class ("meta.method", handle);
+  cdef_class meta_package = cdef_class::_meta_package = make_class ("meta.package", handle);
+
   cdef_class meta_event = make_class ("meta.event", handle);
-  cdef_class meta_package = make_class ("meta.package", handle);
   cdef_class meta_dynproperty = make_class ("meta.dynamicproperty", handle);
 
   /* meta classes are all sealed */
   meta_class.put ("Sealed", true);
   meta_property.put ("Sealed", true);
   meta_method.put ("Sealed", true);
+  meta_package.put ("Sealed", true);
   meta_event.put ("Sealed", true);
-  meta_package.put ("Sealed", true);
   meta_dynproperty.put ("Sealed", true);
 
   /* meta.class properties */
@@ -2532,7 +2571,7 @@
                                             "public", true));
 
   /* create "meta" package */
-  cdef_package package_meta = make_package ("meta");
+  cdef_package package_meta = cdef_package::_meta = make_package ("meta");
   package_meta.install_class (meta_class,       "class");
   package_meta.install_class (meta_property,    "property");
   package_meta.install_class (meta_method,      "method");
--- a/libinterp/octave-value/ov-classdef.h	Fri Jan 04 14:29:13 2013 -0500
+++ b/libinterp/octave-value/ov-classdef.h	Sun Jan 06 12:19:16 2013 -0500
@@ -38,6 +38,9 @@
 
 class tree_classdef;
 
+// This is mainly a boostrap class to declare the expected interface.
+// The actual base class is cdef_class_base, which is declared after
+// cdef_object, such that it can contain cdef_object objects.
 class
 cdef_object_rep
 {
@@ -45,110 +48,102 @@
   friend class cdef_object;
 
 public:
-  cdef_object_rep (void)
-      : refcount (1), cname () { }
-
-  cdef_object_rep (const std::string& nm)
-      : refcount (1), cname (nm) { }
+  cdef_object_rep (void) : refcount (1) { }
 
   virtual ~cdef_object_rep (void) { }
 
   virtual cdef_class get_class (void) const;
 
+  virtual void set_class (const cdef_class&)
+    { gripe_invalid_object ("set_class"); }
+
   virtual cdef_object_rep* clone (void) const
     {
-      error ("clone: invalid object");
+      gripe_invalid_object ("clone");
       return new cdef_object_rep ();
     }
 
-  virtual void put (const std::string& pname, const octave_value& val)
-    { map.assign (pname, val); }
+  virtual bool is_class (void) const { return false; }
+
+  virtual bool is_property (void) const { return false; }
 
-  virtual octave_value get (const std::string& pname) const
-    {
-      Cell val = map.contents (pname);
+  virtual bool is_method (void) const { return false; }
+
+  virtual bool is_package (void) const { return false; }
 
-      if (val.numel () > 0)
-	return val(0, 0);
-      else
-	{
-	  error ("get: unknown slot: %s", pname.c_str ());
-	  return octave_value ();
-	}
+  virtual void put (const std::string&, const octave_value&)
+    { gripe_invalid_object ("put"); }
+
+  virtual octave_value get (const std::string&) const
+    {
+      gripe_invalid_object ("get");
+      return octave_value ();
     }
 
   virtual octave_value_list
-  subsref (const std::string& type, const std::list<octave_value_list>& idx,
-           int nargout, size_t& skip, const cdef_class& context);
+  subsref (const std::string&, const std::list<octave_value_list>&,
+           int, size_t&, const cdef_class&)
+    {
+      gripe_invalid_object ("subsref");
+      return octave_value_list ();
+    }
 
   virtual octave_value
-  subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
-            const octave_value& rhs);
+  subsasgn (const std::string&, const std::list<octave_value_list>&,
+            const octave_value&)
+    {
+      gripe_invalid_object ("subsasgn");
+      return octave_value ();
+    }
 
   virtual string_vector map_keys(void) const;
 
   virtual bool is_valid (void) const { return false; }
 
-  std::string class_name (void) const { return cname; }
+  std::string class_name (void) const;
 
-  void set_class_name (const std::string& nm) { cname = nm; }
-
-  void mark_for_construction (const cdef_class&);
+  virtual void mark_for_construction (const cdef_class&)
+    { gripe_invalid_object ("mark_for_construction"); }
 
-  //bool is_constructed_for (const cdef_class&) const;
-
-  bool is_constructed_for (const std::string& nm) const
+  virtual bool is_constructed_for (const cdef_class&) const
     {
-      return (is_constructed ()
-              || ctor_list.find (nm) == ctor_list.end ());
+      gripe_invalid_object ("is_constructed_for");
+      return false;
     }
 
-  bool is_partially_constructed_for (const std::string& nm) const
+  virtual bool is_partially_constructed_for (const cdef_class&) const
     {
-      std::map< std::string, std::list<std::string> >::const_iterator it;
-
-      if (is_constructed ())
-        return true;
-      else if ((it = ctor_list.find (nm)) == ctor_list.end ()
-               || it->second.empty ())
-        return true;
-
-      for (std::list<std::string>::const_iterator lit = it->second.begin ();
-           lit != it->second.end (); ++lit)
-        if (! is_constructed_for (*lit))
-          return false;
-
-      return true;
+      gripe_invalid_object ("is_partially_constructed_for");
+      return false;
     }
 
-  void mark_as_constructed (void) { ctor_list.clear (); }
+  virtual void mark_as_constructed (void)
+    { gripe_invalid_object ("mark_as_constructed"); }
+
+  virtual void mark_as_constructed (const cdef_class&)
+    { gripe_invalid_object ("mark_as_constructed"); }
 
-  void mark_as_constructed (const std::string& nm) { ctor_list.erase (nm); }
-
-  bool is_constructed (void) const { return ctor_list.empty (); }
+  virtual bool is_constructed (void) const
+    {
+      gripe_invalid_object ("is_constructed");
+      return false;
+    }
 
 protected:
   /* reference count */
   octave_refcount<int> refcount;
 
-  /* class name */
-  std::string cname;
-
-  /* object property values */
-  Octave_map map;
-
-  /* Internal/temporary structure used during object construction */
-  std::map< std::string, std::list<std::string> > ctor_list;
-
 protected:
   /* Restricted copying */
-  cdef_object_rep (const cdef_object_rep& r)
-    : refcount (1), cname (r.cname), map (r.map),
-      ctor_list (r.ctor_list) { }
+  cdef_object_rep (const cdef_object_rep&)
+    : refcount (1) { }
 
 private:
   /* No assignment */
   cdef_object_rep& operator = (const cdef_object_rep& );
+
+  void gripe_invalid_object (const char *who) const
+    { error ("%s: invalid object", who); }
 };
 
 class
@@ -190,8 +185,7 @@
 
   cdef_class get_class (void) const;
 
-  void set_class_name (const std::string& nm)
-    { rep->set_class_name (nm); }
+  void set_class (const cdef_class& cls) { rep->set_class (cls); }
 
   std::string class_name (void) const
     { return rep->class_name (); }
@@ -199,6 +193,14 @@
   cdef_object clone (void) const
     { return cdef_object (rep->clone ()); }
 
+  bool is_class (void) const { return rep->is_class (); }
+
+  bool is_property (void) const { return rep->is_property (); }
+
+  bool is_method (void) const { return rep->is_method (); }
+
+  bool is_package (void) const { return rep->is_package (); }
+
   void put (const std::string& pname, const octave_value& val)
     { rep->put (pname, val); }
 
@@ -226,16 +228,16 @@
 
   bool is_constructed (void) const { return rep->is_constructed (); }
 
-  bool is_constructed_for (const std::string& nm) const
-    { return rep->is_constructed_for (nm); }
+  bool is_constructed_for (const cdef_class& cls) const
+    { return rep->is_constructed_for (cls); }
 
-  bool is_partially_constructed_for (const std::string& nm) const
-    { return rep->is_partially_constructed_for (nm); }
+  bool is_partially_constructed_for (const cdef_class& cls) const
+    { return rep->is_partially_constructed_for (cls); }
 
   void mark_as_constructed (void) { rep->mark_as_constructed (); }
 
-  void mark_as_constructed (const std::string& nm)
-    { rep->mark_as_constructed (nm); }
+  void mark_as_constructed (const cdef_class& cls)
+    { rep->mark_as_constructed (cls); }
 
 protected:
   cdef_object_rep* get_rep (void) { return rep; }
@@ -245,14 +247,110 @@
 };
 
 class
-handle_cdef_object : public cdef_object_rep
+cdef_object_base : public cdef_object_rep
+{
+public:
+  cdef_object_base (void)
+    : cdef_object_rep (), klass ()
+    {
+      register_object ();
+    }
+
+  ~cdef_object_base (void) { unregister_object (); }
+
+  cdef_class get_class (void) const;
+
+  void set_class (const cdef_class& cls);
+
+protected:
+  // Restricted copying!
+  cdef_object_base (const cdef_object_base& obj)
+    : cdef_object_rep (obj), klass (obj.klass)
+    {
+      register_object ();
+    }
+
+private:
+  void register_object (void);
+
+  void unregister_object (void);
+
+private:
+  // The class of the object
+  cdef_object klass;
+
+private:
+  // No assignment!
+  cdef_object_base& operator = (const cdef_object_base&);
+};
+
+class
+cdef_object_scalar : public cdef_object_base
+{
+public:
+  cdef_object_scalar (void) : cdef_object_base () { }
+
+  ~cdef_object_scalar (void) { }
+
+  void put (const std::string& pname, const octave_value& val)
+    { map.assign (pname, val); }
+
+  octave_value get (const std::string& pname) const
+    {
+      Cell val = map.contents (pname);
+
+      if (val.numel () > 0)
+	return val(0, 0);
+      else
+	{
+	  error ("get: unknown slot: %s", pname.c_str ());
+	  return octave_value ();
+	}
+    }
+
+  octave_value_list
+  subsref (const std::string& type, const std::list<octave_value_list>& idx,
+           int nargout, size_t& skip, const cdef_class& context);
+
+  octave_value
+  subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
+            const octave_value& rhs);
+
+  void mark_for_construction (const cdef_class&);
+
+  bool is_constructed_for (const cdef_class& cls) const;
+
+  bool is_partially_constructed_for (const cdef_class& cls) const;
+
+  void mark_as_constructed (void) { ctor_list.clear (); }
+
+  void mark_as_constructed (const cdef_class& cls) { ctor_list.erase (cls); }
+
+  bool is_constructed (void) const { return ctor_list.empty (); }
+
+protected:
+  // Object property values
+  Octave_map map;
+
+  // Internal/temporary structure used during object construction
+  std::map< cdef_class, std::list<cdef_class> > ctor_list;
+
+protected:
+  // Restricted object copying!
+  cdef_object_scalar (const cdef_object_scalar& obj)
+    : cdef_object_base (obj), map (obj.map), ctor_list (obj.ctor_list) { }
+
+private:
+  // No assignment!
+  cdef_object_scalar& operator = (const cdef_object_scalar&);
+};
+
+class
+handle_cdef_object : public cdef_object_scalar
 {
 public:
   handle_cdef_object (void)
-      : cdef_object_rep () { }
-
-  handle_cdef_object (const std::string& nm)
-      : cdef_object_rep (nm) { }
+      : cdef_object_scalar () { }
 
   ~handle_cdef_object (void);
 
@@ -272,29 +370,28 @@
 };
 
 class
-value_cdef_object : public cdef_object_rep
+value_cdef_object : public cdef_object_scalar
 {
 public:
   value_cdef_object (void)
-      : cdef_object_rep () { }
-
-  value_cdef_object (const std::string& nm)
-      : cdef_object_rep (nm) { }
+      : cdef_object_scalar () { }
 
   ~value_cdef_object (void);
 
   cdef_object_rep* clone (void) const
     {
-      value_cdef_object* obj = new value_cdef_object (cname);
-      obj->map = map;
+      value_cdef_object* obj = new value_cdef_object (*this);
       return obj;
     }
 
   bool is_valid (void) const { return true; }
 
 private:
-  // No copying
-  value_cdef_object (const value_cdef_object&);
+  // Private copying!
+  value_cdef_object (const value_cdef_object& obj)
+    : cdef_object_scalar (obj) { }
+
+  // No assignment!
   value_cdef_object& operator = (const value_cdef_object&);
 };
 
@@ -307,15 +404,18 @@
   cdef_class_rep : public handle_cdef_object
   {
   public:
-    cdef_class_rep (const std::string& nm)
-	: handle_cdef_object (nm), handle_class (false) { }
+    cdef_class_rep (void)
+	: handle_cdef_object (), handle_class (false) { }
 
-    cdef_class_rep (const std::string& nm,
-                    const std::list<cdef_class>& superclasses);
+    cdef_class_rep (const std::list<cdef_class>& superclasses);
+
+    bool is_class (void) const { return true; }
 
     std::string get_name (void) const
       { return get ("Name").string_value (); }
 
+    void set_name (const std::string& nm) { put ("Name", nm); }
+
     cdef_method find_method (const std::string& nm, bool local = false);
 
     void install_method (const cdef_method& meth);
@@ -361,6 +461,12 @@
     void find_methods (std::map<std::string, cdef_method>& meths,
                        bool only_inherited);
 
+    cdef_class wrap (void)
+      {
+        refcount++;
+        return cdef_class (this);
+      }
+
   private:
     // The @-directory were this class is loaded from.
     // (not used yet)
@@ -379,7 +485,7 @@
     // The list of super-class constructors that are called implicitly by the
     // the classdef engine when creating an object. These constructors are not
     // called explicitly by the class constructor.
-    std::list<std::string> implicit_ctor_list;
+    std::list<cdef_class> implicit_ctor_list;
 
     // Utility iterator typedef's.
     typedef std::map<std::string,cdef_method>::iterator method_iterator;
@@ -393,12 +499,10 @@
   cdef_class (void)
       : cdef_object () { }
 
-  cdef_class (const std::string& nm)
-      : cdef_object (new cdef_class_rep (nm)) { }
-
   cdef_class (const std::string& nm,
               const std::list<cdef_class>& superclasses)
-      : cdef_object (new cdef_class_rep (nm, superclasses)) { }
+      : cdef_object (new cdef_class_rep (superclasses))
+    { get_rep ()->set_name (nm); }
 
   cdef_class (const cdef_class& cls)
       : cdef_object (cls) { }
@@ -407,7 +511,7 @@
       : cdef_object (obj)
     {
       // This should never happen...
-      if (class_name () != "meta.class")
+      if (! is_class ())
 	error ("internal error: invalid assignment from %s to meta.class object",
 	       class_name ().c_str ());
     }
@@ -421,7 +525,7 @@
 
   cdef_class& operator = (const cdef_object& obj)
     {
-      if (obj.class_name () == "meta.class")
+      if (obj.is_class ())
 	cdef_object::operator= (obj);
       else
 	error ("internal error: invalid assignment from %s to meta.class object",
@@ -488,6 +592,11 @@
   bool is_handle_class (void) const
     { return get_rep ()->is_handle_class (); }
 
+  static const cdef_class& meta_class (void) { return _meta_class; }
+  static const cdef_class& meta_property (void) { return _meta_property; }
+  static const cdef_class& meta_method (void) { return _meta_method; }
+  static const cdef_class& meta_package (void) { return _meta_package; }
+
 private:
   cdef_class_rep* get_rep (void)
     { return dynamic_cast<cdef_class_rep *> (cdef_object::get_rep ()); }
@@ -497,6 +606,15 @@
 
   friend bool operator == (const cdef_class&, const cdef_class&);
   friend bool operator != (const cdef_class&, const cdef_class&);
+  friend bool operator < (const cdef_class&, const cdef_class&);
+
+private:
+  static cdef_class _meta_class;
+  static cdef_class _meta_property;
+  static cdef_class _meta_method;
+  static cdef_class _meta_package;
+
+  friend void install_classdef (void);
 };
 
 inline bool
@@ -508,6 +626,11 @@
 operator != (const cdef_class& clsa, const cdef_class& clsb)
 { return ! (clsa == clsb); }
 
+// This is only to be able to use cdef_class as map keys.
+inline bool
+operator < (const cdef_class& clsa, const cdef_class& clsb)
+{ return clsa.get_rep () < clsb.get_rep (); }
+
 class
 cdef_property : public cdef_object
 {
@@ -517,8 +640,16 @@
   cdef_property_rep : public handle_cdef_object
   {
   public:
-    cdef_property_rep (const std::string& nm)
-	: handle_cdef_object (nm) { }
+    cdef_property_rep (void)
+	: handle_cdef_object () { }
+
+    bool is_property (void) const { return true; }
+
+    std::string get_name (void) const { return get("Name").string_value (); }
+
+    void set_name (const std::string& nm) { put ("Name", nm); }
+
+    bool is_constant (void) const { return get("Constant").bool_value (); }
 
     octave_value get_value (void) const { return default_value; }
 
@@ -539,7 +670,8 @@
   cdef_property (void) : cdef_object () { }
 
   cdef_property (const std::string& nm)
-      : cdef_object (new cdef_property_rep (nm)) { }
+      : cdef_object (new cdef_property_rep ())
+    { get_rep ()->set_name (nm); }
 
   cdef_property (const cdef_property& prop)
       : cdef_object (prop) { }
@@ -548,7 +680,7 @@
       : cdef_object (obj)
     {
       // This should never happen...
-      if (class_name () != "meta.property")
+      if (! is_property ())
 	error ("internal error: invalid assignment from %s to meta.property object",
 	       class_name ().c_str ());
     }
@@ -574,11 +706,9 @@
   
   bool check_set_access (void) const;
 
-  std::string get_name (void) const
-    { return get ("Name").string_value (); }
+  std::string get_name (void) const { return get_rep ()->get_name (); }
 
-  bool is_constant (void) const
-    { return get ("Constant").bool_value (); }
+  bool is_constant (void) const { return get_rep ()->is_constant (); }
 
 private:
   cdef_property_rep* get_rep (void)
@@ -597,8 +727,15 @@
   cdef_method_rep : public handle_cdef_object
   {
   public:
-    cdef_method_rep (const std::string& nm)
-	: handle_cdef_object (nm) { }
+    cdef_method_rep (void) : handle_cdef_object () { }
+
+    bool is_method (void) const { return true; }
+
+    std::string get_name (void) const { return get("Name").string_value (); }
+
+    void set_name (const std::string& nm) { put ("Name", nm); }
+
+    bool is_static (void) const { return get("Static").bool_value (); }
 
     octave_value get_function (void) const { return function; }
 
@@ -622,7 +759,8 @@
   cdef_method (void) : cdef_object () { }
 
   cdef_method (const std::string& nm)
-      : cdef_object (new cdef_method_rep (nm)) { }
+      : cdef_object (new cdef_method_rep ())
+    { get_rep ()->set_name (nm); }
 
   cdef_method (const cdef_property& prop)
       : cdef_object (prop) { }
@@ -631,7 +769,7 @@
       : cdef_object (obj)
     {
       // This should never happen...
-      if (class_name () != "meta.method")
+      if (! is_method ())
 	error ("internal error: invalid assignment from %s to meta.method object",
 	       class_name ().c_str ());
     }
@@ -654,11 +792,9 @@
 
   bool check_access (void) const;
   
-  std::string get_name (void) const
-    { return get ("Name").string_value (); }
+  std::string get_name (void) const { return get_rep ()->get_name (); }
 
-  bool is_static (void) const
-    { return get ("Static").bool_value (); }
+  bool is_static (void) const { return get_rep ()->is_static (); }
 
   void set_function (const octave_value& fcn)
     { get_rep ()->set_function (fcn); }
@@ -678,9 +814,42 @@
 };
 
 inline cdef_class
+cdef_object_rep::get_class (void) const
+{
+  gripe_invalid_object ("get_class");
+  return cdef_class ();
+}
+
+inline std::string
+cdef_object_rep::class_name (void) const
+{ return get_class ().get_name (); }
+
+inline cdef_class
 cdef_object::get_class (void) const
 { return rep->get_class (); }
 
+inline cdef_class
+cdef_object_base::get_class (void) const
+{ return cdef_class (klass); }
+
+inline void
+cdef_object_base::set_class (const cdef_class& cls)
+{
+  klass = cls;
+}
+
+inline void
+cdef_object_base::register_object (void)
+{
+  // FIXME: implement this
+}
+
+inline void
+cdef_object_base::unregister_object (void)
+{
+  // FIXME: implement this
+}
+
 inline cdef_method
 cdef_class::find_method (const std::string& nm, bool local)
 { return get_rep ()->find_method (nm, local); }
@@ -698,8 +867,13 @@
   cdef_package_rep : public handle_cdef_object
   {
   public:
-    cdef_package_rep (const std::string& nm)
-      : handle_cdef_object (nm) { }
+    cdef_package_rep (void) : handle_cdef_object () { }
+
+    bool is_package (void) const { return true; }
+
+    std::string get_name (void) const { return get("Name").string_value (); }
+
+    void set_name (const std::string& nm) { put ("Name", nm); }
 
     void install_class (const cdef_class& cls, const std::string& nm);
 
@@ -730,13 +904,14 @@
   cdef_package (void) : cdef_object () { }
 
   cdef_package (const std::string& nm)
-      : cdef_object (new cdef_package_rep (nm)) { }
+      : cdef_object (new cdef_package_rep ())
+    { get_rep ()->set_name (nm); }
 
   cdef_package (const cdef_object& obj)
       : cdef_object (obj)
     {
       // This should never happen...
-      if (class_name () != "meta.package")
+      if (! is_package ())
 	error ("internal error: invalid assignment from %s to meta.package object",
 	       class_name ().c_str ());
     }
@@ -766,12 +941,21 @@
   Cell get_packages (void) const
     { return get_rep ()->get_packages (); }
 
+  std::string get_name (void) const { return get_rep ()->get_name (); }
+
+  static const cdef_package& meta (void) { return _meta; }
+
 private:
   cdef_package_rep* get_rep (void)
     { return dynamic_cast<cdef_package_rep *> (cdef_object::get_rep ()); }
   
   const cdef_package_rep* get_rep (void) const
     { return dynamic_cast<const cdef_package_rep *> (cdef_object::get_rep ()); }
+
+private:
+  static cdef_package _meta;
+
+  friend void install_classdef (void);
 };
 
 class