Repository navigation
Expand file tree
/
Copy pathjperl
More file actions
executable file
·158 lines (147 loc) · 6.85 KB
/
Copy pathjperl
File metadata and controls
executable file
·158 lines (147 loc) · 6.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/bin/bash
#
# PerlOnJava Launcher Script
# This script launches the PerlOnJava runtime environment, which provides
# a Java-based implementation of the Perl programming language.
# Repository: github.com/fglock/PerlOnJava
#
# Get the directory where this script is located without depending on the
# external dirname utility. CPAN build tools can intentionally replace PATH
# with prerequisite script directories before launching a nested $^X.
SCRIPT_SOURCE="${BASH_SOURCE[0]}"
case "$SCRIPT_SOURCE" in
*/*) SCRIPT_PARENT="${SCRIPT_SOURCE%/*}" ;;
*) SCRIPT_PARENT="." ;;
esac
SCRIPT_DIR="$(cd "$SCRIPT_PARENT" && pwd -P)"
# Get the full path to this script to set $^X correctly
JPERL_PATH="$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || echo "$SCRIPT_DIR/jperl")"
# Export environment variable for PerlOnJava to use as $^X
export PERLONJAVA_EXECUTABLE="$JPERL_PATH"
# Use the native shim for $^X when it has been built. This allows a generated
# '#!$^X' script to run directly on platforms that reject chained scripts.
if [ -z "${PERLONJAVA_SHEBANG_EXECUTABLE+x}" ]; then
if [ -x "$SCRIPT_DIR/jperl-exec" ]; then
export PERLONJAVA_SHEBANG_EXECUTABLE="$SCRIPT_DIR/jperl-exec"
elif [ -x "$SCRIPT_DIR/target/jperl-exec" ]; then
export PERLONJAVA_SHEBANG_EXECUTABLE="$SCRIPT_DIR/target/jperl-exec"
fi
fi
# Java 24 virtual threads are the default Perl ithread carrier. Preserve an
# explicit environment selection; the equivalent JVM property in JPERL_OPTS
# still takes precedence inside PerlThreadExecutionPolicy.
if [ -z "${JPERL_THREAD_MODE+x}" ]; then
export JPERL_THREAD_MODE=virtual
fi
# An acceptance run may bind the launcher to one exact standalone artifact.
# Reject an empty or missing override rather than silently falling back.
if [ -n "${PERLONJAVA_JAR+x}" ]; then
if [ ! -f "$PERLONJAVA_JAR" ] || [ ! -s "$PERLONJAVA_JAR" ]; then
echo "ERROR: PERLONJAVA_JAR must name an existing nonempty JAR: $PERLONJAVA_JAR" >&2
exit 1
fi
PERLONJAVA_CP="$PERLONJAVA_JAR"
# Check development environment first (target directory). During Maven's test
# phase the packaged JAR does not exist yet, so use compiled classes plus the
# runtime dependency classpath generated by maven-dependency-plugin.
elif [ -f "$SCRIPT_DIR/target/perlonjava-5.44.1.jar" ]; then
PERLONJAVA_CP="$SCRIPT_DIR/target/perlonjava-5.44.1.jar"
elif [ -d "$SCRIPT_DIR/target/classes" ] && [ -f "$SCRIPT_DIR/target/jperl-test-classpath.txt" ]; then
MAVEN_RUNTIME_CP=$(tr -d '\r\n' < "$SCRIPT_DIR/target/jperl-test-classpath.txt")
PERLONJAVA_CP="$SCRIPT_DIR/target/classes"
if [ -n "$MAVEN_RUNTIME_CP" ]; then
PERLONJAVA_CP="$PERLONJAVA_CP:$MAVEN_RUNTIME_CP"
fi
elif [ -f "$SCRIPT_DIR/perlonjava-5.44.1.jar" ]; then
# Docker or local installation with jar in same directory
PERLONJAVA_CP="$SCRIPT_DIR/perlonjava-5.44.1.jar"
else
# Use installed package path (when installed via deb package)
PERLONJAVA_CP="$SCRIPT_DIR/../lib/perlonjava-5.44.1.jar"
fi
# Determine JVM options based on Java version
# --enable-native-access=ALL-UNNAMED: Required by FFM (Foreign Function & Memory) API
# for native system calls (file operations, process management).
# Perl call frames currently use the Java stack. A 16 MiB stack lets ordinary
# Perl recursion reach ecosystem guard limits (Catalyst defaults to 1000 calls)
# before HotSpot raises StackOverflowError. A later -Xss in JPERL_OPTS still
# overrides this default for callers with different constraints.
JVM_OPTS="-Xss16m --enable-native-access=ALL-UNNAMED"
# Note on JVM heap settings: do NOT set -XX:SoftMaxHeapSize below -Xmx.
# That combination triggers an aggressive G1 GC cadence that interacts
# pathologically with PerlOnJava's weak-ref / selective-refcount
# machinery — DBIx-Class t/96_is_deteministic_value.t hangs at 100% CPU
# under -XX:SoftMaxHeapSize=2g -Xmx4g while passing in seconds without
# the soft cap (or with SoftMax >= Xmx). The JVM's auto-default
# (MaxHeapSize = 1/4 of system RAM) is honored when nothing is set.
# Override via `JPERL_OPTS="-Xmx<size>"` in the environment if needed
# (e.g. memory-intensive tests like re/pat.t).
# Java 23+ warns about sun.misc.Unsafe usage (JEP 471). Add flag to suppress
# warnings from transitive libraries (ASM, ICU4J, etc.) that still use it.
JAVA_BIN="${PERLONJAVA_JAVA_BIN:-}"
if [ -z "$JAVA_BIN" ] && [ -n "${JAVA_HOME:-}" ] && [ -x "$JAVA_HOME/bin/java" ]; then
JAVA_BIN="$JAVA_HOME/bin/java"
fi
if [ -z "$JAVA_BIN" ]; then
JAVA_BIN="$(command -v java 2>/dev/null || true)"
fi
if [ -z "$JAVA_BIN" ] || [ ! -x "$JAVA_BIN" ]; then
echo "ERROR: PerlOnJava requires Java 24 or later; java was not found in PATH." >&2
exit 1
fi
export PERLONJAVA_JAVA_BIN="$JAVA_BIN"
JAVA_VERSION_OUTPUT="$("$JAVA_BIN" -version 2>&1)"
if [[ "$JAVA_VERSION_OUTPUT" =~ version\ \"([0-9]+) ]]; then
JAVA_VERSION="${BASH_REMATCH[1]}"
else
JAVA_VERSION=""
fi
if ! [[ "$JAVA_VERSION" =~ ^[0-9]+$ ]] || [ "$JAVA_VERSION" -lt 24 ]; then
echo "ERROR: PerlOnJava requires Java 24 or later (found: ${JAVA_VERSION:-unknown})." >&2
exit 1
fi
if [ "$JAVA_VERSION" -ge 23 ] 2>/dev/null; then
JVM_OPTS="$JVM_OPTS --sun-misc-unsafe-memory-access=allow"
fi
# Note: Only include CLASSPATH if set, to avoid empty prefix that would add current dir to path
if [ -n "$CLASSPATH" ]; then
CP="$CLASSPATH:$PERLONJAVA_CP"
else
CP="$PERLONJAVA_CP"
fi
# On POSIX systems a JVM started under the C locale cannot faithfully decode
# non-ASCII process arguments. Perl still treats argv as bytes, so preserve
# non-ASCII arguments as ASCII hex while crossing the native/JVM boundary;
# Main restores their byte values before parsing the Perl command line.
ARGV_LOCALE="${LC_ALL:-${LC_CTYPE:-${LANG:-}}}"
case "$ARGV_LOCALE" in
C|POSIX)
ARGV_NEEDS_RESTORE=0
ARGV_REPLACED=()
for ARGV_ITEM in "$@"; do
ARGV_HEX=""
ARGV_HAS_HIGH_BYTE=0
for ((ARGV_INDEX = 0; ARGV_INDEX < ${#ARGV_ITEM}; ARGV_INDEX++)); do
ARGV_CHARACTER="${ARGV_ITEM:ARGV_INDEX:1}"
printf -v ARGV_BYTE_VALUE '%d' "'$ARGV_CHARACTER"
ARGV_BYTE_VALUE=$((ARGV_BYTE_VALUE & 255))
printf -v ARGV_BYTE_HEX '%02x' "$ARGV_BYTE_VALUE"
ARGV_HEX+="$ARGV_BYTE_HEX"
if (( 16#$ARGV_BYTE_HEX >= 128 )); then
ARGV_HAS_HIGH_BYTE=1
fi
done
if [ "$ARGV_HAS_HIGH_BYTE" -eq 1 ]; then
ARGV_REPLACED+=("__PERLONJAVA_RAWARG_HEX__$ARGV_HEX")
ARGV_NEEDS_RESTORE=1
else
ARGV_REPLACED+=("$ARGV_ITEM")
fi
done
if [ "$ARGV_NEEDS_RESTORE" -eq 1 ]; then
set -- "${ARGV_REPLACED[@]}"
JVM_OPTS="$JVM_OPTS -Dperlonjava.rawargv.hex=true"
fi
;;
esac
exec "$JAVA_BIN" $JVM_OPTS ${JPERL_OPTS} -cp "$CP" org.perlonjava.app.cli.Main "$@"