# 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

Reply via email to