|
4 | 4 | import org.objectweb.asm.Opcodes; |
5 | 5 | import org.perlonjava.astnode.*; |
6 | 6 | import org.perlonjava.astvisitor.EmitterVisitor; |
| 7 | +import org.perlonjava.perlmodule.Strict; |
7 | 8 | import org.perlonjava.runtime.PerlCompilerException; |
8 | 9 | import org.perlonjava.runtime.RuntimeContextType; |
9 | 10 |
|
@@ -469,16 +470,32 @@ public static void handleArrowArrayDeref(EmitterVisitor emitterVisitor, BinaryOp |
469 | 470 | Node elem = right.elements.getFirst(); |
470 | 471 | elem.accept(emitterVisitor.with(RuntimeContextType.SCALAR)); |
471 | 472 |
|
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 | + } |
482 | 499 | } else { |
483 | 500 | // Multiple indices: use slice method (only for get operation) |
484 | 501 | if (!arrayOperation.equals("get")) { |
@@ -526,15 +543,32 @@ public static void handleArrowHashDeref(EmitterVisitor emitterVisitor, BinaryOpe |
526 | 543 | emitterVisitor.ctx.logDebug("visit -> (HashLiteralNode) autoquote " + node.right); |
527 | 544 | nodeRight.accept(emitterVisitor.with(RuntimeContextType.SCALAR)); |
528 | 545 |
|
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); |
| 546 | + // Check if strict refs is enabled at compile time |
| 547 | + if (emitterVisitor.ctx.symbolTable.isStrictOptionEnabled(Strict.HINT_STRICT_REFS)) { |
| 548 | + // Use strict version (throws error on symbolic references) |
| 549 | + String methodName = switch (hashOperation) { |
| 550 | + case "get" -> "hashDerefGet"; |
| 551 | + case "delete" -> "hashDerefDelete"; |
| 552 | + case "exists" -> "hashDerefExists"; |
| 553 | + default -> |
| 554 | + throw new PerlCompilerException(node.tokenIndex, "Not implemented: hash operation: " + hashOperation, emitterVisitor.ctx.errorUtil); |
| 555 | + }; |
| 556 | + emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perlonjava/runtime/RuntimeScalar", |
| 557 | + methodName, "(Lorg/perlonjava/runtime/RuntimeScalar;)Lorg/perlonjava/runtime/RuntimeScalar;", false); |
| 558 | + } else { |
| 559 | + // Use non-strict version (allows symbolic references) |
| 560 | + String methodName = switch (hashOperation) { |
| 561 | + case "get" -> "hashDerefGetNonStrict"; |
| 562 | + case "delete" -> "hashDerefDeleteNonStrict"; |
| 563 | + case "exists" -> "hashDerefExistsNonStrict"; |
| 564 | + default -> |
| 565 | + throw new PerlCompilerException(node.tokenIndex, "Not implemented: hash operation: " + hashOperation, emitterVisitor.ctx.errorUtil); |
| 566 | + }; |
| 567 | + // Push the current package name for symbolic reference resolution |
| 568 | + emitterVisitor.pushCurrentPackage(); |
| 569 | + emitterVisitor.ctx.mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "org/perlonjava/runtime/RuntimeScalar", |
| 570 | + methodName, "(Lorg/perlonjava/runtime/RuntimeScalar;Ljava/lang/String;)Lorg/perlonjava/runtime/RuntimeScalar;", false); |
| 571 | + } |
538 | 572 | EmitOperator.handleVoidContext(emitterVisitor); |
539 | 573 | } |
540 | 574 | } |
0 commit comments