# New Ticket Created by  Jarkko Hietaniemi 
# Please include the string:  [perl #31029]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=31029 >


Things like this

        (int*)&something_not_int

just aren't cool.  The attached patch does a horrible hack for
build_nativecall.pl to introduce the necessary temp variables.

With this patch IRIX64 is now passing all but one of the nci.t.
A separate report on that will follow.

-- 
Jarkko Hietaniemi <[EMAIL PROTECTED]> http://www.iki.fi/jhi/ "There is this special
biologist word we use for 'stable'.  It is 'dead'." -- Jack Cohen

--- build_tools/build_nativecall.pl.dist        2004-08-09 23:41:41.000000000 +0300
+++ build_tools/build_nativecall.pl     2004-08-09 23:41:53.000000000 +0300
@@ -114,7 +114,7 @@
                       S => "STRING *",
                      );
 
-my (%ret_assign) = (p => "PMC_data(final_destination) = return_data;\nREG_PMC(5) = 
final_destination;",
+my (%ret_assign) = (p => "PMC_data(final_destination) = return_data;\n    REG_PMC(5) 
= final_destination;",
                    i => "REG_INT(5) = return_data;",
                    3 => "REG_INT(5) = *return_data;",
                    l => "REG_INT(5) = return_data;",
@@ -126,9 +126,9 @@
                     P => "REG_PMC(5) = return_data;",
                     S => "REG_STR(5) = return_data;",
                    v => "",
-                   t => "final_destination = string_from_cstring(interpreter, 
return_data, 0);\nREG_STR(5) = final_destination;",
-#                  b => "PObj_bufstart(final_destination) = return_data;\nREG_STR(5) 
= final_destination",
-#                  B => "PObj_bufstart(final_destination) = *return_data;\nREG_STR(5) 
= final_destination",
+                   t => "final_destination = string_from_cstring(interpreter, 
return_data, 0);\n    REG_STR(5) = final_destination;",
+#                  b => "PObj_bufstart(final_destination) = return_data;\n    
REG_STR(5) = final_destination",
+#                  B => "PObj_bufstart(final_destination) = *return_data;\n    
REG_STR(5) = final_destination",
                    s => "REG_INT(5) = return_data;",
                    );
 
@@ -223,7 +223,7 @@
     }
 
     # Header
-    generate_func_header($ret, $args, (join ",", @arg), $ret_type{$ret},
+    generate_func_header($ret, $args, [EMAIL PROTECTED], $ret_type{$ret},
                         $ret_type_decl{$ret}, $func_call_assign{$ret},
                         $other_decl{$ret},  $ret_assign{$ret});
 
@@ -375,7 +375,7 @@
 }
 
 sub generate_func_header {
-    my ($return, $params, $call_params, $ret_type, $ret_type_decl,
+    my ($return, $params, $args, $ret_type, $ret_type_decl,
        $return_assign, $other_decl, $final_assign) = @_;
     $other_decl ||= "";
 
@@ -383,18 +383,39 @@
     my $proto = join ', ', map { $proto_type{$_} } split '', $params;
     $extra_preamble = join("", @extra_preamble);
     $extra_postamble = join("", @extra_postamble);
+    # This is an after-the-fact hack: real fix would be in make_arg
+    # or somewhere at that level.  The main point being that one cannot
+    # just cast pointers and expect things to magically align.  Instead
+    # of trying to: (int*)&something_not_int, one HAS to use temporary
+    # variables.  We detect and collect those to "temp".
+    my @temp;
+    for my $i (0..$#$args) {
+        if ($args->[$i] =~ /^\((.+)\*\)&(.+)$/) {
+           $temp[$i] = [ $1, $2 ];
+           $args->[$i] = "&arg$i";
+       }
+    }
+    my $call_params = join(",", @$args);
+    my @tempi = grep { defined $temp[$_] } 0..$#$args;
+    my $temp_decl = join("\n    ", map { "$temp[$_]->[0] arg$_;"} @tempi);
+    my $temp_in   = join("\n    ", map { "arg$_ = $temp[$_]->[1];"} @tempi);
+    my $temp_out  = join("\n    ", map { "$temp[$_]->[1] = arg$_;"} @tempi);
+    $return_data = "$return_assign $final_assign" =~ /return_data/ ? "$ret_type_decl 
return_data;" : "";
     print NCI <<HEADER;
 static void
 pcf_${return}_$params(Interp *interpreter, PMC *self)
 {
     typedef $ret_type (*func_t)($proto);
     func_t pointer;
-    $ret_type_decl return_data;
+    $return_data
+    $temp_decl
     $other_decl
     $extra_preamble
 
     pointer =  (func_t)D2FPTR(PMC_struct_val(self));
+    $temp_in
     $return_assign ($ret_type)(*pointer)($call_params);
+    $temp_out
     $final_assign
     $extra_postamble
 HEADER
@@ -405,7 +426,7 @@
 pcf_${return}(Interp *interpreter, PMC *self)
 {
     $ret_type (*pointer)(void);
-    $ret_type_decl return_data;
+    $return_data
     $other_decl
     $extra_preamble
 

Reply via email to