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_int_ptr_ptr(PARROT_INTERP, PMC *nci, SHIM(PMC *self)) { typedef int(* func_t)(void *, void *); func_t fn_pointer; void *orig_func; PMC * const ctx = CURRENT_CONTEXT(interp); PMC * const call_object = Parrot_pcc_get_signature(interp, ctx); INTVAL t_0; int v_0; PMC * t_1; void * v_1; PMC * t_2; void * v_2; Parrot_pcc_fill_params_from_c_args(interp, call_object, "PP", &t_1, &t_2); v_1 = PMC_IS_NULL(t_1) ? NULL : VTABLE_get_pointer(interp, t_1);; v_2 = PMC_IS_NULL(t_2) ? NULL : VTABLE_get_pointer(interp, 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); t_0 = (INTVAL)v_0; Parrot_pcc_set_call_from_c_args(interp, call_object, "I", t_0); }
static void callback_CD(PARROT_INTERP, ARGIN(char *external_data), ARGMOD(PMC *user_data)) { ASSERT_ARGS(callback_CD) PMC *passed_interp; /* the interp that originated the CB */ PMC *passed_synchronous; /* flagging synchronous execution */ int synchronous = 0; /* cb is hitting this sub somewhen * inmidst, or not */ STRING *sc; /* * 3) check interpreter ... */ sc = CONST_STRING(interp, "_interpreter"); passed_interp = Parrot_pmc_getprop(interp, user_data, sc); if (VTABLE_get_pointer(interp, passed_interp) != interp) PANIC(interp, "callback gone to wrong interpreter"); sc = CONST_STRING(interp, "_synchronous"); passed_synchronous = Parrot_pmc_getprop(interp, user_data, sc); if (!PMC_IS_NULL(passed_synchronous) && VTABLE_get_bool(interp, passed_synchronous)) synchronous = 1; /* * 4) check if the call_back is synchronous: * - if yes we are inside the NCI call * we could run the Sub immediately now (I think) * - if no, and that's always safe, post a callback event */ if (synchronous) { /* * just call the sub */ Parrot_run_callback(interp, user_data, external_data); } else { /* * create a CB_EVENT, put user_data and data inside and finito * * *if* this function is finally no void, i.e. the calling * C program awaits a return result from the callback, * then wait for the CB_EVENT_xx to finish and return the * result */ PMC * const callback = Parrot_pmc_new(interp, enum_class_Callback); Parrot_Callback_attributes * const cb_data = PARROT_CALLBACK(callback); cb_data->user_data = user_data; cb_data->external_data = (PMC*) external_data; Parrot_cx_schedule_immediate(interp, callback); } }
static void pcf_void_ptr(PARROT_INTERP, PMC *nci, SHIM(PMC *self)) { typedef void(* func_t)(void *); 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_1; void * v_1; Parrot_pcc_fill_params_from_c_args(interp, call_object, "P", &t_1); v_1 = PMC_IS_NULL(t_1) ? NULL : VTABLE_get_pointer(interp, t_1);; GETATTR_NCI_orig_func(interp, nci, orig_func); fn_pointer = (func_t)D2FPTR(orig_func); (*fn_pointer)(v_1); Parrot_pcc_set_call_from_c_args(interp, call_object, ""); }
/* 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); }
Create a new thread, cloning the current interpreter. The argument C<type> is currently ignored. =cut */ PARROT_CANNOT_RETURN_NULL PMC * Parrot_thread_create(PARROT_INTERP, SHIM(INTVAL type), INTVAL clone_flags) { ASSERT_ARGS(Parrot_thread_create) PMC * const new_interp_pmc = clone_interpreter(interp, clone_flags); Interp * const new_interp = (Interp *)VTABLE_get_pointer(interp, new_interp_pmc); /* Parrot_pmc_new sets parent_interpreter which would confuse the GC */ new_interp->parent_interpreter = NULL; new_interp->thread_data = mem_internal_allocate_zeroed_typed(Thread_data); MUTEX_INIT(new_interp->thread_data->interp_lock); new_interp->thread_data->tid = 0; new_interp->thread_data->main_interp = interp; Interp_flags_SET(new_interp, PARROT_IS_THREAD); new_interp->wake_up = 0; COND_INIT(new_interp->sleep_cond); MUTEX_INIT(new_interp->sleep_mutex); if (! interp->thread_data) { /* first time we go multi threaded */ interp->thread_data = mem_internal_allocate_zeroed_typed(Thread_data);