Running Scripts
PetaPerl’s pperl command executes Perl scripts with a familiar interface. Most perl5 options work identically.
Basic Execution
# Run a script
pperl script.pl
# Run with arguments
pperl script.pl arg1 arg2
# Execute one-liner
pperl -e 'say "Hello, World!"'
# Check syntax without running
pperl -c script.pl
Command-Line Options
Perl-Compatible Options
| Option | Description | Example |
|---|---|---|
-e 'code' | Execute one-liner (modern features always on) | pperl -e 'say "hi"' |
-c | Check syntax only | pperl -c script.pl |
-w | Enable warnings | pperl -w script.pl |
-v | Show version | pperl -v |
-V | Verbose configuration | pperl -V |
-h, -?, --help | Show help message | pperl --help |
Combined short flags:
pperl -wc script.pl # Enable warnings + syntax check
PetaPerl-Specific Options
| Option | Description | Default |
|---|---|---|
--stats, -s | Show performance statistics (time, memory, ops) | Disabled |
--trace, -t | Enable execution tracing | Disabled |
--timeout=SECS | Set execution timeout in seconds | None |
--p5 | Use P5 runtime (see below) | Disabled |
Choosing a Runtime
PetaPerl has two runtime engines. The default PP runtime uses safe, idiomatic Rust
and supports JIT compilation and auto-parallelization. The P5 runtime (--p5) is
a line-for-line Rust transliteration of perl5’s C interpreter — it matches perl5
performance out of the box but does not support JIT or parallelization.
Use --p5 when you need maximum compatibility with perl5’s edge-case behaviour or
baseline performance without JIT. Use the default PP runtime (with JIT enabled) for
compute-heavy workloads where parallelization and JIT provide significant speedups.
See Dual Runtime Architecture for technical details.
Performance Options
| Option | Description | Default |
|---|---|---|
--no-jit | Disable JIT compilation | JIT enabled |
--no-parallel | Disable auto-parallelization | Parallel enabled |
--threads=N | Number of threads for parallelization | All CPUs |
--parallel-threshold=N | Minimum iterations to parallelize | 100 |
Caching and Analysis Options
| Option | Description |
|---|---|
--cache | Enable bytecode caching (~/.pperl/cache/) |
--flush | Clear all bytecode caches and exit |
--dump-optree | Dump canonical op tree (don’t execute) |
--from-json, -j | Read op tree from stdin (B::PetaPerl JSON format) |
--optree, -o | Read op tree from stdin (B::Concise format) |
--compare-bytecode | Compare op trees: perl5 backend vs native parser |
Unsupported perl5 Options
These perl5 flags are not implemented:
| Option | Description | Workaround |
|---|---|---|
-I | Add include path | Use PERL5LIB |
-E | Execute with features | Use -e (features always on) |
-M / -m | Load module | Use use in code |
-n / -p | Implicit input loop | Write explicit loop |
-l | Auto line-ending | Use chomp/say |
-a / -F | Autosplit | Use split explicitly |
-i | In-place edit | Use open/close |
-d | Debugger | - |
-x | Extract script | - |
-T | Taint mode | - |
Examples
One-Liners
Modern features (say, state, etc.) are always enabled.
# Print hello
pperl -e 'say "Hello!"'
# Process input
echo "hello" | pperl -e 'while (<>) { say uc($_) }'
# Math
pperl -e 'say 2 + 2'
# Generate data
pperl -e 'say join ",", 1..10'
Syntax Checking
# Check single file
pperl -c script.pl
# Output: script.pl syntax OK
# Check with warnings enabled
pperl -wc script.pl
Script Arguments
Arguments after the script name populate @ARGV.
pperl process.pl file1.txt file2.txt
# process.pl
for my $file (@ARGV) {
say "Processing: $file";
}
Performance Statistics
pperl --stats script.pl
Output:
--- Performance Statistics ---
Wall-clock time: 0.042 seconds
Peak memory (RSS): 12.34 MB (12640 KB)
Ops executed: 1523 (36261 ops/sec)
------------------------------
Execution Tracing
See every op executed (debugging aid).
pperl --trace script.pl
Output shows:
[TRACE] NextState
[TRACE] Const("Hello")
[TRACE] Print
Parser Comparison
Compare native Rust parser output against a perl5-generated JSON op tree (analysis tool).
pperl --compare-bytecode script.pl
Shows differences in generated op trees. Useful for parser validation.
Op Tree Inspection
Dump canonical op tree representation without executing.
pperl --dump-optree script.pl
Shows internal op tree structure:
NextState(file="script.pl", line=1)
→ Const(sv="Hello")
→ Print
→ LeaveSub
Execution Model
Parser Pipeline
Source → Lexer → Parser → AST → Codegen → OpArena → Interpreter
Fast, pure Rust. No perl5 dependency at runtime.
JSON Op Tree Loading (Analysis Only)
Source → perl + B::PetaPerl → JSON → OpArena → Interpreter
For analysis and parser validation, pperl can load a perl5-generated op tree via --from-json or compare it against the native parser via --compare-bytecode. This is not used during normal execution.
Timeouts
By default, pperl has no execution timeout. Use --timeout=SECS to set one:
# No timeout (default)
pperl script.pl
# Set timeout (useful for untrusted code or testing)
pperl --timeout=60 script.pl
pperl --timeout=5 script.pl
The test harness sets its own timeout (default 5 seconds per test). This is separate from the --timeout flag.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Runtime error or compile error |
| 2 | Command-line usage error |
Environment Variables
| Variable | Effect | Default |
|---|---|---|
PPERL_MAX_RECURSION | Maximum subroutine recursion depth | 1000 |
PPERL_CACHE | Bytecode cache directory | - |
PERL5LIB | Module search path | - |
Example:
export PPERL_MAX_RECURSION=5000
pperl deeply_recursive.pl
export PPERL_CACHE=/tmp/pperl-cache
pperl --cache script.pl
Warnings
Enable warnings with -w or -W:
pperl -w script.pl
Warnings appear on stderr. Currently implemented:
- Use of uninitialized value
- Undefined subroutine call
Standard Streams
# Read stdin
while (my $line = <STDIN>) {
print "Got: $line";
}
# Write stdout
print "Output\n";
say "Output with newline";
# Write stderr
warn "Warning message\n";
Redirection works normally:
pperl script.pl < input.txt > output.txt 2> errors.txt
Shebang Support
PetaPerl scripts support shebang for direct execution.
#!/usr/bin/env pperl
say "Hello from PetaPerl!";
Make executable and run:
chmod +x script.pl
./script.pl
Module Loading
use strict;
use warnings;
use Data::Dumper;
my $data = { foo => 42 };
print Dumper($data);
Module search path: same as perl5’s @INC. Set PERL5LIB to add directories.
Current limitations:
- XS modules not supported (native modules only)
- Some pragmas (strict, warnings) parsed but not fully enforced
- Pure Perl modules work if they don’t use unsupported features
Differences from perl5
Always-Enabled Features
Modern Perl features are always available (no use feature needed):
say- print with newlinestate- persistent lexical variables//- defined-or operator~~- smart match (partial)
Default Timeout
pperl has no default timeout (same as perl5). Use --timeout=SECS to set one for untrusted scripts.
Parser
pperl always uses the native Rust parser. There is no runtime fallback to perl5.
Debugging
Syntax Errors
pperl -c script.pl
Reports parse errors with line numbers:
Parse error: Expected ';' after statement
at script.pl line 42
Runtime Errors
Errors show stack trace:
Runtime error: Undefined subroutine &main::foo
called at script.pl line 10
Execution Tracing
pperl --trace script.pl
Shows every op executed. Very verbose. Useful for understanding execution flow.
Performance Tips
Benchmarking
time pperl script.pl
Or use --stats for detailed metrics:
pperl --stats script.pl
Performance Characteristics
PetaPerl’s performance varies by workload:
- Interpreter fast paths: Common operations (integer arithmetic, assignment, comparison) run at or near perl5 speed
- JIT-compiled loops: Arithmetic-heavy loops compile to native code via Cranelift, achieving up to 76x faster than perl5
- JIT + parallelization: Embarrassingly parallel workloads on multi-core systems achieve up to 431x faster than perl5 (Mandelbrot 1000x1000)
- String-heavy code: Comparable to perl5 with PvBuf optimizations
- Module loading: Similar to perl5 for Pure Perl modules
Use --no-jit and --no-parallel to isolate interpreter-only performance.
Common Workflows
Script Development
# Edit script
vim script.pl
# Check syntax
pperl -c script.pl
# Run with warnings
pperl -w script.pl
# Debug with tracing (if needed)
pperl --trace script.pl
Testing
# Syntax check all scripts
find . -name '*.pl' -exec pperl -c {} \;
# Run test suite
pperl t/test.pl
Production Deployment
# Run production script (no timeout by default)
pperl production.pl
# Monitor performance
pperl --stats production.pl
Advanced Usage
Loading Op Tree from JSON (Analysis)
For parser validation and analysis:
# JSON format (B::PetaPerl) — reads from stdin
perl -MO=PetaPerl script.pl | pperl --from-json
# Short form
perl -MO=PetaPerl script.pl | pperl -j
This loads a perl5-generated op tree and executes it in the PetaPerl runtime, bypassing the native parser.
Comparing Parsers
Compare native parser output against a perl5-generated op tree:
pperl --compare-bytecode script.pl
Shows structural differences. Exit code 0 = equivalent, 1 = different.
Troubleshooting
“Can’t open perl script”
File doesn’t exist or wrong path.
pperl script.pl # Must exist
“Undefined subroutine”
Sub not defined or not visible in current scope.
sub greet { say "hi" }
greet(); # OK
greeet(); # Error: Undefined subroutine
“Timeout expired”
Script ran longer than the --timeout value.
pperl --timeout=120 long_script.pl # Increase timeout
pperl long_script.pl # No timeout (default)
“Parse error”
Syntax error in script. Use -c to check:
pperl -c script.pl
“Is perl installed and in PATH?”
The --from-json/-j and --compare-bytecode analysis tools require system perl 5.42+ with B::PetaPerl installed. Normal execution does not require perl.
Version Information
pperl -v
Shows brief version and copyright.
pperl -V
Shows detailed configuration:
Summary of PetaPerl configuration:
PetaPerl:
version='0.1.0'
binary='pperl'
Runtime:
backend=Rust interpreter + function-pointer dispatch
jit=Cranelift (for/while loops)
parallelism=Rayon (auto-parallel map/grep/for/while)
Perl compatibility:
parser=native Rust
perl_required=no (5.42+ optional for --from-json/--compare-bytecode analysis)
platforms=Linux only
Platform Support
PetaPerl runs on Linux only (any architecture).
Not supported: Windows, macOS, BSD, VMS, etc.
This simplification allows aggressive optimization for Linux-specific features.
Future Enhancements
Planned features:
- Profiling output (
--profile) - Extended JIT coverage (string operations, subroutine inlining)
- Extended parallelization (more loop patterns, pipeline parallelism)
Track progress: https://gl.petatech.eu/petatech/peta-perl