Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

OptionDescriptionExample
-e 'code'Execute one-liner (modern features always on)pperl -e 'say "hi"'
-cCheck syntax onlypperl -c script.pl
-wEnable warningspperl -w script.pl
-vShow versionpperl -v
-VVerbose configurationpperl -V
-h, -?, --helpShow help messagepperl --help

Combined short flags:

pperl -wc script.pl  # Enable warnings + syntax check

PetaPerl-Specific Options

OptionDescriptionDefault
--stats, -sShow performance statistics (time, memory, ops)Disabled
--trace, -tEnable execution tracingDisabled
--timeout=SECSSet execution timeout in secondsNone
--p5Use 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

OptionDescriptionDefault
--no-jitDisable JIT compilationJIT enabled
--no-parallelDisable auto-parallelizationParallel enabled
--threads=NNumber of threads for parallelizationAll CPUs
--parallel-threshold=NMinimum iterations to parallelize100

Caching and Analysis Options

OptionDescription
--cacheEnable bytecode caching (~/.pperl/cache/)
--flushClear all bytecode caches and exit
--dump-optreeDump canonical op tree (don’t execute)
--from-json, -jRead op tree from stdin (B::PetaPerl JSON format)
--optree, -oRead op tree from stdin (B::Concise format)
--compare-bytecodeCompare op trees: perl5 backend vs native parser

Unsupported perl5 Options

These perl5 flags are not implemented:

OptionDescriptionWorkaround
-IAdd include pathUse PERL5LIB
-EExecute with featuresUse -e (features always on)
-M / -mLoad moduleUse use in code
-n / -pImplicit input loopWrite explicit loop
-lAuto line-endingUse chomp/say
-a / -FAutosplitUse split explicitly
-iIn-place editUse open/close
-dDebugger-
-xExtract script-
-TTaint 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

CodeMeaning
0Success
1Runtime error or compile error
2Command-line usage error

Environment Variables

VariableEffectDefault
PPERL_MAX_RECURSIONMaximum subroutine recursion depth1000
PPERL_CACHEBytecode cache directory-
PERL5LIBModule 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 newline
  • state - 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