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 2012/04/14 16:04:18 UTC
[lucy-commits] svn commit: r1326105 - in /lucy/trunk: clownfish/perl/lib/Clownfish/
clownfish/src/ core/Lucy/Object/
Author: nwellnhof
Date: Sat Apr 14 14:04:17 2012
New Revision: 1326105
URL: http://svn.apache.org/viewvc?rev=1326105&view=rev
Log:
Initialize VTables during run-time
Modified:
lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs
lucy/trunk/clownfish/src/CFCBindAliases.c
lucy/trunk/clownfish/src/CFCBindClass.c
lucy/trunk/clownfish/src/CFCBindClass.h
lucy/trunk/clownfish/src/CFCBindCore.c
lucy/trunk/clownfish/src/CFCPerl.c
lucy/trunk/core/Lucy/Object/VTable.c
lucy/trunk/core/Lucy/Object/VTable.cfh
Modified: lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs
URL: http://svn.apache.org/viewvc/lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs?rev=1326105&r1=1326104&r2=1326105&view=diff
==============================================================================
--- lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs (original)
+++ lucy/trunk/clownfish/perl/lib/Clownfish/CFC.xs Sat Apr 14 14:04:17 2012
@@ -1804,10 +1804,10 @@ CODE:
OUTPUT: RETVAL
SV*
-to_c(self)
+to_c_data(self)
CFCBindClass *self;
CODE:
- RETVAL = S_sv_eat_c_string(CFCBindClass_to_c(self));
+ RETVAL = S_sv_eat_c_string(CFCBindClass_to_c_data(self));
OUTPUT: RETVAL
SV*
Modified: lucy/trunk/clownfish/src/CFCBindAliases.c
URL: http://svn.apache.org/viewvc/lucy/trunk/clownfish/src/CFCBindAliases.c?rev=1326105&r1=1326104&r2=1326105&view=diff
==============================================================================
--- lucy/trunk/clownfish/src/CFCBindAliases.c (original)
+++ lucy/trunk/clownfish/src/CFCBindAliases.c Sat Apr 14 14:04:17 2012
@@ -95,6 +95,7 @@ struct alias aliases[] = {
{"cfish_VTable", "lucy_VTable"},
{"CFISH_VTABLE", "LUCY_VTABLE"},
+ {"cfish_VTable_bootstrap", "lucy_VTable_bootstrap"},
{"cfish_VTable_add_to_registry", "lucy_VTable_add_to_registry"},
{"cfish_VTable_add_alias_to_registry", "lucy_VTable_add_alias_to_registry"},
{"cfish_VTable_offset_of_parent", "lucy_VTable_offset_of_parent"},
Modified: lucy/trunk/clownfish/src/CFCBindClass.c
URL: http://svn.apache.org/viewvc/lucy/trunk/clownfish/src/CFCBindClass.c?rev=1326105&r1=1326104&r2=1326105&view=diff
==============================================================================
--- lucy/trunk/clownfish/src/CFCBindClass.c (original)
+++ lucy/trunk/clownfish/src/CFCBindClass.c Sat Apr 14 14:04:17 2012
@@ -34,7 +34,7 @@ struct CFCBindClass {
CFCBase base;
CFCClass *client;
char *full_callbacks_var;
- char *full_name_var;
+ char *full_methods_var;
char *short_names_macro;
};
@@ -50,12 +50,6 @@ S_to_c_header_dynamic(CFCBindClass *self
static char*
S_struct_definition(CFCBindClass *self);
-/* C code defining the ZombieCharBuf which contains the class name for this
- * class.
- */
-static char*
-S_name_var_definition(CFCBindClass *self);
-
// Return C code defining the class's VTable.
static char*
S_vtable_definition(CFCBindClass *self);
@@ -112,10 +106,10 @@ CFCBindClass_init(CFCBindClass *self, CF
const char *full_vtable_var = CFCClass_full_vtable_var(client);
const char *PREFIX = CFCClass_get_PREFIX(client);
self->full_callbacks_var = (char*)MALLOCATE(strlen(full_vtable_var) + 20);
- self->full_name_var = (char*)MALLOCATE(strlen(full_vtable_var) + 20);
+ self->full_methods_var = (char*)MALLOCATE(strlen(full_vtable_var) + 20);
self->short_names_macro = (char*)MALLOCATE(strlen(PREFIX) + 20);
sprintf(self->full_callbacks_var, "%s_CALLBACKS", full_vtable_var);
- sprintf(self->full_name_var, "%s_CLASS_NAME", full_vtable_var);
+ sprintf(self->full_methods_var, "%s_METHODS", full_vtable_var);
sprintf(self->short_names_macro, "%sUSE_SHORT_NAMES", PREFIX);
return self;
@@ -124,7 +118,7 @@ CFCBindClass_init(CFCBindClass *self, CF
void
CFCBindClass_destroy(CFCBindClass *self) {
FREEMEM(self->full_callbacks_var);
- FREEMEM(self->full_name_var);
+ FREEMEM(self->full_methods_var);
FREEMEM(self->short_names_macro);
CFCBase_decref((CFCBase*)self->client);
CFCBase_destroy((CFCBase*)self);
@@ -290,7 +284,7 @@ S_to_c_header_dynamic(CFCBindClass *self
}
char*
-CFCBindClass_to_c(CFCBindClass *self) {
+CFCBindClass_to_c_data(CFCBindClass *self) {
CFCClass *client = self->client;
if (CFCClass_inert(client)) {
@@ -300,9 +294,8 @@ CFCBindClass_to_c(CFCBindClass *self) {
const char *include_h = CFCClass_include_h(client);
const char *autocode = CFCClass_get_autocode(client);
const char *vt_type = CFCClass_full_vtable_type(client);
+ const char *vt_hidden = CFCClass_full_vtable_hidden(client);
const char *cnick = CFCClass_get_cnick(client);
- char *class_name_def = S_name_var_definition(self);
- char *vtable_def = S_vtable_definition(self);
CFCMethod **methods = CFCClass_methods(client);
CFCMethod **fresh_methods = CFCClass_fresh_methods(client);
@@ -319,6 +312,10 @@ CFCBindClass_to_c(CFCBindClass *self) {
cb_var = CFCUtil_cat(cb_var, "cfish_Callback *", self->full_callbacks_var,
"[] = {\n ", NULL);
+ char *method_var = CFCUtil_strdup("");
+ method_var = CFCUtil_cat(method_var, "cfish_method_t ",
+ self->full_methods_var, "[] = {\n ", NULL);
+
for (int meth_num = 0; methods[meth_num] != NULL; meth_num++) {
CFCMethod *method = methods[meth_num];
int method_is_fresh = S_method_is_fresh(method, fresh_methods);
@@ -365,11 +362,18 @@ CFCBindClass_to_c(CFCBindClass *self) {
cb_var = CFCUtil_cat(cb_var, "&", full_cb_sym, ",\n ", NULL);
}
+ // Define method implementations.
+ const char *implementing_sym = CFCMethod_implementing_func_sym(method);
+ method_var = CFCUtil_cat(method_var, "(cfish_method_t)",
+ implementing_sym, ",\n ", NULL);
+
FREEMEM(offset_str);
}
// Close callbacks variable definition.
cb_var = CFCUtil_cat(cb_var, "NULL\n};\n", NULL);
+ // Close methods variable definition.
+ method_var = CFCUtil_cat(method_var, "NULL\n};\n", NULL);
const char pattern[] =
"#include \"%s\"\n"
@@ -398,7 +402,7 @@ CFCBindClass_to_c(CFCBindClass *self) {
"\n"
"%s\n"
"\n"
- "/* Define the variable which holds this class's class name.\n"
+ "/* Define this class's method implementations.\n"
" */\n"
"\n"
"%s\n"
@@ -406,7 +410,7 @@ CFCBindClass_to_c(CFCBindClass *self) {
"/* Define this class's VTable.\n"
" */\n"
"\n"
- "%s\n"
+ "%s %s;\n"
"\n"
"/* Include auxilary automatically generated code for this class.\n"
" */\n"
@@ -419,21 +423,21 @@ CFCBindClass_to_c(CFCBindClass *self) {
+ strlen(cb_funcs)
+ strlen(cb_objects)
+ strlen(cb_var)
- + strlen(class_name_def)
- + strlen(vtable_def)
+ + strlen(method_var)
+ + strlen(vt_type)
+ + strlen(vt_hidden)
+ strlen(autocode)
+ 100;
char *code = (char*)MALLOCATE(size);
sprintf(code, pattern, include_h, offsets, cb_funcs, cb_objects, cb_var,
- class_name_def, vtable_def, autocode);
+ method_var, vt_type, vt_hidden, autocode);
+ FREEMEM(method_var);
FREEMEM(fresh_methods);
FREEMEM(offsets);
FREEMEM(cb_funcs);
FREEMEM(cb_objects);
FREEMEM(cb_var);
- FREEMEM(class_name_def);
- FREEMEM(vtable_def);
return code;
}
@@ -464,38 +468,17 @@ S_struct_definition(CFCBindClass *self)
return struct_def;
}
-static char*
-S_name_var_definition(CFCBindClass *self) {
- const char *class_name = CFCClass_get_class_name(self->client);
- unsigned class_name_len = (unsigned)strlen(class_name);
-
- const char pattern[] =
- "static cfish_ZombieCharBuf %s = {\n"
- " CFISH_ZOMBIECHARBUF,\n"
- " {1}, /* ref.count */\n"
- " \"%s\",\n"
- " %u,\n"
- " 0\n"
- "};\n\n";
- size_t size = sizeof(pattern)
- + strlen(self->full_name_var)
- + class_name_len
- + 15 // class_name_len
- + 20;
- char *name_var_def = (char*)MALLOCATE(size);
- sprintf(name_var_def, pattern, self->full_name_var, class_name,
- class_name_len);
+// Return C code bootstrapping the class's VTable.
+char*
+CFCBindClass_to_vtable_bootstrap(CFCBindClass *self) {
+ CFCClass *client = self->client;
- return name_var_def;
-}
+ if (CFCClass_inert(client)) {
+ return CFCUtil_strdup("");
+ }
-// Return C code defining the class's VTable.
-static char*
-S_vtable_definition(CFCBindClass *self) {
- CFCClass *client = self->client;
CFCClass *parent = CFCClass_get_parent(client);
- CFCMethod **methods = CFCClass_methods(client);
- const char *vt_type = CFCClass_full_vtable_type(client);
+ const char *class_name = CFCClass_get_class_name(client);
const char *vt_var = CFCClass_full_vtable_var(client);
const char *struct_sym = CFCClass_full_struct_sym(client);
@@ -504,56 +487,31 @@ S_vtable_definition(CFCBindClass *self)
? CFCClass_full_vtable_var(parent)
: "NULL"; // No parent, e.g. Obj or inert classes.
- // Spec functions which implement the methods, casting to quiet compiler.
- char *method_str = CFCUtil_strdup("");
- int num_methods = 0;
- for (; methods[num_methods] != NULL; num_methods++) {
- CFCMethod *method = methods[num_methods];
- const char *implementing_sym = CFCMethod_implementing_func_sym(method);
- size_t size = strlen(method_str) + strlen(implementing_sym) + 50;
- method_str = (char*)REALLOCATE(method_str, size);
- if (strlen(method_str)) {
- strcat(method_str, ",\n");
- }
- strcat(method_str, " (cfish_method_t)");
- strcat(method_str, implementing_sym);
- }
-
char pattern[] =
- "\n"
- "%s %s_vt = {\n"
- " CFISH_VTABLE, /* vtable vtable */\n"
- " {1}, /* ref.count */\n"
- " %s, /* parent */\n"
- " (cfish_CharBuf*)&%s,\n"
- " 0, /* flags */\n"
- " NULL, /* \"void *x\" member reserved for future use */\n"
- " sizeof(%s), /* obj_alloc_size */\n"
- " offsetof(cfish_VTable, methods)\n"
- " + %d * sizeof(cfish_method_t), /* vt_alloc_size */\n"
- " &%s, /* callbacks */\n"
- " {\n"
- "%s\n"
- " }\n"
- "};\n\n";
+ " cfish_VTable_bootstrap(\n"
+ " %s, /* vtable */\n"
+ " %s, /* parent */\n"
+ " \"%s\", /* name */\n"
+ " 0, /* flags */\n"
+ " NULL, /* \"void *x\" member reserved for future use */\n"
+ " sizeof(%s), /* obj_alloc_size */\n"
+ " %s, /* callbacks */\n"
+ " %s /* methods */\n"
+ " );\n";
size_t size = sizeof(pattern)
- + strlen(vt_type)
+ strlen(vt_var)
+ strlen(parent_ref)
- + strlen(self->full_name_var)
+ + strlen(class_name)
+ strlen(struct_sym)
- + 10 /* num_methods */
+ strlen(self->full_callbacks_var)
- + strlen(method_str)
+ + strlen(self->full_methods_var)
+ 40;
- char *vtable_def = (char*)MALLOCATE(size);
- sprintf(vtable_def, pattern, vt_type, vt_var, parent_ref,
- self->full_name_var, struct_sym, num_methods,
- self->full_callbacks_var, method_str);
+ char *code = (char*)MALLOCATE(size);
+ sprintf(code, pattern, vt_var, parent_ref, class_name, struct_sym,
+ self->full_callbacks_var, self->full_methods_var);
- FREEMEM(method_str);
- return vtable_def;
+ return code;
}
// Declare cfish_Callback objects.
Modified: lucy/trunk/clownfish/src/CFCBindClass.h
URL: http://svn.apache.org/viewvc/lucy/trunk/clownfish/src/CFCBindClass.h?rev=1326105&r1=1326104&r2=1326105&view=diff
==============================================================================
--- lucy/trunk/clownfish/src/CFCBindClass.h (original)
+++ lucy/trunk/clownfish/src/CFCBindClass.h Sat Apr 14 14:04:17 2012
@@ -49,11 +49,15 @@ CFCBindClass_destroy(CFCBindClass *self)
char*
CFCBindClass_to_c_header(CFCBindClass *self);
-/** Return the .c file which contains autogenerated C code necessary for the
- * class to function properly.
+/** Return the C data definitions necessary for the class to function properly.
*/
char*
-CFCBindClass_to_c(CFCBindClass *self);
+CFCBindClass_to_c_data(CFCBindClass *self);
+
+/** Return the autogenerated C code necessary to bootstrap the class.
+ */
+char*
+CFCBindClass_to_vtable_bootstrap(CFCBindClass *self);
#ifdef __cplusplus
}
Modified: lucy/trunk/clownfish/src/CFCBindCore.c
URL: http://svn.apache.org/viewvc/lucy/trunk/clownfish/src/CFCBindCore.c?rev=1326105&r1=1326104&r2=1326105&view=diff
==============================================================================
--- lucy/trunk/clownfish/src/CFCBindCore.c (original)
+++ lucy/trunk/clownfish/src/CFCBindCore.c Sat Apr 14 14:04:17 2012
@@ -26,6 +26,7 @@
#include "CFCClass.h"
#include "CFCFile.h"
#include "CFCHierarchy.h"
+#include "CFCParcel.h"
#include "CFCUtil.h"
struct CFCBindCore {
@@ -114,10 +115,15 @@ CFCBindCore_write_all_modified(CFCBindCo
static void
S_write_parcel_h(CFCBindCore *self) {
CFCHierarchy *hierarchy = self->hierarchy;
+ CFCParcel *parcel = NULL;
// Declare object structs for all instantiable classes.
+ // Obtain parcel prefix for use in bootstrap function name.
char *typedefs = CFCUtil_strdup("");
CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy);
+ if (!ordered[0]) {
+ CFCUtil_die("No classes found.");
+ }
for (int i = 0; ordered[i] != NULL; i++) {
CFCClass *klass = ordered[i];
if (!CFCClass_inert(klass)) {
@@ -125,7 +131,12 @@ S_write_parcel_h(CFCBindCore *self) {
typedefs = CFCUtil_cat(typedefs, "typedef struct ", full_struct,
" ", full_struct, ";\n", NULL);
}
+ if (parcel && CFCClass_get_parcel(klass) != parcel) {
+ CFCUtil_die("Multiple parcels not yet supported.");
+ }
+ parcel = CFCClass_get_parcel(klass);
}
+ const char *prefix = CFCParcel_get_prefix(parcel);
FREEMEM(ordered);
// Create Clownfish aliases if necessary.
@@ -205,6 +216,9 @@ S_write_parcel_h(CFCBindCore *self) {
" size_t offset;\n"
"} cfish_Callback;\n"
"\n"
+ "void\n"
+ "%sbootstrap_parcel();\n"
+ "\n"
"#ifdef __cplusplus\n"
"}\n"
"#endif\n"
@@ -217,10 +231,11 @@ S_write_parcel_h(CFCBindCore *self) {
+ strlen(self->header)
+ strlen(aliases)
+ strlen(typedefs)
+ + strlen(prefix)
+ strlen(self->footer)
+ 50;
char *file_content = (char*)MALLOCATE(size);
- sprintf(file_content, pattern, self->header, aliases, typedefs,
+ sprintf(file_content, pattern, self->header, aliases, typedefs, prefix,
self->footer);
// Unlink then write file.
@@ -239,62 +254,72 @@ S_write_parcel_h(CFCBindCore *self) {
static void
S_write_parcel_c(CFCBindCore *self) {
CFCHierarchy *hierarchy = self->hierarchy;
+ CFCParcel *parcel = NULL;
// Aggregate C code from all files.
- char *content = CFCUtil_strdup("");
+ // Obtain parcel prefix for use in bootstrap function name.
char *privacy_syms = CFCUtil_strdup("");
char *includes = CFCUtil_strdup("");
- CFCFile **files = CFCHierarchy_files(hierarchy);
- for (int i = 0; files[i] != NULL; i++) {
- CFCFile *file = files[i];
- CFCBase **blocks = CFCFile_blocks(file);
- for (int j = 0; blocks[j] != NULL; j++) {
- const char *cfc_class = CFCBase_get_cfc_class(blocks[j]);
- if (strcmp(cfc_class, "Clownfish::CFC::Model::Class") != 0) {
- continue;
- }
-
- CFCClass *klass = (CFCClass*)blocks[j];
- if (CFCClass_included(klass)) { continue; }
-
- CFCBindClass *class_binding = CFCBindClass_new(klass);
- char *c_code = CFCBindClass_to_c(class_binding);
- content = CFCUtil_cat(content, c_code, "\n", NULL);
- FREEMEM(c_code);
- CFCBase_decref((CFCBase*)class_binding);
- const char *privacy_sym = CFCClass_privacy_symbol(klass);
- privacy_syms = CFCUtil_cat(privacy_syms, "#define ",
- privacy_sym, "\n", NULL);
- const char *include_h = CFCClass_include_h(klass);
- includes = CFCUtil_cat(includes, "#include \"", include_h,
- "\"\n", NULL);
+ char *c_data = CFCUtil_strdup("");
+ char *vt_bootstrap = CFCUtil_strdup("");
+ CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy);
+ if (!ordered[0]) {
+ CFCUtil_die("No classes found.");
+ }
+ for (int i = 0; ordered[i] != NULL; i++) {
+ CFCClass *klass = ordered[i];
+ if (CFCClass_included(klass)) { continue; }
+
+ CFCBindClass *class_binding = CFCBindClass_new(klass);
+ char *class_c_data = CFCBindClass_to_c_data(class_binding);
+ c_data = CFCUtil_cat(c_data, class_c_data, "\n", NULL);
+ FREEMEM(class_c_data);
+ char *vt_boot = CFCBindClass_to_vtable_bootstrap(class_binding);
+ vt_bootstrap = CFCUtil_cat(vt_bootstrap, vt_boot, NULL);
+ FREEMEM(vt_boot);
+ CFCBase_decref((CFCBase*)class_binding);
+ const char *privacy_sym = CFCClass_privacy_symbol(klass);
+ privacy_syms = CFCUtil_cat(privacy_syms, "#define ",
+ privacy_sym, "\n", NULL);
+ const char *include_h = CFCClass_include_h(klass);
+ includes = CFCUtil_cat(includes, "#include \"", include_h,
+ "\"\n", NULL);
+ if (parcel && CFCClass_get_parcel(klass) != parcel) {
+ CFCUtil_die("Multiple parcels not yet supported.");
}
+ parcel = CFCClass_get_parcel(klass);
}
+ const char *prefix = CFCParcel_get_prefix(parcel);
+ FREEMEM(ordered);
char pattern[] =
"%s\n"
"\n"
- "#define C_LUCY_ZOMBIECHARBUF\n"
- "#define C_LUCY_VTABLE\n"
"%s\n"
"#include \"parcel.h\"\n"
- "#include \"Lucy/Object/CharBuf.h\"\n"
"#include \"Lucy/Object/VTable.h\"\n"
"%s\n"
"\n"
"%s\n"
"\n"
+ "void\n"
+ "%sbootstrap_parcel() {\n"
+ "%s"
+ "}\n"
+ "\n"
"%s\n";
size_t size = sizeof(pattern)
+ strlen(self->header)
+ strlen(privacy_syms)
+ strlen(includes)
- + strlen(content)
+ + strlen(c_data)
+ + strlen(prefix)
+ + strlen(vt_bootstrap)
+ strlen(self->footer)
+ 50;
char *file_content = (char*)MALLOCATE(size);
sprintf(file_content, pattern, self->header, privacy_syms, includes,
- content, self->footer);
+ c_data, prefix, vt_bootstrap, self->footer);
// Unlink then open file.
const char *src_dest = CFCHierarchy_get_source_dest(hierarchy);
@@ -306,7 +331,7 @@ S_write_parcel_c(CFCBindCore *self) {
FREEMEM(privacy_syms);
FREEMEM(includes);
- FREEMEM(content);
- FREEMEM(file_content);
+ FREEMEM(c_data);
+ FREEMEM(vt_bootstrap);
}
Modified: lucy/trunk/clownfish/src/CFCPerl.c
URL: http://svn.apache.org/viewvc/lucy/trunk/clownfish/src/CFCPerl.c?rev=1326105&r1=1326104&r2=1326105&view=diff
==============================================================================
--- lucy/trunk/clownfish/src/CFCPerl.c (original)
+++ lucy/trunk/clownfish/src/CFCPerl.c Sat Apr 14 14:04:17 2012
@@ -237,6 +237,7 @@ S_write_boot_c(CFCPerl *self) {
char *pound_includes = CFCUtil_strdup("");
char *registrations = CFCUtil_strdup("");
char *isa_pushes = CFCUtil_strdup("");
+ const char *prefix = CFCParcel_get_prefix(self->parcel);
for (size_t i = 0; ordered[i] != NULL; i++) {
CFCClass *klass = ordered[i];
@@ -312,6 +313,8 @@ S_write_boot_c(CFCPerl *self) {
"\n"
"void\n"
"%s() {\n"
+ " %sbootstrap_parcel();\n"
+ "\n"
" AV *isa;\n"
" cfish_ZombieCharBuf *alias = CFISH_ZCB_WRAP_STR(\"\", 0);\n"
"%s\n"
@@ -326,13 +329,14 @@ S_write_boot_c(CFCPerl *self) {
+ strlen(self->boot_h_file)
+ strlen(pound_includes)
+ strlen(self->boot_func)
+ + strlen(prefix)
+ strlen(registrations)
+ strlen(isa_pushes)
+ strlen(self->footer)
+ 100;
char *content = (char*)MALLOCATE(size);
sprintf(content, pattern, self->header, self->boot_h_file, pound_includes,
- self->boot_func, registrations, isa_pushes, self->footer);
+ self->boot_func, prefix, registrations, isa_pushes, self->footer);
CFCUtil_write_file(self->boot_c_path, content, strlen(content));
FREEMEM(content);
Modified: lucy/trunk/core/Lucy/Object/VTable.c
URL: http://svn.apache.org/viewvc/lucy/trunk/core/Lucy/Object/VTable.c?rev=1326105&r1=1326104&r2=1326105&view=diff
==============================================================================
--- lucy/trunk/core/Lucy/Object/VTable.c (original)
+++ lucy/trunk/core/Lucy/Object/VTable.c Sat Apr 14 14:04:17 2012
@@ -16,6 +16,7 @@
#define C_LUCY_VTABLE
#define C_LUCY_OBJ
+#define C_LUCY_CHARBUF
#define LUCY_USE_SHORT_NAMES
#define CHY_USE_SHORT_NAMES
@@ -40,6 +41,41 @@ S_scrunch_charbuf(CharBuf *source, CharB
LockFreeRegistry *VTable_registry = NULL;
+VTable*
+VTable_bootstrap(VTable *self, VTable *parent, const char *name, int flags,
+ void *x, size_t obj_alloc_size, void *callbacks,
+ cfish_method_t *methods) {
+ // Create CharBuf manually, since the CharBuf VTable might not be
+ // bootstrapped yet.
+ CharBuf *name_cb = (CharBuf*)Memory_wrapped_calloc(sizeof(CharBuf), 1);
+ size_t name_len = strlen(name);
+
+ name_cb->vtable = CHARBUF;
+ name_cb->ref.count = 1;
+ name_cb->ptr = (char*)MALLOCATE(name_len + 1);
+ name_cb->size = name_len;
+ name_cb->cap = name_len + 1;
+ strcpy(name_cb->ptr, name);
+
+ self->vtable = CFISH_VTABLE;
+ self->ref.count = 1;
+ self->parent = parent;
+ self->name = name_cb;
+ self->flags = flags;
+ self->x = x;
+ self->obj_alloc_size = obj_alloc_size;
+ self->callbacks = callbacks;
+
+ int n;
+ for (n = 0; methods[n]; ++n) {
+ self->methods[n] = methods[n];
+ }
+ self->vt_alloc_size = offsetof(cfish_VTable, methods)
+ + n * sizeof(cfish_method_t);
+
+ return self;
+}
+
void
VTable_destroy(VTable *self) {
THROW(ERR, "Insane attempt to destroy VTable for class '%o'", self->name);
Modified: lucy/trunk/core/Lucy/Object/VTable.cfh
URL: http://svn.apache.org/viewvc/lucy/trunk/core/Lucy/Object/VTable.cfh?rev=1326105&r1=1326104&r2=1326105&view=diff
==============================================================================
--- lucy/trunk/core/Lucy/Object/VTable.cfh (original)
+++ lucy/trunk/core/Lucy/Object/VTable.cfh Sat Apr 14 14:04:17 2012
@@ -37,6 +37,11 @@ class Lucy::Object::VTable inherits Lucy
inert LockFreeRegistry *registry;
inert size_t offset_of_parent;
+ inert VTable*
+ bootstrap(VTable *self, VTable *parent, const char *name, int flags,
+ void *x, size_t obj_alloc_size, void *callbacks,
+ cfish_method_t *methods);
+
/** 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.