Skip to content
Closed
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
6 changes: 3 additions & 3 deletions src/main/java/org/perlonjava/core/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,22 @@ public final class Configuration {
* Automatically populated by Gradle/Maven during build.
* DO NOT EDIT MANUALLY - this value is replaced at build time.
*/
public static final String gitCommitId = "d7eacf972";
public static final String gitCommitId = "82e5e452d";

/**
* Git commit date of the build (ISO format: YYYY-MM-DD).
* Automatically populated by Gradle/Maven during build.
* DO NOT EDIT MANUALLY - this value is replaced at build time.
*/
public static final String gitCommitDate = "2026-04-28";
public static final String gitCommitDate = "2026-04-29";

/**
* Build timestamp in Perl 5 "Compiled at" format (e.g., "Apr 7 2026 11:20:00").
* Automatically populated by Gradle during build.
* Parsed by App::perlbrew and other tools via: perl -V | grep "Compiled at"
* DO NOT EDIT MANUALLY - this value is replaced at build time.
*/
public static final String buildTimestamp = "Apr 28 2026 21:49:56";
public static final String buildTimestamp = "Apr 29 2026 09:31:10";

// Prevent instantiation
private Configuration() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,14 @@ else if (code == null) {
// Notify B::Hooks::EndOfScope that we're starting to load a file
// This enables on_scope_end callbacks to know which file they belong to
BHooksEndOfScope.beginFileLoad(parsedArgs.fileName);


// Source filters installed in the caller's file must not leak into
// the file being required/do'd. Save the outer filter state and start
// with a clean state for this compilation unit; restore on the way out.
org.perlonjava.runtime.perlmodule.FilterUtilCall.FilterStateSnapshot
filterSnapshot = org.perlonjava.runtime.perlmodule.FilterUtilCall
.saveAndResetFilterState();

try {
featureManager = new FeatureFlags();

Expand Down Expand Up @@ -755,6 +762,11 @@ else if (code == null) {
// Restore the caller's hints hash
hintHash.elements.clear();
hintHash.elements.putAll(savedHintHash);

// Restore the caller's source-filter state (filters installed in
// the required file must not leak back to the caller).
org.perlonjava.runtime.perlmodule.FilterUtilCall
.restoreFilterState(filterSnapshot);
}

// Return result based on context
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,52 @@ public static void clearFilters() {
context.currentLine = 0;
}

/**
* Snapshot of filter state (stack + "installed during use" flag).
* Source filters are scoped to the file/compilation unit in which
* they were installed; when we begin parsing a new file (e.g. via
* {@code require}/{@code do}), we save the outer state, start with
* a clean state, and restore on the way out.
*/
public static class FilterStateSnapshot {
final RuntimeList filterStack;
final boolean installedDuringUse;

FilterStateSnapshot(RuntimeList filterStack, boolean installedDuringUse) {
this.filterStack = filterStack;
this.installedDuringUse = installedDuringUse;
}
}

/**
* Save the current filter state and reset to a clean state.
* Call this before compiling a new file (require/do); pair with
* {@link #restoreFilterState(FilterStateSnapshot)}.
*/
public static FilterStateSnapshot saveAndResetFilterState() {
FilterContext context = filterContext.get();
FilterStateSnapshot snapshot =
new FilterStateSnapshot(context.filterStack, filterInstalledDuringUse.get());
context.filterStack = new RuntimeList();
context.sourceLines = null;
context.currentLine = 0;
filterInstalledDuringUse.set(false);
return snapshot;
}

/**
* Restore filter state previously saved by
* {@link #saveAndResetFilterState()}.
*/
public static void restoreFilterState(FilterStateSnapshot snapshot) {
if (snapshot == null) return;
FilterContext context = filterContext.get();
context.filterStack = snapshot.filterStack;
context.sourceLines = null;
context.currentLine = 0;
filterInstalledDuringUse.set(snapshot.installedDuringUse);
}

/**
* Context for managing active source filters.
*/
Expand Down
Loading