Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 20 additions & 22 deletions dev/tools/perl_test_runner.pl
Original file line number Diff line number Diff line change
Expand Up @@ -161,26 +161,22 @@ sub run_tests_parallel {
sub process_test_result {
my ($test_info, $test_dir) = @_;

# Look for result file from child
my $temp_pattern = "/tmp/perl_test_*";
my @temp_files = glob($temp_pattern);

# Each child writes one JSON blob to a path keyed by its PID — no fragile
# glob+scan of /tmp across parallel forks (would mis-assign results under
# load when multiple temp files coexist or decode attempts leave stale refs).
my $child_pid = $test_info->{child_pid};
my $result_path = "/tmp/perl_test_runner_result_$child_pid";
my $result_data;
for my $temp_file (@temp_files) {
if (-f $temp_file && open my $fh, '<', $temp_file) {
local $/;
my $json_data = <$fh>;
close $fh;

eval {
$result_data = JSON::PP->new->decode($json_data);
};

if ($result_data && $result_data->{test_file} eq $test_info->{test_file}) {
unlink $temp_file;
last;
}
}
if (defined $child_pid && -f $result_path && open my $fh, '<', $result_path) {
local $/;
my $json_data = <$fh>;
close $fh;
unlink $result_path;
eval {
$result_data = JSON::PP->new->decode($json_data);
1;
};
$result_data = undef unless $result_data;
}

# Fallback if we couldn't read the result
Expand Down Expand Up @@ -403,9 +399,10 @@ sub start_test_job {
# Child process
my $result = run_single_test($test_file);

# Write result to temporary file for parent to read
my $temp_file = "/tmp/perl_test_$$" . "_" . time() . "_" . rand(1000);
if (open my $fh, '>', $temp_file) {
# Exactly one canonical path per child PID so the parent's waitpid reap
# reads the matching JSON — never scan shared /tmp/perl_test_* blobs.
my $result_path = "/tmp/perl_test_runner_result_$$";
if (open my $fh, '>', $result_path) {
print $fh JSON::PP->new->encode({
test_file => $test_file,
test_index => $test_index,
Expand All @@ -421,6 +418,7 @@ sub start_test_job {
test_file => $test_file,
test_index => $test_index,
start_time => time(),
child_pid => $pid,
};
}
}
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/org/perlonjava/runtime/operators/MathOperators.java
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,18 @@ public static RuntimeScalar modulusAssignWarn(RuntimeScalar arg1, RuntimeScalar
* @return A new RuntimeScalar representing the integer division result.
*/
public static RuntimeScalar integerDivide(RuntimeScalar arg1, RuntimeScalar arg2) {
// Like divide(): overloaded packages (Math::BigInt, Math::BigRat, …) still receive
// operator dispatch under "use integer"; native IV division must not bypass overload.
int blessId = blessedId(arg1);
int blessId2 = blessedId(arg2);
if (blessId < 0 || blessId2 < 0) {
RuntimeScalar result =
OverloadContext.tryTwoArgumentOverload(arg1, arg2, blessId, blessId2, "(/", "/");
if (result != null) {
return result;
}
}

long dividend = arg1.getLong();
long divisor = arg2.getLong();

Expand All @@ -832,6 +844,16 @@ public static RuntimeScalar integerDivide(RuntimeScalar arg1, RuntimeScalar arg2
* @return A new RuntimeScalar representing the integer division result.
*/
public static RuntimeScalar integerDivideWarn(RuntimeScalar arg1, RuntimeScalar arg2) {
int blessId = blessedId(arg1);
int blessId2 = blessedId(arg2);
if (blessId < 0 || blessId2 < 0) {
RuntimeScalar result =
OverloadContext.tryTwoArgumentOverload(arg1, arg2, blessId, blessId2, "(/", "/");
if (result != null) {
return result;
}
}

// Convert to number with warning for uninitialized values
arg1 = arg1.getNumberWarn("integer division (/)");
arg2 = arg2.getNumberWarn("integer division (/)");
Expand Down Expand Up @@ -873,6 +895,16 @@ public static RuntimeScalar integerDivideAssignWarn(RuntimeScalar arg1, RuntimeS
* @return A new RuntimeScalar representing the integer modulus.
*/
public static RuntimeScalar integerModulus(RuntimeScalar arg1, RuntimeScalar arg2) {
int blessId = blessedId(arg1);
int blessId2 = blessedId(arg2);
if (blessId < 0 || blessId2 < 0) {
RuntimeScalar result =
OverloadContext.tryTwoArgumentOverload(arg1, arg2, blessId, blessId2, "(%", "%");
if (result != null) {
return result;
}
}

long dividend = arg1.getLong();
long divisor = arg2.getLong();

Expand Down
Loading