You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2014/07/02 17:22:02 UTC

[1/3] Rename Clownfish::VTable to Clownfish::Class

Repository: lucy-clownfish
Updated Branches:
  refs/heads/rename-vtable [created] b85791907


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Obj.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Obj.c b/runtime/core/Clownfish/Obj.c
index d76ea19..db6e44b 100644
--- a/runtime/core/Clownfish/Obj.c
+++ b/runtime/core/Clownfish/Obj.c
@@ -15,7 +15,7 @@
  */
 
 #define C_CFISH_OBJ
-#define C_CFISH_VTABLE
+#define C_CFISH_CLASS
 #define CFISH_USE_SHORT_NAMES
 #define CHY_USE_SHORT_NAMES
 
@@ -29,7 +29,7 @@
 #include "Clownfish/String.h"
 #include "Clownfish/Err.h"
 #include "Clownfish/Hash.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 #include "Clownfish/Util/Memory.h"
 
 Obj*
@@ -50,14 +50,14 @@ Obj_Hash_Sum_IMP(Obj *self) {
 }
 
 bool
-Obj_Is_A_IMP(Obj *self, VTable *ancestor) {
-    VTable *vtable = self ? self->vtable : NULL;
+Obj_Is_A_IMP(Obj *self, Class *ancestor) {
+    Class *klass = self ? self->klass : NULL;
 
-    while (vtable != NULL) {
-        if (vtable == ancestor) {
+    while (klass != NULL) {
+        if (klass == ancestor) {
             return true;
         }
-        vtable = vtable->parent;
+        klass = klass->parent;
     }
 
     return false;
@@ -89,14 +89,14 @@ Obj_To_Bool_IMP(Obj *self) {
     return !!Obj_To_I64(self);
 }
 
-VTable*
-Obj_Get_VTable_IMP(Obj *self) {
-    return self->vtable;
+Class*
+Obj_Get_Class_IMP(Obj *self) {
+    return self->klass;
 }
 
 String*
 Obj_Get_Class_Name_IMP(Obj *self) {
-    return VTable_Get_Name(self->vtable);
+    return Class_Get_Name(self->klass);
 }
 
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Obj.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Obj.cfh b/runtime/core/Clownfish/Obj.cfh
index fafccfc..669accf 100644
--- a/runtime/core/Clownfish/Obj.cfh
+++ b/runtime/core/Clownfish/Obj.cfh
@@ -21,7 +21,7 @@ parcel Clownfish;
 
 public class Clownfish::Obj {
 
-    VTable *vtable;
+    Class *klass;
 
     /** Abstract initializer.
      */
@@ -79,13 +79,13 @@ public class Clownfish::Obj {
     public void
     Destroy(Obj *self);
 
-    /** Invoke the Destroy() method found in <code>vtable</code> on
+    /** Invoke the Destroy() method found in <code>klass</code> on
      * <code>self</code>.
      *
      * TODO: Eliminate this function if we can arrive at a proper SUPER syntax.
      */
     inert inline void
-    super_destroy(Obj *self, VTable *vtable);
+    super_destroy(Obj *self, Class *klass);
 
     /** Indicate whether two objects are the same.  By default, compares the
      * memory address.
@@ -111,10 +111,10 @@ public class Clownfish::Obj {
     public int32_t
     Hash_Sum(Obj *self);
 
-    /** Return the object's VTable.
+    /** Return the object's Class.
      */
-    public VTable*
-    Get_VTable(Obj *self);
+    public Class*
+    Get_Class(Obj *self);
 
     /** Return the name of the class that the object belongs to.
      */
@@ -124,7 +124,7 @@ public class Clownfish::Obj {
     /** Indicate whether the object is a descendent of <code>ancestor</code>.
      */
     public bool
-    Is_A(Obj *self, VTable *ancestor);
+    Is_A(Obj *self, Class *ancestor);
 
     /** Generic stringification: "ClassName@hex_mem_address".
      */
@@ -156,14 +156,14 @@ public class Clownfish::Obj {
 
 __C__
 static CFISH_INLINE void
-cfish_Obj_super_destroy(cfish_Obj *self, cfish_VTable *vtable) {
+cfish_Obj_super_destroy(cfish_Obj *self, cfish_Class *class) {
     CFISH_Obj_Destroy_t super_destroy
-        = CFISH_SUPER_METHOD_PTR(vtable, CFISH_Obj_Destroy);
+        = CFISH_SUPER_METHOD_PTR(class, CFISH_Obj_Destroy);
     super_destroy(self);
 }
 
-#define CFISH_SUPER_DESTROY(_self, _vtable) \
-    cfish_Obj_super_destroy((cfish_Obj*)_self, _vtable)
+#define CFISH_SUPER_DESTROY(_self, _class) \
+    cfish_Obj_super_destroy((cfish_Obj*)_self, _class)
 
 static CFISH_INLINE cfish_Obj*
 cfish_Obj_incref(cfish_Obj *self) {
@@ -182,7 +182,7 @@ cfish_Obj_decref(cfish_Obj *self) {
 #define CFISH_DECREF(_self) cfish_Obj_decref((cfish_Obj*)_self)
 
 #ifdef CFISH_USE_SHORT_NAMES
-  #define SUPER_DESTROY(_self, _vtable)   CFISH_SUPER_DESTROY(_self, _vtable)
+  #define SUPER_DESTROY(_self, _class)    CFISH_SUPER_DESTROY(_self, _class)
   #define INCREF(_self)                   CFISH_INCREF(_self)
   #define DECREF(_self)                   CFISH_DECREF(_self)
 #endif

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/String.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/String.c b/runtime/core/Clownfish/String.c
index 9f691ad..2b1f854 100644
--- a/runtime/core/Clownfish/String.c
+++ b/runtime/core/Clownfish/String.c
@@ -28,7 +28,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 #include "Clownfish/String.h"
 
 #include "Clownfish/CharBuf.h"
@@ -56,13 +56,13 @@ Str_new_from_utf8(const char *utf8, size_t size) {
     if (!StrHelp_utf8_valid(utf8, size)) {
         DIE_INVALID_UTF8(utf8, size);
     }
-    String *self = (String*)VTable_Make_Obj(STRING);
+    String *self = (String*)Class_Make_Obj(STRING);
     return Str_init_from_trusted_utf8(self, utf8, size);
 }
 
 String*
 Str_new_from_trusted_utf8(const char *utf8, size_t size) {
-    String *self = (String*)VTable_Make_Obj(STRING);
+    String *self = (String*)Class_Make_Obj(STRING);
     return Str_init_from_trusted_utf8(self, utf8, size);
 }
 
@@ -88,13 +88,13 @@ Str_new_steal_utf8(char *utf8, size_t size) {
     if (!StrHelp_utf8_valid(utf8, size)) {
         DIE_INVALID_UTF8(utf8, size);
     }
-    String *self = (String*)VTable_Make_Obj(STRING);
+    String *self = (String*)Class_Make_Obj(STRING);
     return Str_init_steal_trusted_utf8(self, utf8, size);
 }
 
 String*
 Str_new_steal_trusted_utf8(char *utf8, size_t size) {
-    String *self = (String*)VTable_Make_Obj(STRING);
+    String *self = (String*)Class_Make_Obj(STRING);
     return Str_init_steal_trusted_utf8(self, utf8, size);
 }
 
@@ -111,13 +111,13 @@ Str_new_wrap_utf8(const char *utf8, size_t size) {
     if (!StrHelp_utf8_valid(utf8, size)) {
         DIE_INVALID_UTF8(utf8, size);
     }
-    String *self = (String*)VTable_Make_Obj(STRING);
+    String *self = (String*)Class_Make_Obj(STRING);
     return Str_init_wrap_trusted_utf8(self, utf8, size);
 }
 
 String*
 Str_new_wrap_trusted_utf8(const char *utf8, size_t size) {
-    String *self = (String*)VTable_Make_Obj(STRING);
+    String *self = (String*)Class_Make_Obj(STRING);
     return Str_init_wrap_trusted_utf8(self, utf8, size);
 }
 
@@ -136,7 +136,7 @@ Str_new_from_char(int32_t code_point) {
     size_t  size = StrHelp_encode_utf8_char(code_point, (uint8_t*)ptr);
     ptr[size] = '\0';
 
-    String *self = (String*)VTable_Make_Obj(STRING);
+    String *self = (String*)Class_Make_Obj(STRING);
     self->ptr    = ptr;
     self->size   = size;
     self->origin = self;
@@ -157,7 +157,7 @@ Str_newf(const char *pattern, ...) {
 
 static String*
 S_new_substring(String *string, size_t byte_offset, size_t size) {
-    String *self = (String*)VTable_Make_Obj(STRING);
+    String *self = (String*)Class_Make_Obj(STRING);
 
     if (string->origin == NULL) {
         // Copy substring of wrapped strings.
@@ -176,7 +176,7 @@ Obj*
 Str_Inc_RefCount_IMP(String *self) {
     if (self->origin == NULL) {
         // Copy wrapped strings when the refcount is increased.
-        String *copy = (String*)VTable_Make_Obj(STRING);
+        String *copy = (String*)Class_Make_Obj(STRING);
         return (Obj*)Str_init_from_trusted_utf8(copy, self->ptr, self->size);
     }
     else {
@@ -336,7 +336,7 @@ Str_Cat_Trusted_Utf8_IMP(String *self, const char* ptr, size_t size) {
     memcpy(result_ptr, self->ptr, self->size);
     memcpy(result_ptr + self->size, ptr, size);
     result_ptr[result_size] = '\0';
-    String *result = (String*)VTable_Make_Obj(STRING);
+    String *result = (String*)Class_Make_Obj(STRING);
     return Str_init_steal_trusted_utf8(result, result_ptr, result_size);
 }
 
@@ -553,7 +553,7 @@ SStr_new_from_str(void *allocation, size_t alloc_size, String *string) {
     memcpy(ptr, string->ptr, size);
     ptr[size] = '\0';
 
-    StackString *self = (StackString*)VTable_Init_Obj(STACKSTRING, allocation);
+    StackString *self = (StackString*)Class_Init_Obj(STACKSTRING, allocation);
     self->ptr    = ptr;
     self->size   = size;
     self->origin = NULL;
@@ -563,7 +563,7 @@ SStr_new_from_str(void *allocation, size_t alloc_size, String *string) {
 StackString*
 SStr_wrap_str(void *allocation, const char *ptr, size_t size) {
     StackString *self
-        = (StackString*)VTable_Init_Obj(STACKSTRING, allocation);
+        = (StackString*)Class_Init_Obj(STACKSTRING, allocation);
     self->size   = size;
     self->ptr    = ptr;
     self->origin = NULL;
@@ -589,7 +589,7 @@ SStr_Destroy_IMP(StackString *self) {
 
 StringIterator*
 StrIter_new(String *string, size_t byte_offset) {
-    StringIterator *self = (StringIterator*)VTable_Make_Obj(STRINGITERATOR);
+    StringIterator *self = (StringIterator*)Class_Make_Obj(STRINGITERATOR);
     self->string      = (String*)INCREF(string);
     self->byte_offset = byte_offset;
     return self;
@@ -903,7 +903,7 @@ StrIter_Destroy_IMP(StringIterator *self) {
 StackStringIterator*
 SStrIter_new(void *allocation, String *string, size_t byte_offset) {
     StackStringIterator *self
-        = (StackStringIterator*)VTable_Init_Obj(STACKSTRINGITERATOR,
+        = (StackStringIterator*)Class_Init_Obj(STACKSTRINGITERATOR,
                                                 allocation);
     // Assume that the string will be available for the lifetime of the
     // iterator and don't increase its refcount.

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestByteBuf.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestByteBuf.c b/runtime/core/Clownfish/Test/TestByteBuf.c
index dcea3b5..3aba1f1 100644
--- a/runtime/core/Clownfish/Test/TestByteBuf.c
+++ b/runtime/core/Clownfish/Test/TestByteBuf.c
@@ -25,11 +25,11 @@
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/TestHarness/TestUtils.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestByteBuf*
 TestBB_new() {
-    return (TestByteBuf*)VTable_Make_Obj(TESTBYTEBUF);
+    return (TestByteBuf*)Class_Make_Obj(TESTBYTEBUF);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestCharBuf.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestCharBuf.c b/runtime/core/Clownfish/Test/TestCharBuf.c
index 48c36a1..4070ae7 100644
--- a/runtime/core/Clownfish/Test/TestCharBuf.c
+++ b/runtime/core/Clownfish/Test/TestCharBuf.c
@@ -31,14 +31,14 @@
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/TestHarness/TestUtils.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 static char smiley[] = { (char)0xE2, (char)0x98, (char)0xBA, 0 };
 static uint32_t smiley_len = 3;
 
 TestCharBuf*
 TestCB_new() {
-    return (TestCharBuf*)VTable_Make_Obj(TESTCHARBUF);
+    return (TestCharBuf*)Class_Make_Obj(TESTCHARBUF);
 }
 
 static CharBuf*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestErr.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestErr.c b/runtime/core/Clownfish/Test/TestErr.c
index 5627d7d..b31313d 100644
--- a/runtime/core/Clownfish/Test/TestErr.c
+++ b/runtime/core/Clownfish/Test/TestErr.c
@@ -23,11 +23,11 @@
 #include "Clownfish/Err.h"
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestErr*
 TestErr_new() {
-    return (TestErr*)VTable_Make_Obj(TESTERR);
+    return (TestErr*)Class_Make_Obj(TESTERR);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestHash.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestHash.c b/runtime/core/Clownfish/Test/TestHash.c
index e5000c9..54ec399 100644
--- a/runtime/core/Clownfish/Test/TestHash.c
+++ b/runtime/core/Clownfish/Test/TestHash.c
@@ -29,11 +29,11 @@
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/VArray.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestHash*
 TestHash_new() {
-    return (TestHash*)VTable_Make_Obj(TESTHASH);
+    return (TestHash*)Class_Make_Obj(TESTHASH);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestLockFreeRegistry.c b/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
index 515db9a..4f69ce0 100644
--- a/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
+++ b/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
@@ -27,11 +27,11 @@
 #include "Clownfish/LockFreeRegistry.h"
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestLockFreeRegistry*
 TestLFReg_new() {
-    return (TestLockFreeRegistry*)VTable_Make_Obj(TESTLOCKFREEREGISTRY);
+    return (TestLockFreeRegistry*)Class_Make_Obj(TESTLOCKFREEREGISTRY);
 }
 
 StupidHashCharBuf*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestNum.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestNum.c b/runtime/core/Clownfish/Test/TestNum.c
index f84c2c0..c30a169 100644
--- a/runtime/core/Clownfish/Test/TestNum.c
+++ b/runtime/core/Clownfish/Test/TestNum.c
@@ -24,11 +24,11 @@
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/TestHarness/TestUtils.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestNum*
 TestNum_new() {
-    return (TestNum*)VTable_Make_Obj(TESTNUM);
+    return (TestNum*)Class_Make_Obj(TESTNUM);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestObj.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestObj.c b/runtime/core/Clownfish/Test/TestObj.c
index 63e2bae..7b4a955 100644
--- a/runtime/core/Clownfish/Test/TestObj.c
+++ b/runtime/core/Clownfish/Test/TestObj.c
@@ -28,22 +28,22 @@
 #include "Clownfish/Err.h"
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestObj*
 TestObj_new() {
-    return (TestObj*)VTable_Make_Obj(TESTOBJ);
+    return (TestObj*)Class_Make_Obj(TESTOBJ);
 }
 
 static Obj*
 S_new_testobj() {
-    StackString *klass = SSTR_WRAP_UTF8("TestObj", 7);
+    StackString *class_name = SSTR_WRAP_UTF8("TestObj", 7);
     Obj *obj;
-    VTable *vtable = VTable_fetch_vtable((String*)klass);
-    if (!vtable) {
-        vtable = VTable_singleton((String*)klass, OBJ);
+    Class *klass = Class_fetch_class((String*)class_name);
+    if (!klass) {
+        klass = Class_singleton((String*)class_name, OBJ);
     }
-    obj = VTable_Make_Obj(vtable);
+    obj = Class_Make_Obj(klass);
     return Obj_init(obj);
 }
 
@@ -99,13 +99,13 @@ test_Hash_Sum(TestBatchRunner *runner) {
 static void
 test_Is_A(TestBatchRunner *runner) {
     String *string     = Str_new_from_trusted_utf8("", 0);
-    VTable *str_vtable = Str_Get_VTable(string);
-    String *klass      = Str_Get_Class_Name(string);
+    Class  *str_class  = Str_Get_Class(string);
+    String *class_name = Str_Get_Class_Name(string);
 
     TEST_TRUE(runner, Str_Is_A(string, STRING), "String Is_A String.");
     TEST_TRUE(runner, Str_Is_A(string, OBJ), "String Is_A Obj.");
-    TEST_TRUE(runner, str_vtable == STRING, "Get_VTable");
-    TEST_TRUE(runner, Str_Equals(VTable_Get_Name(STRING), (Obj*)klass),
+    TEST_TRUE(runner, str_class == STRING, "Get_Class");
+    TEST_TRUE(runner, Str_Equals(Class_Get_Name(STRING), (Obj*)class_name),
               "Get_Class_Name");
 
     DECREF(string);
@@ -156,7 +156,7 @@ S_verify_abstract_error(TestBatchRunner *runner, Err_Attempt_t routine,
 
 static void
 test_abstract_routines(TestBatchRunner *runner) {
-    Obj *blank = VTable_Make_Obj(OBJ);
+    Obj *blank = Class_Make_Obj(OBJ);
     S_verify_abstract_error(runner, S_attempt_init, blank, "init");
 
     Obj *obj = S_new_testobj();

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestString.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestString.c b/runtime/core/Clownfish/Test/TestString.c
index 634154a..17c8354 100644
--- a/runtime/core/Clownfish/Test/TestString.c
+++ b/runtime/core/Clownfish/Test/TestString.c
@@ -32,7 +32,7 @@
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/Util/Memory.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 #define SMILEY "\xE2\x98\xBA"
 static char smiley[] = { (char)0xE2, (char)0x98, (char)0xBA, 0 };
@@ -41,7 +41,7 @@ static uint32_t smiley_cp  = 0x263A;
 
 TestString*
 TestStr_new() {
-    return (TestString*)VTable_Make_Obj(TESTSTRING);
+    return (TestString*)Class_Make_Obj(TESTSTRING);
 }
 
 static String*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/TestVArray.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestVArray.c b/runtime/core/Clownfish/Test/TestVArray.c
index 06c1590..4a9334f 100644
--- a/runtime/core/Clownfish/Test/TestVArray.c
+++ b/runtime/core/Clownfish/Test/TestVArray.c
@@ -30,11 +30,11 @@
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/VArray.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestVArray*
 TestVArray_new() {
-    return (TestVArray*)VTable_Make_Obj(TESTVARRAY);
+    return (TestVArray*)Class_Make_Obj(TESTVARRAY);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/Util/TestAtomic.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestAtomic.c b/runtime/core/Clownfish/Test/Util/TestAtomic.c
index 320ff91..f87279a 100644
--- a/runtime/core/Clownfish/Test/Util/TestAtomic.c
+++ b/runtime/core/Clownfish/Test/Util/TestAtomic.c
@@ -22,11 +22,11 @@
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/Util/Atomic.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestAtomic*
 TestAtomic_new() {
-    return (TestAtomic*)VTable_Make_Obj(TESTATOMIC);
+    return (TestAtomic*)Class_Make_Obj(TESTATOMIC);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/Util/TestMemory.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestMemory.c b/runtime/core/Clownfish/Test/Util/TestMemory.c
index 1878242..0f1278f 100644
--- a/runtime/core/Clownfish/Test/Util/TestMemory.c
+++ b/runtime/core/Clownfish/Test/Util/TestMemory.c
@@ -25,11 +25,11 @@
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/Util/Memory.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestMemory*
 TestMemory_new() {
-    return (TestMemory*)VTable_Make_Obj(TESTMEMORY);
+    return (TestMemory*)Class_Make_Obj(TESTMEMORY);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/Util/TestNumberUtils.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestNumberUtils.c b/runtime/core/Clownfish/Test/Util/TestNumberUtils.c
index 5840c34..09dc894 100644
--- a/runtime/core/Clownfish/Test/Util/TestNumberUtils.c
+++ b/runtime/core/Clownfish/Test/Util/TestNumberUtils.c
@@ -30,11 +30,11 @@
 #include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/Util/Memory.h"
 #include "Clownfish/Util/NumberUtils.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestNumberUtils*
 TestNumUtil_new() {
-    return (TestNumberUtils*)VTable_Make_Obj(TESTNUMBERUTILS);
+    return (TestNumberUtils*)Class_Make_Obj(TESTNUMBERUTILS);
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Test/Util/TestStringHelper.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestStringHelper.c b/runtime/core/Clownfish/Test/Util/TestStringHelper.c
index 339de02..bcf33a2 100644
--- a/runtime/core/Clownfish/Test/Util/TestStringHelper.c
+++ b/runtime/core/Clownfish/Test/Util/TestStringHelper.c
@@ -26,7 +26,7 @@
 #include "Clownfish/Test.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/Util/StringHelper.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 /* This alternative implementation of utf8_valid() is (presumably) slower, but
  * it implements the standard in a more linear, easy-to-grok way.
@@ -34,7 +34,7 @@
 #define TRAIL_OK(n) (n >= 0x80 && n <= 0xBF)
 TestStringHelper*
 TestStrHelp_new() {
-    return (TestStringHelper*)VTable_Make_Obj(TESTSTRINGHELPER);
+    return (TestStringHelper*)Class_Make_Obj(TESTSTRINGHELPER);
 }
 
 static bool

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/TestHarness/TestBatchRunner.c b/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
index 72cebf2..a237df9 100644
--- a/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
+++ b/runtime/core/Clownfish/TestHarness/TestBatchRunner.c
@@ -28,7 +28,7 @@
 #include "Clownfish/TestHarness/TestBatch.h"
 #include "Clownfish/TestHarness/TestFormatter.h"
 #include "Clownfish/VArray.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 struct try_run_tests_context {
     TestBatchRunner *runner;
@@ -44,7 +44,7 @@ S_vtest_true(TestBatchRunner *self, bool condition, const char *pattern,
 
 TestBatchRunner*
 TestBatchRunner_new(TestFormatter *formatter) {
-    TestBatchRunner *self = (TestBatchRunner*)VTable_Make_Obj(TESTBATCHRUNNER);
+    TestBatchRunner *self = (TestBatchRunner*)Class_Make_Obj(TESTBATCHRUNNER);
     return TestBatchRunner_init(self, formatter);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/TestHarness/TestFormatter.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/TestHarness/TestFormatter.c b/runtime/core/Clownfish/TestHarness/TestFormatter.c
index c5016be..529ed1d 100644
--- a/runtime/core/Clownfish/TestHarness/TestFormatter.c
+++ b/runtime/core/Clownfish/TestHarness/TestFormatter.c
@@ -29,7 +29,7 @@
 #include "Clownfish/TestHarness/TestBatch.h"
 #include "Clownfish/TestHarness/TestSuiteRunner.h"
 #include "Clownfish/Util/Memory.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestFormatter*
 TestFormatter_init(TestFormatter *self) {
@@ -65,7 +65,7 @@ TestFormatter_batch_comment(TestFormatter *self, const char *fmt, ...) {
 TestFormatterCF*
 TestFormatterCF_new() {
     TestFormatterCF *self
-        = (TestFormatterCF*)VTable_Make_Obj(TESTFORMATTERCF);
+        = (TestFormatterCF*)Class_Make_Obj(TESTFORMATTERCF);
     return TestFormatterCF_init(self);
 }
 
@@ -140,7 +140,7 @@ TestFormatterCF_Summary_IMP(TestFormatterCF *self, TestSuiteRunner *runner) {
 TestFormatterTAP*
 TestFormatterTAP_new() {
     TestFormatterTAP *self
-        = (TestFormatterTAP*)VTable_Make_Obj(TESTFORMATTERTAP);
+        = (TestFormatterTAP*)Class_Make_Obj(TESTFORMATTERTAP);
     return TestFormatterTAP_init(self);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/TestHarness/TestSuite.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/TestHarness/TestSuite.c b/runtime/core/Clownfish/TestHarness/TestSuite.c
index a396b16..d3d4b54 100644
--- a/runtime/core/Clownfish/TestHarness/TestSuite.c
+++ b/runtime/core/Clownfish/TestHarness/TestSuite.c
@@ -32,14 +32,14 @@
 #include "Clownfish/TestHarness/TestFormatter.h"
 #include "Clownfish/TestHarness/TestSuiteRunner.h"
 #include "Clownfish/VArray.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 static void
 S_unbuffer_stdout();
 
 TestSuite*
 TestSuite_new() {
-    TestSuite *self = (TestSuite*)VTable_Make_Obj(TESTSUITE);
+    TestSuite *self = (TestSuite*)Class_Make_Obj(TESTSUITE);
     return TestSuite_init(self);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/TestHarness/TestSuiteRunner.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/TestHarness/TestSuiteRunner.c b/runtime/core/Clownfish/TestHarness/TestSuiteRunner.c
index 64be5bd..20400b3 100644
--- a/runtime/core/Clownfish/TestHarness/TestSuiteRunner.c
+++ b/runtime/core/Clownfish/TestHarness/TestSuiteRunner.c
@@ -24,11 +24,11 @@
 #include "Clownfish/TestHarness/TestBatch.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
 #include "Clownfish/TestHarness/TestFormatter.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 TestSuiteRunner*
 TestSuiteRunner_new(TestFormatter *formatter) {
-    TestSuiteRunner *self = (TestSuiteRunner*)VTable_Make_Obj(TESTSUITERUNNER);
+    TestSuiteRunner *self = (TestSuiteRunner*)Class_Make_Obj(TESTSUITERUNNER);
     return TestSuiteRunner_init(self, formatter);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/VArray.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/VArray.c b/runtime/core/Clownfish/VArray.c
index e3d49d3..e7e667c 100644
--- a/runtime/core/Clownfish/VArray.c
+++ b/runtime/core/Clownfish/VArray.c
@@ -23,7 +23,7 @@
 
 #include "charmony.h"
 
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 #include "Clownfish/VArray.h"
 #include "Clownfish/Err.h"
 #include "Clownfish/Util/Memory.h"
@@ -31,7 +31,7 @@
 
 VArray*
 VA_new(uint32_t capacity) {
-    VArray *self = (VArray*)VTable_Make_Obj(VARRAY);
+    VArray *self = (VArray*)Class_Make_Obj(VARRAY);
     VA_init(self, capacity);
     return self;
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/VTable.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/VTable.c b/runtime/core/Clownfish/VTable.c
deleted file mode 100644
index fe6d718..0000000
--- a/runtime/core/Clownfish/VTable.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define C_CFISH_VTABLE
-#define C_CFISH_OBJ
-#define C_CFISH_STRING
-#define C_CFISH_METHOD
-#define CFISH_USE_SHORT_NAMES
-#define CHY_USE_SHORT_NAMES
-
-#include "charmony.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "Clownfish/VTable.h"
-#include "Clownfish/String.h"
-#include "Clownfish/CharBuf.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Hash.h"
-#include "Clownfish/LockFreeRegistry.h"
-#include "Clownfish/Method.h"
-#include "Clownfish/Num.h"
-#include "Clownfish/VArray.h"
-#include "Clownfish/Util/Atomic.h"
-#include "Clownfish/Util/Memory.h"
-
-size_t VTable_offset_of_parent = offsetof(VTable, parent);
-
-// Remove spaces and underscores, convert to lower case.
-static String*
-S_scrunch_string(String *source);
-
-static Method*
-S_find_method(VTable *self, const char *meth_name);
-
-static int32_t
-S_claim_parcel_id(void);
-
-LockFreeRegistry *VTable_registry = NULL;
-
-void
-VTable_bootstrap(const VTableSpec *specs, size_t num_specs)
-{
-    int32_t parcel_id = S_claim_parcel_id();
-
-    /* Pass 1:
-     * - Initialize IVARS_OFFSET.
-     * - Allocate memory.
-     * - Initialize parent, flags, obj_alloc_size, vt_alloc_size.
-     * - Assign parcel_id.
-     * - Initialize method pointers.
-     */
-    for (size_t i = 0; i < num_specs; ++i) {
-        const VTableSpec *spec = &specs[i];
-        VTable *parent = spec->parent ? *spec->parent : NULL;
-
-        size_t ivars_offset = 0;
-        if (spec->ivars_offset_ptr != NULL) {
-            if (parent) {
-                VTable *ancestor = parent;
-                while (ancestor && ancestor->parcel_id == parcel_id) {
-                    ancestor = ancestor->parent;
-                }
-                ivars_offset = ancestor ? ancestor->obj_alloc_size : 0;
-                *spec->ivars_offset_ptr = ivars_offset;
-            }
-            else {
-                *spec->ivars_offset_ptr = 0;
-            }
-        }
-
-        size_t novel_offset = parent
-                              ? parent->vt_alloc_size
-                              : offsetof(VTable, method_ptrs);
-        size_t vt_alloc_size = novel_offset
-                               + spec->num_novel_meths
-                                 * sizeof(cfish_method_t);
-        VTable *vtable = (VTable*)Memory_wrapped_calloc(vt_alloc_size, 1);
-
-        vtable->parent         = parent;
-        vtable->parcel_id      = parcel_id;
-        vtable->flags          = 0;
-        vtable->obj_alloc_size = ivars_offset + spec->ivars_size;
-        vtable->vt_alloc_size  = vt_alloc_size;
-
-        if (parent) {
-            size_t parent_ptrs_size = parent->vt_alloc_size
-                                      - offsetof(VTable, method_ptrs);
-            memcpy(vtable->method_ptrs, parent->method_ptrs, parent_ptrs_size);
-        }
-
-        for (size_t i = 0; i < spec->num_inherited_meths; ++i) {
-            const InheritedMethSpec *mspec = &spec->inherited_meth_specs[i];
-            *mspec->offset = *mspec->parent_offset;
-        }
-
-        for (size_t i = 0; i < spec->num_overridden_meths; ++i) {
-            const OverriddenMethSpec *mspec = &spec->overridden_meth_specs[i];
-            *mspec->offset = *mspec->parent_offset;
-            VTable_Override_IMP(vtable, mspec->func, *mspec->offset);
-        }
-
-        for (size_t i = 0; i < spec->num_novel_meths; ++i) {
-            const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
-            *mspec->offset = novel_offset;
-            novel_offset += sizeof(cfish_method_t);
-            VTable_Override_IMP(vtable, mspec->func, *mspec->offset);
-        }
-
-        *spec->vtable = vtable;
-    }
-
-    /* Pass 2:
-     * - Initialize 'vtable' instance variable.
-     * - Initialize refcount.
-     */
-    for (size_t i = 0; i < num_specs; ++i) {
-        const VTableSpec *spec = &specs[i];
-        VTable *vtable = *spec->vtable;
-
-        VTable_Init_Obj_IMP(VTABLE, vtable);
-    }
-
-    /* Now it's safe to call methods.
-     *
-     * Pass 3:
-     * - Inititalize name and method array.
-     * - Register vtable.
-     */
-    for (size_t i = 0; i < num_specs; ++i) {
-        const VTableSpec *spec = &specs[i];
-        VTable *vtable = *spec->vtable;
-
-        vtable->name    = Str_newf("%s", spec->name);
-        vtable->methods = VA_new(0);
-
-        for (size_t i = 0; i < spec->num_novel_meths; ++i) {
-            const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
-            String *name = Str_newf("%s", mspec->name);
-            Method *method = Method_new(name, mspec->callback_func,
-                                        *mspec->offset);
-            VA_Push(vtable->methods, (Obj*)method);
-            DECREF(name);
-        }
-
-        VTable_add_to_registry(vtable);
-    }
-}
-
-void
-VTable_Destroy_IMP(VTable *self) {
-    THROW(ERR, "Insane attempt to destroy VTable for class '%o'", self->name);
-}
-
-VTable*
-VTable_Clone_IMP(VTable *self) {
-    VTable *twin
-        = (VTable*)Memory_wrapped_calloc(self->vt_alloc_size, 1);
-
-    memcpy(twin, self, self->vt_alloc_size);
-    VTable_Init_Obj(self->vtable, twin); // Set refcount.
-    twin->name = Str_Clone(self->name);
-
-    return twin;
-}
-
-Obj*
-VTable_Inc_RefCount_IMP(VTable *self) {
-    return (Obj*)self;
-}
-
-uint32_t
-VTable_Dec_RefCount_IMP(VTable *self) {
-    UNUSED_VAR(self);
-    return 1;
-}
-
-uint32_t
-VTable_Get_RefCount_IMP(VTable *self) {
-    UNUSED_VAR(self);
-    /* VTable_Get_RefCount() lies to other Clownfish code about the refcount
-     * because we don't want to have to synchronize access to the cached host
-     * object to which we have delegated responsibility for keeping refcounts.
-     * It always returns 1 because 1 is a positive number, and thus other
-     * Clownfish code will be fooled into believing it never needs to take
-     * action such as initiating a destructor.
-     *
-     * It's possible that the host has in fact increased the refcount of the
-     * cached host object if there are multiple refs to it on the other side
-     * of the Clownfish/host border, but returning 1 is good enough to fool
-     * Clownfish code.
-     */
-    return 1;
-}
-
-void
-VTable_Override_IMP(VTable *self, cfish_method_t method, size_t offset) {
-    union { char *char_ptr; cfish_method_t *func_ptr; } pointer;
-    pointer.char_ptr = ((char*)self) + offset;
-    pointer.func_ptr[0] = method;
-}
-
-String*
-VTable_Get_Name_IMP(VTable *self) {
-    return self->name;
-}
-
-VTable*
-VTable_Get_Parent_IMP(VTable *self) {
-    return self->parent;
-}
-
-size_t
-VTable_Get_Obj_Alloc_Size_IMP(VTable *self) {
-    return self->obj_alloc_size;
-}
-
-VArray*
-VTable_Get_Methods_IMP(VTable *self) {
-    return self->methods;
-}
-
-void
-VTable_init_registry() {
-    LockFreeRegistry *reg = LFReg_new(256);
-    if (Atomic_cas_ptr((void*volatile*)&VTable_registry, NULL, reg)) {
-        return;
-    }
-    else {
-        DECREF(reg);
-    }
-}
-
-VTable*
-VTable_singleton(String *class_name, VTable *parent) {
-    if (VTable_registry == NULL) {
-        VTable_init_registry();
-    }
-
-    VTable *singleton = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)class_name);
-    if (singleton == NULL) {
-        VArray *fresh_host_methods;
-        uint32_t num_fresh;
-
-        if (parent == NULL) {
-            String *parent_class = VTable_find_parent_class(class_name);
-            if (parent_class == NULL) {
-                THROW(ERR, "Class '%o' doesn't descend from %o", class_name,
-                      OBJ->name);
-            }
-            else {
-                parent = VTable_singleton(parent_class, NULL);
-                DECREF(parent_class);
-            }
-        }
-
-        // Copy source vtable.
-        singleton = VTable_Clone(parent);
-
-        // Turn clone into child.
-        singleton->parent = parent;
-        DECREF(singleton->name);
-        singleton->name = Str_Clone(class_name);
-
-        // Allow host methods to override.
-        fresh_host_methods = VTable_fresh_host_methods(class_name);
-        num_fresh = VA_Get_Size(fresh_host_methods);
-        if (num_fresh) {
-            Hash *meths = Hash_new(num_fresh);
-            for (uint32_t i = 0; i < num_fresh; i++) {
-                String *meth = (String*)VA_Fetch(fresh_host_methods, i);
-                String *scrunched = S_scrunch_string(meth);
-                Hash_Store(meths, (Obj*)scrunched, (Obj*)CFISH_TRUE);
-                DECREF(scrunched);
-            }
-            for (VTable *vtable = parent; vtable; vtable = vtable->parent) {
-                uint32_t max = VA_Get_Size(vtable->methods);
-                for (uint32_t i = 0; i < max; i++) {
-                    Method *method = (Method*)VA_Fetch(vtable->methods, i);
-                    if (method->callback_func) {
-                        String *scrunched = S_scrunch_string(method->name);
-                        if (Hash_Fetch(meths, (Obj*)scrunched)) {
-                            VTable_Override(singleton, method->callback_func,
-                                            method->offset);
-                        }
-                        DECREF(scrunched);
-                    }
-                }
-            }
-            DECREF(meths);
-        }
-        DECREF(fresh_host_methods);
-
-        // Register the new class, both locally and with host.
-        if (VTable_add_to_registry(singleton)) {
-            // Doing this after registering is racy, but hard to fix. :(
-            VTable_register_with_host(singleton, parent);
-        }
-        else {
-            DECREF(singleton);
-            singleton = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)class_name);
-            if (!singleton) {
-                THROW(ERR, "Failed to either insert or fetch VTable for '%o'",
-                      class_name);
-            }
-        }
-    }
-
-    return singleton;
-}
-
-static String*
-S_scrunch_string(String *source) {
-    CharBuf *buf = CB_new(Str_Get_Size(source));
-    StringIterator *iter = Str_Top(source);
-    int32_t code_point;
-    while (STRITER_DONE != (code_point = StrIter_Next(iter))) {
-        if (code_point > 127) {
-            THROW(ERR, "Can't fold case for %o", source);
-        }
-        else if (code_point != '_') {
-            CB_Cat_Char(buf, tolower(code_point));
-        }
-    }
-    String *retval = CB_Yield_String(buf);
-    DECREF(iter);
-    DECREF(buf);
-    return retval;
-}
-
-bool
-VTable_add_to_registry(VTable *vtable) {
-    if (VTable_registry == NULL) {
-        VTable_init_registry();
-    }
-    if (LFReg_Fetch(VTable_registry, (Obj*)vtable->name)) {
-        return false;
-    }
-    else {
-        String *klass = Str_Clone(vtable->name);
-        bool retval
-            = LFReg_Register(VTable_registry, (Obj*)klass, (Obj*)vtable);
-        DECREF(klass);
-        return retval;
-    }
-}
-
-bool
-VTable_add_alias_to_registry(VTable *vtable, const char *alias_ptr,
-                             size_t alias_len) {
-    if (VTable_registry == NULL) {
-        VTable_init_registry();
-    }
-    StackString *alias = SSTR_WRAP_UTF8(alias_ptr, alias_len);
-    if (LFReg_Fetch(VTable_registry, (Obj*)alias)) {
-        return false;
-    }
-    else {
-        String *klass = SStr_Clone(alias);
-        bool retval
-            = LFReg_Register(VTable_registry, (Obj*)klass, (Obj*)vtable);
-        DECREF(klass);
-        return retval;
-    }
-}
-
-VTable*
-VTable_fetch_vtable(String *class_name) {
-    VTable *vtable = NULL;
-    if (VTable_registry != NULL) {
-        vtable = (VTable*)LFReg_Fetch(VTable_registry, (Obj*)class_name);
-    }
-    return vtable;
-}
-
-void
-VTable_Add_Host_Method_Alias_IMP(VTable *self, const char *alias,
-                             const char *meth_name) {
-    Method *method = S_find_method(self, meth_name);
-    if (!method) {
-        fprintf(stderr, "Method %s not found\n", meth_name);
-        abort();
-    }
-    method->host_alias = Str_newf("%s", alias);
-}
-
-void
-VTable_Exclude_Host_Method_IMP(VTable *self, const char *meth_name) {
-    Method *method = S_find_method(self, meth_name);
-    if (!method) {
-        fprintf(stderr, "Method %s not found\n", meth_name);
-        abort();
-    }
-    method->is_excluded = true;
-}
-
-static Method*
-S_find_method(VTable *self, const char *name) {
-    size_t   name_len = strlen(name);
-    uint32_t size     = VA_Get_Size(self->methods);
-
-    for (uint32_t i = 0; i < size; i++) {
-        Method *method = (Method*)VA_Fetch(self->methods, i);
-        if (Str_Equals_Utf8(method->name, name, name_len)) {
-            return method;
-        }
-    }
-
-    return NULL;
-}
-
-static size_t parcel_count;
-
-static int32_t
-S_claim_parcel_id(void) {
-    // TODO: use ordinary cas rather than cas_ptr.
-    union { size_t num; void *ptr; } old_value;
-    union { size_t num; void *ptr; } new_value;
-
-    bool succeeded = false;
-    do {
-        old_value.num = parcel_count;
-        new_value.num = old_value.num + 1;
-        succeeded = Atomic_cas_ptr((void*volatile*)&parcel_count,
-                                   old_value.ptr, new_value.ptr);
-    } while (!succeeded);
-
-    return new_value.num;
-}
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/VTable.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/VTable.cfh b/runtime/core/Clownfish/VTable.cfh
deleted file mode 100644
index 97e5cf6..0000000
--- a/runtime/core/Clownfish/VTable.cfh
+++ /dev/null
@@ -1,155 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-/** Virtual method dispatch table.
- *
- * VTables, which are the first element in any Clownfish object, are actually
- * objects themselves.  (Their first element is a VTable which describes the
- * behavior of VTables.)
- */
-
-class Clownfish::VTable inherits Clownfish::Obj {
-
-    VTable            *parent;
-    String            *name;
-    uint32_t           flags;
-    int32_t            parcel_id;
-    size_t             obj_alloc_size;
-    size_t             vt_alloc_size;
-    VArray            *methods;
-    cfish_method_t[1]  method_ptrs; /* flexible array */
-
-    inert LockFreeRegistry *registry;
-    inert size_t offset_of_parent;
-
-    inert void
-    bootstrap(const cfish_VTableSpec *specs, size_t num_specs);
-
-    /** Return a singleton.  If a VTable can be found in the registry based on
-     * the supplied class name, it will be returned.  Otherwise, a new VTable
-     * will be created using [parent] as a base.
-     *
-     * If [parent] is NULL, an attempt will be made to find it using
-     * VTable_find_parent_class().  If the attempt fails, an error will
-     * result.
-     */
-    inert VTable*
-    singleton(String *class_name, VTable *parent);
-
-    /** Register a vtable, so that it can be retrieved by class name.
-     *
-     * TODO: Move this functionality to some kind of class loader.
-     *
-     * @return true on success, false if the class was already registered.
-     */
-    inert bool
-    add_to_registry(VTable *vtable);
-
-    inert bool
-    add_alias_to_registry(VTable *vtable, const char *alias_ptr,
-                          size_t alias_len);
-
-    /** Initialize the registry.
-     */
-    inert void
-    init_registry();
-
-    /** Tell the host about the new class.
-     */
-    inert void
-    register_with_host(VTable *vtable, VTable *parent);
-
-    /** Find a registered class and return its vtable.  May return NULL if the
-     * class is not registered.
-     */
-    inert nullable VTable*
-    fetch_vtable(String *class_name);
-
-    /** Given a class name, return the name of a parent class which descends
-     * from Clownfish::Obj, or NULL if such a class can't be found.
-     */
-    inert nullable String*
-    find_parent_class(String *class_name);
-
-    /** List all of the methods defined directly within a host subclass.
-     */
-    inert incremented VArray*
-    fresh_host_methods(String *class_name);
-
-    /** Replace a function pointer in the VTable.
-     */
-    void
-    Override(VTable *self, cfish_method_t method_ptr, size_t offset);
-
-    /** Create an empty object of the type defined by the VTable: allocate,
-     * assign its vtable and give it an initial refcount of 1.  The caller is
-     * responsible for initialization.
-     */
-    Obj*
-    Make_Obj(VTable *self);
-
-    /** Take a raw memory allocation which is presumed to be of adequate size,
-     * assign its vtable and give it an initial refcount of 1.
-     */
-    Obj*
-    Init_Obj(VTable *self, void *allocation);
-
-    /** Create a new object to go with the supplied host object.
-     */
-    Obj*
-    Foster_Obj(VTable *self, void *host_obj);
-
-    void
-    Add_Host_Method_Alias(VTable *self, const char *alias,
-                          const char *meth_name);
-
-    void
-    Exclude_Host_Method(VTable *self, const char *meth_name);
-
-    String*
-    Get_Name(VTable *self);
-
-    VTable*
-    Get_Parent(VTable *self);
-
-    size_t
-    Get_Obj_Alloc_Size(VTable *self);
-
-    VArray*
-    Get_Methods(VTable *self);
-
-    public incremented VTable*
-    Clone(VTable *self);
-
-    incremented Obj*
-    Inc_RefCount(VTable *self);
-
-    uint32_t
-    Dec_RefCount(VTable *self);
-
-    uint32_t
-    Get_RefCount(VTable *self);
-
-    void*
-    To_Host(VTable *self);
-
-    public void
-    Destroy(VTable *self);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/buildlib/Clownfish/Build/Binding.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/buildlib/Clownfish/Build/Binding.pm b/runtime/perl/buildlib/Clownfish/Build/Binding.pm
index d61718d..7593d32 100644
--- a/runtime/perl/buildlib/Clownfish/Build/Binding.pm
+++ b/runtime/perl/buildlib/Clownfish/Build/Binding.pm
@@ -31,7 +31,7 @@ sub bind_all {
     $class->bind_float64;
     $class->bind_obj;
     $class->bind_varray;
-    $class->bind_vtable;
+    $class->bind_class;
     $class->bind_stringhelper;
 }
 
@@ -457,7 +457,7 @@ is_a(self, class_name)
     cfish_String *class_name;
 CODE:
 {
-    cfish_VTable *target = cfish_VTable_fetch_vtable(class_name);
+    cfish_Class *target = cfish_Class_fetch_class(class_name);
     RETVAL = CFISH_Obj_Is_A(self, target);
 }
 OUTPUT: RETVAL
@@ -553,23 +553,23 @@ END_XS_CODE
     Clownfish::CFC::Binding::Perl::Class->register($binding);
 }
 
-sub bind_vtable {
+sub bind_class {
     my @hand_rolled = qw( Make_Obj );
 
     my $xs_code = <<'END_XS_CODE';
-MODULE = Clownfish   PACKAGE = Clownfish::VTable
+MODULE = Clownfish   PACKAGE = Clownfish::Class
 
 SV*
 _get_registry()
 CODE:
-    if (cfish_VTable_registry == NULL) {
-        cfish_VTable_init_registry();
+    if (cfish_Class_registry == NULL) {
+        cfish_Class_init_registry();
     }
-    RETVAL = (SV*)CFISH_Obj_To_Host((cfish_Obj*)cfish_VTable_registry);
+    RETVAL = (SV*)CFISH_Obj_To_Host((cfish_Obj*)cfish_Class_registry);
 OUTPUT: RETVAL
 
 SV*
-fetch_vtable(unused_sv, class_name_sv)
+fetch_class(unused_sv, class_name_sv)
     SV *unused_sv;
     SV *class_name_sv;
 CODE:
@@ -578,9 +578,9 @@ CODE:
     STRLEN size;
     char *ptr = SvPVutf8(class_name_sv, size);
     cfish_StackString *class_name = CFISH_SSTR_WRAP_UTF8(ptr, size);
-    cfish_VTable *vtable
-        = cfish_VTable_fetch_vtable((cfish_String*)class_name);
-    RETVAL = vtable ? (SV*)CFISH_VTable_To_Host(vtable) : &PL_sv_undef;
+    cfish_Class *klass
+        = cfish_Class_fetch_class((cfish_String*)class_name);
+    RETVAL = klass ? (SV*)CFISH_Class_To_Host(klass) : &PL_sv_undef;
 }
 OUTPUT: RETVAL
 
@@ -591,34 +591,34 @@ CODE:
 {
     CFISH_UNUSED_VAR(unused_sv);
     cfish_String *class_name = NULL;
-    cfish_VTable *parent     = NULL;
+    cfish_Class  *parent     = NULL;
     bool args_ok
         = XSBind_allot_params(&(ST(0)), 1, items,
                               ALLOT_OBJ(&class_name, "class_name", 10, true,
                                         CFISH_STRING, alloca(cfish_SStr_size())),
                               ALLOT_OBJ(&parent, "parent", 6, false,
-                                        CFISH_VTABLE, NULL),
+                                        CFISH_CLASS, NULL),
                               NULL);
     if (!args_ok) {
         CFISH_RETHROW(CFISH_INCREF(cfish_Err_get_error()));
     }
-    cfish_VTable *singleton = cfish_VTable_singleton(class_name, parent);
-    RETVAL = (SV*)CFISH_VTable_To_Host(singleton);
+    cfish_Class *singleton = cfish_Class_singleton(class_name, parent);
+    RETVAL = (SV*)CFISH_Class_To_Host(singleton);
 }
 OUTPUT: RETVAL
 
 SV*
 make_obj(self)
-    cfish_VTable *self;
+    cfish_Class *self;
 CODE:
-    cfish_Obj *blank = CFISH_VTable_Make_Obj(self);
+    cfish_Obj *blank = CFISH_Class_Make_Obj(self);
     RETVAL = CFISH_OBJ_TO_SV_NOINC(blank);
 OUTPUT: RETVAL
 END_XS_CODE
 
     my $binding = Clownfish::CFC::Binding::Perl::Class->new(
         parcel     => "Clownfish",
-        class_name => "Clownfish::VTable",
+        class_name => "Clownfish::Class",
     );
     $binding->exclude_method($_) for @hand_rolled;
     $binding->append_xs($xs_code);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/lib/Clownfish.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/lib/Clownfish.pm b/runtime/perl/lib/Clownfish.pm
index d683245..5b02103 100644
--- a/runtime/perl/lib/Clownfish.pm
+++ b/runtime/perl/lib/Clownfish.pm
@@ -89,7 +89,7 @@ sub error {$Clownfish::Err::error}
 }
 
 {
-    package Clownfish::VTable;
+    package Clownfish::Class;
     our $VERSION = '0.003000';
     $VERSION = eval $VERSION;
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/lib/Clownfish.pod
----------------------------------------------------------------------
diff --git a/runtime/perl/lib/Clownfish.pod b/runtime/perl/lib/Clownfish.pod
index 456ff59..cfb3c79 100644
--- a/runtime/perl/lib/Clownfish.pod
+++ b/runtime/perl/lib/Clownfish.pod
@@ -209,7 +209,7 @@ file.
 
 For every class, a global variable with the uppercase name
 C<{PARCEL_NICK}_{CLASS_LAST_COMP}> is defined. This variable is a pointer to
-a Clownfish::VTable object which is initialized when bootstrapping the parcel.
+a Clownfish::Class object which is initialized when bootstrapping the parcel.
 
 Example of a class declaration:
 
@@ -226,7 +226,7 @@ This will generate:
         /* Instance variables */
     };
     typedef struct pfind_VisibilityGraph pfind_VisibilityGraph;
-    extern cfish_VTable *PFIND_VISIBILITYGRAPH;
+    extern cfish_Class *PFIND_VISIBILITYGRAPH;
 
 =head3 Class exposure
 
@@ -431,7 +431,7 @@ implementation will look like:
 
 Clownfish defines a macro named C<CFISH_METHOD_PTR> that looks up the pointer
 to the implementing function of a method. The first parameter of the macro is
-a pointer to the Clownfish::VTable object of the method's class, the second is
+a pointer to the Clownfish::Class object of the method's class, the second is
 the unshortened name of the method wrapper. If short names for the Clownfish
 parcel are used, the macro is also available under the name C<METHOD_PTR>.
 
@@ -512,7 +512,7 @@ Example:
 =head3 Object creation
 
 Objects are allocated by invoking the C<Make_Obj> method on a class's
-Clownfish::VTable object.
+Clownfish::Class object.
 
 Any inert function can be used to construct objects from C. But to support
 inheritance and object creation from the host language, Clownfish classes
@@ -550,7 +550,7 @@ Example:
 
     Train*
     Train_new(double max_speed, double track_gauge) {
-        Train *self = (Train*)VTable_Make_Obj(TRAIN);
+        Train *self = (Train*)Class_Make_Obj(TRAIN);
         return Train_init(self, max_speed, track_gauge);
     }
 
@@ -586,7 +586,7 @@ This public method takes no arguments besides C<self> and has no return value.
 It should release the resources held by the object and finally call the
 C<Destroy> method of the superclass via the C<CFISH_SUPER_DESTROY> macro with
 short name C<SUPER_DESTROY>. This macro takes the C<self> pointer as first
-argument and a pointer to the object's Clownfish::VTable as second argument.
+argument and a pointer to the object's Clownfish::Class as second argument.
 The C<Destroy> method of the Clownfish::Obj class will eventually free the
 object struct.
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/lib/Clownfish/Class.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/lib/Clownfish/Class.pm b/runtime/perl/lib/Clownfish/Class.pm
new file mode 100644
index 0000000..ed4b538
--- /dev/null
+++ b/runtime/perl/lib/Clownfish/Class.pm
@@ -0,0 +1,25 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+package Clownfish::Class;
+use Clownfish;
+our $VERSION = '0.003000';
+$VERSION = eval $VERSION;
+
+1;
+
+__END__
+
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/lib/Clownfish/VTable.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/lib/Clownfish/VTable.pm b/runtime/perl/lib/Clownfish/VTable.pm
deleted file mode 100644
index b5f5eb5..0000000
--- a/runtime/perl/lib/Clownfish/VTable.pm
+++ /dev/null
@@ -1,25 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-package Clownfish::VTable;
-use Clownfish;
-our $VERSION = '0.003000';
-$VERSION = eval $VERSION;
-
-1;
-
-__END__
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/t/021-class.t
----------------------------------------------------------------------
diff --git a/runtime/perl/t/021-class.t b/runtime/perl/t/021-class.t
new file mode 100644
index 0000000..61feec2
--- /dev/null
+++ b/runtime/perl/t/021-class.t
@@ -0,0 +1,57 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+use strict;
+use warnings;
+
+package MyHash;
+use base qw( Clownfish::Hash );
+
+sub oodle { }
+
+package main;
+
+use Test::More tests => 5;
+
+my $stringified;
+my $storage = Clownfish::Hash->new;
+
+{
+    my $subclassed_hash = MyHash->new;
+    $stringified = $subclassed_hash->to_string;
+
+    isa_ok( $subclassed_hash, "MyHash", "Perl isa reports correct subclass" );
+
+   # Store the subclassed object.  At the end of this block, the Perl object
+   # will go out of scope and DESTROY will be called, but the Clownfish object
+   # will persist.
+    $storage->store( "test", $subclassed_hash );
+}
+
+my $resurrected = $storage->_fetch("test");
+
+isa_ok( $resurrected, "MyHash", "subclass name survived Perl destruction" );
+is( $resurrected->to_string, $stringified,
+    "It's the same Hash from earlier (though a different Perl object)" );
+
+my $booga = Clownfish::String->new("booga");
+$resurrected->store( "ooga", $booga );
+
+is( $resurrected->fetch("ooga"),
+    "booga", "subclassed object still performs correctly at the C level" );
+
+my $methods = Clownfish::Class::_fresh_host_methods('MyHash');
+is_deeply( $methods->to_perl, ['oodle'], "fresh_host_methods" );
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/t/021-vtable.t
----------------------------------------------------------------------
diff --git a/runtime/perl/t/021-vtable.t b/runtime/perl/t/021-vtable.t
deleted file mode 100644
index d2e0c14..0000000
--- a/runtime/perl/t/021-vtable.t
+++ /dev/null
@@ -1,57 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-use strict;
-use warnings;
-
-package MyHash;
-use base qw( Clownfish::Hash );
-
-sub oodle { }
-
-package main;
-
-use Test::More tests => 5;
-
-my $stringified;
-my $storage = Clownfish::Hash->new;
-
-{
-    my $subclassed_hash = MyHash->new;
-    $stringified = $subclassed_hash->to_string;
-
-    isa_ok( $subclassed_hash, "MyHash", "Perl isa reports correct subclass" );
-
-   # Store the subclassed object.  At the end of this block, the Perl object
-   # will go out of scope and DESTROY will be called, but the Clownfish object
-   # will persist.
-    $storage->store( "test", $subclassed_hash );
-}
-
-my $resurrected = $storage->_fetch("test");
-
-isa_ok( $resurrected, "MyHash", "subclass name survived Perl destruction" );
-is( $resurrected->to_string, $stringified,
-    "It's the same Hash from earlier (though a different Perl object)" );
-
-my $booga = Clownfish::String->new("booga");
-$resurrected->store( "ooga", $booga );
-
-is( $resurrected->fetch("ooga"),
-    "booga", "subclassed object still performs correctly at the C level" );
-
-my $methods = Clownfish::VTable::_fresh_host_methods('MyHash');
-is_deeply( $methods->to_perl, ['oodle'], "fresh_host_methods" );
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/xs/XSBind.c
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index 4c7a275..9f45d14 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -15,7 +15,7 @@
  */
 
 #define C_CFISH_OBJ
-#define C_CFISH_VTABLE
+#define C_CFISH_CLASS
 #define C_CFISH_LOCKFREEREGISTRY
 #define NEED_newRV_noinc
 #include "charmony.h"
@@ -49,55 +49,55 @@ S_cfish_hash_to_perl_hash(cfish_Hash *hash);
 
 cfish_Obj*
 XSBind_new_blank_obj(SV *either_sv) {
-    cfish_VTable *vtable;
+    cfish_Class *klass;
 
-    // Get a VTable.
+    // Get a Class.
     if (sv_isobject(either_sv)
         && sv_derived_from(either_sv, "Clownfish::Obj")
        ) {
-        // Use the supplied object's VTable.
+        // Use the supplied object's Class.
         IV iv_ptr = SvIV(SvRV(either_sv));
         cfish_Obj *self = INT2PTR(cfish_Obj*, iv_ptr);
-        vtable = self->vtable;
+        klass = self->klass;
     }
     else {
-        // Use the supplied class name string to find a VTable.
+        // Use the supplied class name string to find a Class.
         STRLEN len;
         char *ptr = SvPVutf8(either_sv, len);
-        cfish_StackString *klass = CFISH_SSTR_WRAP_UTF8(ptr, len);
-        vtable = cfish_VTable_singleton((cfish_String*)klass, NULL);
+        cfish_StackString *class_name = CFISH_SSTR_WRAP_UTF8(ptr, len);
+        klass = cfish_Class_singleton((cfish_String*)class_name, NULL);
     }
 
-    // Use the VTable to allocate a new blank object of the right size.
-    return CFISH_VTable_Make_Obj(vtable);
+    // Use the Class to allocate a new blank object of the right size.
+    return CFISH_Class_Make_Obj(klass);
 }
 
 cfish_Obj*
-XSBind_sv_to_cfish_obj(SV *sv, cfish_VTable *vtable, void *allocation) {
-    cfish_Obj *retval = XSBind_maybe_sv_to_cfish_obj(sv, vtable, allocation);
+XSBind_sv_to_cfish_obj(SV *sv, cfish_Class *klass, void *allocation) {
+    cfish_Obj *retval = XSBind_maybe_sv_to_cfish_obj(sv, klass, allocation);
     if (!retval) {
-        THROW(CFISH_ERR, "Not a %o", CFISH_VTable_Get_Name(vtable));
+        THROW(CFISH_ERR, "Not a %o", CFISH_Class_Get_Name(klass));
     }
     return retval;
 }
 
 cfish_Obj*
-XSBind_maybe_sv_to_cfish_obj(SV *sv, cfish_VTable *vtable, void *allocation) {
+XSBind_maybe_sv_to_cfish_obj(SV *sv, cfish_Class *klass, void *allocation) {
     cfish_Obj *retval = NULL;
     if (XSBind_sv_defined(sv)) {
         // Assume that the class name is always NULL-terminated. Somewhat
         // dangerous but should be safe.
         if (sv_isobject(sv)
-            && sv_derived_from(sv, CFISH_Str_Get_Ptr8(CFISH_VTable_Get_Name(vtable)))
+            && sv_derived_from(sv, CFISH_Str_Get_Ptr8(CFISH_Class_Get_Name(klass)))
            ) {
             // Unwrap a real Clownfish object.
             IV tmp = SvIV(SvRV(sv));
             retval = INT2PTR(cfish_Obj*, tmp);
         }
         else if (allocation &&
-                 (vtable == CFISH_STACKSTRING
-                  || vtable == CFISH_STRING
-                  || vtable == CFISH_OBJ)
+                 (klass == CFISH_STACKSTRING
+                  || klass == CFISH_STRING
+                  || klass == CFISH_OBJ)
                 ) {
             // Wrap the string from an ordinary Perl scalar inside a
             // StackString.
@@ -109,10 +109,10 @@ XSBind_maybe_sv_to_cfish_obj(SV *sv, cfish_VTable *vtable, void *allocation) {
             // Attempt to convert Perl hashes and arrays into their Clownfish
             // analogues.
             SV *inner = SvRV(sv);
-            if (SvTYPE(inner) == SVt_PVAV && vtable == CFISH_VARRAY) {
+            if (SvTYPE(inner) == SVt_PVAV && klass == CFISH_VARRAY) {
                 retval = (cfish_Obj*)S_perl_array_to_cfish_array((AV*)inner);
             }
-            else if (SvTYPE(inner) == SVt_PVHV && vtable == CFISH_HASH) {
+            else if (SvTYPE(inner) == SVt_PVHV && klass == CFISH_HASH) {
                 retval = (cfish_Obj*)S_perl_hash_to_cfish_hash((HV*)inner);
             }
 
@@ -396,7 +396,7 @@ XSBind_enable_overload(void *pobj) {
 
 static bool
 S_extract_from_sv(SV *value, void *target, const char *label,
-                  bool required, int type, cfish_VTable *vtable,
+                  bool required, int type, cfish_Class *klass,
                   void *allocation) {
     bool valid_assignment = false;
 
@@ -460,7 +460,7 @@ S_extract_from_sv(SV *value, void *target, const char *label,
                 break;
             case XSBIND_WANT_OBJ: {
                     cfish_Obj *object
-                        = XSBind_maybe_sv_to_cfish_obj(value, vtable,
+                        = XSBind_maybe_sv_to_cfish_obj(value, klass,
                                                        allocation);
                     if (object) {
                         *((cfish_Obj**)target) = object;
@@ -470,7 +470,7 @@ S_extract_from_sv(SV *value, void *target, const char *label,
                         cfish_String *mess
                             = CFISH_MAKE_MESS(
                                   "Invalid value for '%s' - not a %o",
-                                  label, CFISH_VTable_Get_Name(vtable));
+                                  label, CFISH_Class_Get_Name(klass));
                         cfish_Err_set_error(cfish_Err_new(mess));
                         return false;
                     }
@@ -526,7 +526,7 @@ XSBind_allot_params(SV** stack, int32_t start, int32_t num_stack_elems, ...) {
         int   label_len = va_arg(args, int);
         int   required  = va_arg(args, int);
         int   type      = va_arg(args, int);
-        cfish_VTable *vtable = va_arg(args, cfish_VTable*);
+        cfish_Class *klass = va_arg(args, cfish_Class*);
         void *allocation = va_arg(args, void*);
 
         // Iterate through the stack looking for labels which match this param
@@ -558,7 +558,7 @@ XSBind_allot_params(SV** stack, int32_t start, int32_t num_stack_elems, ...) {
             // Found the arg.  Extract the value.
             SV *value = stack[found_arg + 1];
             bool got_arg = S_extract_from_sv(value, target, label,
-                                                   required, type, vtable,
+                                                   required, type, klass,
                                                    allocation);
             if (!got_arg) {
                 CFISH_ERR_ADD_FRAME(cfish_Err_get_error());
@@ -601,7 +601,7 @@ S_lazy_init_host_obj(cfish_Obj *self) {
     sv_setiv(inner_obj, PTR2IV(self));
 
     // Connect class association.
-    cfish_String *class_name = CFISH_VTable_Get_Name(self->vtable);
+    cfish_String *class_name = CFISH_Class_Get_Name(self->klass);
     HV *stash = gv_stashpvn(CFISH_Str_Get_Ptr8(class_name),
                             CFISH_Str_Get_Size(class_name), TRUE);
     SvSTASH_set(inner_obj, (HV*)SvREFCNT_inc(stash));
@@ -669,53 +669,53 @@ CFISH_Obj_To_Host_IMP(cfish_Obj *self) {
     return newRV_inc((SV*)self->ref.host_obj);
 }
 
-/*************************** Clownfish::VTable ******************************/
+/*************************** Clownfish::Class ******************************/
 
 cfish_Obj*
-CFISH_VTable_Make_Obj_IMP(cfish_VTable *self) {
+CFISH_Class_Make_Obj_IMP(cfish_Class *self) {
     cfish_Obj *obj
         = (cfish_Obj*)cfish_Memory_wrapped_calloc(self->obj_alloc_size, 1);
-    obj->vtable = self;
+    obj->klass = self;
     obj->ref.count = (1 << XSBIND_REFCOUNT_SHIFT) | XSBIND_REFCOUNT_FLAG;
     return obj;
 }
 
 cfish_Obj*
-CFISH_VTable_Init_Obj_IMP(cfish_VTable *self, void *allocation) {
+CFISH_Class_Init_Obj_IMP(cfish_Class *self, void *allocation) {
     cfish_Obj *obj = (cfish_Obj*)allocation;
-    obj->vtable = self;
+    obj->klass = self;
     obj->ref.count = (1 << XSBIND_REFCOUNT_SHIFT) | XSBIND_REFCOUNT_FLAG;
     return obj;
 }
 
 cfish_Obj*
-CFISH_VTable_Foster_Obj_IMP(cfish_VTable *self, void *host_obj) {
+CFISH_Class_Foster_Obj_IMP(cfish_Class *self, void *host_obj) {
     cfish_Obj *obj
         = (cfish_Obj*)cfish_Memory_wrapped_calloc(self->obj_alloc_size, 1);
     SV *inner_obj = SvRV((SV*)host_obj);
-    obj->vtable = self;
+    obj->klass = self;
     sv_setiv(inner_obj, PTR2IV(obj));
     obj->ref.host_obj = inner_obj;
     return obj;
 }
 
 void
-cfish_VTable_register_with_host(cfish_VTable *singleton, cfish_VTable *parent) {
+cfish_Class_register_with_host(cfish_Class *singleton, cfish_Class *parent) {
     dSP;
     ENTER;
     SAVETMPS;
     EXTEND(SP, 2);
     PUSHMARK(SP);
-    mPUSHs((SV*)CFISH_VTable_To_Host(singleton));
-    mPUSHs((SV*)CFISH_VTable_To_Host(parent));
+    mPUSHs((SV*)CFISH_Class_To_Host(singleton));
+    mPUSHs((SV*)CFISH_Class_To_Host(parent));
     PUTBACK;
-    call_pv("Clownfish::VTable::_register", G_VOID | G_DISCARD);
+    call_pv("Clownfish::Class::_register", G_VOID | G_DISCARD);
     FREETMPS;
     LEAVE;
 }
 
 cfish_VArray*
-cfish_VTable_fresh_host_methods(cfish_String *class_name) {
+cfish_Class_fresh_host_methods(cfish_String *class_name) {
     dSP;
     ENTER;
     SAVETMPS;
@@ -723,7 +723,7 @@ cfish_VTable_fresh_host_methods(cfish_String *class_name) {
     PUSHMARK(SP);
     mPUSHs(XSBind_str_to_sv(class_name));
     PUTBACK;
-    call_pv("Clownfish::VTable::_fresh_host_methods", G_SCALAR);
+    call_pv("Clownfish::Class::_fresh_host_methods", G_SCALAR);
     SPAGAIN;
     cfish_VArray *methods = (cfish_VArray*)XSBind_perl_to_cfish(POPs);
     PUTBACK;
@@ -733,7 +733,7 @@ cfish_VTable_fresh_host_methods(cfish_String *class_name) {
 }
 
 cfish_String*
-cfish_VTable_find_parent_class(cfish_String *class_name) {
+cfish_Class_find_parent_class(cfish_String *class_name) {
     dSP;
     ENTER;
     SAVETMPS;
@@ -741,7 +741,7 @@ cfish_VTable_find_parent_class(cfish_String *class_name) {
     PUSHMARK(SP);
     mPUSHs(XSBind_str_to_sv(class_name));
     PUTBACK;
-    call_pv("Clownfish::VTable::_find_parent_class", G_SCALAR);
+    call_pv("Clownfish::Class::_find_parent_class", G_SCALAR);
     SPAGAIN;
     SV *parent_class_sv = POPs;
     PUTBACK;
@@ -753,10 +753,10 @@ cfish_VTable_find_parent_class(cfish_String *class_name) {
 }
 
 void*
-CFISH_VTable_To_Host_IMP(cfish_VTable *self) {
+CFISH_Class_To_Host_IMP(cfish_Class *self) {
     bool first_time = self->ref.count & XSBIND_REFCOUNT_FLAG ? true : false;
-    CFISH_VTable_To_Host_t to_host
-        = CFISH_SUPER_METHOD_PTR(CFISH_VTABLE, CFISH_VTable_To_Host);
+    CFISH_Class_To_Host_t to_host
+        = CFISH_SUPER_METHOD_PTR(CFISH_CLASS, CFISH_Class_To_Host);
     SV *host_obj = (SV*)to_host(self);
     if (first_time) {
         SvSHARE((SV*)self->ref.host_obj);
@@ -853,8 +853,8 @@ CFISH_Err_To_Host_IMP(cfish_Err *self) {
 }
 
 void
-cfish_Err_throw_mess(cfish_VTable *vtable, cfish_String *message) {
-    CHY_UNUSED_VAR(vtable);
+cfish_Err_throw_mess(cfish_Class *klass, cfish_String *message) {
+    CHY_UNUSED_VAR(klass);
     cfish_Err *err = cfish_Err_new(message);
     cfish_Err_do_throw(err);
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/perl/xs/XSBind.h
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.h b/runtime/perl/xs/XSBind.h
index 5df36f9..73b5ebb 100644
--- a/runtime/perl/xs/XSBind.h
+++ b/runtime/perl/xs/XSBind.h
@@ -27,7 +27,7 @@
 #include "Clownfish/Hash.h"
 #include "Clownfish/Num.h"
 #include "Clownfish/VArray.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 /* Avoid conflicts with Clownfish bool type. */
 #define HAS_BOOL
@@ -59,20 +59,20 @@ cfish_XSBind_sv_defined(SV *sv) {
 }
 
 /** If the SV contains a Clownfish object which passes an "isa" test against the
- * passed-in VTable, return a pointer to it.  If not, but
+ * passed-in Class, return a pointer to it.  If not, but
  * <code>allocation</code> is non-NULL and a StackString would satisfy the
  * "isa" test, stringify the SV, create a StackString using
  * <code>allocation</code>, assign the SV's string to it, and return that
  * instead.  If all else fails, throw an exception.
  */
 CFISH_VISIBLE cfish_Obj*
-cfish_XSBind_sv_to_cfish_obj(SV *sv, cfish_VTable *vtable, void *allocation);
+cfish_XSBind_sv_to_cfish_obj(SV *sv, cfish_Class *klass, void *allocation);
 
 /** As XSBind_sv_to_cfish_obj above, but returns NULL instead of throwing an
  * exception.
  */
 CFISH_VISIBLE cfish_Obj*
-cfish_XSBind_maybe_sv_to_cfish_obj(SV *sv, cfish_VTable *vtable,
+cfish_XSBind_maybe_sv_to_cfish_obj(SV *sv, cfish_Class *klass,
                                    void *allocation);
 
 
@@ -187,9 +187,9 @@ cfish_XSBind_enable_overload(void *pobj);
  *
  * Use the following macro if a Clownfish object is desired:
  *
- *     ALLOT_OBJ(ptr, key, keylen, required, vtable, allocation)
+ *     ALLOT_OBJ(ptr, key, keylen, required, klass, allocation)
  *
- * The "vtable" argument must be the VTable corresponding to the class of the
+ * The "klass" argument must be the Class corresponding to the class of the
  * desired object.  The "allocation" argument must be a blob of memory
  * allocated on the stack sufficient to hold a StackString.  (Use
  * cfish_SStr_size() to find the allocation size.)
@@ -295,8 +295,8 @@ cfish_XSBind_allot_params(SV** stack, int32_t start,
     ptr, key, keylen, required, XSBIND_WANT_F32, NULL, NULL
 #define XSBIND_ALLOT_F64(ptr, key, keylen, required) \
     ptr, key, keylen, required, XSBIND_WANT_F64, NULL, NULL
-#define XSBIND_ALLOT_OBJ(ptr, key, keylen, required, vtable, allocation) \
-    ptr, key, keylen, required, XSBIND_WANT_OBJ, vtable, allocation
+#define XSBIND_ALLOT_OBJ(ptr, key, keylen, required, klass, allocation) \
+    ptr, key, keylen, required, XSBIND_WANT_OBJ, klass, allocation
 #define XSBIND_ALLOT_SV(ptr, key, keylen, required) \
     ptr, key, keylen, required, XSBIND_WANT_SV, NULL, NULL
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/ruby/ext/Bind.h
----------------------------------------------------------------------
diff --git a/runtime/ruby/ext/Bind.h b/runtime/ruby/ext/Bind.h
index 805afae..12a5ba3 100644
--- a/runtime/ruby/ext/Bind.h
+++ b/runtime/ruby/ext/Bind.h
@@ -32,7 +32,7 @@ extern "C" {
 #include "Clownfish/Hash.h"
 #include "Clownfish/Num.h"
 #include "Clownfish/VArray.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 VALUE Bind_cfish_to_ruby(cfish_Obj *obj);
 VALUE Bind_str_to_ruby(cfish_String *str);


[3/3] git commit: Rename Class ivar 'method_ptrs' to 'vtable'

Posted by nw...@apache.org.
Rename Class ivar 'method_ptrs' to 'vtable'


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/b8579190
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/b8579190
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/b8579190

Branch: refs/heads/rename-vtable
Commit: b8579190715c14d36c8e5ef6fc05a9994c295be0
Parents: 0c8e0f1
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Wed Jul 2 17:19:47 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Wed Jul 2 17:19:47 2014 +0200

----------------------------------------------------------------------
 runtime/core/Clownfish/Class.c   | 9 +++++----
 runtime/core/Clownfish/Class.cfh | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b8579190/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 70fd483..4bfaad9 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -87,7 +87,7 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
 
         size_t novel_offset = parent
                               ? parent->class_alloc_size
-                              : offsetof(Class, method_ptrs);
+                              : offsetof(Class, vtable);
         size_t class_alloc_size = novel_offset
                                   + spec->num_novel_meths
                                     * sizeof(cfish_method_t);
@@ -100,9 +100,10 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
         klass->class_alloc_size = class_alloc_size;
 
         if (parent) {
-            size_t parent_ptrs_size = parent->class_alloc_size
-                                      - offsetof(Class, method_ptrs);
-            memcpy(klass->method_ptrs, parent->method_ptrs, parent_ptrs_size);
+            // Copy parent vtable.
+            size_t parent_vt_size = parent->class_alloc_size
+                                    - offsetof(Class, vtable);
+            memcpy(klass->vtable, parent->vtable, parent_vt_size);
         }
 
         for (size_t i = 0; i < spec->num_inherited_meths; ++i) {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/b8579190/runtime/core/Clownfish/Class.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh
index fd4e183..2d07add 100644
--- a/runtime/core/Clownfish/Class.cfh
+++ b/runtime/core/Clownfish/Class.cfh
@@ -32,7 +32,7 @@ class Clownfish::Class inherits Clownfish::Obj {
     size_t             obj_alloc_size;
     size_t             class_alloc_size;
     VArray            *methods;
-    cfish_method_t[1]  method_ptrs; /* flexible array */
+    cfish_method_t[1]  vtable; /* flexible array */
 
     inert LockFreeRegistry *registry;
     inert size_t offset_of_parent;


[2/3] git commit: Rename Clownfish::VTable to Clownfish::Class

Posted by nw...@apache.org.
Rename Clownfish::VTable to Clownfish::Class


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/0c8e0f14
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/0c8e0f14
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/0c8e0f14

Branch: refs/heads/rename-vtable
Commit: 0c8e0f14a2a5990e891214716550635f2c621f7c
Parents: 5fc4513
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Wed Jul 2 16:43:39 2014 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Wed Jul 2 17:17:34 2014 +0200

----------------------------------------------------------------------
 compiler/perl/lib/Clownfish/CFC.xs              |   8 +-
 compiler/src/CFCBindClass.c                     |  61 +--
 compiler/src/CFCBindClass.h                     |   2 +-
 compiler/src/CFCBindCore.c                      |  84 ++--
 compiler/src/CFCBindMethod.c                    |   6 +-
 compiler/src/CFCBindMethod.h                    |   6 +-
 compiler/src/CFCClass.c                         |  30 +-
 compiler/src/CFCClass.h                         |   8 +-
 compiler/src/CFCMethod.h                        |   8 +-
 compiler/src/CFCPerl.c                          |   8 +-
 compiler/src/CFCPerlClass.c                     |  12 +-
 compiler/src/CFCPerlMethod.c                    |   6 +-
 compiler/src/CFCPerlSub.c                       |   4 +-
 compiler/src/CFCPerlTypeMap.c                   |  14 +-
 compiler/src/CFCRuby.c                          |   2 +-
 compiler/src/CFCType.c                          |  18 +-
 compiler/src/CFCType.h                          |   4 +-
 runtime/c/src/Clownfish/Class.c                 |  79 ++++
 runtime/c/src/Clownfish/Err.c                   |   6 +-
 runtime/c/src/Clownfish/VTable.c                |  79 ----
 runtime/core/Clownfish/ByteBuf.c                |  10 +-
 runtime/core/Clownfish/CharBuf.c                |   6 +-
 runtime/core/Clownfish/Class.c                  | 446 +++++++++++++++++++
 runtime/core/Clownfish/Class.cfh                | 155 +++++++
 runtime/core/Clownfish/Err.c                    |  38 +-
 runtime/core/Clownfish/Err.cfh                  |  46 +-
 runtime/core/Clownfish/Hash.c                   |   6 +-
 runtime/core/Clownfish/LockFreeRegistry.c       |   4 +-
 runtime/core/Clownfish/LockFreeRegistry.cfh     |   2 +-
 runtime/core/Clownfish/Method.c                 |   6 +-
 runtime/core/Clownfish/Num.c                    |  14 +-
 runtime/core/Clownfish/Obj.c                    |  22 +-
 runtime/core/Clownfish/Obj.cfh                  |  24 +-
 runtime/core/Clownfish/String.c                 |  30 +-
 runtime/core/Clownfish/Test/TestByteBuf.c       |   4 +-
 runtime/core/Clownfish/Test/TestCharBuf.c       |   4 +-
 runtime/core/Clownfish/Test/TestErr.c           |   4 +-
 runtime/core/Clownfish/Test/TestHash.c          |   4 +-
 .../core/Clownfish/Test/TestLockFreeRegistry.c  |   4 +-
 runtime/core/Clownfish/Test/TestNum.c           |   4 +-
 runtime/core/Clownfish/Test/TestObj.c           |  24 +-
 runtime/core/Clownfish/Test/TestString.c        |   4 +-
 runtime/core/Clownfish/Test/TestVArray.c        |   4 +-
 runtime/core/Clownfish/Test/Util/TestAtomic.c   |   4 +-
 runtime/core/Clownfish/Test/Util/TestMemory.c   |   4 +-
 .../core/Clownfish/Test/Util/TestNumberUtils.c  |   4 +-
 .../core/Clownfish/Test/Util/TestStringHelper.c |   4 +-
 .../Clownfish/TestHarness/TestBatchRunner.c     |   4 +-
 .../core/Clownfish/TestHarness/TestFormatter.c  |   6 +-
 runtime/core/Clownfish/TestHarness/TestSuite.c  |   4 +-
 .../Clownfish/TestHarness/TestSuiteRunner.c     |   4 +-
 runtime/core/Clownfish/VArray.c                 |   4 +-
 runtime/core/Clownfish/VTable.c                 | 446 -------------------
 runtime/core/Clownfish/VTable.cfh               | 155 -------
 .../perl/buildlib/Clownfish/Build/Binding.pm    |  36 +-
 runtime/perl/lib/Clownfish.pm                   |   2 +-
 runtime/perl/lib/Clownfish.pod                  |  12 +-
 runtime/perl/lib/Clownfish/Class.pm             |  25 ++
 runtime/perl/lib/Clownfish/VTable.pm            |  25 --
 runtime/perl/t/021-class.t                      |  57 +++
 runtime/perl/t/021-vtable.t                     |  57 ---
 runtime/perl/xs/XSBind.c                        |  92 ++--
 runtime/perl/xs/XSBind.h                        |  16 +-
 runtime/ruby/ext/Bind.h                         |   2 +-
 64 files changed, 1138 insertions(+), 1135 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/compiler/perl/lib/Clownfish/CFC.xs b/compiler/perl/lib/Clownfish/CFC.xs
index f093f49..b5734ce 100644
--- a/compiler/perl/lib/Clownfish/CFC.xs
+++ b/compiler/perl/lib/Clownfish/CFC.xs
@@ -287,8 +287,8 @@ ALIAS:
     inert                 = 16
     get_struct_sym        = 18
     full_struct_sym       = 20
-    short_vtable_var      = 22
-    full_vtable_var       = 24
+    short_class_var       = 22
+    full_class_var        = 24
     include_h             = 28
     get_docucomment       = 30
     children              = 32
@@ -352,12 +352,12 @@ PPCODE:
             }
             break;
         case 22: {
-                const char *value = CFCClass_short_vtable_var(self);
+                const char *value = CFCClass_short_class_var(self);
                 retval = value ? newSVpvn(value, strlen(value)) : newSV(0);
             }
             break;
         case 24: {
-                const char *value = CFCClass_full_vtable_var(self);
+                const char *value = CFCClass_full_class_var(self);
                 retval = value ? newSVpvn(value, strlen(value)) : newSV(0);
             }
             break;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindClass.c b/compiler/src/CFCBindClass.c
index 2b0a53a..ebeb07d 100644
--- a/compiler/src/CFCBindClass.c
+++ b/compiler/src/CFCBindClass.c
@@ -183,7 +183,7 @@ S_ivars_func(CFCBindClass *self) {
 static char*
 S_to_c_header_dynamic(CFCBindClass *self) {
     const char *privacy_symbol  = CFCClass_privacy_symbol(self->client);
-    const char *vt_var          = CFCClass_full_vtable_var(self->client);
+    const char *class_var       = CFCClass_full_class_var(self->client);
     const char *PREFIX          = CFCClass_get_PREFIX(self->client);
     char *ivars                 = S_ivars_func(self);
     char *struct_def            = S_struct_definition(self);
@@ -230,10 +230,10 @@ S_to_c_header_dynamic(CFCBindClass *self) {
         "\n"
         "%s\n"
         "\n"
-        "/* Declare the VTable singleton for this class.\n"
+        "/* Declare the Class singleton for this class.\n"
         " */\n"
         "\n"
-        "extern %sVISIBLE cfish_VTable *%s;\n"
+        "extern %sVISIBLE cfish_Class *%s;\n"
         "\n"
         "/* Define \"short names\" for this class's symbols.\n"
         " */\n"
@@ -244,7 +244,7 @@ S_to_c_header_dynamic(CFCBindClass *self) {
         = CFCUtil_sprintf(pattern, parent_include, privacy_symbol, ivars,
                           struct_def, privacy_symbol, inert_var_defs,
                           sub_declarations, method_typedefs, method_defs,
-                          PREFIX, vt_var, short_names);
+                          PREFIX, class_var, short_names);
 
     FREEMEM(ivars);
     FREEMEM(struct_def);
@@ -268,7 +268,7 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
 
     const char *ivars_offset = CFCClass_full_ivars_offset(client);
 
-    const char *vt_var    = CFCClass_full_vtable_var(client);
+    const char *class_var    = CFCClass_full_class_var(client);
 
     CFCMethod **methods  = CFCClass_methods(client);
 
@@ -303,11 +303,11 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
                 // doesn't allow us to initialize a pointer to an anonymous
                 // array inside a global struct, we have to give it a real
                 // symbol and then store a pointer to that symbol inside the
-                // VTableSpec struct.
+                // ClassSpec struct.
                 novel_ms_var
                     = CFCUtil_cat(novel_ms_var,
                                   "static const cfish_NovelMethSpec ",
-                                  vt_var, "_NOVEL_METHS[] = {\n", NULL);
+                                  class_var, "_NOVEL_METHS[] = {\n", NULL);
             }
             else {
                 novel_ms_var = CFCUtil_cat(novel_ms_var, ",\n", NULL);
@@ -322,7 +322,8 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
                 overridden_ms_var
                     = CFCUtil_cat(overridden_ms_var,
                                   "static const cfish_OverriddenMethSpec ",
-                                  vt_var, "_OVERRIDDEN_METHS[] = {\n", NULL);
+                                  class_var, "_OVERRIDDEN_METHS[] = {\n",
+                                  NULL);
             }
             else {
                 overridden_ms_var
@@ -338,7 +339,7 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
                 inherited_ms_var
                     = CFCUtil_cat(inherited_ms_var,
                                   "static const cfish_InheritedMethSpec ",
-                                  vt_var, "_INHERITED_METHS[] = {\n", NULL);
+                                  class_var, "_INHERITED_METHS[] = {\n", NULL);
             }
             else {
                 inherited_ms_var = CFCUtil_cat(inherited_ms_var, ",\n", NULL);
@@ -368,7 +369,7 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
         "size_t %s;\n"
         "\n"
         "/* Offsets for method pointers, measured in bytes, from the top\n"
-        " * of this class's vtable.\n"
+        " * of this class's singleton object.\n"
         " */\n"
         "\n"
         "%s\n"
@@ -378,21 +379,21 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
         "\n"
         "%s\n"
         "\n"
-        "/* Define the MethSpec structs used during VTable initialization.\n"
+        "/* Define the MethSpec structs used during Class initialization.\n"
         " */\n"
         "\n"
         "%s"
         "%s"
         "%s"
-        "/* Define this class's VTable.\n"
+        "/* Define the pointer to the Class singleton object.\n"
         " */\n"
         "\n"
-        "cfish_VTable *%s;\n"
+        "cfish_Class *%s;\n"
         "\n";
     char *code
         = CFCUtil_sprintf(pattern, ivars_offset, offsets, method_defs,
                           novel_ms_var, overridden_ms_var, inherited_ms_var,
-                          vt_var);
+                          class_var);
 
     FREEMEM(offsets);
     FREEMEM(method_defs);
@@ -445,22 +446,22 @@ S_struct_definition(CFCBindClass *self) {
     return struct_def;
 }
 
-// Return C definition of the class's VTableSpec.
+// Return C definition of the class's ClassSpec.
 char*
 CFCBindClass_spec_def(CFCBindClass *self) {
     CFCClass *client = self->client;
 
     CFCClass   *parent       = CFCClass_get_parent(client);
     const char *class_name   = CFCClass_get_class_name(client);
-    const char *vt_var       = CFCClass_full_vtable_var(client);
+    const char *class_var    = CFCClass_full_class_var(client);
     const char *struct_sym   = CFCClass_full_struct_sym(client);
     const char *ivars_struct = CFCClass_full_ivars_struct(client);
     const char *prefix       = CFCClass_get_prefix(client);
 
-    // Create a pointer to the parent class's vtable.
+    // Create a pointer to the parent Class object.
     char *parent_ref;
     if (parent) {
-        parent_ref = CFCUtil_sprintf("&%s", CFCClass_full_vtable_var(parent));
+        parent_ref = CFCUtil_sprintf("&%s", CFCClass_full_class_var(parent));
     }
     else {
         // No parent, e.g. Obj or inert classes.
@@ -490,13 +491,15 @@ CFCBindClass_spec_def(CFCBindClass *self) {
     }
 
     char *novel_ms_var      = num_novel
-                              ? CFCUtil_sprintf("%s_NOVEL_METHS", vt_var)
+                              ? CFCUtil_sprintf("%s_NOVEL_METHS", class_var)
                               : CFCUtil_strdup("NULL");
     char *overridden_ms_var = num_overridden
-                              ? CFCUtil_sprintf("%s_OVERRIDDEN_METHS", vt_var)
+                              ? CFCUtil_sprintf("%s_OVERRIDDEN_METHS",
+                                                class_var)
                               : CFCUtil_strdup("NULL");
     char *inherited_ms_var  = num_inherited
-                              ? CFCUtil_sprintf("%s_INHERITED_METHS", vt_var)
+                              ? CFCUtil_sprintf("%s_INHERITED_METHS",
+                                                class_var)
                               : CFCUtil_strdup("NULL");
 
     const char *ivars_or_not = strcmp(prefix, "cfish_") == 0
@@ -505,7 +508,7 @@ CFCBindClass_spec_def(CFCBindClass *self) {
 
     char pattern[] =
         "    {\n"
-        "        &%s, /* vtable */\n"
+        "        &%s, /* class */\n"
         "        %s, /* parent */\n"
         "        \"%s\", /* name */\n"
         "        sizeof(%s), /* ivars_size */\n"
@@ -518,7 +521,7 @@ CFCBindClass_spec_def(CFCBindClass *self) {
         "        %s /* inherited_meth_specs */\n"
         "    }";
     char *code
-        = CFCUtil_sprintf(pattern, vt_var, parent_ref, class_name,
+        = CFCUtil_sprintf(pattern, class_var, parent_ref, class_name,
                           ivars_or_not, ivars_offset_name, num_novel,
                           num_overridden, num_inherited, novel_ms_var,
                           overridden_ms_var, inherited_ms_var);
@@ -646,14 +649,14 @@ S_short_names(CFCBindClass *self) {
                               "\n", NULL);
 
     if (!CFCClass_inert(client)) {
-        const char *short_struct = CFCClass_get_struct_sym(client);
-        const char *full_struct  = CFCClass_full_struct_sym(client);
-        const char *short_vt_var = CFCClass_short_vtable_var(client);
-        const char *full_vt_var  = CFCClass_full_vtable_var(client);
+        const char *short_struct    = CFCClass_get_struct_sym(client);
+        const char *full_struct     = CFCClass_full_struct_sym(client);
+        const char *short_class_var = CFCClass_short_class_var(client);
+        const char *full_class_var  = CFCClass_full_class_var(client);
         short_names = CFCUtil_cat(short_names, "  #define ",
                                   short_struct, " ", full_struct, "\n",
-                                  "  #define ", short_vt_var, " ",
-                                  full_vt_var, "\n", NULL);
+                                  "  #define ", short_class_var, " ",
+                                  full_class_var, "\n", NULL);
     }
 
     CFCFunction **functions = CFCClass_functions(client);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCBindClass.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindClass.h b/compiler/src/CFCBindClass.h
index 6cb9347..7dd915a 100644
--- a/compiler/src/CFCBindClass.h
+++ b/compiler/src/CFCBindClass.h
@@ -54,7 +54,7 @@ CFCBindClass_to_c_header(CFCBindClass *self);
 char*
 CFCBindClass_to_c_data(CFCBindClass *self);
 
-/** Return the autogenerated C definition of class's VTableSpec.
+/** Return the autogenerated C definition of class's ClassSpec.
  */
 char*
 CFCBindClass_spec_def(CFCBindClass *self);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c
index 0e24d74..390682a 100644
--- a/compiler/src/CFCBindCore.c
+++ b/compiler/src/CFCBindCore.c
@@ -188,21 +188,21 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "typedef void\n"
         "(*cfish_method_t)(const void *vself);\n"
         "\n"
-        "/* Access the function pointer for a given method from the vtable.\n"
+        "/* Access the function pointer for a given method from the class.\n"
         " */\n"
-        "#define CFISH_METHOD_PTR(_vtable, _full_meth) \\\n"
-        "     ((_full_meth ## _t)cfish_method(_vtable, _full_meth ## _OFFSET))\n"
+        "#define CFISH_METHOD_PTR(_class, _full_meth) \\\n"
+        "     ((_full_meth ## _t)cfish_method(_class, _full_meth ## _OFFSET))\n"
         "\n"
         "static CFISH_INLINE cfish_method_t\n"
-        "cfish_method(const void *vtable, size_t offset) {\n"
+        "cfish_method(const void *klass, size_t offset) {\n"
         "    union { char *cptr; cfish_method_t *fptr; } ptr;\n"
-        "    ptr.cptr = (char*)vtable + offset;\n"
+        "    ptr.cptr = (char*)klass + offset;\n"
         "    return ptr.fptr[0];\n"
         "}\n"
         "\n"
         "typedef struct cfish_Dummy {\n"
         "   CFISH_OBJ_HEAD\n"
-        "   void *vtable;\n"
+        "   void *klass;\n"
         "} cfish_Dummy;\n"
         "\n"
         "/* Access the function pointer for a given method from the object.\n"
@@ -210,25 +210,25 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "static CFISH_INLINE cfish_method_t\n"
         "cfish_obj_method(const void *object, size_t offset) {\n"
         "    cfish_Dummy *dummy = (cfish_Dummy*)object;\n"
-        "    return cfish_method(dummy->vtable, offset);\n"
+        "    return cfish_method(dummy->klass, offset);\n"
         "}\n"
         "\n"
-        "/* Access the function pointer for the given method in the superclass's\n"
-        " * vtable. */\n"
-        "#define CFISH_SUPER_METHOD_PTR(_vtable, _full_meth) \\\n"
-        "     ((_full_meth ## _t)cfish_super_method(_vtable, \\\n"
+        "/* Access the function pointer for the given method in the\n"
+        " * superclass. */\n"
+        "#define CFISH_SUPER_METHOD_PTR(_class, _full_meth) \\\n"
+        "     ((_full_meth ## _t)cfish_super_method(_class, \\\n"
         "                                           _full_meth ## _OFFSET))\n"
         "\n"
-        "extern CFISH_VISIBLE size_t cfish_VTable_offset_of_parent;\n"
+        "extern CFISH_VISIBLE size_t cfish_Class_offset_of_parent;\n"
         "static CFISH_INLINE cfish_method_t\n"
-        "cfish_super_method(const void *vtable, size_t offset) {\n"
-        "    char *vt_as_char = (char*)vtable;\n"
-        "    cfish_VTable **parent_ptr\n"
-        "        = (cfish_VTable**)(vt_as_char + cfish_VTable_offset_of_parent);\n"
+        "cfish_super_method(const void *klass, size_t offset) {\n"
+        "    char *class_as_char = (char*)klass;\n"
+        "    cfish_Class **parent_ptr\n"
+        "        = (cfish_Class**)(class_as_char + cfish_Class_offset_of_parent);\n"
         "    return cfish_method(*parent_ptr, offset);\n"
         "}\n"
         "\n"
-        "/* Structs for VTable initialization.\n"
+        "/* Structs for Class initialization.\n"
         " */\n"
         "\n"
         "typedef struct cfish_NovelMethSpec {\n"
@@ -249,19 +249,19 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "    size_t *parent_offset;\n"
         "} cfish_InheritedMethSpec;\n"
         "\n"
-        "typedef struct cfish_VTableSpec {\n"
-        "    cfish_VTable **vtable;\n"
-        "    cfish_VTable **parent;\n"
-        "    const char    *name;\n"
-        "    size_t         ivars_size;\n"
-        "    size_t        *ivars_offset_ptr;\n"
-        "    uint32_t       num_novel_meths;\n"
-        "    uint32_t       num_overridden_meths;\n"
-        "    uint32_t       num_inherited_meths;\n"
+        "typedef struct cfish_ClassSpec {\n"
+        "    cfish_Class **klass;\n"
+        "    cfish_Class **parent;\n"
+        "    const char   *name;\n"
+        "    size_t        ivars_size;\n"
+        "    size_t       *ivars_offset_ptr;\n"
+        "    uint32_t      num_novel_meths;\n"
+        "    uint32_t      num_overridden_meths;\n"
+        "    uint32_t      num_inherited_meths;\n"
         "    const cfish_NovelMethSpec      *novel_meth_specs;\n"
         "    const cfish_OverriddenMethSpec *overridden_meth_specs;\n"
         "    const cfish_InheritedMethSpec  *inherited_meth_specs;\n"
-        "} cfish_VTableSpec;\n"
+        "} cfish_ClassSpec;\n"
         "\n"
         "#ifdef CFISH_USE_SHORT_NAMES\n"
         "  #define METHOD_PTR               CFISH_METHOD_PTR\n"
@@ -269,7 +269,7 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "  #define NovelMethSpec            cfish_NovelMethSpec\n"
         "  #define OverriddenMethSpec       cfish_OverriddenMethSpec\n"
         "  #define InheritedMethSpec        cfish_InheritedMethSpec\n"
-        "  #define VTableSpec               cfish_VTableSpec\n"
+        "  #define ClassSpec                cfish_ClassSpec\n"
         "#endif\n"
         "\n";
 
@@ -359,8 +359,8 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
     char *privacy_syms = CFCUtil_strdup("");
     char *includes     = CFCUtil_strdup("");
     char *c_data       = CFCUtil_strdup("");
-    char *vt_specs = CFCUtil_strdup(
-        "static const cfish_VTableSpec vtable_specs[] = {\n");
+    char *class_specs  = CFCUtil_strdup(
+        "static const cfish_ClassSpec class_specs[] = {\n");
     int num_specs = 0;
     CFCClass **ordered  = CFCHierarchy_ordered_classes(hierarchy);
     for (int i = 0; ordered[i] != NULL; i++) {
@@ -378,11 +378,11 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
         FREEMEM(class_c_data);
         if (!CFCClass_inert(klass)) {
             if (num_specs != 0) {
-                vt_specs = CFCUtil_cat(vt_specs, ",\n", NULL);
+                class_specs = CFCUtil_cat(class_specs, ",\n", NULL);
             }
-            char *vt_spec = CFCBindClass_spec_def(class_binding);
-            vt_specs = CFCUtil_cat(vt_specs, vt_spec, NULL);
-            FREEMEM(vt_spec);
+            char *class_spec = CFCBindClass_spec_def(class_binding);
+            class_specs = CFCUtil_cat(class_specs, class_spec, NULL);
+            FREEMEM(class_spec);
             ++num_specs;
         }
         CFCBase_decref((CFCBase*)class_binding);
@@ -390,13 +390,13 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
         privacy_syms = CFCUtil_cat(privacy_syms, "#define ",
                                    privacy_sym, "\n", NULL);
     }
-    vt_specs = CFCUtil_cat(vt_specs, "\n};\n", NULL);
+    class_specs = CFCUtil_cat(class_specs, "\n};\n", NULL);
     FREEMEM(ordered);
 
     // Bootstrapping code for prerequisite parcels.
     //
     // bootstrap_inheritance() first calls bootstrap_inheritance() for all
-    // parcels from which classes are inherited. Then the VTables of the parcel
+    // parcels from which classes are inherited. Then the Classes of the parcel
     // are initialized. It aborts on recursive invocation.
     //
     // bootstrap_parcel() first calls bootstrap_inheritance() of its own
@@ -423,7 +423,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
     char pattern[] =
         "%s\n"
         "\n"
-        "#define C_CFISH_VTABLE\n"          // Needed for abstract methods.
+        "#define C_CFISH_CLASS\n"            // Needed for abstract methods.
         "#include <stdio.h>\n"
         "#include <stdlib.h>\n"
         "%s\n"
@@ -433,12 +433,12 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
         "#include \"Clownfish/Err.h\"\n"     // Needed for dump/load.
         "#include \"Clownfish/Num.h\"\n"     // Needed for dump/load.
         "#include \"Clownfish/VArray.h\"\n"  // Needed for dump/load.
-        "#include \"Clownfish/VTable.h\"\n"  // Needed for bootstrap.
+        "#include \"Clownfish/Class.h\"\n"   // Needed for bootstrap.
         "%s\n"
         "\n"
         "%s\n"
         "\n"
-        "/* VTableSpec structs for initialization.\n"
+        "/* ClassSpec structs for initialization.\n"
         " */\n"
         "%s\n"
         "\n"
@@ -454,7 +454,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
         "    if (bootstrap_state >= 2) { return; }\n"
         "    bootstrap_state = 1;\n"
         "%s" // Bootstrap inherited parcels.
-        "    cfish_VTable_bootstrap(vtable_specs, %d);\n"
+        "    cfish_Class_bootstrap(class_specs, %d);\n"
         "    bootstrap_state = 2;\n"
         "}\n"
         "\n"
@@ -470,7 +470,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
         "%s\n";
     char *file_content
         = CFCUtil_sprintf(pattern, self->header, privacy_syms, prefix,
-                          includes, c_data, vt_specs, prefix, inh_bootstrap,
+                          includes, c_data, class_specs, prefix, inh_bootstrap,
                           num_specs, prefix, prefix, prereq_bootstrap, prefix,
                           self->footer);
 
@@ -485,7 +485,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
     FREEMEM(privacy_syms);
     FREEMEM(includes);
     FREEMEM(c_data);
-    FREEMEM(vt_specs);
+    FREEMEM(class_specs);
     FREEMEM(inh_bootstrap);
     FREEMEM(prereq_bootstrap);
     FREEMEM(file_content);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCBindMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindMethod.c b/compiler/src/CFCBindMethod.c
index 3448e44..58de50d 100644
--- a/compiler/src/CFCBindMethod.c
+++ b/compiler/src/CFCBindMethod.c
@@ -253,8 +253,8 @@ CFCBindMeth_abstract_method_def(CFCMethod *method) {
     CFCParamList *param_list = CFCMethod_get_param_list(method);
     const char *params = CFCParamList_to_c(param_list);
     const char *full_func_sym = CFCMethod_imp_func(method);
-    const char *vtable_var
-        = CFCType_get_vtable_var(CFCMethod_self_type(method));
+    const char *class_var
+        = CFCType_get_class_var(CFCMethod_self_type(method));
     CFCType    *return_type  = CFCMethod_get_return_type(method);
     const char *ret_type_str = CFCType_to_c(return_type);
     const char *macro_sym    = CFCMethod_get_macro_sym(method);
@@ -272,7 +272,7 @@ CFCBindMeth_abstract_method_def(CFCMethod *method) {
         "}\n";
     char *abstract_def
         = CFCUtil_sprintf(pattern, ret_type_str, full_func_sym, params,
-                          vtable_var, unused, macro_sym, return_statement);
+                          class_var, unused, macro_sym, return_statement);
 
     FREEMEM(unused);
     FREEMEM(return_statement);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCBindMethod.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindMethod.h b/compiler/src/CFCBindMethod.h
index 45bbb31..2f837cb 100644
--- a/compiler/src/CFCBindMethod.h
+++ b/compiler/src/CFCBindMethod.h
@@ -45,20 +45,20 @@ char*
 CFCBindMeth_typedef_dec(struct CFCMethod *method, struct CFCClass *klass);
 
 /** Return C code defining the MethSpec object for a novel method, which
- * is used during VTable initialization.
+ * is used during Class initialization.
  */
 char*
 CFCBindMeth_novel_spec_def(struct CFCMethod *method);
 
 /** Return C code defining the MethSpec object for an overridden method,
- * which is used during VTable initialization.
+ * which is used during Class initialization.
  */
 char*
 CFCBindMeth_overridden_spec_def(struct CFCMethod *method,
                                 struct CFCClass *klass);
 
 /** Return C code defining the MethSpec object for an inherited method,
- * which is used during VTable initialization.
+ * which is used during Class initialization.
  */
 char*
 CFCBindMeth_inherited_spec_def(struct CFCMethod *method,

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.c b/compiler/src/CFCClass.c
index dc74cd1..e896818 100644
--- a/compiler/src/CFCClass.c
+++ b/compiler/src/CFCClass.c
@@ -73,8 +73,8 @@ struct CFCClass {
     char *ivars_func;
     char *full_ivars_func;
     char *full_ivars_offset;
-    char *short_vtable_var;
-    char *full_vtable_var;
+    char *short_class_var;
+    char *full_class_var;
     char *privacy_symbol;
     char *include_h;
 };
@@ -150,12 +150,12 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
                        : CFCUtil_strdup(class_name);
     const char *prefix = CFCClass_get_prefix(self);
     size_t struct_sym_len = strlen(self->struct_sym);
-    self->short_vtable_var = (char*)MALLOCATE(struct_sym_len + 1);
+    self->short_class_var = (char*)MALLOCATE(struct_sym_len + 1);
     size_t i;
     for (i = 0; i < struct_sym_len; i++) {
-        self->short_vtable_var[i] = toupper(self->struct_sym[i]);
+        self->short_class_var[i] = toupper(self->struct_sym[i]);
     }
-    self->short_vtable_var[struct_sym_len] = '\0';
+    self->short_class_var[struct_sym_len] = '\0';
     self->full_struct_sym   = CFCUtil_sprintf("%s%s", prefix, self->struct_sym);
     self->ivars_struct      = CFCUtil_sprintf("%sIVARS", self->struct_sym);
     self->full_ivars_struct = CFCUtil_sprintf("%sIVARS", self->full_struct_sym);
@@ -165,12 +165,12 @@ CFCClass_do_create(CFCClass *self, struct CFCParcel *parcel,
                                               CFCClass_get_nickname(self));
     self->full_ivars_offset = CFCUtil_sprintf("%s_OFFSET", self->full_ivars_func);
     size_t full_struct_sym_len = strlen(self->full_struct_sym);
-    self->full_vtable_var = (char*)MALLOCATE(full_struct_sym_len + 1);
+    self->full_class_var = (char*)MALLOCATE(full_struct_sym_len + 1);
     for (i = 0; self->full_struct_sym[i] != '\0'; i++) {
-        self->full_vtable_var[i] = toupper(self->full_struct_sym[i]);
+        self->full_class_var[i] = toupper(self->full_struct_sym[i]);
     }
-    self->full_vtable_var[i] = '\0';
-    self->privacy_symbol = CFCUtil_sprintf("C_%s", self->full_vtable_var);
+    self->full_class_var[i] = '\0';
+    self->privacy_symbol = CFCUtil_sprintf("C_%s", self->full_class_var);
 
     // Build the relative path to the autogenerated C header file.
     if (file_spec) {
@@ -239,9 +239,9 @@ CFCClass_destroy(CFCClass *self) {
     FREEMEM(self->ivars_func);
     FREEMEM(self->full_ivars_func);
     FREEMEM(self->full_ivars_offset);
-    FREEMEM(self->short_vtable_var);
+    FREEMEM(self->short_class_var);
     FREEMEM(self->full_struct_sym);
-    FREEMEM(self->full_vtable_var);
+    FREEMEM(self->full_class_var);
     FREEMEM(self->privacy_symbol);
     FREEMEM(self->include_h);
     CFCSymbol_destroy((CFCSymbol*)self);
@@ -792,13 +792,13 @@ CFCClass_full_ivars_offset(CFCClass *self) {
 }
 
 const char*
-CFCClass_short_vtable_var(CFCClass *self) {
-    return self->short_vtable_var;
+CFCClass_short_class_var(CFCClass *self) {
+    return self->short_class_var;
 }
 
 const char*
-CFCClass_full_vtable_var(CFCClass *self) {
-    return self->full_vtable_var;
+CFCClass_full_class_var(CFCClass *self) {
+    return self->full_class_var;
 }
 
 const char*

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCClass.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCClass.h b/compiler/src/CFCClass.h
index 41691b2..9dde5b4 100644
--- a/compiler/src/CFCClass.h
+++ b/compiler/src/CFCClass.h
@@ -257,15 +257,15 @@ CFCClass_full_ivars_func(CFCClass *self);
 const char*
 CFCClass_full_ivars_offset(CFCClass *self);
 
-/** The short name of the global VTable object for this class.
+/** The short name of the global Class object for this class.
  */
 const char*
-CFCClass_short_vtable_var(CFCClass *self);
+CFCClass_short_class_var(CFCClass *self);
 
-/** Fully qualified vtable variable name, including the parcel prefix.
+/** Fully qualified Class variable name, including the parcel prefix.
  */
 const char*
-CFCClass_full_vtable_var(CFCClass *self);
+CFCClass_full_class_var(CFCClass *self);
 
 /** Access the symbol which unlocks the class struct definition and other
  * private information.

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCMethod.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCMethod.h b/compiler/src/CFCMethod.h
index eef5129..54d7e38 100644
--- a/compiler/src/CFCMethod.h
+++ b/compiler/src/CFCMethod.h
@@ -21,8 +21,8 @@
  * Obj.
  *
  * When compiling Clownfish code to C, Method objects generate all the code
- * that Function objects do, but also create symbols for indirect invocation via
- * VTable.
+ * that Function objects do, but also create symbols for indirect invocation
+ * via vtables.
  */
 
 #ifndef H_CFCMETHOD
@@ -129,8 +129,8 @@ CFCMethod_short_method_sym(CFCMethod *self, struct CFCClass *invoker);
 char*
 CFCMethod_full_method_sym(CFCMethod *self, struct CFCClass *invoker);
 
-/** Create the fully qualified name of the variable which stores the method's
- * vtable offset, e.g. "Crust_LobClaw_Pinch_OFFSET".
+/** Create the fully qualified name of the variable which stores the method
+ * pointer's offset, e.g. "Crust_LobClaw_Pinch_OFFSET".
  * @param invoker Class for which the symbol is created. If invoker is NULL,
  * use the class where the method is defined.
  *

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCPerl.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerl.c b/compiler/src/CFCPerl.c
index d931ea2..df5d7d4 100644
--- a/compiler/src/CFCPerl.c
+++ b/compiler/src/CFCPerl.c
@@ -232,17 +232,17 @@ S_write_boot_c(CFCPerl *self) {
         // to be read.
         CFCPerlClass *class_binding = CFCPerlClass_singleton(class_name);
         if (class_binding) {
-            const char *vtable_var = CFCClass_full_vtable_var(klass);
+            const char *class_var = CFCClass_full_class_var(klass);
             const char **aliases
                 = CFCPerlClass_get_class_aliases(class_binding);
             for (size_t j = 0; aliases[j] != NULL; j++) {
                 const char *alias = aliases[j];
                 size_t alias_len  = strlen(alias);
                 const char pattern[] =
-                    "    cfish_VTable_add_alias_to_registry("
+                    "    cfish_Class_add_alias_to_registry("
                     "%s, \"%s\", %u);\n";
                 char *alias_add
-                    = CFCUtil_sprintf(pattern, vtable_var, alias,
+                    = CFCUtil_sprintf(pattern, class_var, alias,
                                       (unsigned)alias_len);
                 alias_adds = CFCUtil_cat(alias_adds, alias_add, NULL);
                 FREEMEM(alias_add);
@@ -279,7 +279,7 @@ S_write_boot_c(CFCPerl *self) {
         "\n"
         "#include \"boot.h\"\n"
         "#include \"Clownfish/String.h\"\n"
-        "#include \"Clownfish/VTable.h\"\n"
+        "#include \"Clownfish/Class.h\"\n"
         "%s\n"
         "\n"
         "void\n"

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCPerlClass.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlClass.c b/compiler/src/CFCPerlClass.c
index 5349d5c..9d52b16 100644
--- a/compiler/src/CFCPerlClass.c
+++ b/compiler/src/CFCPerlClass.c
@@ -292,7 +292,7 @@ CFCPerlClass_method_bindings(CFCClass *klass) {
          *
          * Also create an XSub binding for each override.  Each of these
          * directly calls the implementing function, rather than invokes the
-         * method on the object using VTable method dispatch.  Doing things
+         * method on the object using vtable method dispatch.  Doing things
          * this way allows SUPER:: invocations from Perl-space to work
          * properly.
          */
@@ -555,7 +555,7 @@ CFCPerlClass_get_class_aliases(CFCPerlClass *self) {
 // Generate C code which initializes method metadata.
 char*
 CFCPerlClass_method_metadata_code(CFCPerlClass *self) {
-    const char *vtable_var = CFCClass_full_vtable_var(self->client);
+    const char *class_var = CFCClass_full_class_var(self->client);
     CFCMethod **fresh_methods = CFCClass_fresh_methods(self->client);
     char *code = CFCUtil_strdup("");
 
@@ -566,13 +566,13 @@ CFCPerlClass_method_metadata_code(CFCPerlClass *self) {
         const char *macro_sym = CFCMethod_get_macro_sym(method);
         const char *alias     = CFCMethod_get_host_alias(method);
         if (alias) {
-            code = CFCUtil_cat(code, "    CFISH_VTable_Add_Host_Method_Alias(",
-                               vtable_var, ", \"", alias, "\", \"", macro_sym,
+            code = CFCUtil_cat(code, "    CFISH_Class_Add_Host_Method_Alias(",
+                               class_var, ", \"", alias, "\", \"", macro_sym,
                                "\");\n", NULL);
         }
         if (CFCMethod_excluded_from_host(method)) {
-            code = CFCUtil_cat(code, "    CFISH_VTable_Exclude_Host_Method(",
-                               vtable_var, ", \"", macro_sym, "\");\n", NULL);
+            code = CFCUtil_cat(code, "    CFISH_Class_Exclude_Host_Method(",
+                               class_var, ", \"", macro_sym, "\");\n", NULL);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCPerlMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlMethod.c b/compiler/src/CFCPerlMethod.c
index a5c0bd0..d9d8255 100644
--- a/compiler/src/CFCPerlMethod.c
+++ b/compiler/src/CFCPerlMethod.c
@@ -171,7 +171,7 @@ S_xsub_body(CFCPerlMethod *self) {
     char *full_meth    = CFCMethod_full_method_sym(method, klass);
     char *method_ptr
         = CFCUtil_sprintf("%s method = CFISH_METHOD_PTR(%s, %s);\n    ",
-                          full_typedef, CFCClass_full_vtable_var(klass),
+                          full_typedef, CFCClass_full_class_var(klass),
                           full_meth);
     body = CFCUtil_cat(body, method_ptr, NULL);
     FREEMEM(full_typedef);
@@ -225,9 +225,9 @@ S_self_assign_statement(CFCPerlMethod *self, CFCType *type) {
     if (!CFCType_is_object(type)) {
         CFCUtil_die("Not an object type: %s", type_c);
     }
-    const char *vtable_var = CFCType_get_vtable_var(type);
+    const char *class_var = CFCType_get_class_var(type);
     char pattern[] = "%s self = (%s)XSBind_sv_to_cfish_obj(ST(0), %s, NULL);";
-    char *statement = CFCUtil_sprintf(pattern, type_c, type_c, vtable_var);
+    char *statement = CFCUtil_sprintf(pattern, type_c, type_c, class_var);
 
     return statement;
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCPerlSub.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlSub.c b/compiler/src/CFCPerlSub.c
index 5d8d1f2..ba5e84d 100644
--- a/compiler/src/CFCPerlSub.c
+++ b/compiler/src/CFCPerlSub.c
@@ -142,7 +142,7 @@ S_allot_params_arg(CFCType *type, const char *label, int required) {
 
     if (CFCType_is_object(type)) {
         const char *struct_sym = CFCType_get_specifier(type);
-        const char *vtable_var = CFCType_get_vtable_var(type);
+        const char *class_var  = CFCType_get_class_var(type);
 
         // Share buffers rather than copy between Perl scalars and Clownfish
         // string types.
@@ -157,7 +157,7 @@ S_allot_params_arg(CFCType *type, const char *label, int required) {
                                  : "NULL";
         const char pattern[] = "ALLOT_OBJ(&%s, \"%s\", %u, %s, %s, %s)";
         char *arg = CFCUtil_sprintf(pattern, label, label, label_len,
-                                    req_string, vtable_var, allocation);
+                                    req_string, class_var, allocation);
         return arg;
     }
     else if (CFCType_is_primitive(type)) {

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCPerlTypeMap.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCPerlTypeMap.c b/compiler/src/CFCPerlTypeMap.c
index c7d513d..7997ea9 100644
--- a/compiler/src/CFCPerlTypeMap.c
+++ b/compiler/src/CFCPerlTypeMap.c
@@ -40,7 +40,7 @@ CFCPerlTypeMap_from_perl(CFCType *type, const char *xs_var) {
 
     if (CFCType_is_object(type)) {
         const char *struct_sym = CFCType_get_specifier(type);
-        const char *vtable_var = CFCType_get_vtable_var(type);
+        const char *class_var  = CFCType_get_class_var(type);
         const char *allocation;
         if (strcmp(struct_sym, "cfish_String") == 0
             || strcmp(struct_sym, "cfish_Obj") == 0
@@ -53,7 +53,7 @@ CFCPerlTypeMap_from_perl(CFCType *type, const char *xs_var) {
             allocation = "NULL";
         }
         const char pattern[] = "(%s*)XSBind_sv_to_cfish_obj(%s, %s, %s)";
-        result = CFCUtil_sprintf(pattern, struct_sym, xs_var, vtable_var,
+        result = CFCUtil_sprintf(pattern, struct_sym, xs_var, class_var,
                                  allocation);
     }
     else if (CFCType_is_primitive(type)) {
@@ -265,9 +265,9 @@ CFCPerlTypeMap_write_xs_typemap(CFCHierarchy *hierarchy) {
     for (int i = 0; classes[i] != NULL; i++) {
         CFCClass *klass = classes[i];
         const char *full_struct_sym = CFCClass_full_struct_sym(klass);
-        const char *vtable_var      = CFCClass_full_vtable_var(klass);
+        const char *class_var       = CFCClass_full_class_var(klass);
 
-        start = CFCUtil_cat(start, full_struct_sym, "*\t", vtable_var, "_\n",
+        start = CFCUtil_cat(start, full_struct_sym, "*\t", class_var, "_\n",
                             NULL);
         const char *allocation;
         if (strcmp(full_struct_sym, "cfish_String") == 0) {
@@ -278,12 +278,12 @@ CFCPerlTypeMap_write_xs_typemap(CFCHierarchy *hierarchy) {
         else {
             allocation = "NULL";
         }
-        input = CFCUtil_cat(input, vtable_var, "_\n"
+        input = CFCUtil_cat(input, class_var, "_\n"
                             "    $var = (", full_struct_sym,
-                            "*)XSBind_sv_to_cfish_obj($arg, ", vtable_var,
+                            "*)XSBind_sv_to_cfish_obj($arg, ", class_var,
                             ", ", allocation, ");\n\n", NULL);
 
-        output = CFCUtil_cat(output, vtable_var, "_\n"
+        output = CFCUtil_cat(output, class_var, "_\n"
                              "    $arg = (SV*)CFISH_Obj_To_Host((cfish_Obj*)$var);\n"
                              "    CFISH_DECREF($var);\n"
                              "\n", NULL);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCRuby.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCRuby.c b/compiler/src/CFCRuby.c
index b69b9d2..c185218 100644
--- a/compiler/src/CFCRuby.c
+++ b/compiler/src/CFCRuby.c
@@ -198,7 +198,7 @@ S_write_boot_c(CFCRuby *self) {
         "#include \"%s\"\n"
         "#include \"%sparcel.h\"\n"
         "#include \"Clownfish/String.h\"\n"
-        "#include \"Clownfish/VTable.h\"\n"
+        "#include \"Clownfish/Class.h\"\n"
         "%s\n"
         "\n"
         "void\n"

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCType.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCType.c b/compiler/src/CFCType.c
index 50d7d6f..c444591 100644
--- a/compiler/src/CFCType.c
+++ b/compiler/src/CFCType.c
@@ -35,7 +35,7 @@ struct CFCType {
     CFCBase  base;
     int      flags;
     char    *specifier;
-    char    *vtable_var;
+    char    *class_var;
     int      indirection;
     struct CFCParcel *parcel;
     char    *c_string;
@@ -92,7 +92,7 @@ CFCType_init(CFCType *self, int flags, struct CFCParcel *parcel,
     self->width       = 0;
     self->array       = NULL;
     self->child       = NULL;
-    self->vtable_var  = NULL;
+    self->class_var   = NULL;
 
     return self;
 }
@@ -291,7 +291,7 @@ CFCType_destroy(CFCType *self) {
     FREEMEM(self->specifier);
     FREEMEM(self->c_string);
     FREEMEM(self->array);
-    FREEMEM(self->vtable_var);
+    FREEMEM(self->class_var);
     CFCBase_destroy((CFCBase*)self);
 }
 
@@ -353,14 +353,14 @@ CFCType_get_specifier(CFCType *self) {
 }
 
 const char*
-CFCType_get_vtable_var(CFCType *self) {
-    if (!self->vtable_var) {
-        self->vtable_var = CFCUtil_strdup(self->specifier);
-        for (int i = 0; self->vtable_var[i] != 0; i++) {
-            self->vtable_var[i] = toupper(self->vtable_var[i]);
+CFCType_get_class_var(CFCType *self) {
+    if (!self->class_var) {
+        self->class_var = CFCUtil_strdup(self->specifier);
+        for (int i = 0; self->class_var[i] != 0; i++) {
+            self->class_var[i] = toupper(self->class_var[i]);
         }
     }
-    return self->vtable_var;
+    return self->class_var;
 }
 
 int

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/compiler/src/CFCType.h
----------------------------------------------------------------------
diff --git a/compiler/src/CFCType.h b/compiler/src/CFCType.h
index fbcc6e2..dddab6a 100644
--- a/compiler/src/CFCType.h
+++ b/compiler/src/CFCType.h
@@ -195,11 +195,11 @@ CFCType_set_specifier(CFCType *self, const char *specifier);
 const char*
 CFCType_get_specifier(CFCType *self);
 
-/** Return the name of the VTable variable which corresponds to the object
+/** Return the name of the Class variable which corresponds to the object
  * type.  Returns NULL for non-object types.
  */
 const char*
-CFCType_get_vtable_var(CFCType *self);
+CFCType_get_class_var(CFCType *self);
 
 int
 CFCType_get_indirection(CFCType *self);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/c/src/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/c/src/Clownfish/Class.c b/runtime/c/src/Clownfish/Class.c
new file mode 100644
index 0000000..f6fe24b
--- /dev/null
+++ b/runtime/c/src/Clownfish/Class.c
@@ -0,0 +1,79 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define CHY_USE_SHORT_NAMES
+#define CFISH_USE_SHORT_NAMES
+#define C_CFISH_OBJ
+#define C_CFISH_CLASS
+
+#include "charmony.h"
+
+#include "Clownfish/Class.h"
+#include "Clownfish/String.h"
+#include "Clownfish/Err.h"
+#include "Clownfish/Util/Memory.h"
+#include "Clownfish/VArray.h"
+
+Obj*
+Class_Make_Obj_IMP(Class *self) {
+    Obj *obj = (Obj*)Memory_wrapped_calloc(self->obj_alloc_size, 1);
+    obj->klass = self;
+    obj->refcount = 1;
+    return obj;
+}
+
+Obj*
+Class_Init_Obj_IMP(Class *self, void *allocation) {
+    Obj *obj = (Obj*)allocation;
+    obj->klass = self;
+    obj->refcount = 1;
+    return obj;
+}
+
+Obj*
+Class_Foster_Obj_IMP(Class *self, void *host_obj) {
+    UNUSED_VAR(self);
+    UNUSED_VAR(host_obj);
+    THROW(ERR, "TODO");
+    UNREACHABLE_RETURN(Obj*);
+}
+
+void
+Class_register_with_host(Class *singleton, Class *parent) {
+    UNUSED_VAR(singleton);
+    UNUSED_VAR(parent);
+}
+
+VArray*
+Class_fresh_host_methods(String *class_name) {
+    UNUSED_VAR(class_name);
+    return VA_new(0);
+}
+
+String*
+Class_find_parent_class(String *class_name) {
+    UNUSED_VAR(class_name);
+    THROW(ERR, "TODO");
+    UNREACHABLE_RETURN(String*);
+}
+
+void*
+Class_To_Host_IMP(Class *self) {
+    UNUSED_VAR(self);
+    THROW(ERR, "TODO");
+    UNREACHABLE_RETURN(void*);
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/c/src/Clownfish/Err.c
----------------------------------------------------------------------
diff --git a/runtime/c/src/Clownfish/Err.c b/runtime/c/src/Clownfish/Err.c
index 112a9b1..885b17c 100644
--- a/runtime/c/src/Clownfish/Err.c
+++ b/runtime/c/src/Clownfish/Err.c
@@ -27,7 +27,7 @@
 #include "Clownfish/Err.h"
 #include "Clownfish/String.h"
 #include "Clownfish/Util/Memory.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 /* TODO: Thread safety */
 static Err *current_error;
@@ -74,8 +74,8 @@ Err_To_Host_IMP(Err *self) {
 }
 
 void
-Err_throw_mess(VTable *vtable, String *message) {
-    UNUSED_VAR(vtable);
+Err_throw_mess(Class *klass, String *message) {
+    UNUSED_VAR(klass);
     Err *err = Err_new(message);
     Err_do_throw(err);
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/c/src/Clownfish/VTable.c
----------------------------------------------------------------------
diff --git a/runtime/c/src/Clownfish/VTable.c b/runtime/c/src/Clownfish/VTable.c
deleted file mode 100644
index 5617900..0000000
--- a/runtime/c/src/Clownfish/VTable.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define CHY_USE_SHORT_NAMES
-#define CFISH_USE_SHORT_NAMES
-#define C_CFISH_OBJ
-#define C_CFISH_VTABLE
-
-#include "charmony.h"
-
-#include "Clownfish/VTable.h"
-#include "Clownfish/String.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Util/Memory.h"
-#include "Clownfish/VArray.h"
-
-Obj*
-VTable_Make_Obj_IMP(VTable *self) {
-    Obj *obj = (Obj*)Memory_wrapped_calloc(self->obj_alloc_size, 1);
-    obj->vtable = self;
-    obj->refcount = 1;
-    return obj;
-}
-
-Obj*
-VTable_Init_Obj_IMP(VTable *self, void *allocation) {
-    Obj *obj = (Obj*)allocation;
-    obj->vtable = self;
-    obj->refcount = 1;
-    return obj;
-}
-
-Obj*
-VTable_Foster_Obj_IMP(VTable *self, void *host_obj) {
-    UNUSED_VAR(self);
-    UNUSED_VAR(host_obj);
-    THROW(ERR, "TODO");
-    UNREACHABLE_RETURN(Obj*);
-}
-
-void
-VTable_register_with_host(VTable *singleton, VTable *parent) {
-    UNUSED_VAR(singleton);
-    UNUSED_VAR(parent);
-}
-
-VArray*
-VTable_fresh_host_methods(String *class_name) {
-    UNUSED_VAR(class_name);
-    return VA_new(0);
-}
-
-String*
-VTable_find_parent_class(String *class_name) {
-    UNUSED_VAR(class_name);
-    THROW(ERR, "TODO");
-    UNREACHABLE_RETURN(String*);
-}
-
-void*
-VTable_To_Host_IMP(VTable *self) {
-    UNUSED_VAR(self);
-    THROW(ERR, "TODO");
-    UNREACHABLE_RETURN(void*);
-}
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/ByteBuf.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/ByteBuf.c b/runtime/core/Clownfish/ByteBuf.c
index c267d28..8ba056f 100644
--- a/runtime/core/Clownfish/ByteBuf.c
+++ b/runtime/core/Clownfish/ByteBuf.c
@@ -24,7 +24,7 @@
 #include <stdio.h>
 #include <ctype.h>
 
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 #include "Clownfish/ByteBuf.h"
 #include "Clownfish/Err.h"
 #include "Clownfish/Util/Memory.h"
@@ -34,7 +34,7 @@ S_grow(ByteBuf *self, size_t size);
 
 ByteBuf*
 BB_new(size_t capacity) {
-    ByteBuf *self = (ByteBuf*)VTable_Make_Obj(BYTEBUF);
+    ByteBuf *self = (ByteBuf*)Class_Make_Obj(BYTEBUF);
     return BB_init(self, capacity);
 }
 
@@ -50,7 +50,7 @@ BB_init(ByteBuf *self, size_t capacity) {
 
 ByteBuf*
 BB_new_bytes(const void *bytes, size_t size) {
-    ByteBuf *self = (ByteBuf*)VTable_Make_Obj(BYTEBUF);
+    ByteBuf *self = (ByteBuf*)Class_Make_Obj(BYTEBUF);
     BB_init(self, size);
     memcpy(self->buf, bytes, size);
     self->size = size;
@@ -59,7 +59,7 @@ BB_new_bytes(const void *bytes, size_t size) {
 
 ByteBuf*
 BB_new_steal_bytes(void *bytes, size_t size, size_t capacity) {
-    ByteBuf *self = (ByteBuf*)VTable_Make_Obj(BYTEBUF);
+    ByteBuf *self = (ByteBuf*)Class_Make_Obj(BYTEBUF);
     return BB_init_steal_bytes(self, bytes, size, capacity);
 }
 
@@ -221,7 +221,7 @@ BB_Compare_To_IMP(ByteBuf *self, Obj *other) {
 
 ViewByteBuf*
 ViewBB_new(char *buf, size_t size) {
-    ViewByteBuf *self = (ViewByteBuf*)VTable_Make_Obj(VIEWBYTEBUF);
+    ViewByteBuf *self = (ViewByteBuf*)Class_Make_Obj(VIEWBYTEBUF);
     return ViewBB_init(self, buf, size);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/CharBuf.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/CharBuf.c b/runtime/core/Clownfish/CharBuf.c
index 8dbeb36..51ff416 100644
--- a/runtime/core/Clownfish/CharBuf.c
+++ b/runtime/core/Clownfish/CharBuf.c
@@ -32,7 +32,7 @@
 #include "Clownfish/String.h"
 #include "Clownfish/Util/Memory.h"
 #include "Clownfish/Util/StringHelper.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 // Helper function for throwing invalid UTF-8 error. Since THROW uses
 // a String internally, calling THROW with invalid UTF-8 would create an
@@ -50,7 +50,7 @@ S_die_invalid_pattern(const char *pattern);
 
 CharBuf*
 CB_new(size_t size) {
-    CharBuf *self = (CharBuf*)VTable_Make_Obj(CHARBUF);
+    CharBuf *self = (CharBuf*)Class_Make_Obj(CHARBUF);
     return CB_init(self, size);
 }
 
@@ -84,7 +84,7 @@ CB_new_from_utf8(const char *ptr, size_t size) {
 
 CharBuf*
 CB_new_from_trusted_utf8(const char *ptr, size_t size) {
-    CharBuf *self = (CharBuf*)VTable_Make_Obj(CHARBUF);
+    CharBuf *self = (CharBuf*)Class_Make_Obj(CHARBUF);
 
     // Derive.
     self->ptr = (char*)MALLOCATE(size + 1);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
new file mode 100644
index 0000000..70fd483
--- /dev/null
+++ b/runtime/core/Clownfish/Class.c
@@ -0,0 +1,446 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define C_CFISH_CLASS
+#define C_CFISH_OBJ
+#define C_CFISH_STRING
+#define C_CFISH_METHOD
+#define CFISH_USE_SHORT_NAMES
+#define CHY_USE_SHORT_NAMES
+
+#include "charmony.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "Clownfish/Class.h"
+#include "Clownfish/String.h"
+#include "Clownfish/CharBuf.h"
+#include "Clownfish/Err.h"
+#include "Clownfish/Hash.h"
+#include "Clownfish/LockFreeRegistry.h"
+#include "Clownfish/Method.h"
+#include "Clownfish/Num.h"
+#include "Clownfish/VArray.h"
+#include "Clownfish/Util/Atomic.h"
+#include "Clownfish/Util/Memory.h"
+
+size_t Class_offset_of_parent = offsetof(Class, parent);
+
+// Remove spaces and underscores, convert to lower case.
+static String*
+S_scrunch_string(String *source);
+
+static Method*
+S_find_method(Class *self, const char *meth_name);
+
+static int32_t
+S_claim_parcel_id(void);
+
+LockFreeRegistry *Class_registry = NULL;
+
+void
+Class_bootstrap(const ClassSpec *specs, size_t num_specs)
+{
+    int32_t parcel_id = S_claim_parcel_id();
+
+    /* Pass 1:
+     * - Initialize IVARS_OFFSET.
+     * - Allocate memory.
+     * - Initialize parent, flags, obj_alloc_size, class_alloc_size.
+     * - Assign parcel_id.
+     * - Initialize method pointers.
+     */
+    for (size_t i = 0; i < num_specs; ++i) {
+        const ClassSpec *spec = &specs[i];
+        Class *parent = spec->parent ? *spec->parent : NULL;
+
+        size_t ivars_offset = 0;
+        if (spec->ivars_offset_ptr != NULL) {
+            if (parent) {
+                Class *ancestor = parent;
+                while (ancestor && ancestor->parcel_id == parcel_id) {
+                    ancestor = ancestor->parent;
+                }
+                ivars_offset = ancestor ? ancestor->obj_alloc_size : 0;
+                *spec->ivars_offset_ptr = ivars_offset;
+            }
+            else {
+                *spec->ivars_offset_ptr = 0;
+            }
+        }
+
+        size_t novel_offset = parent
+                              ? parent->class_alloc_size
+                              : offsetof(Class, method_ptrs);
+        size_t class_alloc_size = novel_offset
+                                  + spec->num_novel_meths
+                                    * sizeof(cfish_method_t);
+        Class *klass = (Class*)Memory_wrapped_calloc(class_alloc_size, 1);
+
+        klass->parent           = parent;
+        klass->parcel_id        = parcel_id;
+        klass->flags            = 0;
+        klass->obj_alloc_size   = ivars_offset + spec->ivars_size;
+        klass->class_alloc_size = class_alloc_size;
+
+        if (parent) {
+            size_t parent_ptrs_size = parent->class_alloc_size
+                                      - offsetof(Class, method_ptrs);
+            memcpy(klass->method_ptrs, parent->method_ptrs, parent_ptrs_size);
+        }
+
+        for (size_t i = 0; i < spec->num_inherited_meths; ++i) {
+            const InheritedMethSpec *mspec = &spec->inherited_meth_specs[i];
+            *mspec->offset = *mspec->parent_offset;
+        }
+
+        for (size_t i = 0; i < spec->num_overridden_meths; ++i) {
+            const OverriddenMethSpec *mspec = &spec->overridden_meth_specs[i];
+            *mspec->offset = *mspec->parent_offset;
+            Class_Override_IMP(klass, mspec->func, *mspec->offset);
+        }
+
+        for (size_t i = 0; i < spec->num_novel_meths; ++i) {
+            const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
+            *mspec->offset = novel_offset;
+            novel_offset += sizeof(cfish_method_t);
+            Class_Override_IMP(klass, mspec->func, *mspec->offset);
+        }
+
+        *spec->klass = klass;
+    }
+
+    /* Pass 2:
+     * - Initialize 'klass' instance variable.
+     * - Initialize refcount.
+     */
+    for (size_t i = 0; i < num_specs; ++i) {
+        const ClassSpec *spec = &specs[i];
+        Class *klass = *spec->klass;
+
+        Class_Init_Obj_IMP(CLASS, klass);
+    }
+
+    /* Now it's safe to call methods.
+     *
+     * Pass 3:
+     * - Inititalize name and method array.
+     * - Register class.
+     */
+    for (size_t i = 0; i < num_specs; ++i) {
+        const ClassSpec *spec = &specs[i];
+        Class *klass = *spec->klass;
+
+        klass->name    = Str_newf("%s", spec->name);
+        klass->methods = VA_new(0);
+
+        for (size_t i = 0; i < spec->num_novel_meths; ++i) {
+            const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
+            String *name = Str_newf("%s", mspec->name);
+            Method *method = Method_new(name, mspec->callback_func,
+                                        *mspec->offset);
+            VA_Push(klass->methods, (Obj*)method);
+            DECREF(name);
+        }
+
+        Class_add_to_registry(klass);
+    }
+}
+
+void
+Class_Destroy_IMP(Class *self) {
+    THROW(ERR, "Insane attempt to destroy Class for class '%o'", self->name);
+}
+
+Class*
+Class_Clone_IMP(Class *self) {
+    Class *twin
+        = (Class*)Memory_wrapped_calloc(self->class_alloc_size, 1);
+
+    memcpy(twin, self, self->class_alloc_size);
+    Class_Init_Obj(self->klass, twin); // Set refcount.
+    twin->name = Str_Clone(self->name);
+
+    return twin;
+}
+
+Obj*
+Class_Inc_RefCount_IMP(Class *self) {
+    return (Obj*)self;
+}
+
+uint32_t
+Class_Dec_RefCount_IMP(Class *self) {
+    UNUSED_VAR(self);
+    return 1;
+}
+
+uint32_t
+Class_Get_RefCount_IMP(Class *self) {
+    UNUSED_VAR(self);
+    /* Class_Get_RefCount() lies to other Clownfish code about the refcount
+     * because we don't want to have to synchronize access to the cached host
+     * object to which we have delegated responsibility for keeping refcounts.
+     * It always returns 1 because 1 is a positive number, and thus other
+     * Clownfish code will be fooled into believing it never needs to take
+     * action such as initiating a destructor.
+     *
+     * It's possible that the host has in fact increased the refcount of the
+     * cached host object if there are multiple refs to it on the other side
+     * of the Clownfish/host border, but returning 1 is good enough to fool
+     * Clownfish code.
+     */
+    return 1;
+}
+
+void
+Class_Override_IMP(Class *self, cfish_method_t method, size_t offset) {
+    union { char *char_ptr; cfish_method_t *func_ptr; } pointer;
+    pointer.char_ptr = ((char*)self) + offset;
+    pointer.func_ptr[0] = method;
+}
+
+String*
+Class_Get_Name_IMP(Class *self) {
+    return self->name;
+}
+
+Class*
+Class_Get_Parent_IMP(Class *self) {
+    return self->parent;
+}
+
+size_t
+Class_Get_Obj_Alloc_Size_IMP(Class *self) {
+    return self->obj_alloc_size;
+}
+
+VArray*
+Class_Get_Methods_IMP(Class *self) {
+    return self->methods;
+}
+
+void
+Class_init_registry() {
+    LockFreeRegistry *reg = LFReg_new(256);
+    if (Atomic_cas_ptr((void*volatile*)&Class_registry, NULL, reg)) {
+        return;
+    }
+    else {
+        DECREF(reg);
+    }
+}
+
+Class*
+Class_singleton(String *class_name, Class *parent) {
+    if (Class_registry == NULL) {
+        Class_init_registry();
+    }
+
+    Class *singleton = (Class*)LFReg_Fetch(Class_registry, (Obj*)class_name);
+    if (singleton == NULL) {
+        VArray *fresh_host_methods;
+        uint32_t num_fresh;
+
+        if (parent == NULL) {
+            String *parent_class = Class_find_parent_class(class_name);
+            if (parent_class == NULL) {
+                THROW(ERR, "Class '%o' doesn't descend from %o", class_name,
+                      OBJ->name);
+            }
+            else {
+                parent = Class_singleton(parent_class, NULL);
+                DECREF(parent_class);
+            }
+        }
+
+        // Copy source class.
+        singleton = Class_Clone(parent);
+
+        // Turn clone into child.
+        singleton->parent = parent;
+        DECREF(singleton->name);
+        singleton->name = Str_Clone(class_name);
+
+        // Allow host methods to override.
+        fresh_host_methods = Class_fresh_host_methods(class_name);
+        num_fresh = VA_Get_Size(fresh_host_methods);
+        if (num_fresh) {
+            Hash *meths = Hash_new(num_fresh);
+            for (uint32_t i = 0; i < num_fresh; i++) {
+                String *meth = (String*)VA_Fetch(fresh_host_methods, i);
+                String *scrunched = S_scrunch_string(meth);
+                Hash_Store(meths, (Obj*)scrunched, (Obj*)CFISH_TRUE);
+                DECREF(scrunched);
+            }
+            for (Class *klass = parent; klass; klass = klass->parent) {
+                uint32_t max = VA_Get_Size(klass->methods);
+                for (uint32_t i = 0; i < max; i++) {
+                    Method *method = (Method*)VA_Fetch(klass->methods, i);
+                    if (method->callback_func) {
+                        String *scrunched = S_scrunch_string(method->name);
+                        if (Hash_Fetch(meths, (Obj*)scrunched)) {
+                            Class_Override(singleton, method->callback_func,
+                                            method->offset);
+                        }
+                        DECREF(scrunched);
+                    }
+                }
+            }
+            DECREF(meths);
+        }
+        DECREF(fresh_host_methods);
+
+        // Register the new class, both locally and with host.
+        if (Class_add_to_registry(singleton)) {
+            // Doing this after registering is racy, but hard to fix. :(
+            Class_register_with_host(singleton, parent);
+        }
+        else {
+            DECREF(singleton);
+            singleton = (Class*)LFReg_Fetch(Class_registry, (Obj*)class_name);
+            if (!singleton) {
+                THROW(ERR, "Failed to either insert or fetch Class for '%o'",
+                      class_name);
+            }
+        }
+    }
+
+    return singleton;
+}
+
+static String*
+S_scrunch_string(String *source) {
+    CharBuf *buf = CB_new(Str_Get_Size(source));
+    StringIterator *iter = Str_Top(source);
+    int32_t code_point;
+    while (STRITER_DONE != (code_point = StrIter_Next(iter))) {
+        if (code_point > 127) {
+            THROW(ERR, "Can't fold case for %o", source);
+        }
+        else if (code_point != '_') {
+            CB_Cat_Char(buf, tolower(code_point));
+        }
+    }
+    String *retval = CB_Yield_String(buf);
+    DECREF(iter);
+    DECREF(buf);
+    return retval;
+}
+
+bool
+Class_add_to_registry(Class *klass) {
+    if (Class_registry == NULL) {
+        Class_init_registry();
+    }
+    if (LFReg_Fetch(Class_registry, (Obj*)klass->name)) {
+        return false;
+    }
+    else {
+        String *class_name = Str_Clone(klass->name);
+        bool retval
+            = LFReg_Register(Class_registry, (Obj*)class_name, (Obj*)klass);
+        DECREF(class_name);
+        return retval;
+    }
+}
+
+bool
+Class_add_alias_to_registry(Class *klass, const char *alias_ptr,
+                             size_t alias_len) {
+    if (Class_registry == NULL) {
+        Class_init_registry();
+    }
+    StackString *alias = SSTR_WRAP_UTF8(alias_ptr, alias_len);
+    if (LFReg_Fetch(Class_registry, (Obj*)alias)) {
+        return false;
+    }
+    else {
+        String *class_name = SStr_Clone(alias);
+        bool retval
+            = LFReg_Register(Class_registry, (Obj*)class_name, (Obj*)klass);
+        DECREF(class_name);
+        return retval;
+    }
+}
+
+Class*
+Class_fetch_class(String *class_name) {
+    Class *klass = NULL;
+    if (Class_registry != NULL) {
+        klass = (Class*)LFReg_Fetch(Class_registry, (Obj*)class_name);
+    }
+    return klass;
+}
+
+void
+Class_Add_Host_Method_Alias_IMP(Class *self, const char *alias,
+                             const char *meth_name) {
+    Method *method = S_find_method(self, meth_name);
+    if (!method) {
+        fprintf(stderr, "Method %s not found\n", meth_name);
+        abort();
+    }
+    method->host_alias = Str_newf("%s", alias);
+}
+
+void
+Class_Exclude_Host_Method_IMP(Class *self, const char *meth_name) {
+    Method *method = S_find_method(self, meth_name);
+    if (!method) {
+        fprintf(stderr, "Method %s not found\n", meth_name);
+        abort();
+    }
+    method->is_excluded = true;
+}
+
+static Method*
+S_find_method(Class *self, const char *name) {
+    size_t   name_len = strlen(name);
+    uint32_t size     = VA_Get_Size(self->methods);
+
+    for (uint32_t i = 0; i < size; i++) {
+        Method *method = (Method*)VA_Fetch(self->methods, i);
+        if (Str_Equals_Utf8(method->name, name, name_len)) {
+            return method;
+        }
+    }
+
+    return NULL;
+}
+
+static size_t parcel_count;
+
+static int32_t
+S_claim_parcel_id(void) {
+    // TODO: use ordinary cas rather than cas_ptr.
+    union { size_t num; void *ptr; } old_value;
+    union { size_t num; void *ptr; } new_value;
+
+    bool succeeded = false;
+    do {
+        old_value.num = parcel_count;
+        new_value.num = old_value.num + 1;
+        succeeded = Atomic_cas_ptr((void*volatile*)&parcel_count,
+                                   old_value.ptr, new_value.ptr);
+    } while (!succeeded);
+
+    return new_value.num;
+}
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Class.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh
new file mode 100644
index 0000000..fd4e183
--- /dev/null
+++ b/runtime/core/Clownfish/Class.cfh
@@ -0,0 +1,155 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+parcel Clownfish;
+
+/** Class.
+ *
+ * Classes, which are the first element in any Clownfish object, are actually
+ * objects themselves.  (Their first element is a Class which describes the
+ * behavior of Classes.)
+ */
+
+class Clownfish::Class inherits Clownfish::Obj {
+
+    Class             *parent;
+    String            *name;
+    uint32_t           flags;
+    int32_t            parcel_id;
+    size_t             obj_alloc_size;
+    size_t             class_alloc_size;
+    VArray            *methods;
+    cfish_method_t[1]  method_ptrs; /* flexible array */
+
+    inert LockFreeRegistry *registry;
+    inert size_t offset_of_parent;
+
+    inert void
+    bootstrap(const cfish_ClassSpec *specs, size_t num_specs);
+
+    /** Return a singleton.  If a Class can be found in the registry based on
+     * the supplied class name, it will be returned.  Otherwise, a new Class
+     * will be created using [parent] as a base.
+     *
+     * If [parent] is NULL, an attempt will be made to find it using
+     * Class_find_parent_class().  If the attempt fails, an error will
+     * result.
+     */
+    inert Class*
+    singleton(String *class_name, Class *parent);
+
+    /** Register a class, so that it can be retrieved by class name.
+     *
+     * TODO: Move this functionality to some kind of class loader.
+     *
+     * @return true on success, false if the class was already registered.
+     */
+    inert bool
+    add_to_registry(Class *klass);
+
+    inert bool
+    add_alias_to_registry(Class *klass, const char *alias_ptr,
+                          size_t alias_len);
+
+    /** Initialize the registry.
+     */
+    inert void
+    init_registry();
+
+    /** Tell the host about the new class.
+     */
+    inert void
+    register_with_host(Class *klass, Class *parent);
+
+    /** Find a registered class.  May return NULL if the class is not
+     * registered.
+     */
+    inert nullable Class*
+    fetch_class(String *class_name);
+
+    /** Given a class name, return the name of a parent class which descends
+     * from Clownfish::Obj, or NULL if such a class can't be found.
+     */
+    inert nullable String*
+    find_parent_class(String *class_name);
+
+    /** List all of the methods defined directly within a host subclass.
+     */
+    inert incremented VArray*
+    fresh_host_methods(String *class_name);
+
+    /** Replace a function pointer in the Class's vtable.
+     */
+    void
+    Override(Class *self, cfish_method_t method_ptr, size_t offset);
+
+    /** Create an empty object of the type defined by the Class: allocate,
+     * assign its class and give it an initial refcount of 1.  The caller is
+     * responsible for initialization.
+     */
+    Obj*
+    Make_Obj(Class *self);
+
+    /** Take a raw memory allocation which is presumed to be of adequate size,
+     * assign its class and give it an initial refcount of 1.
+     */
+    Obj*
+    Init_Obj(Class *self, void *allocation);
+
+    /** Create a new object to go with the supplied host object.
+     */
+    Obj*
+    Foster_Obj(Class *self, void *host_obj);
+
+    void
+    Add_Host_Method_Alias(Class *self, const char *alias,
+                          const char *meth_name);
+
+    void
+    Exclude_Host_Method(Class *self, const char *meth_name);
+
+    String*
+    Get_Name(Class *self);
+
+    Class*
+    Get_Parent(Class *self);
+
+    size_t
+    Get_Obj_Alloc_Size(Class *self);
+
+    VArray*
+    Get_Methods(Class *self);
+
+    public incremented Class*
+    Clone(Class *self);
+
+    incremented Obj*
+    Inc_RefCount(Class *self);
+
+    uint32_t
+    Dec_RefCount(Class *self);
+
+    uint32_t
+    Get_RefCount(Class *self);
+
+    void*
+    To_Host(Class *self);
+
+    public void
+    Destroy(Class *self);
+}
+
+

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Err.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Err.c b/runtime/core/Clownfish/Err.c
index 742ffcc..84ad334 100644
--- a/runtime/core/Clownfish/Err.c
+++ b/runtime/core/Clownfish/Err.c
@@ -16,7 +16,7 @@
 
 #define C_CFISH_ERR
 #define C_CFISH_OBJ
-#define C_CFISH_VTABLE
+#define C_CFISH_CLASS
 #define CFISH_USE_SHORT_NAMES
 #define CHY_USE_SHORT_NAMES
 
@@ -30,12 +30,12 @@
 
 #include "Clownfish/CharBuf.h"
 #include "Clownfish/String.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 #include "Clownfish/Util/Memory.h"
 
 Err*
 Err_new(String *mess) {
-    Err *self = (Err*)VTable_Make_Obj(ERR);
+    Err *self = (Err*)Class_Make_Obj(ERR);
     return Err_init(self, mess);
 }
 
@@ -74,14 +74,14 @@ S_str_vnewf(char *pattern, va_list args) {
     return message;
 }
 void
-THROW(VTable *vtable, char *pattern, ...) {
+THROW(Class *klass, char *pattern, ...) {
     va_list args;
 
     va_start(args, pattern);
     String *message = S_str_vnewf(pattern, args);
     va_end(args);
 
-    Err *err = (Err*)VTable_Make_Obj(vtable);
+    Err *err = (Err*)Class_Make_Obj(klass);
     err = Err_init(err, message);
     Err_do_throw(err);
 }
@@ -180,7 +180,7 @@ Err_rethrow(Err *self, const char *file, int line, const char *func) {
 }
 
 void
-Err_throw_at(VTable *vtable, const char *file, int line,
+Err_throw_at(Class *klass, const char *file, int line,
              const char *func, const char *pattern, ...) {
     va_list args;
 
@@ -188,46 +188,46 @@ Err_throw_at(VTable *vtable, const char *file, int line,
     String *message = S_vmake_mess(file, line, func, pattern, args);
     va_end(args);
 
-    Err *err = (Err*)VTable_Make_Obj(vtable);
+    Err *err = (Err*)Class_Make_Obj(klass);
     err = Err_init(err, message);
     Err_do_throw(err);
 }
 
 // Inlined, slightly optimized version of Obj_is_a.
 static CFISH_INLINE bool
-SI_obj_is_a(Obj *obj, VTable *target_vtable) {
-    VTable *vtable = obj->vtable;
+SI_obj_is_a(Obj *obj, Class *target_class) {
+    Class *klass = obj->klass;
 
-    while (vtable != NULL) {
-        if (vtable == target_vtable) {
+    while (klass != NULL) {
+        if (klass == target_class) {
             return true;
         }
-        vtable = vtable->parent;
+        klass = klass->parent;
     }
 
     return false;
 }
 
 Obj*
-Err_downcast(Obj *obj, VTable *vtable, const char *file, int line,
+Err_downcast(Obj *obj, Class *klass, const char *file, int line,
              const char *func) {
-    if (obj && !SI_obj_is_a(obj, vtable)) {
+    if (obj && !SI_obj_is_a(obj, klass)) {
         Err_throw_at(ERR, file, line, func, "Can't downcast from %o to %o",
-                     Obj_Get_Class_Name(obj), VTable_Get_Name(vtable));
+                     Obj_Get_Class_Name(obj), Class_Get_Name(klass));
     }
     return obj;
 }
 
 Obj*
-Err_certify(Obj *obj, VTable *vtable, const char *file, int line,
+Err_certify(Obj *obj, Class *klass, const char *file, int line,
             const char *func) {
     if (!obj) {
         Err_throw_at(ERR, file, line, func, "Object isn't a %o, it's NULL",
-                     VTable_Get_Name(vtable));
+                     Class_Get_Name(klass));
     }
-    else if (!SI_obj_is_a(obj, vtable)) {
+    else if (!SI_obj_is_a(obj, klass)) {
         Err_throw_at(ERR, file, line, func, "Can't downcast from %o to %o",
-                     Obj_Get_Class_Name(obj), VTable_Get_Name(vtable));
+                     Obj_Get_Class_Name(obj), Class_Get_Name(klass));
     }
     return obj;
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Err.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Err.cfh b/runtime/core/Clownfish/Err.cfh
index 348e0ed..155b649 100644
--- a/runtime/core/Clownfish/Err.cfh
+++ b/runtime/core/Clownfish/Err.cfh
@@ -102,7 +102,7 @@ public class Clownfish::Err inherits Clownfish::Obj {
     /** Raise an exception. Usually invoked via the THROW macro.
      */
     inert void
-    throw_at(VTable *vtable, const char *file, int line, const char *func,
+    throw_at(Class *klass, const char *file, int line, const char *func,
                const char *pattern, ...);
 
     /** Throw an existing exception after tacking on additional context data.
@@ -113,11 +113,11 @@ public class Clownfish::Err inherits Clownfish::Obj {
     /** Raise an exception.  Clean up the supplied message by decrementing its
      * refcount.
      *
-     * @param vtable The vtable for the Err class to throw.
+     * @param klass The Err class to throw.
      * @param message Error message, to be output verbatim.
      */
     inert void
-    throw_mess(VTable *vtable, decremented String *message);
+    throw_mess(Class *klass, decremented String *message);
 
     /** Invoke host exception handling.
      */
@@ -140,27 +140,27 @@ public class Clownfish::Err inherits Clownfish::Obj {
               const char *pattern, ...);
 
     /** Verify that <code>obj</code> is either NULL or inherits from
-     * the class represented by <code>vtable</code>.
+     * <code>klass</code>.
      *
      * @return the object.
      */
     inert nullable Obj*
-    downcast(Obj *obj, VTable *vtable, const char *file, int line,
+    downcast(Obj *obj, Class *klass, const char *file, int line,
                 const char *func);
 
-    /** Verify that <code>obj</code> is not NULL and inherits from the class
-     * represented by <code>vtable</code>.
+    /** Verify that <code>obj</code> is not NULL and inherits from
+     * <code>klass</code>.
      *
      * @return the object.
      */
     inert Obj*
-    certify(Obj *obj, VTable *vtable, const char *file, int line,
+    certify(Obj *obj, Class *klass, const char *file, int line,
             const char *func);
 
     /** Verify that an object belongs to a subclass and not an abstract class.
      */
     inert inline void
-    abstract_class_check(Obj *obj, VTable *vtable);
+    abstract_class_check(Obj *obj, Class *klass);
 
     /** On Windows, return a newly allocated buffer containing the string
      * description for the the last error in the thread.
@@ -189,8 +189,8 @@ __C__
  */
 #ifdef CFISH_HAS_VARIADIC_MACROS
  #ifdef CFISH_HAS_ISO_VARIADIC_MACROS
-  #define CFISH_THROW(_vtable, ...) \
-    cfish_Err_throw_at(_vtable, __FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, \
+  #define CFISH_THROW(_class, ...) \
+    cfish_Err_throw_at(_class, __FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, \
                        __VA_ARGS__)
   #define CFISH_WARN(...) \
     cfish_Err_warn_at(__FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, __VA_ARGS__)
@@ -198,8 +198,8 @@ __C__
     cfish_Err_make_mess(__FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, \
                         __VA_ARGS__)
  #elif defined(CFISH_HAS_GNUC_VARIADIC_MACROS)
-  #define CFISH_THROW(_vtable, args...) \
-    cfish_Err_throw_at(_vtable, __FILE__, __LINE__, \
+  #define CFISH_THROW(_class, args...) \
+    cfish_Err_throw_at(_class, __FILE__, __LINE__, \
                        CFISH_ERR_FUNC_MACRO, ##args)
   #define CFISH_WARN(args...) \
     cfish_Err_warn_at(__FILE__, __LINE__, CFISH_ERR_FUNC_MACRO, ##args)
@@ -208,26 +208,26 @@ __C__
  #endif
 #else
   void
-  CFISH_THROW(cfish_VTable *vtable, char* format, ...);
+  CFISH_THROW(cfish_Class *klass, char* format, ...);
   void
   CFISH_WARN(char* format, ...);
   cfish_String*
   CFISH_MAKE_MESS(char* format, ...);
 #endif
 
-#define CFISH_DOWNCAST(_obj, _vtable) \
-    cfish_Err_downcast((cfish_Obj*)(_obj), (_vtable), \
+#define CFISH_DOWNCAST(_obj, _class) \
+    cfish_Err_downcast((cfish_Obj*)(_obj), (_class), \
                        __FILE__, __LINE__, CFISH_ERR_FUNC_MACRO)
 
 
-#define CFISH_CERTIFY(_obj, _vtable) \
-    cfish_Err_certify((cfish_Obj*)(_obj), (_vtable), \
+#define CFISH_CERTIFY(_obj, _class) \
+    cfish_Err_certify((cfish_Obj*)(_obj), (_class), \
                       __FILE__, __LINE__, CFISH_ERR_FUNC_MACRO)
 
 static CFISH_INLINE void
-cfish_Err_abstract_class_check(cfish_Obj *obj, cfish_VTable *vtable) {
-    cfish_VTable *const my_vtable = (cfish_VTable*)((cfish_Dummy*)obj)->vtable;
-    if (my_vtable == vtable) {
+cfish_Err_abstract_class_check(cfish_Obj *obj, cfish_Class *klass) {
+    cfish_Class *const my_class = (cfish_Class*)((cfish_Dummy*)obj)->klass;
+    if (my_class == klass) {
         cfish_String *mess = CFISH_MAKE_MESS("%o is an abstract class",
                                               CFISH_Obj_Get_Class_Name(obj));
         CFISH_Obj_Dec_RefCount(obj);
@@ -235,8 +235,8 @@ cfish_Err_abstract_class_check(cfish_Obj *obj, cfish_VTable *vtable) {
     }
 }
 
-#define CFISH_ABSTRACT_CLASS_CHECK(_obj, _vtable) \
-    cfish_Err_abstract_class_check(((cfish_Obj*)_obj), _vtable)
+#define CFISH_ABSTRACT_CLASS_CHECK(_obj, _class) \
+    cfish_Err_abstract_class_check(((cfish_Obj*)_obj), _class)
 
 #ifdef CFISH_USE_SHORT_NAMES
   #define THROW                 CFISH_THROW

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Hash.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Hash.c b/runtime/core/Clownfish/Hash.c
index ed6cb6f..3e86b96 100644
--- a/runtime/core/Clownfish/Hash.c
+++ b/runtime/core/Clownfish/Hash.c
@@ -24,7 +24,7 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 #include "Clownfish/Hash.h"
 #include "Clownfish/String.h"
@@ -56,12 +56,12 @@ SI_rebuild_hash(Hash *self);
 
 void
 Hash_init_class() {
-    TOMBSTONE = (HashTombStone*)VTable_Make_Obj(HASHTOMBSTONE);
+    TOMBSTONE = (HashTombStone*)Class_Make_Obj(HASHTOMBSTONE);
 }
 
 Hash*
 Hash_new(uint32_t capacity) {
-    Hash *self = (Hash*)VTable_Make_Obj(HASH);
+    Hash *self = (Hash*)Class_Make_Obj(HASH);
     return Hash_init(self, capacity);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/LockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/LockFreeRegistry.c b/runtime/core/Clownfish/LockFreeRegistry.c
index 2ad0205..94446c7 100644
--- a/runtime/core/Clownfish/LockFreeRegistry.c
+++ b/runtime/core/Clownfish/LockFreeRegistry.c
@@ -20,7 +20,7 @@
 
 #include "Clownfish/LockFreeRegistry.h"
 #include "Clownfish/Err.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 #include "Clownfish/Util/Atomic.h"
 #include "Clownfish/Util/Memory.h"
 
@@ -35,7 +35,7 @@ typedef struct cfish_LFRegEntry {
 LockFreeRegistry*
 LFReg_new(size_t capacity) {
     LockFreeRegistry *self
-        = (LockFreeRegistry*)VTable_Make_Obj(LOCKFREEREGISTRY);
+        = (LockFreeRegistry*)Class_Make_Obj(LOCKFREEREGISTRY);
     return LFReg_init(self, capacity);
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/LockFreeRegistry.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/LockFreeRegistry.cfh b/runtime/core/Clownfish/LockFreeRegistry.cfh
index 319935f..bb41fbd 100644
--- a/runtime/core/Clownfish/LockFreeRegistry.cfh
+++ b/runtime/core/Clownfish/LockFreeRegistry.cfh
@@ -16,7 +16,7 @@
 
 parcel Clownfish;
 
-/** Specialized lock free hash table for storing VTables.
+/** Specialized lock free hash table for storing Classes.
  */
 class Clownfish::LockFreeRegistry nickname LFReg inherits Clownfish::Obj {
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Method.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Method.c b/runtime/core/Clownfish/Method.c
index e7a72e5..03824b1 100644
--- a/runtime/core/Clownfish/Method.c
+++ b/runtime/core/Clownfish/Method.c
@@ -23,11 +23,11 @@
 #include "Clownfish/Method.h"
 #include "Clownfish/String.h"
 #include "Clownfish/Err.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 Method*
 Method_new(String *name, cfish_method_t callback_func, size_t offset) {
-    Method *self = (Method*)VTable_Make_Obj(METHOD);
+    Method *self = (Method*)Class_Make_Obj(METHOD);
     return Method_init(self, name, callback_func, offset);
 }
 
@@ -61,7 +61,7 @@ Method_Dec_RefCount_IMP(Method *self) {
 uint32_t
 Method_Get_RefCount_IMP(Method *self) {
     UNUSED_VAR(self);
-    // See comments in VTable.c
+    // See comments in Class.c
     return 1;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0c8e0f14/runtime/core/Clownfish/Num.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Num.c b/runtime/core/Clownfish/Num.c
index cf38a86..24a6de7 100644
--- a/runtime/core/Clownfish/Num.c
+++ b/runtime/core/Clownfish/Num.c
@@ -30,7 +30,7 @@
 #include "Clownfish/Num.h"
 #include "Clownfish/String.h"
 #include "Clownfish/Err.h"
-#include "Clownfish/VTable.h"
+#include "Clownfish/Class.h"
 
 Num*
 Num_init(Num *self) {
@@ -99,7 +99,7 @@ IntNum_To_String_IMP(IntNum *self) {
 
 Float32*
 Float32_new(float value) {
-    Float32 *self = (Float32*)VTable_Make_Obj(FLOAT32);
+    Float32 *self = (Float32*)Class_Make_Obj(FLOAT32);
     return Float32_init(self, value);
 }
 
@@ -149,7 +149,7 @@ Float32_Mimic_IMP(Float32 *self, Obj *other) {
 
 Float64*
 Float64_new(double value) {
-    Float64 *self = (Float64*)VTable_Make_Obj(FLOAT64);
+    Float64 *self = (Float64*)Class_Make_Obj(FLOAT64);
     return Float64_init(self, value);
 }
 
@@ -200,7 +200,7 @@ Float64_Hash_Sum_IMP(Float64 *self) {
 
 Integer32*
 Int32_new(int32_t value) {
-    Integer32 *self = (Integer32*)VTable_Make_Obj(INTEGER32);
+    Integer32 *self = (Integer32*)Class_Make_Obj(INTEGER32);
     return Int32_init(self, value);
 }
 
@@ -250,7 +250,7 @@ Int32_Hash_Sum_IMP(Integer32 *self) {
 
 Integer64*
 Int64_new(int64_t value) {
-    Integer64 *self = (Integer64*)VTable_Make_Obj(INTEGER64);
+    Integer64 *self = (Integer64*)Class_Make_Obj(INTEGER64);
     return Int64_init(self, value);
 }
 
@@ -322,10 +322,10 @@ BoolNum *Bool_false_singleton;
 
 void
 Bool_init_class() {
-    Bool_true_singleton          = (BoolNum*)VTable_Make_Obj(BOOLNUM);
+    Bool_true_singleton          = (BoolNum*)Class_Make_Obj(BOOLNUM);
     Bool_true_singleton->value   = true;
     Bool_true_singleton->string  = Str_newf("true");
-    Bool_false_singleton         = (BoolNum*)VTable_Make_Obj(BOOLNUM);
+    Bool_false_singleton         = (BoolNum*)Class_Make_Obj(BOOLNUM);
     Bool_false_singleton->value  = false;
     Bool_false_singleton->string = Str_newf("false");
 }