Repository: lucy-clownfish Updated Branches: refs/heads/master d0babb78c -> f7960be90
Eliminate generation and usage of callbacks.h. * Declare OVERRIDE symbols in per-class header files. * Make signatures for invalid OVERRIDES match the original method. * Generate OVERRIDE symbols centrally rather than for each host. Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/c3df5a6a Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/c3df5a6a Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/c3df5a6a Branch: refs/heads/master Commit: c3df5a6ac10a0a7872039cd800772eb30c1be022 Parents: d0babb7 Author: Marvin Humphrey <[email protected]> Authored: Tue Mar 17 11:03:28 2015 -0700 Committer: Marvin Humphrey <[email protected]> Committed: Thu Mar 19 08:59:01 2015 -0700 ---------------------------------------------------------------------- compiler/src/CFCBindClass.c | 52 +++++++++++++++++++++++- compiler/src/CFCBindCore.c | 1 - compiler/src/CFCC.c | 44 ++------------------ compiler/src/CFCPerl.c | 85 +++++---------------------------------- compiler/src/CFCPerlMethod.c | 57 +++++++++++++------------- 5 files changed, 90 insertions(+), 149 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c3df5a6a/compiler/src/CFCBindClass.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCBindClass.c b/compiler/src/CFCBindClass.c index 2de2bd3..35b4efb 100644 --- a/compiler/src/CFCBindClass.c +++ b/compiler/src/CFCBindClass.c @@ -74,6 +74,10 @@ S_inert_var_declarations(CFCBindClass *self); static char* S_method_defs(CFCBindClass *self); +// Declare override symbols for functions which wrap host callbacks. +static char* +S_override_decs(CFCBindClass *self); + // Define short names for all of the symbols associated with this class. static char* S_short_names(CFCBindClass *self); @@ -195,6 +199,7 @@ S_to_c_header_dynamic(CFCBindClass *self) { char *inert_var_defs = S_inert_var_declarations(self); char *method_typedefs = S_method_typedefs(self); char *method_defs = S_method_defs(self); + char *override_decs = S_override_decs(self); char *short_names = S_short_names(self); char pattern[] = @@ -233,6 +238,11 @@ S_to_c_header_dynamic(CFCBindClass *self) { "\n" "%s\n" "\n" + "/* Declare callbacks for wrapping host overrides.\n" + " */\n" + "\n" + "%s\n" + "\n" "/* Define \"short names\" for this class's symbols.\n" " */\n" "\n" @@ -242,7 +252,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, - short_names); + override_decs, short_names); FREEMEM(ivars); FREEMEM(struct_def); @@ -645,6 +655,46 @@ S_method_defs(CFCBindClass *self) { return method_defs; } +static char* +S_override_decs(CFCBindClass *self) { + CFCMethod **fresh_methods = CFCClass_fresh_methods(self->client); + char *decs = CFCUtil_strdup(""); + char *nulls = CFCUtil_strdup(""); + + for (int i = 0; fresh_methods[i] != NULL; i++) { + CFCMethod *method = fresh_methods[i]; + if (CFCMethod_final(method) || !CFCMethod_novel(method)) { + continue; + } + const char *override_sym = CFCMethod_full_override_sym(method); + CFCType *return_type = CFCMethod_get_return_type(method); + CFCParamList *param_list = CFCMethod_get_param_list(method); + const char *ret_type_str = CFCType_to_c(return_type); + const char *params = CFCParamList_to_c(param_list); + char pattern[] = + "%s\n" + "%s(%s);\n"; + char *callback_dec + = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params); + decs = CFCUtil_cat(decs, callback_dec, NULL); + FREEMEM(callback_dec); + + nulls = CFCUtil_cat(nulls, "#define ", override_sym, " NULL\n", NULL); + } + + char pattern[] = + "#ifdef CFISH_NO_DYNAMIC_OVERRIDES\n" + "%s" + "#else\n" + "%s" + "#endif\n" + ; + char *content = CFCUtil_sprintf(pattern, nulls, decs); + + FREEMEM(nulls); + FREEMEM(decs); + return content; +} // Define short names for all of the symbols associated with this class. static char* http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c3df5a6a/compiler/src/CFCBindCore.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c index 5ad2ca2..5a55793 100644 --- a/compiler/src/CFCBindCore.c +++ b/compiler/src/CFCBindCore.c @@ -506,7 +506,6 @@ S_write_parcel_c(CFCBindCore *self, CFCParcel *parcel) { "\n" "%s" "\n" - "#include \"callbacks.h\"\n" "#include \"Clownfish/Class.h\"\n" // Needed for bootstrap. "%s\n" "\n" http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c3df5a6a/compiler/src/CFCC.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCC.c b/compiler/src/CFCC.c index adc6013..fbc8930 100644 --- a/compiler/src/CFCC.c +++ b/compiler/src/CFCC.c @@ -85,47 +85,7 @@ CFCC_destroy(CFCC *self) { */ void CFCC_write_callbacks(CFCC *self) { - CFCHierarchy *hierarchy = self->hierarchy; - CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy); - char *all_cb_decs = CFCUtil_strdup(""); - - for (int i = 0; ordered[i] != NULL; i++) { - CFCClass *klass = ordered[i]; - - if (!CFCClass_included(klass)) { - char *cb_decs = S_callback_decs(klass); - all_cb_decs = CFCUtil_cat(all_cb_decs, cb_decs, NULL); - FREEMEM(cb_decs); - } - } - - FREEMEM(ordered); - - const char pattern[] = - "%s\n" - "#ifndef CFCCALLBACKS_H\n" - "#define CFCCALLBACKS_H 1\n" - "\n" - "#include <stddef.h>\n" - "\n" - "%s" - "\n" - "#endif /* CFCCALLBACKS_H */\n" - "\n" - "%s\n" - "\n"; - char *file_content = CFCUtil_sprintf(pattern, self->c_header, all_cb_decs, - self->c_footer); - - // Unlink then write file. - const char *inc_dest = CFCHierarchy_get_include_dest(hierarchy); - char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "callbacks.h", inc_dest); - remove(filepath); - CFCUtil_write_file(filepath, file_content, strlen(file_content)); - FREEMEM(filepath); - - FREEMEM(all_cb_decs); - FREEMEM(file_content); + return; } static char* @@ -220,6 +180,8 @@ CFCC_write_hostdefs(CFCC *self) { "#define CFISH_OBJ_HEAD \\\n" " size_t refcount;\n" "\n" + "#define CFISH_NO_DYNAMIC_OVERRIDES\n" + "\n" "#endif /* H_CFISH_HOSTDEFS */\n" "\n" "%s\n"; http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c3df5a6a/compiler/src/CFCPerl.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerl.c b/compiler/src/CFCPerl.c index 983eab6..6464bdf 100644 --- a/compiler/src/CFCPerl.c +++ b/compiler/src/CFCPerl.c @@ -54,9 +54,6 @@ static void S_replace_double_colons(char *text, char replacement); static void -S_write_callbacks_h(CFCPerl *self); - -static void S_write_callbacks_c(CFCPerl *self); static const CFCMeta CFCPERL_META = { @@ -506,22 +503,16 @@ CFCPerl_write_bindings(CFCPerl *self) { void CFCPerl_write_callbacks(CFCPerl *self) { - S_write_callbacks_h(self); S_write_callbacks_c(self); } -/* Write the "callbacks.h" header file, which contains declarations of host - * callbacks. - */ static void -S_write_callbacks_h(CFCPerl *self) { - CFCParcel **parcels = CFCParcel_all_parcels(); - CFCHierarchy *hierarchy = self->hierarchy; - CFCClass **ordered = CFCHierarchy_ordered_classes(hierarchy); - char *includes = CFCUtil_strdup(""); - char *cb_decs = CFCUtil_strdup(""); - - for (int i = 0; parcels[i]; ++i) { +S_write_callbacks_c(CFCPerl *self) { + CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy); + CFCParcel **parcels = CFCParcel_all_parcels(); + char *includes = CFCUtil_strdup(""); + + for (int i = 0; parcels[i]; i++) { CFCParcel *parcel = parcels[i]; if (!CFCParcel_included(parcel)) { const char *prefix = CFCParcel_get_prefix(parcel); @@ -530,72 +521,13 @@ S_write_callbacks_h(CFCPerl *self) { } } - for (int i = 0; ordered[i] != NULL; i++) { - CFCClass *klass = ordered[i]; - if (CFCClass_included(klass)) { continue; } - - CFCMethod **fresh_methods = CFCClass_fresh_methods(klass); - for (int meth_num = 0; fresh_methods[meth_num] != NULL; meth_num++) { - CFCMethod *method = fresh_methods[meth_num]; - - // Declare callback. - if (CFCMethod_novel(method) && !CFCMethod_final(method)) { - char *cb_dec = CFCPerlMethod_callback_dec(method); - cb_decs = CFCUtil_cat(cb_decs, cb_dec, "\n", NULL); - FREEMEM(cb_dec); - } - } - } - - FREEMEM(ordered); - - const char pattern[] = - "%s\n" - "#ifndef CFCCALLBACKS_H\n" - "#define CFCCALLBACKS_H 1\n" - "\n" - "#ifdef __cplusplus\n" - "extern \"C\" {\n" - "#endif\n" - "\n" - "%s" - "\n" - "%s" - "\n" - "#ifdef __cplusplus\n" - "}\n" - "#endif\n" - "\n" - "#endif /* CFCCALLBACKS_H */\n" - "\n" - "%s\n" - "\n"; - char *file_content - = CFCUtil_sprintf(pattern, self->c_header, includes, cb_decs, - self->c_footer); - - // Unlink then write file. - const char *inc_dest = CFCHierarchy_get_include_dest(hierarchy); - char *filepath = CFCUtil_sprintf("%s" CHY_DIR_SEP "callbacks.h", inc_dest); - remove(filepath); - CFCUtil_write_file(filepath, file_content, strlen(file_content)); - FREEMEM(filepath); - - FREEMEM(includes); - FREEMEM(cb_decs); - FREEMEM(file_content); -} - -static void -S_write_callbacks_c(CFCPerl *self) { - CFCClass **ordered = CFCHierarchy_ordered_classes(self->hierarchy); static const char pattern[] = "%s" "\n" "#include \"XSBind.h\"\n" - "#include \"callbacks.h\"\n" "#include \"Clownfish/Err.h\"\n" "#include \"Clownfish/Obj.h\"\n" + "%s" "\n" "static void\n" "S_finish_callback_void(const char *meth_name) {\n" @@ -668,7 +600,7 @@ S_write_callbacks_c(CFCPerl *self) { " return retval;\n" "}\n" "\n"; - char *content = CFCUtil_sprintf(pattern, self->c_header); + char *content = CFCUtil_sprintf(pattern, self->c_header, includes); for (size_t i = 0; ordered[i] != NULL; i++) { CFCClass *klass = ordered[i]; @@ -697,6 +629,7 @@ S_write_callbacks_c(CFCPerl *self) { FREEMEM(filepath); FREEMEM(content); + FREEMEM(includes); FREEMEM(ordered); } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c3df5a6a/compiler/src/CFCPerlMethod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlMethod.c b/compiler/src/CFCPerlMethod.c index ef53b73..2a2aa5f 100644 --- a/compiler/src/CFCPerlMethod.c +++ b/compiler/src/CFCPerlMethod.c @@ -429,27 +429,15 @@ S_xsub_def_positional_args(CFCPerlMethod *self) { char* CFCPerlMethod_callback_dec(CFCMethod *method) { const char *override_sym = CFCMethod_full_override_sym(method); - - char *callback_dec; - if (!CFCPerlMethod_can_be_bound(method)) { - char pattern[] = - "void\n" - "%s(cfish_Obj *self);\n"; - callback_dec = CFCUtil_sprintf(pattern, override_sym); - } - else { - CFCType *return_type = CFCMethod_get_return_type(method); - CFCParamList *param_list = CFCMethod_get_param_list(method); - const char *ret_type_str = CFCType_to_c(return_type); - const char *params = CFCParamList_to_c(param_list); - - char pattern[] = - "%s\n" - "%s(%s);\n"; - callback_dec - = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params); - } - + CFCType *return_type = CFCMethod_get_return_type(method); + CFCParamList *param_list = CFCMethod_get_param_list(method); + const char *ret_type_str = CFCType_to_c(return_type); + const char *params = CFCParamList_to_c(param_list); + char pattern[] = + "%s\n" + "%s(%s);\n"; + char *callback_dec + = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params); return callback_dec; } @@ -605,19 +593,28 @@ S_callback_refcount_mods(CFCMethod *method) { static char* S_invalid_callback_def(CFCMethod *method) { - const char *override_sym = CFCMethod_full_override_sym(method); - char *full_method_sym = CFCMethod_full_method_sym(method, NULL); - + const char *override_sym = CFCMethod_full_override_sym(method); + char *full_method_sym = CFCMethod_full_method_sym(method, NULL); + CFCType *return_type = CFCMethod_get_return_type(method); + CFCParamList *param_list = CFCMethod_get_param_list(method); + const char *ret_type_str = CFCType_to_c(return_type); + const char *params = CFCParamList_to_c(param_list); + char *maybe_ret + = CFCType_is_void(return_type) + ? CFCUtil_sprintf("") + : CFCUtil_sprintf("CFISH_UNREACHABLE_RETURN(%s);\n", ret_type_str); char pattern[] = - "void\n" - "%s(cfish_Obj *self) {\n" + "%s\n" + "%s(%s) {\n" " CFISH_UNUSED_VAR(self);\n" " cfish_Err_invalid_callback(\"%s\");\n" - "}\n"; - char *callback_def - = CFCUtil_sprintf(pattern, override_sym, full_method_sym); - + "%s" + "}\n" + ; + char *callback_def = CFCUtil_sprintf(pattern, ret_type_str, override_sym, + params, full_method_sym, maybe_ret); FREEMEM(full_method_sym); + FREEMEM(maybe_ret); return callback_def; }
