Simplify invalid callbacks Invalid callbacks can be made void functions taking only a cfish_Obj parameter.
To reduce code size, the invalid callbacks call a helper function in Err. Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/d9feac00 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/d9feac00 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/d9feac00 Branch: refs/heads/master Commit: d9feac00ad68094fabb66d950acfc5ab4c917928 Parents: c64e94d Author: Nick Wellnhofer <[email protected]> Authored: Sun Jan 4 23:24:13 2015 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Mon Jan 5 00:30:47 2015 +0100 ---------------------------------------------------------------------- compiler/src/CFCPerlMethod.c | 95 +++++++++-------------------------- runtime/core/Clownfish/Err.c | 5 ++ runtime/core/Clownfish/Err.cfh | 5 ++ runtime/perl/t/binding/019-obj.t | 11 +++- 4 files changed, 45 insertions(+), 71 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d9feac00/compiler/src/CFCPerlMethod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlMethod.c b/compiler/src/CFCPerlMethod.c index e39878c..ef53b73 100644 --- a/compiler/src/CFCPerlMethod.c +++ b/compiler/src/CFCPerlMethod.c @@ -53,20 +53,6 @@ S_xsub_def_labeled_params(CFCPerlMethod *self); static char* S_xsub_def_positional_args(CFCPerlMethod *self); -/* Take a NULL-terminated list of CFCVariables and build up a string of - * directives like: - * - * UNUSED_VAR(var1); - * UNUSED_VAR(var2); - */ -static char* -S_build_unused_vars(CFCVariable **vars); - -/* Create an unreachable return statement if necessary, in order to thwart - * compiler warnings. */ -static char* -S_maybe_unreachable(CFCType *return_type); - /* Generate code which converts C types to Perl types and pushes arguments * onto the Perl stack. */ @@ -442,16 +428,27 @@ S_xsub_def_positional_args(CFCPerlMethod *self) { char* CFCPerlMethod_callback_dec(CFCMethod *method) { - CFCType *return_type = CFCMethod_get_return_type(method); - const char *ret_type_str = CFCType_to_c(return_type); const char *override_sym = CFCMethod_full_override_sym(method); - const char *params = CFCParamList_to_c(CFCMethod_get_param_list(method)); - char pattern[] = - "%s\n" - "%s(%s);\n"; - char *callback_dec - = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params); + 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); + } return callback_dec; } @@ -491,36 +488,6 @@ CFCPerlMethod_callback_def(CFCMethod *method) { } static char* -S_build_unused_vars(CFCVariable **vars) { - char *unused = CFCUtil_strdup(""); - - for (int i = 0; vars[i] != NULL; i++) { - const char *var_name = CFCVariable_micro_sym(vars[i]); - size_t size = strlen(unused) + strlen(var_name) + 80; - unused = (char*)REALLOCATE(unused, size); - strcat(unused, "\n CFISH_UNUSED_VAR("); - strcat(unused, var_name); - strcat(unused, ");"); - } - - return unused; -} - -static char* -S_maybe_unreachable(CFCType *return_type) { - char *return_statement; - if (CFCType_is_void(return_type)) { - return_statement = CFCUtil_strdup(""); - } - else { - const char *ret_type_str = CFCType_to_c(return_type); - char pattern[] = "\n CFISH_UNREACHABLE_RETURN(%s);"; - return_statement = CFCUtil_sprintf(pattern, ret_type_str); - } - return return_statement; -} - -static char* S_callback_start(CFCMethod *method) { CFCParamList *param_list = CFCMethod_get_param_list(method); static const char pattern[] = @@ -638,31 +605,19 @@ S_callback_refcount_mods(CFCMethod *method) { static char* S_invalid_callback_def(CFCMethod *method) { - char *full_method_sym = CFCMethod_full_method_sym(method, NULL); - const char *override_sym = CFCMethod_full_override_sym(method); - CFCParamList *param_list = CFCMethod_get_param_list(method); - const char *params = CFCParamList_to_c(param_list); - CFCVariable **param_vars = CFCParamList_get_variables(param_list); - - // Thwart compiler warnings. - CFCType *return_type = CFCMethod_get_return_type(method); - const char *ret_type_str = CFCType_to_c(return_type); - char *unused = S_build_unused_vars(param_vars); - char *unreachable = S_maybe_unreachable(return_type); + char *full_method_sym = CFCMethod_full_method_sym(method, NULL); char pattern[] = - "%s\n" - "%s(%s) {%s\n" - " CFISH_THROW(CFISH_ERR, \"Can't override %s via binding\");%s\n" + "void\n" + "%s(cfish_Obj *self) {\n" + " CFISH_UNUSED_VAR(self);\n" + " cfish_Err_invalid_callback(\"%s\");\n" "}\n"; char *callback_def - = CFCUtil_sprintf(pattern, ret_type_str, override_sym, params, unused, - full_method_sym, unreachable); + = CFCUtil_sprintf(pattern, override_sym, full_method_sym); FREEMEM(full_method_sym); - FREEMEM(unreachable); - FREEMEM(unused); return callback_def; } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d9feac00/runtime/core/Clownfish/Err.c ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/Err.c b/runtime/core/Clownfish/Err.c index e195b3b..68c2365 100644 --- a/runtime/core/Clownfish/Err.c +++ b/runtime/core/Clownfish/Err.c @@ -238,6 +238,11 @@ Err_abstract_method_call(Obj *obj, Class *klass, const char *method_name) { class_name); } +void +Err_invalid_callback(const char *method_name) { + THROW(ERR, "Can't override %s via binding", method_name); +} + #ifdef CHY_HAS_WINDOWS_H #include <windows.h> http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d9feac00/runtime/core/Clownfish/Err.cfh ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/Err.cfh b/runtime/core/Clownfish/Err.cfh index 24b7558..bae7e9e 100644 --- a/runtime/core/Clownfish/Err.cfh +++ b/runtime/core/Clownfish/Err.cfh @@ -168,6 +168,11 @@ public class Clownfish::Err inherits Clownfish::Obj { inert void abstract_method_call(Obj *obj, Class *klass, const char *method_name); + /** Throw an error after an invalid callback was called. + */ + inert void + invalid_callback(const char *method_name); + /** On Windows, return a newly allocated buffer containing the string * description for the the last error in the thread. */ http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/d9feac00/runtime/perl/t/binding/019-obj.t ---------------------------------------------------------------------- diff --git a/runtime/perl/t/binding/019-obj.t b/runtime/perl/t/binding/019-obj.t index 89d1ce3..c548634 100644 --- a/runtime/perl/t/binding/019-obj.t +++ b/runtime/perl/t/binding/019-obj.t @@ -16,7 +16,7 @@ use strict; use warnings; -use Test::More tests => 21; +use Test::More tests => 22; package TestObj; use base qw( Clownfish::Obj ); @@ -49,6 +49,12 @@ use base qw( Clownfish::Obj ); sub DESTROY {} } +package InvalidCallbackTestObj; +use base qw( Clownfish::Obj ); +{ + sub to_host {} +} + package OverriddenAliasTestObj; use base qw( Clownfish::Test::AliasTestObj ); { @@ -128,6 +134,9 @@ SKIP: { "Don't allow methods without nullable return values to return NULL" ); } +eval { InvalidCallbackTestObj->new; }; +like( $@, qr/Can't override CFISH_Obj_To_Host via binding/ ); + my $alias_test = Clownfish::Test::AliasTestObj->new; is( $alias_test->perl_alias, 'C', "Host method aliases work" );
