44import org .objectweb .asm .Opcodes ;
55import org .perlonjava .astnode .*;
66import org .perlonjava .astvisitor .EmitterVisitor ;
7+ import org .perlonjava .perlmodule .Strict ;
78import org .perlonjava .runtime .PerlCompilerException ;
89import org .perlonjava .runtime .RuntimeContextType ;
910
@@ -469,16 +470,32 @@ public static void handleArrowArrayDeref(EmitterVisitor emitterVisitor, BinaryOp
469470 Node elem = right .elements .getFirst ();
470471 elem .accept (emitterVisitor .with (RuntimeContextType .SCALAR ));
471472
472- String methodName = switch (arrayOperation ) {
473- case "get" -> "arrayDerefGet" ;
474- case "delete" -> "arrayDerefDelete" ;
475- case "exists" -> "arrayDerefExists" ;
476- default ->
477- throw new PerlCompilerException (node .tokenIndex , "Not implemented: array operation: " + arrayOperation , emitterVisitor .ctx .errorUtil );
478- };
479-
480- emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" ,
481- methodName , "(Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;" , false );
473+ // Check if strict refs is enabled at compile time
474+ if (emitterVisitor .ctx .symbolTable .isStrictOptionEnabled (Strict .HINT_STRICT_REFS )) {
475+ // Use strict version (throws error on symbolic references)
476+ String methodName = switch (arrayOperation ) {
477+ case "get" -> "arrayDerefGet" ;
478+ case "delete" -> "arrayDerefDelete" ;
479+ case "exists" -> "arrayDerefExists" ;
480+ default ->
481+ throw new PerlCompilerException (node .tokenIndex , "Not implemented: array operation: " + arrayOperation , emitterVisitor .ctx .errorUtil );
482+ };
483+ emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" ,
484+ methodName , "(Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;" , false );
485+ } else {
486+ // Use non-strict version (allows symbolic references)
487+ String methodName = switch (arrayOperation ) {
488+ case "get" -> "arrayDerefGetNonStrict" ;
489+ case "delete" -> "arrayDerefDeleteNonStrict" ;
490+ case "exists" -> "arrayDerefExistsNonStrict" ;
491+ default ->
492+ throw new PerlCompilerException (node .tokenIndex , "Not implemented: array operation: " + arrayOperation , emitterVisitor .ctx .errorUtil );
493+ };
494+ // Push the current package name for symbolic reference resolution
495+ emitterVisitor .pushCurrentPackage ();
496+ emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" ,
497+ methodName , "(Lorg/perlonjava/runtime/RuntimeScalar;Ljava/lang/String;)Lorg/perlonjava/runtime/RuntimeScalar;" , false );
498+ }
482499 } else {
483500 // Multiple indices: use slice method (only for get operation)
484501 if (!arrayOperation .equals ("get" )) {
@@ -489,8 +506,18 @@ public static void handleArrowArrayDeref(EmitterVisitor emitterVisitor, BinaryOp
489506 ListNode nodeRight = right .asListNode ();
490507 nodeRight .accept (emitterVisitor .with (RuntimeContextType .LIST ));
491508
492- emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" ,
493- "arrayDerefGetSlice" , "(Lorg/perlonjava/runtime/RuntimeList;)Lorg/perlonjava/runtime/RuntimeList;" , false );
509+ // Check if strict refs is enabled at compile time
510+ if (emitterVisitor .ctx .symbolTable .isStrictOptionEnabled (Strict .HINT_STRICT_REFS )) {
511+ // Use strict version (throws error on symbolic references)
512+ emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" ,
513+ "arrayDerefGetSlice" , "(Lorg/perlonjava/runtime/RuntimeList;)Lorg/perlonjava/runtime/RuntimeList;" , false );
514+ } else {
515+ // Use non-strict version (allows symbolic references)
516+ // Push the current package name for symbolic reference resolution
517+ emitterVisitor .pushCurrentPackage ();
518+ emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" ,
519+ "arrayDerefGetSliceNonStrict" , "(Lorg/perlonjava/runtime/RuntimeList;Ljava/lang/String;)Lorg/perlonjava/runtime/RuntimeList;" , false );
520+ }
494521
495522 // Context conversion: list slice in scalar/void contexts
496523 if (emitterVisitor .ctx .contextType == RuntimeContextType .SCALAR ) {
@@ -526,15 +553,30 @@ public static void handleArrowHashDeref(EmitterVisitor emitterVisitor, BinaryOpe
526553 emitterVisitor .ctx .logDebug ("visit -> (HashLiteralNode) autoquote " + node .right );
527554 nodeRight .accept (emitterVisitor .with (RuntimeContextType .SCALAR ));
528555
529- String methodName = switch (hashOperation ) {
530- case "get" -> "hashDerefGet" ;
531- case "delete" -> "hashDerefDelete" ;
532- case "exists" -> "hashDerefExists" ;
533- default ->
534- throw new PerlCompilerException (node .tokenIndex , "Not implemented: hash operation: " + hashOperation , emitterVisitor .ctx .errorUtil );
535- };
536-
537- emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" , methodName , "(Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;" , false );
556+ // Check if strict refs is enabled at compile time
557+ if (emitterVisitor .ctx .symbolTable .isStrictOptionEnabled (Strict .HINT_STRICT_REFS )) {
558+ // Use strict version (throws error on symbolic references)
559+ String methodName = switch (hashOperation ) {
560+ case "get" -> "hashDerefGet" ;
561+ case "delete" -> "hashDerefDelete" ;
562+ case "exists" -> "hashDerefExists" ;
563+ default ->
564+ throw new PerlCompilerException (node .tokenIndex , "Not implemented: hash operation: " + hashOperation , emitterVisitor .ctx .errorUtil );
565+ };
566+ emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" , methodName , "(Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;" , false );
567+ } else {
568+ // Use non-strict version (allows symbolic references)
569+ String methodName = switch (hashOperation ) {
570+ case "get" -> "hashDerefGetNonStrict" ;
571+ case "delete" -> "hashDerefDeleteNonStrict" ;
572+ case "exists" -> "hashDerefExistsNonStrict" ;
573+ default ->
574+ throw new PerlCompilerException (node .tokenIndex , "Not implemented: hash operation: " + hashOperation , emitterVisitor .ctx .errorUtil );
575+ };
576+ // Push the current package name for symbolic reference resolution
577+ emitterVisitor .pushCurrentPackage ();
578+ emitterVisitor .ctx .mv .visitMethodInsn (Opcodes .INVOKEVIRTUAL , "org/perlonjava/runtime/RuntimeScalar" , methodName , "(Lorg/perlonjava/runtime/RuntimeScalar;Ljava/lang/String;)Lorg/perlonjava/runtime/RuntimeScalar;" , false );
579+ }
538580 EmitOperator .handleVoidContext (emitterVisitor );
539581 }
540582}
0 commit comments