Permalink
Browse files

Pushing my changes, these don't fix i386 right now, but should soon.

  • Loading branch information...
1 parent 5c5aa0f commit 37945e3d1e1197df41514f5bac4d027d4ae4410c John Harrison committed Jul 1, 2010
Showing with 396 additions and 114 deletions.
  1. +396 −114 src/pmc/nci.pmc
View
510 src/pmc/nci.pmc
@@ -71,8 +71,8 @@ size_t
parse_identifier(PARROT_INTERP,
STRING* sig, size_t start, size_t end,
ffi_type** sig_obj,
- char** pmc_type, size_t *pmc_count,
- char** translation, size_t *translation_length);
+ char* pmc_type, size_t *pmc_count,
+ char* translation, size_t *translation_length);
static
size_t
@@ -100,17 +100,18 @@ find_matching(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
|| ((x) == '4') || ((x) == '5') || ((x) == '6') || ((x) == '7') \
|| ((x) == '8') || ((x) == '9'))
-#define IS_PREFIX(x) (((x) == '*') || ((x) == 'u') || ((x) == 's'))
+#define IS_PREFIX(x) (((x) == '*') || ((x) == 'u'))
#define IS_OLD_TYPE(x) (((x) == 'P') || ((x) == 'J') || ((x) == 'N') || ((x) == 'S') \
|| ((x) == 'O') || ((x) == '@') || ((x) == 'B') || ((x) == 'p') \
- || ((x) == '2') || ((x) == '3') || ((x) == '4') || ((x) == 'U'))
+ || ((x) == '2') || ((x) == '3') || ((x) == '4') || ((x) == 'U') \
+ || ((x) == 'V'))
#define IS_TYPE(x) (((x) == 'i') || ((x) == 'v') || ((x) == 'l') || ((x) == 't') \
|| ((x) == 'c') || ((x) == 'b') || ((x) == 'f') || ((x) == 'd') \
- || IS_OLD_TYPE(x))
+ || ((x) == 's') || IS_OLD_TYPE(x))
-#define IS_POSTFIX(x) (((x) == '{') || IS_DIGIT(x))
+#define IS_POSTFIX(x) ((x) == '{') /* || IS_DIGIT(x)) */
#define IS_INFIX(x) ((x) == '|')
#define IS_START_CIRCUMFIX(x) ((x) == '(')
#define IS_END_CIRCUMFIX(x) ((x) == ')')
@@ -121,6 +122,11 @@ find_matching(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
#define PREFIX_UNSIGNED (1<<1)
#define PREFIX_NATIVE (1<<2)
+typedef struct pmc_holder_t {
+ PMC* p;
+ INTVAL* val;
+} pmc_holder_t;
+
/*
=item C<static INTVAL parse_sig(PARROT_INTERP, STRING *sig,
@@ -141,8 +147,26 @@ parse_sig(PARROT_INTERP, STRING *sig, size_t sig_length, Parrot_NCI_attributes *
ffi_type *return_type;
ffi_type **arg_types;
- size_t i = parse_return(interp, sig, sig_length, nci_info, &return_type);
- parse_args(interp, sig, i, sig_length, nci_info, &arg_types);
+ if (sig_length) {
+ size_t i = parse_return(interp, sig, sig_length, nci_info, &return_type);
+ if (i < sig_length)
+ parse_args(interp, sig, i, sig_length, nci_info, &arg_types);
+ else {
+ arg_types = mem_internal_allocate_n_zeroed_typed(1, ffi_type*);
+ arg_types[0] = &ffi_type_void;
+ nci_info->pcc_params_signature = string_make(interp, "", 1, NULL, 0);
+ nci_info->arg_translation = "";
+ nci_info->arity = 0;
+ }
+ }
+ else {
+ arg_types = mem_internal_allocate_n_zeroed_typed(1, ffi_type*);
+ arg_types[0] = &ffi_type_void;
+ return_type = &ffi_type_void;
+ nci_info->pcc_params_signature = string_make(interp, "", 1, NULL, 0);
+ nci_info->arg_translation = "";
+ nci_info->arity = 0;
+ }
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
nci_info->arity, return_type, arg_types) == FFI_OK) {
@@ -179,7 +203,7 @@ See C<parse_identifier> to see how a single identifer is parsed.
static size_t
parse_return(PARROT_INTERP, STRING *sig, size_t sig_length,
Parrot_NCI_attributes* nci_info, ffi_type **return_type) {
- char t[16] = {0};
+ char *t = mem_allocate_n_zeroed_typed(2, char);
size_t j = 0, k = 0;
/* Should be 1 character plus a NULL" */
char * result_sig = mem_allocate_n_zeroed_typed(2, char);
@@ -190,6 +214,7 @@ parse_return(PARROT_INTERP, STRING *sig, size_t sig_length,
t, &k);
nci_info->pcc_return_signature = string_make(interp, result_sig, 2, NULL, 0);
+ nci_info->return_translation = (void*)t;
mem_sys_free(result_sig);
return result_length;
}
@@ -263,8 +288,8 @@ static size_t
parse_identifier(PARROT_INTERP,
STRING *sig, size_t start, size_t sig_length,
ffi_type **type_obj,
- char **type, size_t *pmc_count,
- char **translation, size_t *translation_count) {
+ char *type, size_t *pmc_count,
+ char *translation, size_t *translation_count) {
size_t i = start;
INTVAL done = 0;
@@ -297,9 +322,11 @@ parse_identifier(PARROT_INTERP,
}
translation[(*translation_count)++] = ' ';
switch (c) {
+ case (INTVAL)' ':
case (INTVAL)'0': /* null ptr or such - doesn't consume a reg */
break;
case (INTVAL)'c':
+ translation[(*translation_count) - 1] = 'c';
type[(*pmc_count)++] = 'I';
if (prefix & PREFIX_UNSIGNED) {
*type_obj = &ffi_type_uchar;
@@ -308,7 +335,9 @@ parse_identifier(PARROT_INTERP,
*type_obj = &ffi_type_schar;
}
break;
+ /*
case (INTVAL)'b':
+ translation[(*translation_count) - 1] = 'b';
type[(*pmc_count)++] = 'I';
if (prefix & PREFIX_UNSIGNED) {
*type_obj = &ffi_type_uint8;
@@ -317,7 +346,19 @@ parse_identifier(PARROT_INTERP,
*type_obj = &ffi_type_sint8;
}
break;
+ */
+ case (INTVAL)'B':
+ translation[(*translation_count) - 1] = 'B';
+ type[(*pmc_count)++] = 'S';
+ *type_obj = &ffi_type_pointer;
+ break;
+ case (INTVAL)'b':
+ translation[(*translation_count) - 1] = 'b';
+ type[(*pmc_count)++] = 'S';
+ *type_obj = &ffi_type_pointer;
+ break;
case (INTVAL)'s':
+ translation[(*translation_count) - 1] = 's';
type[(*pmc_count)++] = 'I';
if (prefix & PREFIX_UNSIGNED) {
*type_obj = &ffi_type_ushort;
@@ -328,6 +369,7 @@ parse_identifier(PARROT_INTERP,
break;
case (INTVAL)'I': /* INTVAL */
case (INTVAL)'i':
+ translation[(*translation_count) - 1] = 'i';
type[(*pmc_count)++] = 'I';
if (prefix & PREFIX_UNSIGNED) {
*type_obj = &ffi_type_uint;
@@ -337,6 +379,7 @@ parse_identifier(PARROT_INTERP,
}
break;
case (INTVAL)'l':
+ translation[(*translation_count) - 1] = 'l';
type[(*pmc_count)++] = 'I';
if (prefix & PREFIX_UNSIGNED) {
*type_obj = &ffi_type_ulong;
@@ -346,6 +389,7 @@ parse_identifier(PARROT_INTERP,
}
break;
case (INTVAL)'q':
+ translation[(*translation_count) - 1] = 'q';
type[(*pmc_count)++] = 'I';
if (prefix & PREFIX_UNSIGNED) {
*type_obj = &ffi_type_uint64;
@@ -359,12 +403,32 @@ parse_identifier(PARROT_INTERP,
*type_obj = &ffi_type_pointer;
break;
case (INTVAL)'p': /* push pmc->data */
- case (INTVAL)'P': /* push PMC * */
- case (INTVAL)'V': /* push PMC * */
+ translation[(*translation_count) - 1] = 'p';
+ type[(*pmc_count)++] = 'P';
+ *type_obj = &ffi_type_pointer;
+ break;
case (INTVAL)'2':
+ translation[(*translation_count) - 1] = '2';
+ type[(*pmc_count)++] = 'P';
+ *type_obj = &ffi_type_pointer;
+ break;
case (INTVAL)'3':
+ translation[(*translation_count) - 1] = '3';
+ type[(*pmc_count)++] = 'P';
+ *type_obj = &ffi_type_pointer;
+ break;
case (INTVAL)'4':
- case (INTVAL)'B':
+ translation[(*translation_count) - 1] = '4';
+ type[(*pmc_count)++] = 'P';
+ *type_obj = &ffi_type_pointer;
+ break;
+ case (INTVAL)'P': /* push PMC * */
+ translation[(*translation_count) - 1] = 'P';
+ type[(*pmc_count)++] = 'P';
+ *type_obj = &ffi_type_pointer;
+ break;
+ case (INTVAL)'V': /* push PMC * */
+ translation[(*translation_count) - 1] = 'V';
type[(*pmc_count)++] = 'P';
*type_obj = &ffi_type_pointer;
break;
@@ -380,16 +444,27 @@ parse_identifier(PARROT_INTERP,
type[(*pmc_count)++] = 'v';
*type_obj = &ffi_type_void;
break;
+#if (DOUBLE_SIZE == 4) /* FLOATVAL is a float */
+ case (INTVAL)'N':
+#endif
case (INTVAL)'f':
+ translation[(*translation_count) - 1] = 'f';
type[(*pmc_count)++] = 'N';
*type_obj = &ffi_type_float;
break;
+#if (DOUBLE_SIZE == 8) /* FLOATVAL is a double */
case (INTVAL)'N':
+#endif
case (INTVAL)'d':
+ translation[(*translation_count) - 1] = 'd';
type[(*pmc_count)++] = 'N';
*type_obj = &ffi_type_double;
break;
+#if (DOUBEL_SIZE > 8) /* FLOATVAL is a long double */
+ case (INTVAL)'N':
+#endif
case (INTVAL)'D':
+ translation[(*translation_count) - 1] = 'D';
type[(*pmc_count)++] = 'N';
*type_obj = &ffi_type_longdouble;
break;
@@ -458,18 +533,15 @@ Parse a prefix character.
static INTVAL
parse_prefix(INTVAL c) {
switch (c) {
- case '*':
- return PREFIX_POINTER;
- break;
- case 'u':
- return PREFIX_UNSIGNED;
- break;
- case 's':
- return PREFIX_SIGNED;
- break;
- default:
- return 0;
- break;
+ case '*':
+ return PREFIX_POINTER;
+ break;
+ case 'u':
+ return PREFIX_UNSIGNED;
+ break;
+ default:
+ return 0;
+ break;
}
return 0;
@@ -495,7 +567,7 @@ parse_structure(PARROT_INTERP, STRING* sig, size_t start, size_t sig_length,
size_t element_counter = 0;
INTVAL c;
- *type_obj = mem_internal_allocate_typed(ffi_type*);
+ *type_obj = (ffi_type*)mem_internal_allocate_typed(ffi_type*);
(*type_obj)->elements = mem_internal_allocate_n_zeroed_typed(struct_len + 1, ffi_type*);
(*type_obj)->size = (*type_obj)->alignment = 0;
@@ -747,6 +819,7 @@ pmclass NCI auto_attrs provides invokable {
ATTR STRING *pcc_params_signature;
ATTR STRING *pcc_return_signature;
ATTR void *arg_translation;
+ ATTR void *return_translation;
ATTR INTVAL arity; /* Cached arity of the NCI. */
/* MMD fields */
@@ -875,6 +948,7 @@ Free all of the memory used internally to store various things, like libffi call
mem_sys_free(nci_info->cif);
mem_sys_free(nci_info->arg_translation);
mem_sys_free(nci_info->arg_types);
+ mem_sys_free(nci_info->return_translation);
}
}
@@ -955,31 +1029,34 @@ class, the PMC arguments are shifted down.
GET_ATTR_orig_func(INTERP, SELF, orig_func);
GET_ATTR_fb_info(INTERP, SELF, fb_info);
- func = orig_func;
+ func = FFI_FN(orig_func);
if (!func) {
/* build the thunk only when necessary */
- func = build_func(interp, nci_info);
+ func = FFI_FN(build_func(interp, nci_info));
if (!func)
Parrot_ex_throw_from_c_args(INTERP, NULL,
EXCEPTION_INVALID_OPERATION,
"attempt to call NULL function");
}
- func = D2FPTR(orig_func);
+ func = FFI_FN(D2FPTR(orig_func));
func(INTERP, SELF, fb_info);
}
else {
PMC *positional, *arg_iter;
+ STRING *void_return;
void **values, **middle_man, **pcc_values, **translation_pointers;
- void *return_data, *return_pointer;
- size_t count, i;
+ void *return_data;
+ size_t count, i, j_offset;
char *tmp_sig;
ffi_cif *cif, pcc_cif;
ffi_type **pcc_args;
- GET_ATTR_cif(INTERP, SELF, cif);
+ PMC * pmc_3;
+
+ cif = nci_info->cif;
GET_ATTR_func(INTERP, SELF, func);
if (!cif) {
@@ -992,87 +1069,253 @@ class, the PMC arguments are shifted down.
"attempt to call NULL function");
}
- values = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 1, void*);
- pcc_args = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 4, ffi_type*);
-
- for (i = 0; i < nci_info->arity + 3; i++) {
- pcc_args[i] = &ffi_type_pointer;
- }
-
- if (ffi_prep_cif(&pcc_cif, FFI_DEFAULT_ABI, 3 + nci_info->arity,
- &ffi_type_void, pcc_args) != FFI_OK) {
- Parrot_ex_throw_from_c_args(INTERP, NULL,
- EXCEPTION_INVALID_OPERATION,
- "Bad signature generated for Parrot_pcc_fill_params_from_c_args in NCI");
- }
+ if (nci_info->arity > 0) {
+ size_t pcc_values_offset, pcc_values_size;
+ /* Function has arguments */
+ values = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 1, void*);
+ pcc_args = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 4, ffi_type*);
+
+ if (nci_info->pcc_params_signature)
+ tmp_sig = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
+
+ pcc_args[0] = &ffi_type_pointer;
+ pcc_args[1] = &ffi_type_pointer;
+ pcc_args[2] = &ffi_type_pointer;
+ pcc_values_size = 0;
+ for (i = 0; i < nci_info->arity; i++) {
+ pcc_args[i + 3] = &ffi_type_pointer;
+ if (tmp_sig[i] == 'N')
+ pcc_values_size += sizeof(FLOATVAL);
+ else if (tmp_sig[i] == 'I')
+ pcc_values_size += sizeof(INTVAL);
+ else if (tmp_sig[i] == 'P' || tmp_sig[i] == 'S')
+ pcc_values_size += sizeof(void*);
+ }
- pcc_values = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 4, void*);
- tmp_sig = Parrot_str_to_cstring(interp, nci_info->pcc_params_signature);
+ if (ffi_prep_cif(&pcc_cif, FFI_DEFAULT_ABI, 3 + nci_info->arity,
+ &ffi_type_void, pcc_args) != FFI_OK) {
+ Parrot_ex_throw_from_c_args(INTERP, NULL,
+ EXCEPTION_INVALID_OPERATION,
+ "Bad signature generated for Parrot_pcc_fill_params_from_c_args in NCI");
+ }
- /* Setup Parrot_pcc_fill_params_from_c_args required arguments */
- pcc_values[0] = &interp;
- pcc_values[1] = &call_object;
- pcc_values[2] = &tmp_sig;
+ fprintf(stderr, "Allocating... %d\n", pcc_values_size);
+
+ pcc_values = mem_internal_allocate_zeroed(pcc_values_size + sizeof(void*) * 4);
+
+ /* Setup Parrot_pcc_fill_params_from_c_args required arguments */
+ pcc_values[0] = &interp;
+ pcc_values[1] = &call_object;
+ pcc_values[2] = &tmp_sig;
+
+ middle_man = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 1, void*);
+
+ /* Fill in arg references, J is magically inserted, so we need
+ * to offset the other variables if a J is supposed to be used
+ */
+ j_offset = 0;
+ pcc_values_offset = 0;
+ for (i = 0; i < nci_info->arity; i++) {
+ if (((char*)nci_info->arg_translation)[i] == 'J')
+ j_offset++;
+ middle_man[i] = &values[i + j_offset];
+ pcc_values[i + 3 + pcc_values_offset] = &middle_man[i];
+ if (tmp_sig[i] == 'N') {
+ pcc_values_offset += 1;
+ }
+ }
- middle_man = mem_internal_allocate_n_zeroed_typed(nci_info->arity + 1, void*);
+ ffi_call(&pcc_cif, FFI_FN(Parrot_pcc_fill_params_from_c_args), NULL, pcc_values);
+ Parrot_str_free_cstring(tmp_sig);
+
+ /*
+ * Apply Argument Transformations
+ * this is mostly to transform STRING* into char*
+ * and add the parrot interp argument if it needs it
+ * but other transformations might apply later, like packing an
+ * object into a ManagedStruct
+ */
+ translation_pointers = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
+ for (i = 0; i < nci_info->arity; i++) {
+ switch ((INTVAL)((char*)nci_info->arg_translation)[i]) {
+ case 'J':
+ values[i] = &interp;
+ break;
+ case 't':
+ if (STRING_IS_NULL((STRING*)values[i])) {
+ translation_pointers[i] = (char*) NULL;
+ }
+ else {
+ translation_pointers[i] = Parrot_str_to_cstring(interp, (STRING*)values[i]);
+ }
+ values[i] = &translation_pointers[i];
+ break;
+ case 'B':
+ if (STRING_IS_NULL((STRING*)values[i])) {
+ translation_pointers[i] = (char*) NULL;
+ }
+ else {
+ translation_pointers[i] = Parrot_str_to_cstring(interp, (STRING*)values[i]);
+ }
+ middle_man[i] = &translation_pointers[i];
+ values[i] = &middle_man[i];
+ break;
+ case 'b':
+ values[i] = &Buffer_bufstart((STRING*)values[i]);
+ break;
+ case 'c':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(char);
+ *((char**)translation_pointers)[i] = (char)*(INTVAL*)middle_man[i];
+ values[i] = translation_pointers[i];
+ break;
+ case '2':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
+ ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)middle_man[i];
+ ((pmc_holder_t*)translation_pointers[i])->val = mem_internal_allocate_zeroed_typed(short);
+ *((pmc_holder_t*)translation_pointers[i])->val = (short)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
+ values[i] = &((pmc_holder_t*)translation_pointers[i])->val;
+ break;
+ case 's':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(short);
+ *((short**)translation_pointers)[i] = (short)*(INTVAL*)middle_man[i];
+ values[i] = translation_pointers[i];
+ break;
+ case '3':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
+ ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)middle_man[i];
+ ((pmc_holder_t*)translation_pointers[i])->val = mem_internal_allocate_zeroed_typed(int);
+ *((pmc_holder_t*)translation_pointers[i])->val = (int)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
+ values[i] = &((pmc_holder_t*)translation_pointers[i])->val;
+ break;
+ case 'i':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(int);
+ *((int**)translation_pointers)[i] = (int)*(INTVAL*)middle_man[i];
+ values[i] = translation_pointers[i];
+ break;
+ case '4':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
+ ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)middle_man[i];
+ ((pmc_holder_t*)translation_pointers[i])->val = mem_internal_allocate_zeroed_typed(long);
+ *((pmc_holder_t*)translation_pointers[i])->val = (long)VTABLE_get_integer(interp, *(PMC**)middle_man[i]);
+ values[i] = &((pmc_holder_t*)translation_pointers[i])->val;
+ break;
+ case 'l':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(long);
+ *((long**)translation_pointers)[i] = (long)*(INTVAL*)middle_man[i];
+ values[i] = translation_pointers[i];
+ break;
+ case 'q':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(long long);
+ *((long long**)translation_pointers)[i] = (long long)*(INTVAL*)middle_man[i];
+ values[i] = translation_pointers[i];
+ break;
+ case 'V':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(pmc_holder_t);
+ ((pmc_holder_t*)translation_pointers[i])->p = *(PMC**)middle_man[i];
+ ((pmc_holder_t*)translation_pointers[i])->val = mem_internal_allocate_zeroed_typed(void*);
+ *((pmc_holder_t*)translation_pointers[i])->val = (void*)VTABLE_get_pointer(interp, *(PMC**)middle_man[i]);
+ values[i] = &((pmc_holder_t*)translation_pointers[i])->val;
+ break;
+ case 'P':
+ translation_pointers[i] = values[i];
+ values[i] = &translation_pointers[i];
+ break;
+ case 'p':
+ translation_pointers[i] = PMC_IS_NULL((PMC*)values[i]) ? (void *)NULL : VTABLE_get_pointer(interp, (PMC*)values[i]);
+ values[i] = &translation_pointers[i];
+ break;
+ case 'f':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(float);
+ *((float**)translation_pointers)[i] = (float)*(FLOATVAL*)middle_man[i];
+ values[i] = translation_pointers[i];
+ break;
+ case 'd':
+ translation_pointers[i] = mem_internal_allocate_zeroed_typed(double);
+ *((double**)translation_pointers)[i] = *(FLOATVAL*)middle_man[i];
+ values[i] = translation_pointers[i];
+ break;
+ case ' ':
+ default:
+ break;
+ }
+ }
- /* Fill in arg references, J is magically inserted, so we need
- * to offset the other variables if a J is supposed to be used
- */
- int j_offset = 0;
- for (i = 0; i < nci_info->arity; i++) {
- if (((INTVAL*)nci_info->arg_translation)[i] == 'J')
- j_offset++;
- middle_man[i] = &values[i + j_offset];
- pcc_values[i + 3] = &middle_man[i];
+ if (pcc_args) {
+ mem_sys_free(pcc_args);
+ }
+ if (pcc_values) {
+ mem_sys_free(pcc_values);
+ }
+ }
+ else {
+ /* No arguments */
+ values = NULL;
}
-
- ffi_call(&pcc_cif, FFI_FN(Parrot_pcc_fill_params_from_c_args), NULL, pcc_values);
- Parrot_str_free_cstring(tmp_sig);
/*
- * Apply Argument Transformations
- * this is mostly to transform STRING* into char*
- * and add the parrot interp argument if it needs it
- * but other transformations might apply later, like packing an
- * object into a ManagedStruct
+ * This will allow for any type of datat to be returned.
+ * Including one day Structures
*/
- translation_pointers = mem_internal_allocate_n_zeroed_typed(nci_info->arity, void*);
- for (i = 0; i < nci_info->arity; i++) {
- switch ((INTVAL)((INTVAL*)nci_info->arg_translation)[i]) {
- case (INTVAL)'J':
- values[i] = &interp;
+ return_data = mem_internal_allocate_zeroed(cif->rtype->size);
+
+ ffi_call(cif, FFI_FN(func), return_data, values);
+
+ if (cif->rtype != &ffi_type_void) {
+ char *s;
+ PMC *ret_object;
+ s = Parrot_str_to_cstring(interp, nci_info->pcc_return_signature);
+ switch (*(char*)nci_info->return_translation) {
+ case 'p':
+ {
+ PMC *final_destination = PMCNULL;
+
+ if (*(void**)return_data != NULL) {
+ final_destination = Parrot_pmc_new(interp, enum_class_UnManagedStruct);
+ VTABLE_set_pointer(interp, final_destination, *(void**)return_data);
+
+ }
+ ret_object = Parrot_pcc_build_call_from_c_args(interp,
+ call_object,
+ s, final_destination);
+
+ }
break;
- case (INTVAL)'t':
- if (STRING_IS_NULL((STRING*)middle_man[i])) {
- translation_pointers[i] = (char*) NULL;
+ case 't':
+ {
+ STRING *final_destination = Parrot_str_new(interp, *(char**)return_data, 0);
+ ret_object = Parrot_pcc_build_call_from_c_args(interp,
+ call_object,
+ s, final_destination);
}
- else {
- translation_pointers[i] = Parrot_str_to_cstring(interp, values[i]);
+ break;
+ case 'f':
+ {
+ FLOATVAL final_destination = *(float*)return_data;
+
+ ret_object = Parrot_pcc_build_call_from_c_args(interp,
+ call_object,
+ s, final_destination);
}
- values[i] = &translation_pointers[i];
break;
- case (INTVAL)' ':
default:
+ switch (s[0]) {
+ case 'N':
+ ret_object = Parrot_pcc_build_call_from_c_args(interp,
+ call_object,
+ s, *(FLOATVAL*)return_data);
+ case 'I':
+ ret_object = Parrot_pcc_build_call_from_c_args(interp,
+ call_object,
+ s, *(INTVAL*)return_data);
+ case 'P':
+ case 'S':
+ default:
+ ret_object = Parrot_pcc_build_call_from_c_args(interp,
+ call_object,
+ s, *(void**)return_data);
+ }
break;
}
- }
-
- /*
- * This will allow for any type of datat to be returned.
- * Including one day Structures
- */
- return_data = mem_internal_allocate(cif->rtype->size);
- return_pointer = &return_data;
-
- ffi_call(cif, FFI_FN(func), &return_pointer, values);
-
- STRING * void_return = string_make(interp, "v", 1, "ascii", 0);
- if (!Parrot_str_equal(interp, nci_info->pcc_return_signature, void_return)) {
- char *s = Parrot_str_to_cstring(interp, nci_info->pcc_return_signature);
- PMC *ret_object = Parrot_pcc_build_call_from_c_args(interp,
- call_object,
- s, return_pointer);
Parrot_str_free_cstring(s);
}
@@ -1081,32 +1324,65 @@ class, the PMC arguments are shifted down.
* and any other translations that use temporary memory
*/
for (i = 0; i < nci_info->arity; i++) {
- switch ((INTVAL)((INTVAL*)nci_info->arg_translation)[i]) {
+ switch ((INTVAL)((char*)nci_info->arg_translation)[i]) {
+ case (INTVAL)'B':
+ if (translation_pointers[i]) {
+ Parrot_str_free_cstring(translation_pointers[i]);
+ }
+ break;
case (INTVAL)'t':
if (translation_pointers[i]) {
Parrot_str_free_cstring(translation_pointers[i]);
}
break;
+ case (INTVAL)'2':
+ VTABLE_set_integer_native(interp, ((pmc_holder_t*)translation_pointers[i])->p, (INTVAL)*(short*)((pmc_holder_t*)translation_pointers[i])->val);
+ if (translation_pointers[i]) {
+ mem_sys_free(translation_pointers[i]);
+ }
+ break;
+ case (INTVAL)'3':
+ VTABLE_set_integer_native(interp, ((pmc_holder_t*)translation_pointers[i])->p, (INTVAL)*(int*)((pmc_holder_t*)translation_pointers[i])->val);
+ if (translation_pointers[i]) {
+ mem_sys_free(translation_pointers[i]);
+ }
+ break;
+ case (INTVAL)'4':
+ VTABLE_set_integer_native(interp, ((pmc_holder_t*)translation_pointers[i])->p, (INTVAL)*(long*)((pmc_holder_t*)translation_pointers[i])->val);
+ if (translation_pointers[i]) {
+ mem_sys_free(translation_pointers[i]);
+ }
+ break;
+ case (INTVAL)'V':
+ VTABLE_set_pointer(interp, ((pmc_holder_t*)translation_pointers[i])->p, (void*)*(void**)((pmc_holder_t*)translation_pointers[i])->val);
+ if (translation_pointers[i]) {
+ mem_sys_free(translation_pointers[i]);
+ }
+ break;
+ case (INTVAL)'d':
+ case (INTVAL)'c':
+ case (INTVAL)'s':
+ case (INTVAL)'i':
+ case (INTVAL)'l':
+ case (INTVAL)'q':
+ if (translation_pointers[i]) {
+ mem_sys_free(translation_pointers[i]);
+ }
+ break;
default:
break;
}
}
+ if (nci_info->arity > 0 && middle_man) {
+ mem_sys_free(middle_man);
+ }
if (return_data) {
mem_sys_free(return_data);
}
- if (pcc_args) {
- mem_sys_free(pcc_args);
- }
- if (pcc_values) {
- mem_sys_free(pcc_values);
- }
if (values) {
mem_sys_free(values);
}
- if (middle_man) {
- mem_sys_free(middle_man);
- }
}
cont = INTERP->current_cont;
@@ -1173,11 +1449,16 @@ Return the arity of the NCI (the number of arguments).
INTVAL arity = 0;
if (nci_info) {
- if (!nci_info->func)
- build_func(INTERP, nci_info);
- if (nci_info->func) {
- arity = nci_info->arity;
- RETURN(INTVAL arity);
+ if (PObj_flag_TEST(private2, SELF)) {
+ }
+ else {
+ if (!nci_info->cif) {
+ nci_info->cif = build_libffi_func(interp, nci_info);
+ }
+ if (nci_info->cif) {
+ arity = nci_info->arity;
+ RETURN(INTVAL arity);
+ }
}
}
@@ -1212,3 +1493,4 @@ Updates by John Harrison, Summer 2010, GSoC.
* vim: expandtab shiftwidth=4:
*/
+

0 comments on commit 37945e3

Please sign in to comment.