Test non-object arguments for undef
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/dfc084ea Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/dfc084ea Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/dfc084ea Branch: refs/heads/master Commit: dfc084ea926ff9ba3da1330313dc270b14c24192 Parents: da15a25 Author: Nick Wellnhofer <wellnho...@aevum.de> Authored: Tue Dec 1 13:39:26 2015 +0100 Committer: Nick Wellnhofer <wellnho...@aevum.de> Committed: Tue Dec 1 16:06:03 2015 +0100 ---------------------------------------------------------------------- compiler/src/CFCPerlConstructor.c | 1 + compiler/src/CFCPerlMethod.c | 4 +++- compiler/src/CFCPerlSub.c | 39 +++++++++++++++++++++++----------- runtime/perl/xs/XSBind.c | 8 +++++-- runtime/perl/xs/XSBind.h | 6 ++++++ 5 files changed, 43 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/dfc084ea/compiler/src/CFCPerlConstructor.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlConstructor.c b/compiler/src/CFCPerlConstructor.c index 68f20e1..c0c3a89 100644 --- a/compiler/src/CFCPerlConstructor.c +++ b/compiler/src/CFCPerlConstructor.c @@ -146,6 +146,7 @@ CFCPerlConstructor_xsub_def(CFCPerlConstructor *self, CFCClass *klass) { " dXSARGS;\n" "%s" // param_specs "%s" // locs_decl + " SV *sv;\n" "%s" // arg_decls " %s retval;\n" "\n" http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/dfc084ea/compiler/src/CFCPerlMethod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlMethod.c b/compiler/src/CFCPerlMethod.c index 6c77e60..911d51d 100644 --- a/compiler/src/CFCPerlMethod.c +++ b/compiler/src/CFCPerlMethod.c @@ -264,6 +264,7 @@ S_xsub_def_labeled_params(CFCPerlMethod *self, CFCClass *klass) { " dXSARGS;\n" "%s" // param_specs " int32_t locations[%d];\n" + " SV *sv;\n" "%s" // arg_decls " %s method;\n" "%s" @@ -355,7 +356,8 @@ S_xsub_def_positional_args(CFCPerlMethod *self, CFCClass *klass) { "XS(%s);\n" "XS(%s) {\n" " dXSARGS;\n" - "%s" + " SV *sv;\n" + "%s" // arg_decls " %s method;\n" "%s" "\n" http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/dfc084ea/compiler/src/CFCPerlSub.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlSub.c b/compiler/src/CFCPerlSub.c index 6942abc..fb50975 100644 --- a/compiler/src/CFCPerlSub.c +++ b/compiler/src/CFCPerlSub.c @@ -182,35 +182,50 @@ S_arg_assignment(CFCVariable *var, const char *val, CFCType *var_type = CFCVariable_get_type(var); char *statement = NULL; - char perl_stack_var[40]; - sprintf(perl_stack_var, "ST(%s)", stack_location); - char *conversion = CFCPerlTypeMap_from_perl(var_type, perl_stack_var, - var_name); + char *conversion = CFCPerlTypeMap_from_perl(var_type, "sv", var_name); if (!conversion) { const char *type_c = CFCType_to_c(var_type); CFCUtil_die("Can't map type '%s'", type_c); } + if (val) { if (CFCType_is_object(var_type)) { - char pattern[] = " arg_%s = %s < items ? %s : %s;\n"; + const char pattern[] = " arg_%s = %s < items ? %s : %s;\n"; statement = CFCUtil_sprintf(pattern, var_name, stack_location, conversion, val); } else { - char pattern[] = - " arg_%s = %s < items && XSBind_sv_defined(aTHX_ %s)\n" + const char pattern[] = + " arg_%s = %s < items && XSBind_sv_defined(aTHX_ sv)\n" " ? %s : %s;\n"; statement = CFCUtil_sprintf(pattern, var_name, stack_location, - perl_stack_var, conversion, val); + conversion, val); } } else { - const char pattern[] = " arg_%s = %s;\n"; - statement = CFCUtil_sprintf(pattern, var_name, conversion); + if (CFCType_is_object(var_type)) { + const char pattern[] = " arg_%s = %s;\n"; + statement = CFCUtil_sprintf(pattern, var_name, conversion); + } + else { + const char pattern[] = + " if (!XSBind_sv_defined(aTHX_ sv)) {\n" + " XSBind_undef_arg_error(aTHX_ \"%s\");\n" + " }\n" + " arg_%s = %s;\n"; + statement = CFCUtil_sprintf(pattern, var_name, var_name, + conversion); + } } - FREEMEM(conversion); - return statement; + const char pattern[] = + " sv = ST(%s);\n" + "%s"; + char *retval = CFCUtil_sprintf(pattern, stack_location, statement); + + FREEMEM(conversion); + FREEMEM(statement); + return retval; } CFCParamList* http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/dfc084ea/runtime/perl/xs/XSBind.c ---------------------------------------------------------------------- diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c index 6175c46..314387b 100644 --- a/runtime/perl/xs/XSBind.c +++ b/runtime/perl/xs/XSBind.c @@ -391,8 +391,7 @@ XSBind_arg_to_cfish(pTHX_ SV *value, const char *label, cfish_Class *klass, } if (!obj) { - THROW(CFISH_ERR, "'%s' must not be undef", label); - CFISH_UNREACHABLE_RETURN(cfish_Obj*); + XSBind_undef_arg_error(aTHX_ label); } return obj; @@ -417,6 +416,11 @@ XSBind_invalid_args_error(pTHX_ CV *cv, const char *param_list) { THROW(CFISH_ERR, "Usage: %s(%s)", GvNAME(CvGV(cv)), param_list); } +void +XSBind_undef_arg_error(pTHX_ const char *label) { + THROW(CFISH_ERR, "'%s' must not be undef", label); +} + /*************************************************************************** * The routines below are declared within the Clownfish core but left * unimplemented and must be defined for each host language. http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/dfc084ea/runtime/perl/xs/XSBind.h ---------------------------------------------------------------------- diff --git a/runtime/perl/xs/XSBind.h b/runtime/perl/xs/XSBind.h index 7c5a9cc..fd9f4a2 100644 --- a/runtime/perl/xs/XSBind.h +++ b/runtime/perl/xs/XSBind.h @@ -202,6 +202,11 @@ cfish_XSBind_arg_to_cfish_nullable(pTHX_ SV *value, const char *label, CFISH_VISIBLE void cfish_XSBind_invalid_args_error(pTHX_ CV *cv, const char *param_list); +/** Throw an error because of an undefined argument. + */ +CFISH_VISIBLE void +cfish_XSBind_undef_arg_error(pTHX_ const char *label); + #define XSBIND_PARAM(key, required) \ { key, (int16_t)sizeof("" key) - 1, (char)required } @@ -228,6 +233,7 @@ cfish_XSBind_invalid_args_error(pTHX_ CV *cv, const char *param_list); #define XSBind_arg_to_cfish cfish_XSBind_arg_to_cfish #define XSBind_arg_to_cfish_nullable cfish_XSBind_arg_to_cfish_nullable #define XSBind_invalid_args_error cfish_XSBind_invalid_args_error +#define XSBind_undef_arg_error cfish_XSBind_undef_arg_error /* Strip the prefix from some common ClownFish symbols where we know there's * no conflict with Perl. It's a little inconsistent to do this rather than