diff --git a/src/main/java/org/perlonjava/codegen/EmitterMethodCreator.java b/src/main/java/org/perlonjava/codegen/EmitterMethodCreator.java index 2b29badc1..cb2babd63 100644 --- a/src/main/java/org/perlonjava/codegen/EmitterMethodCreator.java +++ b/src/main/java/org/perlonjava/codegen/EmitterMethodCreator.java @@ -575,12 +575,14 @@ private static byte[] getBytecodeInternal(EmitterContext ctx, Node ast, boolean // Temporaries are allocated dynamically during bytecode emission via // ctx.symbolTable.allocateLocalVariable(). We pre-initialize slots to ensure // they're not in TOP state when accessed. Use a visitor to estimate the - // actual number needed based on AST structure rather than a fixed count. + // actual number needed based on AST structure. + // Add a modest buffer since visitor doesn't count all allocation sites. int preInitTempLocalsStart = ctx.symbolTable.getCurrentLocalVariableIndex(); - org.perlonjava.astvisitor.TempLocalCountVisitor tempCountVisitor = + org.perlonjava.astvisitor.TempLocalCountVisitor tempCountVisitor = new org.perlonjava.astvisitor.TempLocalCountVisitor(); ast.accept(tempCountVisitor); - int preInitTempLocalsCount = Math.max(128, tempCountVisitor.getMaxTempCount() + 64); // Add buffer + int preInitTempLocalsCount = tempCountVisitor.getMaxTempCount() + 32; // Add 32-slot buffer + ctx.logDebug("Pre-initializing " + preInitTempLocalsCount + " temp locals"); for (int i = preInitTempLocalsStart; i < preInitTempLocalsStart + preInitTempLocalsCount; i++) { mv.visitInsn(Opcodes.ACONST_NULL); mv.visitVarInsn(Opcodes.ASTORE, i);