Add CFCType_get_class Store a weak pointer to CFCClass in CFCType for object types.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/850d69bf Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/850d69bf Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/850d69bf Branch: refs/heads/master Commit: 850d69bfff9f64dbf1a6a9929639b05bf9cc0fc7 Parents: c502223 Author: Nick Wellnhofer <wellnho...@aevum.de> Authored: Mon Feb 27 19:45:52 2017 +0100 Committer: Nick Wellnhofer <wellnho...@aevum.de> Committed: Thu Mar 2 20:08:03 2017 +0100 ---------------------------------------------------------------------- compiler/src/CFCBindMethod.c | 3 +-- compiler/src/CFCCHtml.c | 22 +++++++++------------- compiler/src/CFCGoTypeMap.c | 31 ++++++------------------------- compiler/src/CFCPerlMethod.c | 23 ++++++++++------------- compiler/src/CFCPerlTypeMap.c | 5 +++-- compiler/src/CFCPyMethod.c | 6 ++++-- compiler/src/CFCType.c | 20 +++++++++----------- compiler/src/CFCType.h | 7 +++---- 8 files changed, 45 insertions(+), 72 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCBindMethod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCBindMethod.c b/compiler/src/CFCBindMethod.c index d57a29e..e6880b4 100644 --- a/compiler/src/CFCBindMethod.c +++ b/compiler/src/CFCBindMethod.c @@ -165,8 +165,7 @@ char* CFCBindMeth_abstract_method_def(CFCMethod *method, CFCClass *klass) { CFCType *ret_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(ret_type); - CFCType *type = CFCMethod_self_type(method); - const char *class_var = CFCType_get_class_var(type); + const char *class_var = CFCClass_full_class_var(klass); const char *meth_name = CFCMethod_get_name(method); CFCParamList *param_list = CFCMethod_get_param_list(method); const char *params = CFCParamList_to_c(param_list); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCCHtml.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCCHtml.c b/compiler/src/CFCCHtml.c index 016c15b..6383ada 100644 --- a/compiler/src/CFCCHtml.c +++ b/compiler/src/CFCCHtml.c @@ -1071,19 +1071,15 @@ S_type_to_html(CFCType *type, const char *sep, CFCClass *doc_class) { char *specifier_html = NULL; if (CFCType_is_object(type)) { - CFCClass *klass = NULL; - - // Don't link to doc class. - if (strcmp(specifier, CFCClass_full_struct_sym(doc_class)) != 0) { - klass = CFCClass_fetch_by_struct_sym(specifier); - if (!klass) { - CFCUtil_warn("Class '%s' not found", specifier); - } - else if (!CFCClass_public(klass)) { - CFCUtil_warn("Non-public class '%s' used in public method", - specifier); - klass = NULL; - } + CFCClass *klass = CFCType_get_class(type); + if (klass == doc_class) { + // Don't link to doc class. + klass = NULL; + } + else if (!CFCClass_public(klass)) { + CFCUtil_warn("Non-public class '%s' used in public method", + specifier); + klass = NULL; } const char *underscore = strchr(specifier, '_'); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCGoTypeMap.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCGoTypeMap.c b/compiler/src/CFCGoTypeMap.c index 281fb21..a9f65d1 100644 --- a/compiler/src/CFCGoTypeMap.c +++ b/compiler/src/CFCGoTypeMap.c @@ -24,6 +24,7 @@ #include "CFCVariable.h" #include "CFCType.h" #include "CFCUtil.h" +#include "CFCClass.h" #ifndef true #define true 1 @@ -109,32 +110,12 @@ CFCGoTypeMap_go_type_name(CFCType *type, CFCParcel *current_parcel) { } else if (CFCType_is_object(type)) { // Divide the specifier into prefix and struct name. - const char *specifier = CFCType_get_specifier(type); - size_t prefix_len = 0; - for (size_t max = strlen(specifier); prefix_len < max; prefix_len++) { - if (CFCUtil_isupper(specifier[prefix_len])) { - break; - } - } - if (!prefix_len) { - CFCUtil_die("Can't convert object type name '%s'", specifier); - } - const char *struct_sym = specifier + prefix_len; - - // Find the parcel that the type lives in. - CFCParcel** all_parcels = CFCParcel_all_parcels(); - CFCParcel *parcel = NULL; - for (int i = 0; all_parcels[i] != NULL; i++) { - const char *candidate = CFCParcel_get_prefix(all_parcels[i]); - if (strncmp(candidate, specifier, prefix_len) == 0 - && strlen(candidate) == prefix_len - ) { - parcel = all_parcels[i]; - break; - } - } + CFCClass *klass = CFCType_get_class(type); + const char *struct_sym = CFCClass_get_struct_sym(klass); + CFCParcel *parcel = CFCClass_get_parcel(klass); if (!parcel) { - CFCUtil_die("Can't find parcel for type '%s'", specifier); + CFCUtil_die("Can't find parcel for type '%s'", + CFCType_get_specifier(type)); } // If the type lives in this parcel, return only the struct sym http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCPerlMethod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlMethod.c b/compiler/src/CFCPerlMethod.c index 9f25f92..6a59313 100644 --- a/compiler/src/CFCPerlMethod.c +++ b/compiler/src/CFCPerlMethod.c @@ -42,7 +42,7 @@ S_xsub_body(CFCPerlMethod *self, CFCClass *klass); // Create an assignment statement for extracting $self from the Perl stack. static char* -S_self_assign_statement(CFCPerlMethod *self); +S_self_assign_statement(CFCPerlMethod *self, CFCClass *klass); // Return code for an xsub which uses labeled params. static char* @@ -214,19 +214,16 @@ S_xsub_body(CFCPerlMethod *self, CFCClass *klass) { // Create an assignment statement for extracting $self from the Perl stack. static char* -S_self_assign_statement(CFCPerlMethod *self) { +S_self_assign_statement(CFCPerlMethod *self, CFCClass *klass) { CFCParamList *param_list = CFCMethod_get_param_list(self->method); CFCVariable **vars = CFCParamList_get_variables(param_list); - CFCType *type = CFCVariable_get_type(vars[0]); - const char *self_name = CFCVariable_get_name(vars[0]); - const char *type_c = CFCType_to_c(type); - if (!CFCType_is_object(type)) { - CFCUtil_die("Not an object type: %s", type_c); - } - const char *class_var = CFCType_get_class_var(type); - char pattern[] = "arg_%s = (%s)XSBind_perl_to_cfish_noinc(" + const char *self_name = CFCVariable_get_name(vars[0]); + const char *struct_sym = CFCClass_full_struct_sym(klass); + const char *class_var = CFCClass_full_class_var(klass); + char pattern[] = "arg_%s = (%s*)XSBind_perl_to_cfish_noinc(" "aTHX_ ST(0), %s, NULL);"; - char *statement = CFCUtil_sprintf(pattern, self_name, type_c, class_var); + char *statement = CFCUtil_sprintf(pattern, self_name, struct_sym, + class_var); return statement; } @@ -244,7 +241,7 @@ S_xsub_def_labeled_params(CFCPerlMethod *self, CFCClass *klass) { char *param_specs = CFCPerlSub_build_param_specs((CFCPerlSub*)self, 1); char *arg_decls = CFCPerlSub_arg_declarations((CFCPerlSub*)self, 0); char *meth_type_c = CFCMethod_full_typedef(method, klass); - char *self_assign = S_self_assign_statement(self); + char *self_assign = S_self_assign_statement(self, klass); char *arg_assigns = CFCPerlSub_arg_assignments((CFCPerlSub*)self); char *body = S_xsub_body(self, klass); @@ -314,7 +311,7 @@ S_xsub_def_positional_args(CFCPerlMethod *self, CFCClass *klass) { int num_vars = CFCParamList_num_vars(param_list); char *arg_decls = CFCPerlSub_arg_declarations((CFCPerlSub*)self, 0); char *meth_type_c = CFCMethod_full_typedef(method, klass); - char *self_assign = S_self_assign_statement(self); + char *self_assign = S_self_assign_statement(self, klass); char *arg_assigns = CFCPerlSub_arg_assignments((CFCPerlSub*)self); char *body = S_xsub_body(self, klass); http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCPerlTypeMap.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPerlTypeMap.c b/compiler/src/CFCPerlTypeMap.c index 022aa7f..a94ccdf 100644 --- a/compiler/src/CFCPerlTypeMap.c +++ b/compiler/src/CFCPerlTypeMap.c @@ -41,8 +41,9 @@ CFCPerlTypeMap_from_perl(CFCType *type, const char *xs_var, char *result = NULL; if (CFCType_is_object(type)) { - const char *struct_sym = CFCType_get_specifier(type); - const char *class_var = CFCType_get_class_var(type); + CFCClass *klass = CFCType_get_class(type); + const char *struct_sym = CFCClass_full_struct_sym(klass); + const char *class_var = CFCClass_full_class_var(klass); const char *nullable_str = CFCType_nullable(type) ? "_nullable" : ""; const char *allocation; if (strcmp(struct_sym, "cfish_String") == 0 http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCPyMethod.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCPyMethod.c b/compiler/src/CFCPyMethod.c index 05626a6..9c1328a 100644 --- a/compiler/src/CFCPyMethod.c +++ b/compiler/src/CFCPyMethod.c @@ -113,7 +113,8 @@ S_gen_declaration(CFCVariable *var, const char *val) { if (strcmp(specifier, "cfish_Hash") != 0 && strcmp(specifier, "cfish_Vector") != 0 ) { - const char *class_var = CFCType_get_class_var(type); + CFCClass *klass = CFCType_get_class(type); + const char *class_var = CFCClass_full_class_var(klass); char pattern[] = " CFBindArg wrap_arg_%s = {%s, &%s_ARG};\n" ; @@ -262,9 +263,10 @@ S_build_pymeth_invocation(CFCMethod *method) { invocation = CFCUtil_sprintf(pattern, micro_sym); } else if (CFCType_is_object(return_type)) { + CFCClass *klass = CFCType_get_class(return_type); + const char *ret_class = CFCClass_full_class_var(klass); const char *nullable = CFCType_nullable(return_type) ? "true" : "false"; - const char *ret_class = CFCType_get_class_var(return_type); const char pattern[] = " %s cfcb_RESULT = (%s)CALL_PYMETH_OBJ((PyObject*)self, \"%s\", cfcb_ARGS, %s, %s);"; invocation = CFCUtil_sprintf(pattern, ret_type_str, ret_type_str, micro_sym, http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCType.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCType.c b/compiler/src/CFCType.c index 9489c76..791a65b 100644 --- a/compiler/src/CFCType.c +++ b/compiler/src/CFCType.c @@ -35,9 +35,9 @@ struct CFCType { CFCBase base; int flags; char *specifier; - char *class_var; int indirection; CFCWeakPtr parcel; + CFCWeakPtr klass; char *c_string; size_t width; char *array; @@ -99,7 +99,6 @@ CFCType_init(CFCType *self, int flags, struct CFCParcel *parcel, self->width = 0; self->array = NULL; self->child = NULL; - self->class_var = NULL; return self; } @@ -300,6 +299,7 @@ CFCType_resolve(CFCType *self) { if (!klass) { CFCUtil_die("No class found for type '%s'", specifier); } + CFCWeakPtr_set(&self->klass, (CFCBase*)klass); // Upgrade specifier to full struct sym. self->specifier = CFCUtil_strdup(CFCClass_full_struct_sym(klass)); @@ -313,10 +313,10 @@ CFCType_destroy(CFCType *self) { CFCBase_decref((CFCBase*)self->child); } CFCWeakPtr_destroy(&self->parcel); + CFCWeakPtr_destroy(&self->klass); FREEMEM(self->specifier); FREEMEM(self->c_string); FREEMEM(self->array); - FREEMEM(self->class_var); CFCBase_destroy((CFCBase*)self); } @@ -377,15 +377,13 @@ CFCType_get_specifier(CFCType *self) { return self->specifier; } -const char* -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] = CFCUtil_toupper(self->class_var[i]); - } +CFCClass* +CFCType_get_class(CFCType *self) { + CFCClass *klass = (CFCClass*)CFCWeakPtr_deref(self->klass); + if (!klass) { + CFCUtil_die("Type has no class"); } - return self->class_var; + return klass; } int http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/850d69bf/compiler/src/CFCType.h ---------------------------------------------------------------------- diff --git a/compiler/src/CFCType.h b/compiler/src/CFCType.h index 4fa5042..010c33f 100644 --- a/compiler/src/CFCType.h +++ b/compiler/src/CFCType.h @@ -203,11 +203,10 @@ CFCType_set_specifier(CFCType *self, const char *specifier); const char* CFCType_get_specifier(CFCType *self); -/** Return the name of the Class variable which corresponds to the object - * type. Returns NULL for non-object types. +/** Return the Class object which corresponds to the object type. */ -const char* -CFCType_get_class_var(CFCType *self); +struct CFCClass* +CFCType_get_class(CFCType *self); int CFCType_get_indirection(CFCType *self);