Skip to content

Fix glob assignment to correctly alias SCALAR slot for all reference types#361

Merged
fglock merged 1 commit into
masterfrom
fix/glob-scalar-slot-aliasing
Mar 24, 2026
Merged

Fix glob assignment to correctly alias SCALAR slot for all reference types#361
fglock merged 1 commit into
masterfrom
fix/glob-scalar-slot-aliasing

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Mar 24, 2026

Summary

This PR fixes two related bugs involving glob assignments and symbolic references:

Bug 1: Symbolic subroutine reference resolution in wrong package

&{$hash{key}}() was resolving subroutine names in the 'main' package instead of the current package.

Before:

package foo;
my %subs = (test => 'mysub');
sub mysub { print "called\n" }
&{$subs{test}}();  # Error: Undefined subroutine &main::mysub

After:

package foo;
my %subs = (test => 'mysub');
sub mysub { print "called\n" }
&{$subs{test}}();  # Works: calls foo::mysub

Bug 2: Exporter variable export failing for references

*glob = \$scalar was incorrectly checking what $scalar contained and putting it in the wrong slot (ARRAY slot for arrayrefs, HASH slot for hashrefs, CODE slot for coderefs).

This broke Exporter when exporting variables containing blessed objects or references, affecting modules like Test::Specio.

Before:

package Foo;
our $OBJECT = bless {}, 'MyObj';

package main;
*main::OBJ = \$Foo::OBJECT;
print ref($OBJ);  # prints nothing (undef)

After:

package Foo;
our $OBJECT = bless {}, 'MyObj';

package main;
*main::OBJ = \$Foo::OBJECT;
print ref($OBJ);  # prints "MyObj"

Changes

  • EmitSubroutine.java: Added isBlockDeref flag to detect &{expr} syntax and call codeDerefNonStrict for all block-style code dereferences when strict refs is disabled
  • RuntimeGlob.java: Simplified the REFERENCE case to always alias the SCALAR slot, regardless of what the scalar contains

Test Plan

  • All unit tests pass (make)
  • Full test suite shows no regressions (74.8% pass rate)
  • Test::Specio now correctly exports 40/41 variables (only $UNDEF intentionally undefined)
  • Manual verification of edge cases:
    • Blessed objects export correctly
    • Array/hash/code references stored in scalars export correctly
    • Direct \@array and \%hash assignments to globs still work correctly
    • String/integer scalars work correctly

Generated with Devin

…types

This fixes two related bugs:

1. Symbolic subroutine reference resolution in wrong package
   - &{$hash{key}}() was resolving subroutine names in 'main' package
     instead of the current package
   - Added isBlockDeref flag to detect &{expr} syntax and call
     codeDerefNonStrict for all block-style code dereferences

2. Exporter variable export failing for references
   - *glob = \$scalar was incorrectly checking what $scalar contained
     and putting it in the wrong slot (ARRAY slot for arrayrefs, etc.)
   - Now correctly aliases the SCALAR slot regardless of content
   - This fixes Test::Specio and other modules that export variables
     containing blessed objects or references

The REFERENCE case in RuntimeGlob.set() was simplified to always alias
the SCALAR slot. Direct \@array and \%hash assignments still work
correctly as they come in as ARRAYREFERENCE/HASHREFERENCE types.

Test results:
- All unit tests pass
- Test::Specio now correctly exports 40/41 variables
- Manual verification of edge cases (blessed objects, code refs, etc.)

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock force-pushed the fix/glob-scalar-slot-aliasing branch from 8b02a0b to 75ca618 Compare March 24, 2026 09:17
@fglock fglock merged commit b9b1a7d into master Mar 24, 2026
2 checks passed
@fglock fglock deleted the fix/glob-scalar-slot-aliasing branch March 24, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant