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 2013/07/20 18:05:08 UTC
[lucy-commits] [1/4] git commit: refs/heads/master - Mark VTableSpec and MethSpec
arrays as const
Updated Branches:
refs/heads/master bf58f4a85 -> f089ae805
Mark VTableSpec and MethSpec arrays as const
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/38b92c30
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/38b92c30
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/38b92c30
Branch: refs/heads/master
Commit: 38b92c30f9941c61934b1937d06fe22f1d2708d4
Parents: 8b2c808
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Wed Jul 17 20:25:24 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 20 17:54:51 2013 +0200
----------------------------------------------------------------------
clownfish/compiler/src/CFCBindClass.c | 11 ++++++-----
clownfish/compiler/src/CFCBindCore.c | 8 ++++----
clownfish/runtime/core/Clownfish/VTable.c | 22 +++++++++++-----------
clownfish/runtime/core/Clownfish/VTable.cfh | 2 +-
4 files changed, 22 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/38b92c30/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index f0a86a2..f507596 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -312,7 +312,8 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
// symbol and then store a pointer to that symbol inside the
// VTableSpec struct.
novel_ms_var
- = CFCUtil_cat(novel_ms_var, "static cfish_NovelMethSpec ",
+ = CFCUtil_cat(novel_ms_var,
+ "static const cfish_NovelMethSpec ",
vt_var, "_NOVEL_METHS[] = {\n", NULL);
}
else {
@@ -327,8 +328,8 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
// Start an array of cfish_OverriddenMethSpec structs.
overridden_ms_var
= CFCUtil_cat(overridden_ms_var,
- "static cfish_OverriddenMethSpec ", vt_var,
- "_OVERRIDDEN_METHS[] = {\n", NULL);
+ "static const cfish_OverriddenMethSpec ",
+ vt_var, "_OVERRIDDEN_METHS[] = {\n", NULL);
}
else {
overridden_ms_var
@@ -343,8 +344,8 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
// Start an array of cfish_InheritedMethSpec structs.
inherited_ms_var
= CFCUtil_cat(inherited_ms_var,
- "static cfish_InheritedMethSpec ", vt_var,
- "_INHERITED_METHS[] = {\n", NULL);
+ "static const cfish_InheritedMethSpec ",
+ vt_var, "_INHERITED_METHS[] = {\n", NULL);
}
else {
inherited_ms_var = CFCUtil_cat(inherited_ms_var, ",\n", NULL);
http://git-wip-us.apache.org/repos/asf/lucy/blob/38b92c30/clownfish/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindCore.c b/clownfish/compiler/src/CFCBindCore.c
index 41f634b..af28e6a 100644
--- a/clownfish/compiler/src/CFCBindCore.c
+++ b/clownfish/compiler/src/CFCBindCore.c
@@ -250,9 +250,9 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
" uint32_t num_novel_meths;\n"
" uint32_t num_overridden_meths;\n"
" uint32_t num_inherited_meths;\n"
- " cfish_NovelMethSpec *novel_meth_specs;\n"
- " cfish_OverriddenMethSpec *overridden_meth_specs;\n"
- " cfish_InheritedMethSpec *inherited_meth_specs;\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"
"\n"
"#ifdef CFISH_USE_SHORT_NAMES\n"
@@ -355,7 +355,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
char *includes = CFCUtil_strdup("");
char *c_data = CFCUtil_strdup("");
char *vt_specs = CFCUtil_strdup(
- "static cfish_VTableSpec vtable_specs[] = {\n");
+ "static const cfish_VTableSpec vtable_specs[] = {\n");
int num_specs = 0;
CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy);
for (int i = 0; ordered[i] != NULL; i++) {
http://git-wip-us.apache.org/repos/asf/lucy/blob/38b92c30/clownfish/runtime/core/Clownfish/VTable.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/VTable.c b/clownfish/runtime/core/Clownfish/VTable.c
index 11222e9..58391b2 100644
--- a/clownfish/runtime/core/Clownfish/VTable.c
+++ b/clownfish/runtime/core/Clownfish/VTable.c
@@ -52,7 +52,7 @@ S_claim_parcel_id(void);
LockFreeRegistry *VTable_registry = NULL;
void
-VTable_bootstrap(VTableSpec *specs, size_t num_specs)
+VTable_bootstrap(const VTableSpec *specs, size_t num_specs)
{
int32_t parcel_id = S_claim_parcel_id();
@@ -64,8 +64,8 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
* - Initialize method pointers.
*/
for (size_t i = 0; i < num_specs; ++i) {
- VTableSpec *spec = &specs[i];
- VTable *parent = spec->parent ? *spec->parent : NULL;
+ const VTableSpec *spec = &specs[i];
+ VTable *parent = spec->parent ? *spec->parent : NULL;
size_t ivars_offset = 0;
if (spec->ivars_offset_ptr != NULL) {
@@ -103,18 +103,18 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
}
for (size_t i = 0; i < spec->num_inherited_meths; ++i) {
- InheritedMethSpec *mspec = &spec->inherited_meth_specs[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) {
- OverriddenMethSpec *mspec = &spec->overridden_meth_specs[i];
+ const OverriddenMethSpec *mspec = &spec->overridden_meth_specs[i];
*mspec->offset = *mspec->parent_offset;
VTable_override(vtable, mspec->func, *mspec->offset);
}
for (size_t i = 0; i < spec->num_novel_meths; ++i) {
- NovelMethSpec *mspec = &spec->novel_meth_specs[i];
+ const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
*mspec->offset = novel_offset;
novel_offset += sizeof(cfish_method_t);
VTable_override(vtable, mspec->func, *mspec->offset);
@@ -128,8 +128,8 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
* - Initialize refcount.
*/
for (size_t i = 0; i < num_specs; ++i) {
- VTableSpec *spec = &specs[i];
- VTable *vtable = *spec->vtable;
+ const VTableSpec *spec = &specs[i];
+ VTable *vtable = *spec->vtable;
VTable_init_obj(VTABLE, vtable);
}
@@ -141,14 +141,14 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
* - Register vtable.
*/
for (size_t i = 0; i < num_specs; ++i) {
- VTableSpec *spec = &specs[i];
- VTable *vtable = *spec->vtable;
+ const VTableSpec *spec = &specs[i];
+ VTable *vtable = *spec->vtable;
vtable->name = CB_newf("%s", spec->name);
vtable->methods = VA_new(0);
for (size_t i = 0; i < spec->num_novel_meths; ++i) {
- NovelMethSpec *mspec = &spec->novel_meth_specs[i];
+ const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
CharBuf *name = CB_newf("%s", mspec->name);
Method *method = Method_new(name, mspec->callback_func,
*mspec->offset);
http://git-wip-us.apache.org/repos/asf/lucy/blob/38b92c30/clownfish/runtime/core/Clownfish/VTable.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/VTable.cfh b/clownfish/runtime/core/Clownfish/VTable.cfh
index 6d62f44..c065495 100644
--- a/clownfish/runtime/core/Clownfish/VTable.cfh
+++ b/clownfish/runtime/core/Clownfish/VTable.cfh
@@ -38,7 +38,7 @@ class Clownfish::VTable inherits Clownfish::Obj {
inert size_t offset_of_parent;
inert void
- bootstrap(cfish_VTableSpec *specs, size_t num_specs);
+ bootstrap(const cfish_VTableSpec *specs, size_t num_specs);
/** Return a singleton. If a VTable can be found in the registry based on
* the supplied class name, it will be returned. Otherwise, a new VTable
[lucy-commits] [4/4] git commit: refs/heads/master - Adjust some comments
Posted by nw...@apache.org.
Adjust some comments
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/f089ae80
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/f089ae80
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/f089ae80
Branch: refs/heads/master
Commit: f089ae8051e55fb53dc14d7ff644a2c734fdbb64
Parents: 38b92c3
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Sat Jul 20 18:04:25 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 20 18:04:25 2013 +0200
----------------------------------------------------------------------
clownfish/compiler/src/CFCBindCore.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/f089ae80/clownfish/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindCore.c b/clownfish/compiler/src/CFCBindCore.c
index af28e6a..5a7c94a 100644
--- a/clownfish/compiler/src/CFCBindCore.c
+++ b/clownfish/compiler/src/CFCBindCore.c
@@ -418,7 +418,7 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) {
char pattern[] =
"%s\n"
"\n"
- "#define C_CFISH_VTABLE\n" // Needed for method_ptrs offset.
+ "#define C_CFISH_VTABLE\n" // Needed for abstract methods.
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"%s\n"
@@ -428,7 +428,7 @@ 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 method_ptrs offset.
+ "#include \"Clownfish/VTable.h\"\n" // Needed for bootstrap.
"%s\n"
"\n"
"%s\n"
[lucy-commits] [3/4] git commit: refs/heads/master - Carry over novel flag when
finalizing methods
Posted by nw...@apache.org.
Carry over novel flag when finalizing methods
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/0f184c2a
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/0f184c2a
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/0f184c2a
Branch: refs/heads/master
Commit: 0f184c2a5a7243b3653d82f79a95bd1fc48f7dbd
Parents: bf58f4a
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Wed Jul 17 19:50:44 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 20 17:54:51 2013 +0200
----------------------------------------------------------------------
clownfish/compiler/src/CFCMethod.c | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/0f184c2a/clownfish/compiler/src/CFCMethod.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCMethod.c b/clownfish/compiler/src/CFCMethod.c
index 595cab7..9710209 100644
--- a/clownfish/compiler/src/CFCMethod.c
+++ b/clownfish/compiler/src/CFCMethod.c
@@ -229,6 +229,7 @@ CFCMethod_finalize(CFCMethod *self) {
self->function.param_list,
self->function.docucomment, true,
self->is_abstract);
+ finalized->is_novel = self->is_novel;
return finalized;
}
[lucy-commits] [2/4] git commit: refs/heads/master - Dynamic method offsets
Posted by nw...@apache.org.
Dynamic method offsets
Create separate specs for novel, overridden, and inherited methods and
use them to initialize method offsets dynamically during bootstrap.
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/8b2c8081
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/8b2c8081
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/8b2c8081
Branch: refs/heads/master
Commit: 8b2c8081edd864ce58aeb2cd745705ff4b303d00
Parents: 0f184c2
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Mon Jul 15 01:55:07 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Sat Jul 20 17:54:51 2013 +0200
----------------------------------------------------------------------
clownfish/compiler/perl/lib/Clownfish/CFC.xs | 20 ++-
clownfish/compiler/src/CFCBindClass.c | 192 +++++++++++++++-------
clownfish/compiler/src/CFCBindCore.c | 39 +++--
clownfish/compiler/src/CFCBindMethod.c | 61 +++++--
clownfish/compiler/src/CFCBindMethod.h | 18 +-
clownfish/runtime/core/Clownfish/VTable.c | 43 +++--
6 files changed, 269 insertions(+), 104 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/8b2c8081/clownfish/compiler/perl/lib/Clownfish/CFC.xs
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/lib/Clownfish/CFC.xs b/clownfish/compiler/perl/lib/Clownfish/CFC.xs
index 1b36124..fafe3c3 100644
--- a/clownfish/compiler/perl/lib/Clownfish/CFC.xs
+++ b/clownfish/compiler/perl/lib/Clownfish/CFC.xs
@@ -1971,10 +1971,26 @@ CODE:
OUTPUT: RETVAL
SV*
-_spec_def(meth)
+_novel_spec_def(meth)
CFCMethod *meth;
CODE:
- RETVAL = S_sv_eat_c_string(CFCBindMeth_spec_def(meth));
+ RETVAL = S_sv_eat_c_string(CFCBindMeth_novel_spec_def(meth));
+OUTPUT: RETVAL
+
+SV*
+_overridden_spec_def(meth, klass)
+ CFCMethod *meth;
+ CFCClass *klass;
+CODE:
+ RETVAL = S_sv_eat_c_string(CFCBindMeth_overridden_spec_def(meth, klass));
+OUTPUT: RETVAL
+
+SV*
+_inherited_spec_def(meth, klass)
+ CFCMethod *meth;
+ CFCClass *klass;
+CODE:
+ RETVAL = S_sv_eat_c_string(CFCBindMeth_inherited_spec_def(meth, klass));
OUTPUT: RETVAL
MODULE = Clownfish::CFC PACKAGE = Clownfish::CFC::Binding::Core::Aliases
http://git-wip-us.apache.org/repos/asf/lucy/blob/8b2c8081/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index 8b72db1..f0a86a2 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -34,7 +34,6 @@
struct CFCBindClass {
CFCBase base;
CFCClass *client;
- char *method_specs_var;
char *short_names_macro;
};
@@ -91,9 +90,7 @@ CFCBindClass_init(CFCBindClass *self, CFCClass *client) {
CFCUTIL_NULL_CHECK(client);
self->client = (CFCClass*)CFCBase_incref((CFCBase*)client);
- const char *full_vtable_var = CFCClass_full_vtable_var(client);
const char *PREFIX = CFCClass_get_PREFIX(client);
- self->method_specs_var = CFCUtil_sprintf("%s_METHODS", full_vtable_var);
self->short_names_macro = CFCUtil_sprintf("%sUSE_SHORT_NAMES", PREFIX);
return self;
@@ -101,7 +98,6 @@ CFCBindClass_init(CFCBindClass *self, CFCClass *client) {
void
CFCBindClass_destroy(CFCBindClass *self) {
- FREEMEM(self->method_specs_var);
FREEMEM(self->short_names_macro);
CFCBase_decref((CFCBase*)self->client);
CFCBase_destroy((CFCBase*)self);
@@ -270,6 +266,7 @@ S_to_c_header_dynamic(CFCBindClass *self) {
char*
CFCBindClass_to_c_data(CFCBindClass *self) {
CFCClass *client = self->client;
+ const char *class_name = CFCClass_get_class_name(client);
if (CFCClass_inert(client)) {
return CFCUtil_strdup(CFCClass_get_autocode(client));
@@ -281,55 +278,92 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
const char *vt_var = CFCClass_full_vtable_var(client);
CFCMethod **methods = CFCClass_methods(client);
- CFCMethod **fresh_methods = CFCClass_fresh_methods(client);
- char *offsets = CFCUtil_strdup("");
- char *method_defs = CFCUtil_strdup("");
- char *ms_var = CFCUtil_strdup("");
+ char *offsets = CFCUtil_strdup("");
+ char *method_defs = CFCUtil_strdup("");
+ char *novel_ms_var = CFCUtil_strdup("");
+ char *overridden_ms_var = CFCUtil_strdup("");
+ char *inherited_ms_var = CFCUtil_strdup("");
for (int meth_num = 0; methods[meth_num] != NULL; meth_num++) {
CFCMethod *method = methods[meth_num];
+
+ // Define method offset variable.
char *full_offset_sym = CFCMethod_full_offset_sym(method, client);
- // Create offset in bytes for the method from the top of the VTable
- // object.
- const char pattern[] =
- "size_t %s = offsetof(cfish_VTable, method_ptrs)"
- " + %d * sizeof(cfish_method_t);\n";
- char *offset = CFCUtil_sprintf(pattern, full_offset_sym, meth_num);
- offsets = CFCUtil_cat(offsets, offset, NULL);
+ offsets = CFCUtil_cat(offsets, "size_t ", full_offset_sym, ";\n",
+ NULL);
FREEMEM(full_offset_sym);
- FREEMEM(offset);
- }
- if (fresh_methods[0] != NULL) {
- /* Start an array of cfish_MethodSpec structs. Since C89 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. */
- ms_var = CFCUtil_cat(ms_var, "static cfish_MethodSpec ",
- self->method_specs_var, "[] = {\n", NULL);
-
- for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) {
- CFCMethod *method = fresh_methods[meth_num];
-
- // Create a default implementation for abstract methods.
- if (CFCMethod_abstract(method)) {
- char *method_def = CFCBindMeth_abstract_method_def(method);
- method_defs = CFCUtil_cat(method_defs, method_def, "\n", NULL);
- FREEMEM(method_def);
- }
+ const char *meth_class_name = CFCMethod_get_class_name(method);
+ int is_fresh = strcmp(class_name, meth_class_name) == 0;
- // Define MethodSpec struct.
- if (meth_num != 0) {
- ms_var = CFCUtil_cat(ms_var, ",\n", NULL);
+ // Create a default implementation for abstract methods.
+ if (is_fresh && CFCMethod_abstract(method)) {
+ char *method_def = CFCBindMeth_abstract_method_def(method);
+ method_defs = CFCUtil_cat(method_defs, method_def, "\n", NULL);
+ FREEMEM(method_def);
+ }
+
+ if (is_fresh && CFCMethod_novel(method)) {
+ if (novel_ms_var[0] == '\0') {
+ // Start an array of cfish_NovelMethSpec structs. Since C89
+ // 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.
+ novel_ms_var
+ = CFCUtil_cat(novel_ms_var, "static cfish_NovelMethSpec ",
+ vt_var, "_NOVEL_METHS[] = {\n", NULL);
+ }
+ else {
+ novel_ms_var = CFCUtil_cat(novel_ms_var, ",\n", NULL);
+ }
+ char *ms_def = CFCBindMeth_novel_spec_def(method);
+ novel_ms_var = CFCUtil_cat(novel_ms_var, ms_def, NULL);
+ FREEMEM(ms_def);
+ }
+ else if (is_fresh) {
+ if (overridden_ms_var[0] == '\0') {
+ // Start an array of cfish_OverriddenMethSpec structs.
+ overridden_ms_var
+ = CFCUtil_cat(overridden_ms_var,
+ "static cfish_OverriddenMethSpec ", vt_var,
+ "_OVERRIDDEN_METHS[] = {\n", NULL);
+ }
+ else {
+ overridden_ms_var
+ = CFCUtil_cat(overridden_ms_var, ",\n", NULL);
}
- char *ms_def = CFCBindMeth_spec_def(method);
- ms_var = CFCUtil_cat(ms_var, ms_def, NULL);
+ char *ms_def = CFCBindMeth_overridden_spec_def(method, client);
+ overridden_ms_var = CFCUtil_cat(overridden_ms_var, ms_def, NULL);
FREEMEM(ms_def);
}
+ else {
+ if (inherited_ms_var[0] == '\0') {
+ // Start an array of cfish_InheritedMethSpec structs.
+ inherited_ms_var
+ = CFCUtil_cat(inherited_ms_var,
+ "static cfish_InheritedMethSpec ", vt_var,
+ "_INHERITED_METHS[] = {\n", NULL);
+ }
+ else {
+ inherited_ms_var = CFCUtil_cat(inherited_ms_var, ",\n", NULL);
+ }
+ char *ms_def = CFCBindMeth_inherited_spec_def(method, client);
+ inherited_ms_var = CFCUtil_cat(inherited_ms_var, ms_def, NULL);
+ FREEMEM(ms_def);
+ }
+ }
- // Close MethodSpec array definition.
- ms_var = CFCUtil_cat(ms_var, "\n};\n", NULL);
+ // Close MethSpec array definitions.
+ if (novel_ms_var[0] != '\0') {
+ novel_ms_var = CFCUtil_cat(novel_ms_var, "\n};\n\n", NULL);
+ }
+ if (overridden_ms_var[0] != '\0') {
+ overridden_ms_var = CFCUtil_cat(overridden_ms_var, "\n};\n\n", NULL);
+ }
+ if (inherited_ms_var[0] != '\0') {
+ inherited_ms_var = CFCUtil_cat(inherited_ms_var, "\n};\n\n", NULL);
}
const char pattern[] =
@@ -350,12 +384,12 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
"\n"
"%s\n"
"\n"
- "/* Define the cfish_MethodSpec structs used during VTable\n"
- " * initialization.\n"
+ "/* Define the MethSpec structs used during VTable initialization.\n"
" */\n"
"\n"
- "%s\n"
- "\n"
+ "%s"
+ "%s"
+ "%s"
"/* Define this class's VTable.\n"
" */\n"
"\n"
@@ -366,13 +400,16 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
"\n"
"%s\n"
"\n";
- char *code = CFCUtil_sprintf(pattern, ivars_offset, offsets, method_defs,
- ms_var, vt_var, autocode);
+ char *code
+ = CFCUtil_sprintf(pattern, ivars_offset, offsets, method_defs,
+ novel_ms_var, overridden_ms_var, inherited_ms_var,
+ vt_var, autocode);
- FREEMEM(fresh_methods);
FREEMEM(offsets);
FREEMEM(method_defs);
- FREEMEM(ms_var);
+ FREEMEM(novel_ms_var);
+ FREEMEM(overridden_ms_var);
+ FREEMEM(inherited_ms_var);
return code;
}
@@ -441,16 +478,37 @@ CFCBindClass_spec_def(CFCBindClass *self) {
parent_ref = CFCUtil_strdup("NULL");
}
- int num_fresh = 0;
- int num_novel = 0;
- CFCMethod **fresh_methods = CFCClass_fresh_methods(client);
- for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) {
- CFCMethod *method = fresh_methods[meth_num];
- ++num_fresh;
- if (CFCMethod_novel(method)) { ++num_novel; }
+ int num_novel = 0;
+ int num_overridden = 0;
+ int num_inherited = 0;
+ CFCMethod **methods = CFCClass_methods(client);
+
+ for (int meth_num = 0; methods[meth_num] != NULL; meth_num++) {
+ CFCMethod *method = methods[meth_num];
+ const char *meth_class_name = CFCMethod_get_class_name(method);
+
+ if (strcmp(class_name, meth_class_name) == 0) {
+ if (CFCMethod_novel(method)) {
+ ++num_novel;
+ }
+ else {
+ ++num_overridden;
+ }
+ }
+ else {
+ ++num_inherited;
+ }
}
- FREEMEM(fresh_methods);
- const char *ms_var = num_fresh ? self->method_specs_var : "NULL";
+
+ char *novel_ms_var = num_novel
+ ? CFCUtil_sprintf("%s_NOVEL_METHS", vt_var)
+ : CFCUtil_strdup("NULL");
+ char *overridden_ms_var = num_overridden
+ ? CFCUtil_sprintf("%s_OVERRIDDEN_METHS", vt_var)
+ : CFCUtil_strdup("NULL");
+ char *inherited_ms_var = num_inherited
+ ? CFCUtil_sprintf("%s_INHERITED_METHS", vt_var)
+ : CFCUtil_strdup("NULL");
const char *ivars_or_not = strcmp(prefix, "cfish_") == 0
? struct_sym : ivars_struct;
@@ -463,15 +521,23 @@ CFCBindClass_spec_def(CFCBindClass *self) {
" \"%s\", /* name */\n"
" sizeof(%s), /* ivars_size */\n"
" &%s, /* ivars_offset_ptr */\n"
- " %d, /* num_fresh */\n"
" %d, /* num_novel */\n"
- " %s /* method_specs */\n"
+ " %d, /* num_overridden */\n"
+ " %d, /* num_inherited */\n"
+ " %s, /* novel_meth_specs */\n"
+ " %s, /* overridden_meth_specs */\n"
+ " %s /* inherited_meth_specs */\n"
" }";
- char *code = CFCUtil_sprintf(pattern, vt_var, parent_ref, class_name,
- ivars_or_not, ivars_offset_name,
- num_fresh, num_novel, ms_var);
+ char *code
+ = CFCUtil_sprintf(pattern, vt_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);
FREEMEM(parent_ref);
+ FREEMEM(novel_ms_var);
+ FREEMEM(overridden_ms_var);
+ FREEMEM(inherited_ms_var);
return code;
}
http://git-wip-us.apache.org/repos/asf/lucy/blob/8b2c8081/clownfish/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindCore.c b/clownfish/compiler/src/CFCBindCore.c
index 7abc4c2..41f634b 100644
--- a/clownfish/compiler/src/CFCBindCore.c
+++ b/clownfish/compiler/src/CFCBindCore.c
@@ -223,30 +223,45 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
"/* Structs for VTable initialization.\n"
" */\n"
"\n"
- "typedef struct cfish_MethodSpec {\n"
- " int is_novel;\n"
+ "typedef struct cfish_NovelMethSpec {\n"
+ " size_t *offset;\n"
" const char *name;\n"
" cfish_method_t func;\n"
" cfish_method_t callback_func;\n"
+ "} cfish_NovelMethSpec;\n"
+ "\n"
+ "typedef struct cfish_OverriddenMethSpec {\n"
" size_t *offset;\n"
- "} cfish_MethodSpec;\n"
+ " size_t *parent_offset;\n"
+ " cfish_method_t func;\n"
+ "} cfish_OverriddenMethSpec;\n"
+ "\n"
+ "typedef struct cfish_InheritedMethSpec {\n"
+ " size_t *offset;\n"
+ " 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"
- " size_t num_fresh;\n"
- " size_t num_novel;\n"
- " cfish_MethodSpec *method_specs;\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"
+ " cfish_NovelMethSpec *novel_meth_specs;\n"
+ " cfish_OverriddenMethSpec *overridden_meth_specs;\n"
+ " cfish_InheritedMethSpec *inherited_meth_specs;\n"
"} cfish_VTableSpec;\n"
"\n"
"#ifdef CFISH_USE_SHORT_NAMES\n"
" #define METHOD_PTR CFISH_METHOD_PTR\n"
" #define SUPER_METHOD_PTR CFISH_SUPER_METHOD_PTR\n"
" #define OVERRIDDEN CFISH_OVERRIDDEN\n"
- " #define MethodSpec cfish_MethodSpec\n"
+ " #define NovelMethSpec cfish_NovelMethSpec\n"
+ " #define OverriddenMethSpec cfish_OverriddenMethSpec\n"
+ " #define InheritedMethSpec cfish_InheritedMethSpec\n"
" #define VTableSpec cfish_VTableSpec\n"
"#endif\n"
"\n";
http://git-wip-us.apache.org/repos/asf/lucy/blob/8b2c8081/clownfish/compiler/src/CFCBindMethod.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindMethod.c b/clownfish/compiler/src/CFCBindMethod.c
index c2214a1..3669b04 100644
--- a/clownfish/compiler/src/CFCBindMethod.c
+++ b/clownfish/compiler/src/CFCBindMethod.c
@@ -146,13 +146,12 @@ CFCBindMeth_typedef_dec(struct CFCMethod *method, CFCClass *klass) {
}
char*
-CFCBindMeth_spec_def(CFCMethod *method) {
- const char *macro_sym = CFCMethod_get_macro_sym(method);
- const char *impl_sym = CFCMethod_implementing_func_sym(method);
- int is_novel = CFCMethod_novel(method);
+CFCBindMeth_novel_spec_def(CFCMethod *method) {
+ const char *macro_sym = CFCMethod_get_macro_sym(method);
+ const char *impl_sym = CFCMethod_implementing_func_sym(method);
const char *full_override_sym = "NULL";
- if (is_novel && !CFCMethod_final(method)) {
+ if (!CFCMethod_final(method)) {
full_override_sym = CFCMethod_full_override_sym(method);
}
@@ -160,20 +159,62 @@ CFCBindMeth_spec_def(CFCMethod *method) {
char pattern[] =
" {\n"
- " %d, /* is_novel */\n"
+ " &%s, /* offset */\n"
" \"%s\", /* name */\n"
" (cfish_method_t)%s, /* func */\n"
- " (cfish_method_t)%s, /* callback_func */\n"
- " &%s /* offset */\n"
+ " (cfish_method_t)%s /* callback_func */\n"
" }";
char *def
- = CFCUtil_sprintf(pattern, is_novel, macro_sym, impl_sym,
- full_override_sym, full_offset_sym);
+ = CFCUtil_sprintf(pattern, full_offset_sym, macro_sym, impl_sym,
+ full_override_sym);
FREEMEM(full_offset_sym);
return def;
}
+char*
+CFCBindMeth_overridden_spec_def(CFCMethod *method, CFCClass *klass) {
+ const char *impl_sym = CFCMethod_implementing_func_sym(method);
+
+ char *full_offset_sym = CFCMethod_full_offset_sym(method, NULL);
+
+ CFCClass *parent = CFCClass_get_parent(klass);
+ char *parent_offset_sym = CFCMethod_full_offset_sym(method, parent);
+
+ char pattern[] =
+ " {\n"
+ " &%s, /* offset */\n"
+ " &%s, /* parent_offset */\n"
+ " (cfish_method_t)%s /* func */\n"
+ " }";
+ char *def
+ = CFCUtil_sprintf(pattern, full_offset_sym, parent_offset_sym,
+ impl_sym);
+
+ FREEMEM(full_offset_sym);
+ FREEMEM(parent_offset_sym);
+ return def;
+}
+
+char*
+CFCBindMeth_inherited_spec_def(CFCMethod *method, CFCClass *klass) {
+ char *full_offset_sym = CFCMethod_full_offset_sym(method, klass);
+
+ CFCClass *parent = CFCClass_get_parent(klass);
+ char *parent_offset_sym = CFCMethod_full_offset_sym(method, parent);
+
+ char pattern[] =
+ " {\n"
+ " &%s, /* offset */\n"
+ " &%s /* parent_offset */\n"
+ " }";
+ char *def = CFCUtil_sprintf(pattern, full_offset_sym, parent_offset_sym);
+
+ FREEMEM(full_offset_sym);
+ FREEMEM(parent_offset_sym);
+ return def;
+}
+
static char*
S_build_unused_vars(CFCVariable **vars) {
char *unused = CFCUtil_strdup("");
http://git-wip-us.apache.org/repos/asf/lucy/blob/8b2c8081/clownfish/compiler/src/CFCBindMethod.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindMethod.h b/clownfish/compiler/src/CFCBindMethod.h
index 85945da..9f2f256 100644
--- a/clownfish/compiler/src/CFCBindMethod.h
+++ b/clownfish/compiler/src/CFCBindMethod.h
@@ -44,11 +44,25 @@ CFCBindMeth_method_def(struct CFCMethod *method, struct CFCClass *klass);
char*
CFCBindMeth_typedef_dec(struct CFCMethod *method, struct CFCClass *klass);
-/** Return C code defining the MethodSpec object for this method, which
+/** Return C code defining the MethSpec object for a novel method, which
* is used during VTable initialization.
*/
char*
-CFCBindMeth_spec_def(struct CFCMethod *method);
+CFCBindMeth_novel_spec_def(struct CFCMethod *method);
+
+/** Return C code defining the MethSpec object for an overridden method,
+ * which is used during VTable 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.
+ */
+char*
+CFCBindMeth_inherited_spec_def(struct CFCMethod *method,
+ struct CFCClass *klass);
/** Return C code implementing a version of the method which throws an
* "abstract method" error at runtime, for methods which are declared as
http://git-wip-us.apache.org/repos/asf/lucy/blob/8b2c8081/clownfish/runtime/core/Clownfish/VTable.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/VTable.c b/clownfish/runtime/core/Clownfish/VTable.c
index 268664c..11222e9 100644
--- a/clownfish/runtime/core/Clownfish/VTable.c
+++ b/clownfish/runtime/core/Clownfish/VTable.c
@@ -82,10 +82,12 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
}
}
- size_t vt_alloc_size = parent
- ? parent->vt_alloc_size
- : offsetof(VTable, method_ptrs);
- vt_alloc_size += spec->num_novel * sizeof(cfish_method_t);
+ size_t novel_offset = parent
+ ? parent->vt_alloc_size
+ : offsetof(VTable, method_ptrs);
+ size_t vt_alloc_size = novel_offset
+ + spec->num_novel_meths
+ * sizeof(cfish_method_t);
VTable *vtable = (VTable*)Memory_wrapped_calloc(vt_alloc_size, 1);
vtable->parent = parent;
@@ -100,8 +102,21 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
memcpy(vtable->method_ptrs, parent->method_ptrs, parent_ptrs_size);
}
- for (size_t i = 0; i < spec->num_fresh; ++i) {
- MethodSpec *mspec = &spec->method_specs[i];
+ for (size_t i = 0; i < spec->num_inherited_meths; ++i) {
+ InheritedMethSpec *mspec = &spec->inherited_meth_specs[i];
+ *mspec->offset = *mspec->parent_offset;
+ }
+
+ for (size_t i = 0; i < spec->num_overridden_meths; ++i) {
+ OverriddenMethSpec *mspec = &spec->overridden_meth_specs[i];
+ *mspec->offset = *mspec->parent_offset;
+ VTable_override(vtable, mspec->func, *mspec->offset);
+ }
+
+ for (size_t i = 0; i < spec->num_novel_meths; ++i) {
+ NovelMethSpec *mspec = &spec->novel_meth_specs[i];
+ *mspec->offset = novel_offset;
+ novel_offset += sizeof(cfish_method_t);
VTable_override(vtable, mspec->func, *mspec->offset);
}
@@ -132,15 +147,13 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
vtable->name = CB_newf("%s", spec->name);
vtable->methods = VA_new(0);
- for (size_t i = 0; i < spec->num_fresh; ++i) {
- MethodSpec *mspec = &spec->method_specs[i];
- if (mspec->is_novel) {
- CharBuf *name = CB_newf("%s", mspec->name);
- Method *method = Method_new(name, mspec->callback_func,
- *mspec->offset);
- VA_Push(vtable->methods, (Obj*)method);
- DECREF(name);
- }
+ for (size_t i = 0; i < spec->num_novel_meths; ++i) {
+ NovelMethSpec *mspec = &spec->novel_meth_specs[i];
+ CharBuf *name = CB_newf("%s", mspec->name);
+ Method *method = Method_new(name, mspec->callback_func,
+ *mspec->offset);
+ VA_Push(vtable->methods, (Obj*)method);
+ DECREF(name);
}
VTable_add_to_registry(vtable);