static void pcf_ptr_ptr_STRING(PARROT_INTERP, PMC *nci, SHIM(PMC *self)) { typedef void *(* func_t)(void *, STRING *); func_t fn_pointer; void *orig_func; PMC * const ctx = CURRENT_CONTEXT(interp); PMC * const call_object = Parrot_pcc_get_signature(interp, ctx); PMC * t_0; void * v_0; PMC * t_1; void * v_1; STRING * t_2; STRING * v_2; Parrot_pcc_fill_params_from_c_args(interp, call_object, "PS", &t_1, &t_2); v_1 = PMC_IS_NULL(t_1) ? NULL : VTABLE_get_pointer(interp, t_1);; v_2 = t_2; GETATTR_NCI_orig_func(interp, nci, orig_func); fn_pointer = (func_t)D2FPTR(orig_func); v_0 = (*fn_pointer)(v_1, v_2); if (v_0 != NULL) { t_0 = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, t_0, v_0); } else { t_0 = PMCNULL; }; Parrot_pcc_set_call_from_c_args(interp, call_object, "P", t_0); }
static void pcf_ptr_int_int_int_int(PARROT_INTERP, PMC *nci, SHIM(PMC *self)) { typedef void *(* func_t)(int, int, int, int); func_t fn_pointer; void *orig_func; PMC * const ctx = CURRENT_CONTEXT(interp); PMC * const call_object = Parrot_pcc_get_signature(interp, ctx); PMC * t_0; void * v_0; INTVAL t_1; int v_1; INTVAL t_2; int v_2; INTVAL t_3; int v_3; INTVAL t_4; int v_4; Parrot_pcc_fill_params_from_c_args(interp, call_object, "IIII", &t_1, &t_2, &t_3, &t_4); v_1 = (int)t_1; v_2 = (int)t_2; v_3 = (int)t_3; v_4 = (int)t_4; GETATTR_NCI_orig_func(interp, nci, orig_func); fn_pointer = (func_t)D2FPTR(orig_func); v_0 = (*fn_pointer)(v_1, v_2, v_3, v_4); if (v_0 != NULL) { t_0 = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, t_0, v_0); } else { t_0 = PMCNULL; }; Parrot_pcc_set_call_from_c_args(interp, call_object, "P", t_0); }
/* Initializes the representations registry, building up all of the various * representations. */ void REPR_initialize_registry(PARROT_INTERP) { PMC *dyn_reg_func; /* Allocate name to ID map, and anchor it with the GC. */ repr_name_to_id_map = Parrot_pmc_new(interp, enum_class_Hash); Parrot_pmc_gc_register(interp, repr_name_to_id_map); /* Add all core representations. */ register_repr(interp, Parrot_str_new_constant(interp, "KnowHOWREPR"), KnowHOWREPR_initialize(interp)); register_repr(interp, Parrot_str_new_constant(interp, "P6opaque"), P6opaque_initialize(interp)); register_repr(interp, Parrot_str_new_constant(interp, "P6int"), P6int_initialize(interp)); register_repr(interp, Parrot_str_new_constant(interp, "P6num"), P6num_initialize(interp)); register_repr(interp, Parrot_str_new_constant(interp, "P6str"), P6str_initialize(interp)); register_repr(interp, Parrot_str_new_constant(interp, "HashAttrStore"), HashAttrStore_initialize(interp)); register_repr(interp, Parrot_str_new_constant(interp, "Uninstantiable"), Uninstantiable_initialize(interp)); /* Set up object for dynamically registering extra representations. */ dyn_reg_func = Parrot_pmc_new(interp, enum_class_Pointer); VTABLE_set_pointer(interp, dyn_reg_func, REPR_register_dynamic); VTABLE_set_pmc_keyed_str(interp, interp->root_namespace, Parrot_str_new_constant(interp, "_REGISTER_REPR"), dyn_reg_func); }
/* Gets (creating if needed) a multi-dispatch cache. */ static NQP_md_cache *get_dispatch_cache(PARROT_INTERP, PMC *dispatcher) { PMC *cache_ptr; if (!smo_id) smo_id = Parrot_pmc_get_type_str(interp, Parrot_str_new(interp, "SixModelObject", 0)); if (dispatcher->vtable->base_type == enum_class_Sub && PARROT_SUB(dispatcher)->multi_signature->vtable->base_type == smo_id) { NQP_Routine *r = (NQP_Routine *)PMC_data(PARROT_SUB(dispatcher)->multi_signature); if (PMC_IS_NULL(r->dispatch_cache)) { NQP_md_cache *c = mem_sys_allocate_zeroed(sizeof(NQP_md_cache)); cache_ptr = Parrot_pmc_new(interp, enum_class_Pointer); VTABLE_set_pointer(interp, cache_ptr, c); r->dispatch_cache = cache_ptr; PARROT_GC_WRITE_BARRIER(interp, PARROT_SUB(dispatcher)->multi_signature); } else { cache_ptr = r->dispatch_cache; } } else { Parrot_ex_throw_from_c_args(interp, 0, 1, "Could not find multi-dispatch list"); } return (NQP_md_cache *)VTABLE_get_pointer(interp, cache_ptr); }
void Parrot_nci_load_core_thunks(PARROT_INTERP) { PMC * const iglobals = interp->iglobals; PMC *nci_funcs; PMC *temp_pmc; PARROT_ASSERT(!(PMC_IS_NULL(iglobals))); nci_funcs = VTABLE_get_pmc_keyed_int(interp, iglobals, IGLOBALS_NCI_FUNCS); PARROT_ASSERT(!(PMC_IS_NULL(nci_funcs))); { const int n = 1; static const int sig[] = { 5, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_char); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 5, 6, 5, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_char_short_char); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 1; static const int sig[] = { 16, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_double); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 2; static const int sig[] = { 16, 16, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_double_double); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 1; static const int sig[] = { 15, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_float); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 15, 15, 15, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_float_float_float); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 1; static const int sig[] = { 7, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 4; static const int sig[] = { 7, 7, 7, 7, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_int_int_int); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 2; static const int sig[] = { 7, 30, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_ptr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 7, 30, 30, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_ptr_ptr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 7, 6, 5, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_short_char); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 2; static const int sig[] = { 7, 31, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_int_cstr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 1; static const int sig[] = { 8, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_long); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 1; static const int sig[] = { 30, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 2; static const int sig[] = { 30, 7, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_int); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 30, 7, 7, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_int_int); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 5; static const int sig[] = { 30, 7, 7, 7, 7, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_int_int_int_int); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 30, 7, 30, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_int_ptr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 2; static const int sig[] = { 30, 30, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_ptr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 30, 30, 3, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_ptr_ptr_STRING); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 1; static const int sig[] = { 6, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_short); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 6, 6, 5, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_short_short_char); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 1; static const int sig[] = { 31, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_cstr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 2; static const int sig[] = { 31, 31, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_cstr_cstr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 31, 31, 31, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_cstr_cstr_cstr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 1; static const int sig[] = { 29, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 4; static const int sig[] = { 29, 15, 15, 15, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_float_float_float); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 2; static const int sig[] = { 29, 30, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_ptr); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 2; static const int sig[] = { 29, 4, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_PMC); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 4; static const int sig[] = { 29, 30, 7, 7, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_ptr_int_int); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } { const int n = 3; static const int sig[] = { 29, 30, 4, }; PMC *sig_pmc = Parrot_pmc_new_init_int(interp, enum_class_FixedIntegerArray, n); int i; for (i = 0; i < n; i++) VTABLE_set_integer_keyed_int(interp, sig_pmc, i, sig[i]); temp_pmc = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, temp_pmc, (void *)pcf_void_ptr_PMC); VTABLE_set_pmc_keyed(interp, nci_funcs, sig_pmc, temp_pmc); } }
PARROT_EXPORT PARROT_CANNOT_RETURN_NULL PARROT_WARN_UNUSED_RESULT PMC* Parrot_make_cb(PARROT_INTERP, ARGMOD(PMC* sub), ARGIN(PMC* user_data), ARGIN(STRING *cb_signature)) { ASSERT_ARGS(Parrot_make_cb) PMC *cb, *cb_sig; int type = 0; STRING *sc; /* * we stuff all the information into the user_data PMC and pass that * on to the external sub */ PMC * const interp_pmc = VTABLE_get_pmc_keyed_int(interp, interp->iglobals, (INTVAL) IGLOBALS_INTERPRETER); if (default_interp == NULL) default_interp = interp; /* be sure __LINE__ is consistent */ sc = CONST_STRING(interp, "_interpreter"); Parrot_pmc_setprop(interp, user_data, sc, interp_pmc); sc = CONST_STRING(interp, "_sub"); Parrot_pmc_setprop(interp, user_data, sc, sub); /* only ASCII signatures are supported */ if (STRING_length(cb_signature) == 3) { /* Callback return type ignored */ if (STRING_ord(interp, cb_signature, 1) == 'U') { type = 'D'; } else { if (STRING_ord(interp, cb_signature, 2) == 'U') { type = 'C'; } } } if (type != 'C' && type != 'D') Parrot_ex_throw_from_c_args(interp, NULL, 1, "unhandled signature '%Ss' in make_cb", cb_signature); cb_sig = Parrot_pmc_new(interp, enum_class_String); VTABLE_set_string_native(interp, cb_sig, cb_signature); sc = CONST_STRING(interp, "_signature"); Parrot_pmc_setprop(interp, user_data, sc, cb_sig); /* * We are going to be passing the user_data PMC to external code, but * it may go out of scope until the callback is called -- we don't know * for certain as we don't know when the callback will be called. * Therefore, to prevent the PMC from being destroyed by a GC sweep, * we need to anchor it. * */ Parrot_pmc_gc_register(interp, user_data); /* * Finally, the external lib awaits a function pointer. * Create a PMC that points to Parrot_callback_C (or _D); * it can be passed on with signature 'p'. */ cb = Parrot_pmc_new(interp, enum_class_UnManagedStruct); /* * Currently, we handle only 2 types: * _C ... user_data is 2nd parameter * _D ... user_data is 1st parameter */ if (type == 'C') VTABLE_set_pointer(interp, cb, F2DPTR(Parrot_callback_C)); else VTABLE_set_pointer(interp, cb, F2DPTR(Parrot_callback_D)); Parrot_pmc_gc_register(interp, cb); return cb; }
PARROT_EXPORT void Parrot_run_callback(PARROT_INTERP, ARGMOD(PMC* user_data), ARGIN(void* external_data)) { ASSERT_ARGS(Parrot_run_callback) PMC *signature; PMC *sub; STRING *sig_str; INTVAL ch; char pasm_sig[5]; INTVAL i_param; PMC *p_param; void *param = NULL; /* avoid -Ox warning */ STRING *sc; sc = CONST_STRING(interp, "_sub"); sub = Parrot_pmc_getprop(interp, user_data, sc); sc = CONST_STRING(interp, "_signature"); signature = Parrot_pmc_getprop(interp, user_data, sc); sig_str = VTABLE_get_string(interp, signature); pasm_sig[0] = 'P'; ch = STRING_ord(interp, sig_str, 1); if (ch == 'U') /* user_data Z in pdd16 */ ch = STRING_ord(interp, sig_str, 2); /* ch is now type of external data */ switch (ch) { case 'v': pasm_sig[1] = 'v'; break; case 'l': /* FIXME: issue #742 */ i_param = (INTVAL)(long)(INTVAL) external_data; goto case_I; case 'i': /* FIXME: issue #742 */ i_param = (INTVAL)(int)(INTVAL) external_data; goto case_I; case 's': /* FIXME: issue #742 */ i_param = (INTVAL)(short)(INTVAL) external_data; goto case_I; case 'c': /* FIXME: issue #742 */ i_param = (INTVAL)(char)(INTVAL) external_data; case_I: pasm_sig[1] = 'I'; param = (void*) i_param; break; case 'p': /* created a UnManagedStruct */ p_param = Parrot_pmc_new(interp, enum_class_UnManagedStruct); VTABLE_set_pointer(interp, p_param, external_data); pasm_sig[1] = 'P'; param = (void*) p_param; break; case 't': pasm_sig[1] = 'S'; param = Parrot_str_new(interp, (const char*)external_data, 0); break; default: Parrot_ex_throw_from_c_args(interp, NULL, 1, "unhandled signature char '%c' in run_cb", ch); } pasm_sig[2] = '-'; pasm_sig[3] = '>'; /* no return value supported yet */ pasm_sig[4] = '\0'; Parrot_ext_call(interp, sub, pasm_sig, user_data, param); }