PAX
view release on metacpan or search on metacpan
lib/PAX/StandaloneDispatch.pm view on Meta::CPAN
my ($image, $extract_dir) = @_;
my $err = gensym;
my $pid = open3(my $in, my $out, $err, $image->{output_path}, '--pax-standalone-extract', $extract_dir);
close $in;
local $/;
<$out>;
my $stderr = <$err> // '';
waitpid($pid, 0);
die "standalone extraction failed for $image->{output_path}: $stderr\n" if ($? >> 8) != 0;
}
sub _runtime_paths {
my ($image, $extract_dir) = @_;
my $code_root = File::Spec->catdir($extract_dir, 'code');
my $runtime_root = File::Spec->catdir($extract_dir, 'runtime');
my $assets_root = File::Spec->catdir($extract_dir, 'assets');
my $entrypoint = File::Spec->catfile($code_root, split m{/}, $image->{entrypoint}{logical_path});
my $perl_exec = ($image->{runtime}{mode} // '') eq 'bundled_perl'
? File::Spec->catfile($runtime_root, split m{/}, ($image->{runtime}{perl_binary_logical_path} // 'bin/perl'))
: 'perl';
my @lib_roots = map { File::Spec->catdir($code_root, split m{/}) } @{ $image->{lib_dirs} // [] };
my @runtime_roots = map { File::Spec->catdir($runtime_root, split m{/}) } @{ $image->{runtime}{bundled_inc_roots} // [] };
return {
extract_dir => $extract_dir,
code_root => $code_root,
runtime_root => $runtime_root,
assets_root => $assets_root,
entrypoint => $entrypoint,
manifest_path => File::Spec->catfile($image->{standalone_dir}, 'manifest.json'),
perl_exec => $perl_exec,
perl5lib => join(':', grep { defined && length } (@lib_roots, @runtime_roots)),
};
}
sub _restore_executable_bits {
my ($image, $paths) = @_;
chmod 0700, $paths->{perl_exec} if ($image->{runtime}{mode} // '') eq 'bundled_perl' && -f $paths->{perl_exec};
for my $region (@{ $image->{native_dispatch} // [] }) {
next if !$region->{executable_logical_path};
my $path = File::Spec->catfile($paths->{extract_dir}, split m{/}, $region->{executable_logical_path});
chmod 0700, $path if -f $path;
}
}
sub _run_perl_region {
my (%args) = @_;
my $paths = $args{paths};
my $region = $args{region};
my $perl = $paths->{perl_exec};
my $script = q{
my ($entry, $region, $left, $right) = @ARGV;
require PAX::StandaloneRuntime;
my $rv = PAX::StandaloneRuntime->run(entrypoint => $entry, argv => []);
my $qualified = $region =~ /::/ ? $region : "main::$region";
no strict 'refs';
my $value = &{$qualified}(0 + $left, 0 + $right);
print defined $value ? $value : q{};
};
local $ENV{PERL5LIB} = $paths->{perl5lib} if defined $paths->{perl5lib} && length $paths->{perl5lib};
local $ENV{PAX_EMBEDDED_ASSET_ROOT} = $paths->{assets_root};
local $ENV{PAX_STANDALONE_MANIFEST_PATH} = $paths->{manifest_path};
local $ENV{PAX_STANDALONE_TMPDIR} = $paths->{extract_dir};
my $err = gensym;
my $pid = open3(my $in, my $out, $err, $perl, '-e', $script, $paths->{entrypoint}, $region->{region_name}, $args{left}, $args{right});
close $in;
local $/;
my $stdout = <$out> // '';
my $stderr = <$err> // '';
waitpid($pid, 0);
chomp $stdout;
return {
status => ($? >> 8) == 0 ? 'ok' : 'error',
exit => $? >> 8,
stdout => $stdout,
stderr => $stderr,
value => $stdout =~ /^-?\d+$/ ? 0 + $stdout : undef,
reason => ($? >> 8) == 0 ? 'perl_region_fallback' : 'perl_region_execution_failed',
};
}
1;
=pod
=head1 NAME
PAX::StandaloneDispatch - standalone command and region dispatch helper
=head1 SYNOPSIS
use PAX::StandaloneDispatch;
my $obj = PAX::StandaloneDispatch->new(...);
my $result = $obj->run_i64(...);
=head1 DESCRIPTION
Holds the dispatch information that standalone binaries use to route built-in commands, helpers, and native regions.
=head1 METHODS
=head2 new, run_i64
These are the public entrypoints exposed by this module's current interface.
=head1 PURPOSE
This module exists to keep the standalone command and region dispatch helper logic in one place so the CLI, build
pipeline, and runtime can reuse the same behavior instead of duplicating it.
=head1 WHY IT EXISTS
PAX uses this module when it needs standalone command and region dispatch helper. Keeping that behavior isolated here
makes the surrounding compiler and packaging stages easier to reason about and
safer to evolve.
=head1 WHEN TO USE
( run in 1.516 second using v1.01-cache-2.11-cpan-71847e10f99 )