char* CFCPerlConstructor_xsub_def(CFCPerlConstructor *self) { const char *c_name = self->sub.c_name; CFCParamList *param_list = self->sub.param_list; const char *name_list = CFCParamList_name_list(param_list); CFCVariable **arg_vars = CFCParamList_get_variables(param_list); const char *func_sym = CFCFunction_full_func_sym(self->init_func); char *allot_params = CFCPerlSub_build_allot_params((CFCPerlSub*)self); CFCVariable *self_var = arg_vars[0]; CFCType *self_type = CFCVariable_get_type(self_var); const char *self_type_str = CFCType_to_c(self_type); // Compensate for swallowed refcounts. char *refcount_mods = CFCUtil_strdup(""); for (size_t i = 0; arg_vars[i] != NULL; i++) { CFCVariable *var = arg_vars[i]; CFCType *type = CFCVariable_get_type(var); if (CFCType_is_object(type) && CFCType_decremented(type)) { const char *name = CFCVariable_micro_sym(var); refcount_mods = CFCUtil_cat(refcount_mods, "\n CFISH_INCREF(", name, ");", NULL); } } const char pattern[] = "XS(%s);\n" "XS(%s) {\n" " dXSARGS;\n" " CFISH_UNUSED_VAR(cv);\n" " if (items < 1) { CFISH_THROW(CFISH_ERR, \"Usage: %%s(class_name, ...)\", GvNAME(CvGV(cv))); }\n" " SP -= items;\n" "\n" " %s\n" // Create "self" last, so that earlier exceptions while fetching // params don't trigger a bad invocation of DESTROY. " %s self = (%s)XSBind_new_blank_obj(ST(0));%s\n" "\n" " %s retval = %s(%s);\n" " if (retval) {\n" " ST(0) = (SV*)CFISH_Obj_To_Host((cfish_Obj*)retval);\n" " CFISH_Obj_Dec_RefCount((cfish_Obj*)retval);\n" " }\n" " else {\n" " ST(0) = newSV(0);\n" " }\n" " sv_2mortal(ST(0));\n" " XSRETURN(1);\n" "}\n\n"; char *xsub_def = CFCUtil_sprintf(pattern, c_name, c_name, allot_params, self_type_str, self_type_str, refcount_mods, self_type_str, func_sym, name_list); FREEMEM(refcount_mods); FREEMEM(allot_params); return xsub_def; }
char* CFCPyMethod_constructor_wrapper(CFCFunction *init_func, CFCClass *invoker) { CFCParamList *param_list = CFCFunction_get_param_list(init_func); const char *self_type = CFCType_to_c(CFCFunction_get_return_type(init_func)); char *func_sym = CFCFunction_full_func_sym(init_func, invoker); char *decs = S_gen_decs(param_list, 1); char *increfs = S_gen_arg_increfs(param_list, 1); char *decrefs = S_gen_decrefs(param_list, 1); const char *class_var = CFCClass_full_class_var(invoker); const char *struct_sym = CFCClass_full_struct_sym(invoker); char *error = NULL; char *arg_parsing = S_gen_arg_parsing(param_list, 1, &error); if (error) { CFCUtil_die("%s in constructor for %s", error, CFCClass_get_name(invoker)); } if (!arg_parsing) { CFCUtil_die("Unexpected arg parsing error for %s", CFCClass_get_name(invoker)); } char *first_arg = CFCUtil_sprintf("(%s)CFISH_Class_Make_Obj(%s)", self_type, class_var); char *arg_list = S_gen_arg_list(param_list, first_arg); char pattern[] = "static PyObject*\n" "S_%s_PY_NEW(PyTypeObject *type, PyObject *args, PyObject *kwargs) {\n" "%s" // decs "%s" // arg_parsing "%s" // increfs " %s self = NULL;\n" " CFBIND_TRY(self = %s(%s));\n" "%s" // decrefs " if (CFBind_migrate_cferr()) {\n" " return NULL;\n" " }\n" " return (PyObject*)self;\n" "}\n" ; char *wrapper = CFCUtil_sprintf(pattern, struct_sym, decs, arg_parsing, increfs, self_type, func_sym, arg_list, decrefs); FREEMEM(arg_list); FREEMEM(first_arg); FREEMEM(func_sym); FREEMEM(decrefs); FREEMEM(increfs); FREEMEM(decs); FREEMEM(arg_parsing); return wrapper; }
char* CFCGoClass_gen_ctors(CFCGoClass *self) { CFCFunction *ctor_func = CFCClass_function(self->client, "new"); if (self->suppress_ctor || !ctor_func || !CFCFunction_can_be_bound(ctor_func) ) { return CFCUtil_strdup(""); } CFCParcel *parcel = CFCClass_get_parcel(self->client); CFCParamList *param_list = CFCFunction_get_param_list(ctor_func); CFCType *ret_type = CFCFunction_get_return_type(ctor_func); const char *struct_sym = CFCClass_get_struct_sym(self->client); char *name = CFCUtil_sprintf("New%s", struct_sym); char *cfunc = CFCFunction_full_func_sym(ctor_func, self->client); char *cfargs = CFCGoFunc_ctor_cfargs(parcel, param_list); char *first_line = CFCGoFunc_ctor_start(parcel, name, param_list, ret_type); char *ret_statement = CFCGoFunc_return_statement(parcel, ret_type, "retvalCF"); char pattern[] = "%s" "\tretvalCF := C.%s(%s)\n" "%s" "}\n" ; char *content = CFCUtil_sprintf(pattern, first_line, cfunc, cfargs, ret_statement); FREEMEM(ret_statement); FREEMEM(cfargs); FREEMEM(cfunc); FREEMEM(first_line); FREEMEM(name); return content; }
const char* CFCMethod_implementing_func_sym(CFCMethod *self) { return CFCFunction_full_func_sym((CFCFunction*)self); }