# 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