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:03 UTC
[2/3] git commit: Rename Clownfish::VTable to Clownfish::Class
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");
}