[svn:parrot] r49754 - branches/gsoc_nci/src/pmc
plobsing at svn.parrot.org
plobsing at svn.parrot.org
Sun Oct 31 15:11:06 UTC 2010
Author: plobsing
Date: Sun Oct 31 15:11:05 2010
New Revision: 49754
URL: https://trac.parrot.org/parrot/changeset/49754
Log:
logically separate dynamic call to Parrot_pcc_fill_params_from_c_args
Modified:
branches/gsoc_nci/src/pmc/nci.pmc
Modified: branches/gsoc_nci/src/pmc/nci.pmc
==============================================================================
--- branches/gsoc_nci/src/pmc/nci.pmc Sun Oct 31 15:03:07 2010 (r49753)
+++ branches/gsoc_nci/src/pmc/nci.pmc Sun Oct 31 15:11:05 2010 (r49754)
@@ -61,11 +61,17 @@
typedef struct pmc_holder_t {
PMC* p;
union {
- INTVAL* ival;
- void** pval;
+ INTVAL *ival;
+ void **pval;
};
} pmc_holder_t;
+typedef struct {
+ INTVAL i;
+ FLOATVAL n;
+ STRING *s;
+ PMC *p;
+} parrot_var_t;
/*
@@ -413,11 +419,10 @@
PMC *positional, *arg_iter;
STRING *void_return;
void **values;
- void **pcc_ptr;
+ parrot_var_t *pcc_arg;
void **translation_pointers = NULL; /* Data translation pointers, used to hold values
that are passed by reference so we can update
the objects after the FFI call is over */
- void **pcc_val = NULL; /* A holder for the values passed to pcc */
void **middle_man = NULL; /* An array to hold various pointers so they are not lost if
the function changes values by reference */
void *return_data; /* Holds return data from FFI call */
@@ -439,57 +444,67 @@
"attempt to call NULL function");
}
- if (nci_info->arity > 0) {
- size_t pcc_argc, pcc_values_offset, pcc_values_size, values_size;
- /* Function has arguments */
- tmp_sig = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
+ /* dynamic call to Parrot_pcc_fill_params_from_c_args */
+ {
+ INTVAL pcc_argc = Parrot_str_length(interp, nci_info->pcc_params_signature);
+ char *pcc_sig = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
+
+ void **pcc_arg_ptr, **call_arg;
+
+ ffi_arg ffi_ret_dummy;
+
+ pcc_arg = mem_gc_allocate_n_zeroed_typed(interp, pcc_argc, parrot_var_t);
+ pcc_arg_ptr = mem_gc_allocate_n_zeroed_typed(interp, pcc_argc, void *);
+ call_arg = mem_gc_allocate_n_zeroed_typed(interp, pcc_argc + 3, void*);
+
+ /* setup Parrot_pcc_fill_params_from_c_args required arguments */
+ call_arg[0] = &interp;
+ call_arg[1] = &call_object;
+ call_arg[2] = &pcc_sig;
+
+ // TODO: eliminate PCC signature parsing somehow
+ for (i = 0; i < pcc_argc; i++) {
+ switch (pcc_sig[i]) {
+ case 'I':
+ pcc_arg_ptr[i] = &pcc_arg[i].i;
+ break;
+ case 'N':
+ pcc_arg_ptr[i] = &pcc_arg[i].n;
+ break;
+ case 'S':
+ pcc_arg_ptr[i] = &pcc_arg[i].s;
+ break;
+ case 'P':
+ pcc_arg_ptr[i] = &pcc_arg[i].p;
+ break;
+ }
+
+ call_arg[i + 3] = &pcc_arg_ptr[i];
+ }
+
+ ffi_call(&nci_info->pcc_cif, FFI_FN(Parrot_pcc_fill_params_from_c_args), &ffi_ret_dummy, call_arg);
+
+ mem_gc_free(interp, call_arg);
+ mem_gc_free(interp, pcc_arg_ptr);
+ Parrot_str_free_cstring(pcc_sig);
+ }
+
+ {
+ size_t values_size;
- pcc_values_size = 0;
values_size = 0;
- pcc_argc = Parrot_str_length(interp, nci_info->pcc_params_signature);
/* Add up the size of memory needed for the actual call */
for (i = 0; i < (size_t)nci_info->arity; i++) {
values_size += cif->arg_types[i]->size;
}
- pcc_ptr = (void**)mem_internal_allocate_n_zeroed_typed(pcc_argc + 4, void*);
-
- /* Setup Parrot_pcc_fill_params_from_c_args required arguments */
- pcc_ptr[0] = &interp;
- pcc_ptr[1] = &call_object;
- pcc_ptr[2] = &tmp_sig;
-
- pcc_val = mem_internal_allocate_n_zeroed_typed(pcc_argc, void*);
/* Allocate enough room for the values passed to the ffi function plus add some
padding just to be sure we have enough space. */
values = mem_internal_allocate_zeroed(values_size + 2 * sizeof(void*));
/* Middle man is used to contain */
middle_man = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
- /* Add up the size of the pcc arguments */
- for (i = 0; i < pcc_argc; i++) {
- if (tmp_sig[i] == 'N') {
- pcc_val[i] = mem_internal_allocate_typed(FLOATVAL);
- pcc_ptr[i+3] = &pcc_val[i];
- }
- else if (tmp_sig[i] == 'I') {
- pcc_val[i] = mem_internal_allocate_typed(INTVAL);
- pcc_ptr[i+3] = &pcc_val[i];
- }
- else if (tmp_sig[i] == 'P' || tmp_sig[i] == 'S') {
- pcc_val[i] = mem_internal_allocate_typed(void*);
- pcc_ptr[i+3] = &pcc_val[i];
- }
- }
-
- {
- ffi_arg ret;
- ffi_call(&nci_info->pcc_cif, FFI_FN(Parrot_pcc_fill_params_from_c_args), &ret, pcc_ptr);
- }
-
- Parrot_str_free_cstring(tmp_sig);
-
/*
* Apply Argument Transformations
* this is mostly to transform STRING* into char*
@@ -506,121 +521,109 @@
j_offset++;
break;
case enum_nci_sig_string:
- translation_pointers[i] = *(STRING**)pcc_val[i - j_offset];
+ translation_pointers[i] = pcc_arg[i - j_offset].s;
values[i] = &translation_pointers[i];
break;
case enum_nci_sig_cstring:
- if (STRING_IS_NULL(*(STRING**)pcc_val[i - j_offset])) {
+ if (STRING_IS_NULL(pcc_arg[i - j_offset].s)) {
translation_pointers[i] = (char*) NULL;
}
else {
- translation_pointers[i] = Parrot_str_to_cstring(interp, *(STRING**)pcc_val[i - j_offset]);
+ translation_pointers[i] = Parrot_str_to_cstring(interp, pcc_arg[i - j_offset].s);
}
values[i] = &translation_pointers[i];
break;
case enum_nci_sig_bufref:
- if (STRING_IS_NULL(*(STRING**)pcc_val[i - j_offset])) {
+ if (STRING_IS_NULL(pcc_arg[i - j_offset].s)) {
translation_pointers[i] = (char*) NULL;
}
else {
- translation_pointers[i] = Parrot_str_to_cstring(interp, *(STRING**)pcc_val[i - j_offset]);
+ translation_pointers[i] = Parrot_str_to_cstring(interp, pcc_arg[i - j_offset].s);
}
middle_man[i] = &translation_pointers[i];
values[i] = &middle_man[i];
break;
case enum_nci_sig_cstringref:
- values[i] = &Buffer_bufstart(*(STRING**)pcc_val[i - j_offset]);
+ values[i] = &Buffer_bufstart(pcc_arg[i - j_offset].s);
break;
case enum_nci_sig_char:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(char);
- *((char**)translation_pointers)[i] = (char)*(INTVAL*)pcc_val[i - j_offset];
+ *((char**)translation_pointers)[i] = (char)pcc_arg[i - j_offset].i;
values[i] = translation_pointers[i];
break;
case enum_nci_sig_shortref:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
- ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
+ ((pmc_holder_t*)translation_pointers[i])->p = pcc_arg[i - j_offset].p;
((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(short);
- *((pmc_holder_t*)translation_pointers[i])->ival = (short)VTABLE_get_integer(interp, *(PMC**)pcc_ptr[i - j_offset]);
+ *((pmc_holder_t*)translation_pointers[i])->ival = (short)VTABLE_get_integer(interp, pcc_arg[i - j_offset].p);
values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
break;
case enum_nci_sig_short:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(short);
- *((short**)translation_pointers)[i] = (short)*(INTVAL*)pcc_val[i - j_offset];
+ *((short**)translation_pointers)[i] = (short)pcc_arg[i - j_offset].i;
values[i] = translation_pointers[i];
break;
case enum_nci_sig_intref:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
- ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
+ ((pmc_holder_t*)translation_pointers[i])->p = pcc_arg[i - j_offset].p;
((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(int);
- *((pmc_holder_t*)translation_pointers[i])->ival = (int)VTABLE_get_integer(interp, *(PMC**)pcc_val[i - j_offset]);
+ *((pmc_holder_t*)translation_pointers[i])->ival = (int)VTABLE_get_integer(interp, pcc_arg[i - j_offset].p);
values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
break;
case enum_nci_sig_int:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(int);
- *((int**)translation_pointers)[i] = (int)*(INTVAL*)pcc_val[i - j_offset];
+ *((int**)translation_pointers)[i] = (int)pcc_arg[i - j_offset].i;
values[i] = translation_pointers[i];
break;
case enum_nci_sig_longref:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
- ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
+ ((pmc_holder_t*)translation_pointers[i])->p = pcc_arg[i - j_offset].p;
((pmc_holder_t*)translation_pointers[i])->ival = (INTVAL*)mem_internal_allocate_zeroed_typed(long);
- *((pmc_holder_t*)translation_pointers[i])->ival = (long)VTABLE_get_integer(interp, *(PMC**)pcc_val[i - j_offset]);
+ *((pmc_holder_t*)translation_pointers[i])->ival = (long)VTABLE_get_integer(interp, pcc_arg[i - j_offset].p);
values[i] = &((pmc_holder_t*)translation_pointers[i])->ival;
break;
case enum_nci_sig_long:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(long);
- *((long**)translation_pointers)[i] = (long)*(INTVAL*)pcc_val[i - j_offset];
+ *((long**)translation_pointers)[i] = (long)pcc_arg[i - j_offset].i;
values[i] = translation_pointers[i];
break;
case enum_nci_sig_ptrref:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
- ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)pcc_val[i - j_offset];
+ ((pmc_holder_t*)translation_pointers[i])->p = pcc_arg[i - j_offset].p;
((pmc_holder_t*)translation_pointers[i])->pval = (void**)mem_internal_allocate_zeroed_typed(void*);
- *((pmc_holder_t*)translation_pointers[i])->pval = PMC_IS_NULL(*(PMC**)pcc_val[i - j_offset]) ?
- (void *)NULL : (void*)VTABLE_get_pointer(interp, *(PMC**)pcc_val[i - j_offset]);
+ *((pmc_holder_t*)translation_pointers[i])->pval = PMC_IS_NULL(pcc_arg[i - j_offset].p) ?
+ (void *)NULL : (void*)VTABLE_get_pointer(interp, pcc_arg[i - j_offset].p);
values[i] = &((pmc_holder_t*)translation_pointers[i])->pval;
break;
case enum_nci_sig_pmc:
- translation_pointers[i] = *(PMC**)pcc_val[i - j_offset];
+ translation_pointers[i] = pcc_arg[i - j_offset].p;
values[i] = &translation_pointers[i];
break;
case enum_nci_sig_ptr:
- translation_pointers[i] = PMC_IS_NULL(*(PMC**)pcc_val[i - j_offset]) ?
- (void *)NULL : VTABLE_get_pointer(interp, *(PMC**)pcc_val[i - j_offset]);
+ translation_pointers[i] = PMC_IS_NULL(pcc_arg[i - j_offset].p) ?
+ (void *)NULL : VTABLE_get_pointer(interp, pcc_arg[i - j_offset].p);
values[i] = &translation_pointers[i];
break;
case enum_nci_sig_float:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(float);
- *((float**)translation_pointers)[i] = (float)*(FLOATVAL*)pcc_val[i - j_offset];
+ *((float**)translation_pointers)[i] = (float)pcc_arg[i - j_offset].n;
values[i] = translation_pointers[i];
break;
case enum_nci_sig_double:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(double);
- *((double**)translation_pointers)[i] = *(FLOATVAL*)pcc_val[i - j_offset];
+ *((double**)translation_pointers)[i] = (double)pcc_arg[i - j_offset].n;
values[i] = translation_pointers[i];
break;
case enum_nci_sig_numval:
translation_pointers[i] = mem_internal_allocate_zeroed_typed(FLOATVAL);
- *((FLOATVAL**)translation_pointers)[i] = *(FLOATVAL*)pcc_val[i - j_offset];
+ *((FLOATVAL**)translation_pointers)[i] = pcc_arg[i - j_offset].n;
values[i] = translation_pointers[i];
break;
}
}
- if (pcc_ptr) {
- mem_sys_free(pcc_ptr);
- }
- if (pcc_val) {
- for (i = 0; i < pcc_argc; i++) {
- mem_sys_free(pcc_val[i]);
- }
- if (pcc_val)
- mem_sys_free(pcc_val);
- }
- }
- else {
- /* No arguments */
- values = NULL;
+ if (pcc_arg)
+ mem_gc_free(interp, pcc_arg);
}
/*
More information about the parrot-commits
mailing list