# New Ticket Created by Nick Glencross # Please include the string: [perl #37512] # in the subject line of all future correspondence about this issue. # <URL: https://rt.perl.org/rt3/Ticket/Display.html?id=37512 >
Guys, call_list.txt lists 'T' and 'L' as being prototypes for passing arrays to nci functions, but no implementation exists in build_nativecall.pl. This patch provides an implementation, as well as new tests. Someone might raise the point as to whether the data should be read back into parrot's array, but this is generally going to be tricky and a job for another day. Cheers, Nick
Index: build_tools/build_nativecall.pl =================================================================== --- build_tools/build_nativecall.pl (revision 9534) +++ build_tools/build_nativecall.pl (working copy) @@ -171,6 +171,8 @@ B => "S", v => "v", J => "", + T => "P", + L => "P", ); my $temp_cnt = 0; @@ -466,6 +468,48 @@ "t_$temp_num = GET_NCI_S($reg_num);"; return "t_$temp_num"; }; + /T/ && do { + push @{$temps_ref}, + "PMC* p_$temp_num ; char **m_$temp_num; " . + "int i_$temp_num; int s_$temp_num;"; + push @{$extra_preamble_ref}, + "p_$temp_num = GET_NCI_P($reg_num);\n" . + " s_$temp_num=VTABLE_get_integer (interpreter,p_$temp_num);\n" . + " m_$temp_num=(char **) " . + "malloc((s_$temp_num+1)*sizeof (char *));\n" . + " for(i_$temp_num=0; i_$temp_num<s_$temp_num;i_$temp_num++)\n". + " {STRING* string = VTABLE_get_string_keyed_int (interpreter, ". + "p_$temp_num, i_$temp_num);\n" . + " m_${temp_num}[i_$temp_num] = " . + "string_to_cstring (interpreter, string);}\n" . + " m_${temp_num}[s_$temp_num] = NULL;"; + + push @{$extra_postamble_ref}, + "for(i_$temp_num=0; i_$temp_num<s_$temp_num;i_$temp_num++)\n". + " {string_cstring_free(m_${temp_num}[i_$temp_num]);}\n" . + " free (m_${temp_num});"; + + return "m_$temp_num"; + }; + /L/ && do { + push @{$temps_ref}, + "PMC* p_$temp_num ; long *m_$temp_num; " . + "int i_$temp_num; int s_$temp_num;"; + push @{$extra_preamble_ref}, + "p_$temp_num = GET_NCI_P($reg_num);\n" . + " s_$temp_num=VTABLE_get_integer (interpreter,p_$temp_num);\n" . + " m_$temp_num=(long *) " . + "malloc(s_$temp_num*sizeof (long));\n" . + " for(i_$temp_num=0; i_$temp_num<s_$temp_num;i_$temp_num++)\n". + " {long val = VTABLE_get_integer_keyed_int (interpreter, ". + "p_$temp_num, i_$temp_num);\n" . + " m_${temp_num}[i_$temp_num] = val;}"; + + push @{$extra_postamble_ref}, + "free (m_${temp_num});"; + + return "m_$temp_num"; + }; } sub print_function { Index: src/call_list.txt =================================================================== --- src/call_list.txt (revision 9534) +++ src/call_list.txt (working copy) @@ -41,9 +41,9 @@ # 0 - insert a NULL (pointer) - doesn't comsume a register # J - Parrot_Interp param -# Arrayish things, terminated with NULL/0 +# Arrayish things # L - Long array -# T - Array of string pointers (Converted to cstrings) +# T - Array of string pointers (converted to cstrings) terminated with a NULL # Callback Things @@ -322,3 +322,10 @@ # Sub.__get_regs_used I JOt + +# Enables passing of arrays of char * and long +v iT +v 3T + +v iL +v 3L Index: src/nci_test.c =================================================================== --- src/nci_test.c (revision 9534) +++ src/nci_test.c (working copy) @@ -89,6 +89,8 @@ void nci_vP(void *); void nci_vpii(Outer *, int, int); void nci_vv(void); +void nci_viT(int argc, char *argv[]); +void nci_v3L(int* count, long *longs); /* Declarations for callback tests */ @@ -560,6 +562,33 @@ nci_dlvar_int *= 3; } +/* + +=head1 Functions which act upon Long and String arrays + +=cut + +*/ + + +void +nci_viT (int argc, char *argv[]) { + int i; + for (i = 0 ; i < argc ; i++) { + printf ("%d: %s\n", i, argv[i]); + } +} + + +void +nci_v3L (int* count, long *longs) { + int i; + for (i = 0 ; i < *count ; i++) + printf ("%d: %ld\n", i, longs[i]); + + if (*count) (*count)--; +} + #ifdef TEST char l2 = 4; Index: t/pmc/nci.t =================================================================== --- t/pmc/nci.t (revision 9534) +++ t/pmc/nci.t (working copy) @@ -23,7 +23,7 @@ =cut -use Parrot::Test tests => 59; +use Parrot::Test tests => 61; use Parrot::Config; SKIP: { @@ -2459,3 +2459,74 @@ CODE 42 OUTPUT + +pir_output_is(<< 'CODE', << 'OUTPUT', "nci_viT - (int argc, char *argv[])"); +.sub test :main + .local string library_name + library_name = 'libnci_test' + .local pmc libnci_test + libnci_test = loadlib library_name + .local pmc nci_viT + nci_viT = dlfunc libnci_test, "nci_viT", "viT" + + .local pmc array + array = new Array + array = 5 + array[0] = "hello" + array[1] = "world" + array[3] = -9 + array[4] = 5 + nci_viT (2, array) + nci_viT (5, array) + + array = new FixedIntegerArray + array = 3 + array[0] = 9 + array[1] = -9 + array[2] = -24 + nci_viT (2, array) +.end +CODE +0: hello +1: world +0: hello +1: world +2: +3: -9 +4: 5 +0: 9 +1: -9 +OUTPUT + +pir_output_is(<< 'CODE', << 'OUTPUT', "nci_v3L - (int* argc, long longs[])"); +.sub test :main + .local string library_name + library_name = 'libnci_test' + .local pmc libnci_test + libnci_test = loadlib library_name + .local pmc nci_v3L + nci_v3L = dlfunc libnci_test, "nci_v3L", "v3L" + + .local pmc array + array = new Array + array = 5 + array[0] = "-6" + array[1] = 0 + array[2] = 44.5 + array[3] = -9 + + .local pmc size + size = new Integer + size = 5 + nci_v3L (size, array) + if size == 4 goto OK1 + print "NOK\n" +OK1: +.end +CODE +0: -6 +1: 0 +2: 44 +3: -9 +4: 0 +OUTPUT