Mailing List Archive

r3830 - in trunk: boilerplater/lib/Boilerplater/Binding c_src/KinoSearch c_src/KinoSearch/Obj c_src/KinoSearch/Search c_src/KinoSearch/Util devel/conf perl perl/lib perl/lib/KinoSearch perl/lib/KinoSearch/Obj perl/lib/KinoSearch/Util perl/t perl/xs perl/x
Author: creamyg
Date: 2008-09-06 19:39:58 -0700 (Sat, 06 Sep 2008)
New Revision: 3830

Added:
trunk/perl/t/021-vtable.t
Removed:
trunk/c_src/KinoSearch/Util/DynVirtualTable.bp
trunk/c_src/KinoSearch/Util/DynVirtualTable.c
trunk/perl/lib/KinoSearch/Util/DynVirtualTable.pm
trunk/perl/t/021-dyn_virtual_table.t
Modified:
trunk/boilerplater/lib/Boilerplater/Binding/Perl.pm
trunk/c_src/KinoSearch/Obj.c
trunk/c_src/KinoSearch/Obj/FastObj.c
trunk/c_src/KinoSearch/Obj/Undefined.c
trunk/c_src/KinoSearch/Obj/VTable.bp
trunk/c_src/KinoSearch/Obj/VTable.c
trunk/c_src/KinoSearch/Search/PolyQuery.c
trunk/c_src/KinoSearch/Util/Freezer.c
trunk/c_src/KinoSearch/Util/ToolSet.h
trunk/devel/conf/p510_valgrind.supp
trunk/devel/conf/p588_valgrind.supp
trunk/perl/MANIFEST
trunk/perl/lib/KinoSearch.pm
trunk/perl/lib/KinoSearch/Obj.pm
trunk/perl/lib/KinoSearch/Obj/VTable.pm
trunk/perl/xs/KinoSearch/Obj.c
trunk/perl/xs/KinoSearch/Obj/FastObj.c
trunk/perl/xs/XSBind.c
Log:
Merge DynVirtualTable into VTable -- now all vtables belong to the same class.


Modified: trunk/boilerplater/lib/Boilerplater/Binding/Perl.pm
===================================================================
--- trunk/boilerplater/lib/Boilerplater/Binding/Perl.pm 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/boilerplater/lib/Boilerplater/Binding/Perl.pm 2008-09-07 02:39:58 UTC (rev 3830)
@@ -593,7 +593,7 @@
next if $class->static;
my $vt_type = $PREFIX . $class->vtable_type;
$registrations
- .= qq| ${prefix}DynVT_add_to_registry((${prefix}VTable*)|
+ .= qq| ${prefix}VTable_add_to_registry((${prefix}VTable*)|
. qq|&$PREFIX|
. $class->vtable_var
. qq|);\n|;

Modified: trunk/c_src/KinoSearch/Obj/FastObj.c
===================================================================
--- trunk/c_src/KinoSearch/Obj/FastObj.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Obj/FastObj.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -8,7 +8,6 @@
#include "KinoSearch/Obj/FastObj.h"
#include "KinoSearch/Obj/VTable.h"
#include "KinoSearch/Store/InStream.h"
-#include "KinoSearch/Util/DynVirtualTable.h"
#include "KinoSearch/Util/Carp.h"
#include "KinoSearch/Util/MemManager.h"
#include "KinoSearch/Util/CharBuf.h"
@@ -27,7 +26,7 @@
}
else {
VTable *subclass_vtable
- = (VTable*)DynVT_singleton((CharBuf*)class_name, vtable);
+ = (VTable*)VTable_singleton((CharBuf*)class_name, vtable);
self->_ = REFCOUNT_INC(subclass_vtable);
}
self->ref.count = 1;

Modified: trunk/c_src/KinoSearch/Obj/Undefined.c
===================================================================
--- trunk/c_src/KinoSearch/Obj/Undefined.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Obj/Undefined.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -1,6 +1,6 @@
#define KINO_USE_SHORT_NAMES

-#include "KinoSearch/Util/DynVirtualTable.h"
+#include "KinoSearch/Obj/VTable.h"
#include "KinoSearch/Obj/Undefined.h"

static Undefined the_undef_object = { (VTable*)&UNDEFINED, {1} };

Modified: trunk/c_src/KinoSearch/Obj/VTable.bp
===================================================================
--- trunk/c_src/KinoSearch/Obj/VTable.bp 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Obj/VTable.bp 2008-09-07 02:39:58 UTC (rev 3830)
@@ -5,12 +5,6 @@
* VTables, which are the first element in any KS object, are actually
* objects themselves. (Their first element is a VTable which describes the
* behavior of VTables.)
- *
- * Unlike most other objects, though, VTables are meant to be
- * persistent throughout the life of the process. They are not refcounted,
- * and attempting to call destroy() triggers an error.
- *
- * Dynamic subclasses should use DynVirtualTable instead.
*/

class KinoSearch::Obj::VTable extends KinoSearch::Obj::FastObj {
@@ -22,11 +16,62 @@
Callback **callbacks;
kino_method_t[1] methods; /* flexible array */

+ static Hash *registry;
+
+ /** Return a singleton. If a VTable can be found in the registry based on
+ * the subclass 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_vtable(). If the attempt fails, an error will
+ * result.
+ */
+ static VTable*
+ singleton(const CharBuf *subclass_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.
+ */
+ static void
+ add_to_registry(VTable *vtable);
+
+ /** Initialize the registry hash.
+ */
+ static void
+ init_registry();
+
+ /** Find a registered class and return its vtable. May return NULL if the
+ * class is not registered.
+ */
+ static VTable*
+ fetch_vtable(const CharBuf *class_name);
+
+ /** Given a class name, return the vtable belonging to a parent class, or
+ * NULL if such a vtable can't be found.
+ */
+ static VTable*
+ find_parent_vtable(const CharBuf *class_name);
+
+ /** List all of the methods that a class has overridden via the host
+ * language.
+ */
+ static incremented VArray*
+ novel_native_methods(const CharBuf *class_name);
+
+ /** Replace a function pointer in the VTable.
+ */
+ void
+ Override(VTable *self, kino_method_t method_ptr, size_t offset);
+
CharBuf*
Get_Name(VTable *self);

incremented VTable*
Clone(VTable *self);
+
+ void
+ Dec_RefCount(VTable *self);

void
Destroy(VTable *self);

Modified: trunk/c_src/KinoSearch/Obj/VTable.c
===================================================================
--- trunk/c_src/KinoSearch/Obj/VTable.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Obj/VTable.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -2,25 +2,37 @@
#define CHY_USE_SHORT_NAMES

#include <string.h>
+#include <ctype.h>

#include "KinoSearch/Obj/VTable.h"
+#include "KinoSearch/Obj/Undefined.h"
#include "KinoSearch/Util/Carp.h"
#include "KinoSearch/Util/CharBuf.h"
#include "KinoSearch/Util/Hash.h"
#include "KinoSearch/Util/MemManager.h"
-#include "KinoSearch/Search/ScoreDoc.h"
+#include "KinoSearch/Util/Native.h"
+#include "KinoSearch/Util/VArray.h"

+/* Clean up a VTable when its refcount drops to 0.
+ */
+static void
+remove_from_registry(const CharBuf *name);
+
+/* Remove spaces and underscores, convert to lower case. */
+static void
+scrunch_charbuf(CharBuf *source, CharBuf *target);
+
+Hash *VTable_registry = NULL;
+
void
VTable_destroy(VTable *self)
{
- if (self->_ == (VTable*)&KINO_VTABLE) {
- CONFESS("Attempt to destroy fixed vtable for class '%o'", self->name);
+ if (self->parent && (REFCOUNT(self->parent) == 2)) {
+ remove_from_registry(self->parent->name);
}
- else {
- REFCOUNT_DEC(self->name);
- REFCOUNT_DEC(self->parent);
- FREE_OBJ(self);
- }
+ REFCOUNT_DEC(self->name);
+ REFCOUNT_DEC(self->parent);
+ FREE_OBJ(self);
}

VTable*
@@ -39,9 +51,173 @@
return evil_twin;
}

+void
+VTable_dec_refcount(VTable *self)
+{
+ if (self->ref.count == 2) {
+ remove_from_registry(self->name);
+ }
+ FastObj_dec_refcount((FastObj*)self);
+}
+
+void
+VTable_override(VTable *self, kino_method_t method, size_t offset)
+{
+ union { char *char_ptr; kino_method_t *func_ptr; } pointer;
+ pointer.char_ptr = ((char*)self) + offset;
+ pointer.func_ptr[0] = method;
+}
+
CharBuf*
VTable_get_name(VTable *self) { return self->name; }

+void
+VTable_init_registry()
+{
+ VTable_registry = Hash_new(0);
+}
+
+VTable*
+VTable_singleton(const CharBuf *subclass_name, VTable *parent)
+{
+ VTable *singleton;
+
+ if (VTable_registry == NULL)
+ VTable_init_registry();
+
+ singleton = (VTable*)Hash_Fetch(VTable_registry, subclass_name);
+
+ if (singleton == NULL) {
+ VArray *novel_native_methods;
+
+ if (parent == NULL) {
+ /* (implicit refcount inc) */
+ parent = VTable_find_parent_vtable(subclass_name);
+ if (parent == NULL) {
+ CONFESS("Can't find a parent vtable for '%o'", subclass_name);
+ }
+ }
+ else {
+ REFCOUNT_INC(parent);
+ }
+
+ /* Copy source vtable. */
+ singleton = VTable_Clone(parent);
+ REFCOUNT_DEC(singleton->_);
+ singleton->_ = (VTable*)REFCOUNT_INC(&VTABLE);
+
+ /* Turn clone into child. */
+ REFCOUNT_DEC(singleton->parent);
+ singleton->parent = parent;
+ REFCOUNT_DEC(singleton->name);
+ singleton->name = CB_Clone(subclass_name);
+
+ /* Allow native methods to override. */
+ novel_native_methods = VTable_novel_native_methods(subclass_name);
+ if (novel_native_methods->size) {
+ Hash *meths = Hash_new(novel_native_methods->size);
+ u32_t i;
+ CharBuf *scrunched = CB_new(0);
+ ZombieCharBuf callback_name = ZCB_BLANK;
+ for (i = 0; i < novel_native_methods->size; i++) {
+ CharBuf *meth = (CharBuf*)VA_fetch(novel_native_methods, i);
+ scrunch_charbuf(meth, scrunched);
+ Hash_Store(meths, scrunched, (Obj*)UNDEF);
+ }
+ for (i = 0; singleton->callbacks[i] != NULL; i++) {
+ Callback *const callback = singleton->callbacks[i];
+ ZCB_Assign_Str(&callback_name, callback->name,
+ callback->name_len);
+ scrunch_charbuf((CharBuf*)&callback_name, scrunched);
+ if (Hash_Fetch(meths, scrunched)) {
+ VTable_Override(singleton, callback->func, callback->offset);
+ }
+ }
+ REFCOUNT_DEC(scrunched);
+ REFCOUNT_DEC(meths);
+ }
+ REFCOUNT_DEC(novel_native_methods);
+
+ /* Store the virtual table in the registry. */
+ Hash_Store(VTable_registry, subclass_name, (Obj*)singleton);
+ singleton->ref.count--;
+
+ /* Track globals to help hunt memory leaks. */
+ IFDEF_DEBUG( kino_Debug_num_globals += 2; );
+ }
+
+ return singleton;
+}
+
+static void
+scrunch_charbuf(CharBuf *source, CharBuf *target)
+{
+ ZombieCharBuf iterator = ZCB_BLANK;
+ CB_Iter_Init(source, &iterator);
+ CB_Set_Size(target, 0);
+ while (ZCB_Get_Size(&iterator)) {
+ u32_t code_point = ZCB_Nip_One(&iterator);
+ if (code_point > 127) {
+ CONFESS("Can't fold case for %o", source);
+ }
+ else if (code_point != '_') {
+ CB_Cat_Char(target, tolower(code_point));
+ }
+ }
+}
+
+void
+VTable_add_to_registry(VTable *vtable)
+{
+ VTable *fetched;
+
+ if (VTable_registry == NULL)
+ VTable_init_registry();
+ fetched = (VTable*)Hash_Fetch(VTable_registry, vtable->name);
+ if (fetched) {
+ if (fetched != vtable) {
+ CONFESS("Attempt to redefine a vtable for '%o'",
+ vtable->name);
+ }
+ }
+ else {
+ Hash_Store(VTable_registry, vtable->name, (Obj*)vtable);
+ }
+}
+
+VTable*
+VTable_fetch_vtable(const CharBuf *class_name)
+{
+ VTable *vtable = NULL;
+ if (VTable_registry != NULL) {
+ vtable = (VTable*)Hash_Fetch(VTable_registry, class_name);
+ }
+ return vtable;
+}
+
+VArray*
+VTable_novel_native_methods(const CharBuf *class_name)
+{
+ return (VArray*)Native_callback_obj(&VTABLE,
+ "novel_native_methods", 1, ARG_STR("class_name", class_name));
+}
+
+VTable*
+VTable_find_parent_vtable(const CharBuf *class_name)
+{
+ return (VTable*)Native_callback_obj(&VTABLE,
+ "find_parent_vtable", 1, ARG_STR("class_name", class_name));
+}
+
+static void
+remove_from_registry(const CharBuf *name)
+{
+ if (VTable_registry == NULL)
+ CONFESS("Attempt to remove '%o', but registry is NULL", name);
+ Hash_Delete(VTable_registry, name);
+ IFDEF_DEBUG( kino_Debug_num_globals -= 2; );
+}
+
/* Copyright 2006-2008 Marvin Humphrey
*
* This program is free software; you can redistribute it and/or modify

Modified: trunk/c_src/KinoSearch/Obj.c
===================================================================
--- trunk/c_src/KinoSearch/Obj.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Obj.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -7,7 +7,6 @@

#include "KinoSearch/Obj.h"
#include "KinoSearch/Obj/VTable.h"
-#include "KinoSearch/Util/DynVirtualTable.h"
#include "KinoSearch/Util/Carp.h"
#include "KinoSearch/Util/CharBuf.h"
#include "KinoSearch/Util/Hash.h"

Modified: trunk/c_src/KinoSearch/Search/PolyQuery.c
===================================================================
--- trunk/c_src/KinoSearch/Search/PolyQuery.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Search/PolyQuery.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -9,7 +9,6 @@
#include "KinoSearch/Search/Similarity.h"
#include "KinoSearch/Store/InStream.h"
#include "KinoSearch/Store/OutStream.h"
-#include "KinoSearch/Util/DynVirtualTable.h"
#include "KinoSearch/Util/Freezer.h"

PolyQuery*
@@ -176,7 +175,7 @@
{
CharBuf *class_name = CB_deserialize(NULL, instream);
if (!self) {
- VTable *vtable = (VTable*)DynVT_singleton(class_name, NULL);
+ VTable *vtable = (VTable*)VTable_singleton(class_name, NULL);
Obj_create_t create = (Obj_create_t)METHOD_PTR(vtable, Obj, Create);
self = (PolyCompiler*)create(NULL, NULL, vtable,
vtable->obj_alloc_size);

Deleted: trunk/c_src/KinoSearch/Util/DynVirtualTable.bp
===================================================================
--- trunk/c_src/KinoSearch/Util/DynVirtualTable.bp 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Util/DynVirtualTable.bp 2008-09-07 02:39:58 UTC (rev 3830)
@@ -1,78 +0,0 @@
-parcel KinoSearch cnick Kino;
-
-class KinoSearch::Util::DynVirtualTable cnick DynVT
- extends KinoSearch::Obj::VTable {
-
- /* Note: there cannot be more member vars since VTable stores
- * methods in a flexible array.
- */
-
- /* Return a singleton. If a vtable can be found in the registry based on
- * the subclass name, it will be returned. Otherwise, a new
- * DynVirtualTable will be created using [parent] as a base.
- *
- * If [parent] is null, an attempt will be made to find it using
- * DynVT_find_parent_vtable(). If the attempt fails, an error will
- * result.
- */
- static DynVirtualTable*
- singleton(const CharBuf *subclass_name, VTable *parent);
-
- /** Replace a function pointer in the VTable.
- */
- void
- Override(DynVirtualTable *self, kino_method_t method_ptr, size_t offset);
-
- /* Register a vtable, so that it can be retrieved by class name.
- *
- * Note that this function takes a VTable rather than a
- * DynVirtualTable. TODO: Move this functionality to some kind of class
- * loader.
- */
- static void
- add_to_registry(VTable *vtable);
-
- /* Find a registered class and return its vtable. May return NULL if the
- * class is not registered.
- */
- static VTable*
- fetch_vtable(const CharBuf *class_name);
-
- /* Given a class name, return the vtable belonging to a parent class, or NULL
- * if such a vtable can't be found.
- */
- static VTable*
- find_parent_vtable(const CharBuf *class_name);
-
- /* Initialize the registry hash.
- */
- static void
- init_registry();
-
- /** List all of the methods that a class has overridden via the host
- * language.
- */
- static incremented VArray*
- novel_native_methods(const CharBuf *class_name);
-
- void
- Dec_RefCount(DynVirtualTable *self);
-
- void
- Destroy(DynVirtualTable *self);
-}
-
-__C__
-extern struct kino_Hash *kino_DynVT_registry;
-
-#ifdef KINO_USE_SHORT_NAMES
- #define DynVT_registry kino_DynVT_registry
-#endif
-__END_C__
-
-/* Copyright 2006-2008 Marvin Humphrey
- *
- * This program is free software; you can redistribute it and/or modify
- * under the same terms as Perl itself.
- */
-

Deleted: trunk/c_src/KinoSearch/Util/DynVirtualTable.c
===================================================================
--- trunk/c_src/KinoSearch/Util/DynVirtualTable.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Util/DynVirtualTable.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -1,208 +0,0 @@
-#define CHY_USE_SHORT_NAMES
-#define KINO_USE_SHORT_NAMES
-
-#include <string.h>
-#include <ctype.h>
-#include "charmony.h"
-
-#include "KinoSearch/Util/DynVirtualTable.h"
-#include "KinoSearch/Obj/Undefined.h"
-#include "KinoSearch/Util/CharBuf.h"
-#include "KinoSearch/Util/Hash.h"
-#include "KinoSearch/Util/Carp.h"
-#include "KinoSearch/Util/MemManager.h"
-#include "KinoSearch/Util/Native.h"
-#include "KinoSearch/Util/VArray.h"
-
-Hash *DynVT_registry = NULL;
-
-/* Clean up a vtable when its refcount drops to 0.
- */
-static void
-remove_from_registry(const CharBuf *name);
-
-/* Remove spaces and underscores, convert to lower case. */
-static void
-scrunch_charbuf(CharBuf *source, CharBuf *target);
-
-/* Constructor. Returns singletons, keyed by class name.
- */
-DynVirtualTable*
-DynVT_singleton(const CharBuf *subclass_name, VTable *parent)
-{
- DynVirtualTable *singleton;
-
- if (DynVT_registry == NULL)
- DynVT_init_registry();
-
- singleton = (DynVirtualTable*)Hash_Fetch(DynVT_registry, subclass_name);
-
- if (singleton == NULL) {
- VArray *novel_native_methods;
-
- if (parent == NULL) {
- /* (implicit refcount inc) */
- parent = DynVT_find_parent_vtable(subclass_name);
- if (parent == NULL) {
- CONFESS("Can't find a parent vtable for '%o'", subclass_name);
- }
- }
- else {
- REFCOUNT_INC(parent);
- }
-
- /* Copy source vtable. */
- singleton = (DynVirtualTable*)VTable_Clone(parent);
- REFCOUNT_DEC(singleton->_);
- singleton->_ = (VTable*)REFCOUNT_INC(&DYNVIRTUALTABLE);
-
- /* Turn clone into child. */
- REFCOUNT_DEC(singleton->parent);
- singleton->parent = parent;
- REFCOUNT_DEC(singleton->name);
- singleton->name = CB_Clone(subclass_name);
-
- /* Allow native methods to override. */
- novel_native_methods = DynVT_novel_native_methods(subclass_name);
- if (novel_native_methods->size) {
- Hash *meths = Hash_new(novel_native_methods->size);
- u32_t i;
- CharBuf *scrunched = CB_new(0);
- ZombieCharBuf callback_name = ZCB_BLANK;
- for (i = 0; i < novel_native_methods->size; i++) {
- CharBuf *meth = (CharBuf*)VA_fetch(novel_native_methods, i);
- scrunch_charbuf(meth, scrunched);
- Hash_Store(meths, scrunched, (Obj*)UNDEF);
- }
- for (i = 0; singleton->callbacks[i] != NULL; i++) {
- Callback *const callback = singleton->callbacks[i];
- ZCB_Assign_Str(&callback_name, callback->name,
- callback->name_len);
- scrunch_charbuf((CharBuf*)&callback_name, scrunched);
- if (Hash_Fetch(meths, scrunched)) {
- DynVT_override(singleton, callback->func, callback->offset);
- }
- }
- REFCOUNT_DEC(scrunched);
- REFCOUNT_DEC(meths);
- }
- REFCOUNT_DEC(novel_native_methods);
-
- /* Store the virtual table in the registry. */
- Hash_Store(DynVT_registry, subclass_name, (Obj*)singleton);
- singleton->ref.count--;
-
- /* Track globals to help hunt memory leaks. */
- IFDEF_DEBUG( kino_Debug_num_globals += 2; );
- }
-
- return singleton;
-}
-
-static void
-scrunch_charbuf(CharBuf *source, CharBuf *target)
-{
- ZombieCharBuf iterator = ZCB_BLANK;
- CB_Iter_Init(source, &iterator);
- CB_Set_Size(target, 0);
- while (ZCB_Get_Size(&iterator)) {
- u32_t code_point = ZCB_Nip_One(&iterator);
- if (code_point > 127) {
- CONFESS("Can't fold case for %o", source);
- }
- else if (code_point != '_') {
- CB_Cat_Char(target, tolower(code_point));
- }
- }
-}
-
-void
-DynVT_override(DynVirtualTable *self, kino_method_t method, size_t offset)
-{
- union { char *char_ptr; kino_method_t *func_ptr; } pointer;
- pointer.char_ptr = ((char*)self) + offset;
- pointer.func_ptr[0] = method;
-}
-
-VTable*
-DynVT_find_parent_vtable(const CharBuf *class_name)
-{
- return (VTable*)Native_callback_obj(&DYNVIRTUALTABLE,
- "find_parent_vtable", 1, ARG_STR("class_name", class_name));
-}
-
-void
-DynVT_dec_refcount(DynVirtualTable *self)
-{
- if (self->ref.count == 2) {
- remove_from_registry(self->name);
- }
- FastObj_dec_refcount((FastObj*)self);
-}
-
-void
-DynVT_destroy(DynVirtualTable *self)
-{
- if (self->parent && (REFCOUNT(self->parent) == 2)) {
- remove_from_registry(self->parent->name);
- }
- kino_VTable_destroy((kino_VTable*)self);
-}
-
-void
-DynVT_add_to_registry(VTable *vtable)
-{
- VTable *fetched;
-
- if (DynVT_registry == NULL)
- DynVT_init_registry();
- fetched = (VTable*)Hash_Fetch(DynVT_registry, vtable->name);
- if (fetched) {
- if (fetched != vtable) {
- CONFESS("Attempt to redefine a vtable for '%o'",
- vtable->name);
- }
- }
- else {
- Hash_Store(DynVT_registry, vtable->name, (Obj*)vtable);
- }
-}
-
-VTable*
-DynVT_fetch_vtable(const CharBuf *class_name)
-{
- VTable *vtable = NULL;
- if (DynVT_registry != NULL) {
- vtable = (VTable*)Hash_Fetch(DynVT_registry, class_name);
- }
- return vtable;
-}
-
-void
-DynVT_init_registry()
-{
- DynVT_registry = Hash_new(0);
-}
-
-VArray*
-DynVT_novel_native_methods(const CharBuf *class_name)
-{
- return (VArray*)Native_callback_obj(&DYNVIRTUALTABLE,
- "novel_native_methods", 1, ARG_STR("class_name", class_name));
-}
-
-static void
-remove_from_registry(const CharBuf *name)
-{
- if (DynVT_registry == NULL)
- CONFESS("Attempt to remove '%o', but registry is NULL", name);
- Hash_Delete(DynVT_registry, name);
- IFDEF_DEBUG( kino_Debug_num_globals -= 2; );
-}
-
-/* Copyright 2006-2008 Marvin Humphrey
- *
- * This program is free software; you can redistribute it and/or modify
- * under the same terms as Perl itself.
- */
-

Modified: trunk/c_src/KinoSearch/Util/Freezer.c
===================================================================
--- trunk/c_src/KinoSearch/Util/Freezer.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Util/Freezer.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -5,7 +5,6 @@
#include "KinoSearch/Util/Freezer.h"
#include "KinoSearch/Store/InStream.h"
#include "KinoSearch/Store/OutStream.h"
-#include "KinoSearch/Util/DynVirtualTable.h"

void
Freezer_freeze(Obj *obj, OutStream *outstream)
@@ -18,7 +17,7 @@
Freezer_thaw(InStream *instream)
{
CharBuf *class_name = CB_deserialize(NULL, instream);
- VTable *vtable = (VTable*)DynVT_singleton(class_name, NULL);
+ VTable *vtable = (VTable*)VTable_singleton(class_name, NULL);
Obj_create_t create = (Obj_create_t)METHOD_PTR(vtable, Obj, Create);
Obj *blank = create(NULL, NULL, vtable, vtable->obj_alloc_size);
REFCOUNT_DEC(class_name);

Modified: trunk/c_src/KinoSearch/Util/ToolSet.h
===================================================================
--- trunk/c_src/KinoSearch/Util/ToolSet.h 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/c_src/KinoSearch/Util/ToolSet.h 2008-09-07 02:39:58 UTC (rev 3830)
@@ -24,7 +24,6 @@
#include "KinoSearch/Util/MathUtils.h"
#include "KinoSearch/Util/MemManager.h"
#include "KinoSearch/Util/StringHelper.h"
-#include "KinoSearch/Util/DynVirtualTable.h"
#include "KinoSearch/Util/CharBuf.h"
#include "KinoSearch/Util/VArray.h"
#include "KinoSearch/Util/Hash.h"

Modified: trunk/devel/conf/p510_valgrind.supp
===================================================================
--- trunk/devel/conf/p510_valgrind.supp 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/devel/conf/p510_valgrind.supp 2008-09-07 02:39:58 UTC (rev 3830)
@@ -5,8 +5,8 @@
fun:kino_MemMan_wrapped_calloc
fun:kino_Obj_create
fun:kino_Hash_new
- fun:kino_DynVT_init_registry
- fun:kino_DynVT_add_to_registry
+ fun:kino_VTable_init_registry
+ fun:kino_VTable_add_to_registry
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:*
@@ -17,7 +17,7 @@
fun:malloc
fun:kino_MemMan_wrapped_malloc
fun:kino_Hash_store
- fun:kino_DynVT_add_to_registry
+ fun:kino_VTable_add_to_registry
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:*
@@ -28,7 +28,7 @@
fun:calloc
fun:kino_MemMan_wrapped_calloc
fun:kino_Hash_store
- fun:kino_DynVT_add_to_registry
+ fun:kino_VTable_add_to_registry
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:*
@@ -39,7 +39,7 @@
fun:malloc
fun:kino_MemMan_wrapped_malloc
fun:kino_Hash_store
- fun:kino_DynVT_add_to_registry
+ fun:kino_VTable_add_to_registry
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:*
@@ -52,7 +52,7 @@
fun:kino_FastObj_create
fun:kino_CB_new_from_trusted_utf8
fun:kino_Hash_store
- fun:kino_DynVT_add_to_registry
+ fun:kino_VTable_add_to_registry
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:*
@@ -64,7 +64,7 @@
fun:kino_MemMan_wrapped_malloc
fun:kino_CB_new_from_trusted_utf8
fun:kino_Hash_store
- fun:kino_DynVT_add_to_registry
+ fun:kino_VTable_add_to_registry
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:*

Modified: trunk/devel/conf/p588_valgrind.supp
===================================================================
--- trunk/devel/conf/p588_valgrind.supp 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/devel/conf/p588_valgrind.supp 2008-09-07 02:39:58 UTC (rev 3830)
@@ -4,8 +4,8 @@
fun:malloc
fun:kino_Obj_create
fun:kino_Hash_new
- fun:kino_DynVT_init_registry
- fun:kino_DynVT_register
+ fun:kino_VTable_init_registry
+ fun:kino_VTable_register
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:Perl_pp_entersub
@@ -21,7 +21,7 @@
fun:rebuild_hash
fun:kino_Hash_store_bb
fun:kino_Hash_store
- fun:kino_DynVT_register
+ fun:kino_VTable_register
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:Perl_pp_entersub
@@ -37,7 +37,7 @@
fun:new_entry
fun:kino_Hash_store_bb
fun:kino_Hash_store
- fun:kino_DynVT_register
+ fun:kino_VTable_register
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:Perl_pp_entersub
@@ -56,7 +56,7 @@
fun:new_entry
fun:kino_Hash_store_bb
fun:kino_Hash_store
- fun:kino_DynVT_register
+ fun:kino_VTable_register
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:Perl_pp_entersub
@@ -71,7 +71,7 @@
fun:new_entry
fun:kino_Hash_store_bb
fun:kino_Hash_store
- fun:kino_DynVT_register
+ fun:kino_VTable_register
fun:kino_Boot_bootstrap
fun:boot_KinoSearch
fun:Perl_pp_entersub

Modified: trunk/perl/MANIFEST
===================================================================
--- trunk/perl/MANIFEST 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/MANIFEST 2008-09-07 02:39:58 UTC (rev 3830)
@@ -151,7 +151,6 @@
lib/KinoSearch/Util/CharBuf.pm
lib/KinoSearch/Util/Compat/DirManip.pm
lib/KinoSearch/Util/Debug.pm
-lib/KinoSearch/Util/DynVirtualTable.pm
lib/KinoSearch/Util/Hash.pm
lib/KinoSearch/Util/I32Array.pm
lib/KinoSearch/Util/Json.pm
@@ -253,7 +252,7 @@
t/018-native.t
t/019-obj.t
t/020-subclassing_obj.t
-t/021-dyn_virtual_table.t
+t/021-vtable.t
t/022-bytebuf.t
t/023-stepper.t
t/024-memory_pool.t

Modified: trunk/perl/lib/KinoSearch/Obj/VTable.pm
===================================================================
--- trunk/perl/lib/KinoSearch/Obj/VTable.pm 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/lib/KinoSearch/Obj/VTable.pm 2008-09-07 02:39:58 UTC (rev 3830)
@@ -11,6 +11,18 @@
}
}

+__XS__
+
+MODULE = KinoSearch PACKAGE = KinoSearch::Obj::VTable
+
+SV*
+_get_registry()
+CODE:
+ if (kino_VTable_registry == NULL)
+ kino_VTable_init_registry();
+ RETVAL = Kino_Obj_To_Native(kino_VTable_registry);
+OUTPUT: RETVAL
+
__COPYRIGHT__

Copyright 2007-2008 Marvin Humphrey

Modified: trunk/perl/lib/KinoSearch/Obj.pm
===================================================================
--- trunk/perl/lib/KinoSearch/Obj.pm 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/lib/KinoSearch/Obj.pm 2008-09-07 02:39:58 UTC (rev 3830)
@@ -14,7 +14,7 @@
kino_CharBuf class_name;
CODE:
{
- kino_VTable *target = kino_DynVT_fetch_vtable(&class_name);
+ kino_VTable *target = kino_VTable_fetch_vtable(&class_name);
RETVAL = Kino_Obj_Is_A(self, target);
}
OUTPUT: RETVAL
@@ -72,7 +72,7 @@
kino_ViewFileDes *file_des = kino_ViewFileDes_new(ptr, len);
kino_InStream *instream = kino_InStream_new((kino_FileDes*)file_des);
kino_ZombieCharBuf class_name = sv_to_class_name(blank_obj);
- kino_VTable *vtable = (kino_VTable*)kino_DynVT_singleton(
+ kino_VTable *vtable = (kino_VTable*)kino_VTable_singleton(
(kino_CharBuf*)&class_name, NULL);
kino_Obj *self = KINO_FOSTER(NULL, (*vtable), blank_obj);
kino_Obj *deserialized = Kino_Obj_Deserialize(self, instream);

Deleted: trunk/perl/lib/KinoSearch/Util/DynVirtualTable.pm
===================================================================
--- trunk/perl/lib/KinoSearch/Util/DynVirtualTable.pm 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/lib/KinoSearch/Util/DynVirtualTable.pm 2008-09-07 02:39:58 UTC (rev 3830)
@@ -1,25 +0,0 @@
-use KinoSearch;
-
-1;
-
-__END__
-
-__XS__
-
-MODULE = KinoSearch PACKAGE = KinoSearch::Util::DynVirtualTable
-
-SV*
-_get_registry()
-CODE:
- if (kino_DynVT_registry == NULL)
- kino_DynVT_init_registry();
- RETVAL = Kino_Obj_To_Native(kino_DynVT_registry);
-OUTPUT: RETVAL
-
-__COPYRIGHT__
-
-Copyright 2005-2008 Marvin Humphrey
-
-This program is free software; you can redistribute it and/or modify
-under the same terms as Perl itself.
-

Modified: trunk/perl/lib/KinoSearch.pm
===================================================================
--- trunk/perl/lib/KinoSearch.pm 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/lib/KinoSearch.pm 2008-09-07 02:39:58 UTC (rev 3830)
@@ -188,6 +188,44 @@
}

{
+ package KinoSearch::Obj::VTable;
+
+ sub find_parent_vtable {
+ my ( $ignore, $package ) = @_;
+ return _find_parent_vtable($package);
+ }
+
+ # Depth-first recursive search of @ISA.
+ sub _find_parent_vtable {
+ my $package = shift;
+ my $registry = KinoSearch::Obj::VTable::_get_registry();
+ my $vtable;
+ no strict 'refs';
+ for my $parent ( @{"$package\::ISA"} ) {
+ $vtable = $registry->fetch($parent);
+ last if defined $vtable;
+ $vtable = _find_parent_vtable($parent);
+ last if defined $vtable;
+ }
+ return $vtable;
+ }
+
+ sub novel_native_methods {
+ my ( undef, $package ) = @_;
+ no strict 'refs';
+ my $stash = \%{"$package\::"};
+ my $methods = KinoSearch::Util::VArray->new(
+ capacity => scalar keys %$stash );
+ while ( my ( $symbol, $glob ) = each %$stash ) {
+ next if ref $glob;
+ next unless *$glob{CODE};
+ $methods->push( KinoSearch::Util::CharBuf->new($symbol) );
+ }
+ return $methods;
+ }
+}
+
+{
package KinoSearch::Index::DocReader;

use KinoSearch::Util::StringHelper qw( utf8_flag_on );
@@ -473,44 +511,6 @@
}

{
- package KinoSearch::Util::DynVirtualTable;
-
- sub find_parent_vtable {
- my ( $ignore, $package ) = @_;
- return _find_parent_vtable($package);
- }
-
- # Depth-first recursive search of @ISA.
- sub _find_parent_vtable {
- my $package = shift;
- my $registry = _get_registry();
- my $vtable;
- no strict 'refs';
- for my $parent ( @{"$package\::ISA"} ) {
- $vtable = $registry->fetch($parent);
- last if defined $vtable;
- $vtable = _find_parent_vtable($parent);
- last if defined $vtable;
- }
- return $vtable;
- }
-
- sub novel_native_methods {
- my ( undef, $package ) = @_;
- no strict 'refs';
- my $stash = \%{"$package\::"};
- my $methods = KinoSearch::Util::VArray->new(
- capacity => scalar keys %$stash );
- while ( my ( $symbol, $glob ) = each %$stash ) {
- next if ref $glob;
- next unless *$glob{CODE};
- $methods->push( KinoSearch::Util::CharBuf->new($symbol) );
- }
- return $methods;
- }
-}
-
-{
package KinoSearch::Util::I32Array;
our %new_PARAMS = ( ints => undef );
}

Deleted: trunk/perl/t/021-dyn_virtual_table.t
===================================================================
--- trunk/perl/t/021-dyn_virtual_table.t 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/t/021-dyn_virtual_table.t 2008-09-07 02:39:58 UTC (rev 3830)
@@ -1,65 +0,0 @@
-use strict;
-use warnings;
-
-package MyHash;
-use base qw( KinoSearch::Util::Hash );
-
-sub oodle { }
-
-package RAMFolderOfDeath;
-use base qw( KinoSearch::Store::RAMFolder );
-
-sub open_instream {
- my ( $self, $filename ) = @_;
- die "Sweet, sweet death.";
-}
-
-package main;
-
-use Test::More tests => 8;
-
-use KinoSearch::Util::DynVirtualTable;
-
-use KinoSearch::Util::Hash;
-use KinoSearch::Util::CharBuf;
-
-my $stringified;
-my $storage = KinoSearch::Util::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 kino 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 = KinoSearch::Util::CharBuf->new("booga");
-$resurrected->store( "ooga", $booga );
-
-is( $resurrected->fetch("ooga")->to_string,
- "booga", "subclassed object still performs correctly at the C level" );
-
-my $vtable = KinoSearch::Util::DynVirtualTable->find_parent_vtable("nope");
-ok( !defined $vtable, "Can't find_parent_vtable for non-existent class" );
-$vtable = KinoSearch::Util::DynVirtualTable->find_parent_vtable("MyHash");
-is( $vtable->get_name, "KinoSearch::Util::Hash",
- "find_parent_vtable for custom subclass" );
-
-my $methods
- = KinoSearch::Util::DynVirtualTable->novel_native_methods('MyHash');
-is_deeply( $methods->to_perl, ['oodle'], "novel_native_methods" );
-
-my $folder = RAMFolderOfDeath->new;
-eval { $folder->slurp_file('foo') }; # calls open_instream, which dies per above.
-like( $@, qr/sweet/i, "override vtable method with native perl method" );

Copied: trunk/perl/t/021-vtable.t (from rev 3824, trunk/perl/t/021-dyn_virtual_table.t)
===================================================================
--- trunk/perl/t/021-vtable.t (rev 0)
+++ trunk/perl/t/021-vtable.t 2008-09-07 02:39:58 UTC (rev 3830)
@@ -0,0 +1,65 @@
+use strict;
+use warnings;
+
+package MyHash;
+use base qw( KinoSearch::Util::Hash );
+
+sub oodle { }
+
+package RAMFolderOfDeath;
+use base qw( KinoSearch::Store::RAMFolder );
+
+sub open_instream {
+ my ( $self, $filename ) = @_;
+ die "Sweet, sweet death.";
+}
+
+package main;
+
+use Test::More tests => 8;
+
+use KinoSearch::Obj::VTable;
+
+use KinoSearch::Util::Hash;
+use KinoSearch::Util::CharBuf;
+
+my $stringified;
+my $storage = KinoSearch::Util::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 kino 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 = KinoSearch::Util::CharBuf->new("booga");
+$resurrected->store( "ooga", $booga );
+
+is( $resurrected->fetch("ooga")->to_string,
+ "booga", "subclassed object still performs correctly at the C level" );
+
+my $vtable = KinoSearch::Obj::VTable->find_parent_vtable("nope");
+ok( !defined $vtable, "Can't find_parent_vtable for non-existent class" );
+$vtable = KinoSearch::Obj::VTable->find_parent_vtable("MyHash");
+is( $vtable->get_name, "KinoSearch::Util::Hash",
+ "find_parent_vtable for custom subclass" );
+
+my $methods
+ = KinoSearch::Obj::VTable->novel_native_methods('MyHash');
+is_deeply( $methods->to_perl, ['oodle'], "novel_native_methods" );
+
+my $folder = RAMFolderOfDeath->new;
+eval { $folder->slurp_file('foo') }; # calls open_instream, which dies per above.
+like( $@, qr/sweet/i, "override vtable method with native perl method" );

Modified: trunk/perl/xs/KinoSearch/Obj/FastObj.c
===================================================================
--- trunk/perl/xs/KinoSearch/Obj/FastObj.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/xs/KinoSearch/Obj/FastObj.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -4,7 +4,7 @@
#include "ppport.h"

#include "KinoSearch/Obj/FastObj.h"
-#include "KinoSearch/Util/DynVirtualTable.h"
+#include "KinoSearch/Obj/VTable.h"
#include "KinoSearch/Util/CharBuf.h"
#include "KinoSearch/Util/MemManager.h"

@@ -25,7 +25,7 @@
}
else {
kino_VTable *real_vtable
- = (kino_VTable*)kino_DynVT_singleton(class_name, vtable);
+ = (kino_VTable*)kino_VTable_singleton(class_name, vtable);
self->_ = KINO_REFCOUNT_INC(real_vtable);
}


Modified: trunk/perl/xs/KinoSearch/Obj.c
===================================================================
--- trunk/perl/xs/KinoSearch/Obj.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/xs/KinoSearch/Obj.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -4,9 +4,9 @@
#include "ppport.h"

#include "KinoSearch/Obj.h"
+#include "KinoSearch/Obj/VTable.h"
#include "KinoSearch/Util/Carp.h"
#include "KinoSearch/Util/CharBuf.h"
-#include "KinoSearch/Util/DynVirtualTable.h"
#include "KinoSearch/Util/MemManager.h"
#include "KinoSearch/Util/Native.h"

@@ -26,7 +26,7 @@
}
else {
kino_VTable *real_vtable
- = (kino_VTable*)kino_DynVT_singleton(class_name, vtable);
+ = (kino_VTable*)kino_VTable_singleton(class_name, vtable);
self->_ = KINO_REFCOUNT_INC(real_vtable);
}

@@ -62,7 +62,7 @@
}
else {
kino_VTable *real_vtable
- = (kino_VTable*)kino_DynVT_singleton( class_name, vtable);
+ = (kino_VTable*)kino_VTable_singleton( class_name, vtable);
self->_ = KINO_REFCOUNT_INC(real_vtable);
}
self->ref.native = inner_obj;

Modified: trunk/perl/xs/XSBind.c
===================================================================
--- trunk/perl/xs/XSBind.c 2008-09-07 00:54:25 UTC (rev 3829)
+++ trunk/perl/xs/XSBind.c 2008-09-07 02:39:58 UTC (rev 3830)
@@ -1,6 +1,5 @@
#include "XSBind.h"
#include "KinoSearch/Util/Num.h"
-#include "KinoSearch/Util/DynVirtualTable.h"
#include "KinoSearch/Store/InStream.h"
#include "KinoSearch/Store/OutStream.h"
#include "KinoSearch/Util/StringHelper.h"
@@ -32,7 +31,7 @@
}
else {
kino_ZombieCharBuf klass = sv_to_class_name(either_sv);
- vtable = (kino_VTable*)kino_DynVT_singleton(
+ vtable = (kino_VTable*)kino_VTable_singleton(
(kino_CharBuf*)&klass, NULL);
}



_______________________________________________
kinosearch-commits mailing list
kinosearch-commits@rectangular.com
http://www.rectangular.com/mailman/listinfo/kinosearch-commits