// Create an assignment statement for extracting $self from the Perl stack. static char* S_self_assign_statement(CFCPerlMethod *self, CFCType *type, const char *method_name) { (void)self; // unused const char *type_c = CFCType_to_c(type); if (!CFCType_is_object(type)) { CFCUtil_die("Not an object type: %s", type_c); } const char *vtable_var = CFCType_get_vtable_var(type); char pattern[] = "%s self = (%s)XSBind_sv_to_cfish_obj(ST(0), %s, NULL);"; char *statement = CFCUtil_sprintf(pattern, type_c, type_c, vtable_var); return statement; }
char* CFCBindMeth_abstract_method_def(CFCMethod *method) { CFCParamList *param_list = CFCMethod_get_param_list(method); const char *params = CFCParamList_to_c(param_list); const char *full_func_sym = CFCMethod_implementing_func_sym(method); const char *vtable_var = CFCType_get_vtable_var(CFCMethod_self_type(method)); CFCType *return_type = CFCMethod_get_return_type(method); const char *ret_type_str = CFCType_to_c(return_type); const char *macro_sym = CFCMethod_get_macro_sym(method); // Thwart compiler warnings. CFCVariable **param_vars = CFCParamList_get_variables(param_list); char *unused = S_build_unused_vars(param_vars + 1); char *return_statement = S_maybe_unreachable(return_type); char pattern[] = "%s\n" "%s(%s) {\n" " cfish_CharBuf *klass = self ? Cfish_Obj_Get_Class_Name((cfish_Obj*)self) : %s->name;%s\n" " CFISH_THROW(CFISH_ERR, \"Abstract method '%s' not defined by %%o\", klass);%s\n" "}\n"; size_t needed = sizeof(pattern) + strlen(ret_type_str) + strlen(full_func_sym) + strlen(params) + strlen(vtable_var) + strlen(unused) + strlen(macro_sym) + strlen(return_statement) + 50; char *abstract_def = (char*)MALLOCATE(needed); sprintf(abstract_def, pattern, ret_type_str, full_func_sym, params, vtable_var, unused, macro_sym, return_statement); FREEMEM(unused); FREEMEM(return_statement); return abstract_def; }
char* 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 *vtable_var = CFCType_get_vtable_var(type); if (strcmp(struct_sym, "lucy_CharBuf") == 0 || strcmp(struct_sym, "cfish_CharBuf") == 0 || strcmp(struct_sym, "lucy_Obj") == 0 || strcmp(struct_sym, "cfish_Obj") == 0 ) { // Share buffers rather than copy between Perl scalars and // Clownfish string types. result = CFCUtil_cat(CFCUtil_strdup(""), "(", struct_sym, "*)XSBind_sv_to_cfish_obj(", xs_var, ", ", vtable_var, ", alloca(cfish_ZCB_size()))", NULL); } else { result = CFCUtil_cat(CFCUtil_strdup(""), "(", struct_sym, "*)XSBind_sv_to_cfish_obj(", xs_var, ", ", vtable_var, ", NULL)", NULL); } } else if (CFCType_is_primitive(type)) { const char *specifier = CFCType_get_specifier(type); size_t size = 80 + strlen(xs_var) * 2; result = (char*)MALLOCATE(size); if (strcmp(specifier, "double") == 0) { sprintf(result, "SvNV(%s)", xs_var); } else if (strcmp(specifier, "float") == 0) { sprintf(result, "(float)SvNV(%s)", xs_var); } else if (strcmp(specifier, "int") == 0) { sprintf(result, "(int)SvIV(%s)", xs_var); } else if (strcmp(specifier, "short") == 0) { sprintf(result, "(short)SvIV(%s)", xs_var); } else if (strcmp(specifier, "long") == 0) { const char pattern[] = "((sizeof(long) <= sizeof(IV)) ? (long)SvIV(%s) " ": (long)SvNV(%s))"; sprintf(result, pattern, xs_var, xs_var); } else if (strcmp(specifier, "size_t") == 0) { sprintf(result, "(size_t)SvIV(%s)", xs_var); } else if (strcmp(specifier, "uint64_t") == 0) { sprintf(result, "(uint64_t)SvNV(%s)", xs_var); } else if (strcmp(specifier, "uint32_t") == 0) { sprintf(result, "(uint32_t)SvUV(%s)", xs_var); } else if (strcmp(specifier, "uint16_t") == 0) { sprintf(result, "(uint16_t)SvUV(%s)", xs_var); } else if (strcmp(specifier, "uint8_t") == 0) { sprintf(result, "(uint8_t)SvUV(%s)", xs_var); } else if (strcmp(specifier, "int64_t") == 0) { sprintf(result, "(int64_t)SvNV(%s)", xs_var); } else if (strcmp(specifier, "int32_t") == 0) { sprintf(result, "(int32_t)SvIV(%s)", xs_var); } else if (strcmp(specifier, "int16_t") == 0) { sprintf(result, "(int16_t)SvIV(%s)", xs_var); } else if (strcmp(specifier, "int8_t") == 0) { sprintf(result, "(int8_t)SvIV(%s)", xs_var); } else if (strcmp(specifier, "chy_bool_t") == 0) { sprintf(result, "SvTRUE(%s) ? 1 : 0", xs_var); } else { FREEMEM(result); result = NULL; } } return result; }