Skip to content

Commit 313433a

Browse files
committed
refactoring for "Method too large" error
1 parent 1deb486 commit 313433a

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/main/java/org/perlonjava/codegen/EmitBlock.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
import org.objectweb.asm.Label;
44
import org.objectweb.asm.MethodVisitor;
5-
import org.perlonjava.astnode.BlockNode;
6-
import org.perlonjava.astnode.Node;
5+
import org.perlonjava.astnode.*;
76
import org.perlonjava.astvisitor.EmitterVisitor;
87
import org.perlonjava.runtime.RuntimeContextType;
98

109
import java.util.List;
1110

1211
public class EmitBlock {
12+
// Blocks with too many statements are emitted as a separate subroutine
13+
// in order to avoid "Method too large" error test: in t/re/pat.t
14+
final static int LARGE_BLOCK = 16;
15+
1316
/**
1417
* Emits bytecode for a block of statements.
1518
*
@@ -19,6 +22,28 @@ public class EmitBlock {
1922
public static void emitBlock(EmitterVisitor emitterVisitor, BlockNode node) {
2023
MethodVisitor mv = emitterVisitor.ctx.mv;
2124

25+
// Check if we can emit this as a subroutine, to avoid "Method too large" error.
26+
// TODO: Check for possible goto's, then don't move the block to subroutine
27+
if (node.elements.size() > LARGE_BLOCK
28+
&& !emitterVisitor.ctx.javaClassInfo.gotoLabelStack.isEmpty()
29+
&& !node.getBooleanAnnotation("blockIsSubroutine")) {
30+
// Create sub {...}->()
31+
int index = node.tokenIndex;
32+
BinaryOperatorNode subr = new BinaryOperatorNode(
33+
"->",
34+
new SubroutineNode(
35+
null, null, null,
36+
new BlockNode(List.of(node), index),
37+
false,
38+
index
39+
),
40+
new ListNode(index),
41+
index
42+
);
43+
subr.accept(emitterVisitor);
44+
return;
45+
}
46+
2247
emitterVisitor.ctx.logDebug("generateCodeBlock start context:" + emitterVisitor.ctx.contextType);
2348
int scopeIndex = emitterVisitor.ctx.symbolTable.enterScope();
2449
EmitterVisitor voidVisitor =

src/main/java/org/perlonjava/codegen/EmitSubroutine.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public static void emitSubroutine(EmitterContext ctx, SubroutineNode node) {
3636
}
3737
MethodVisitor mv = ctx.mv;
3838

39+
// Mark the block as subroutine block,
40+
// this prevents the "code too large" transform in emitBlock()
41+
node.block.setAnnotation("blockIsSubroutine", true);
42+
3943
// Retrieve closure variable list
4044
// Alternately, scan the AST for variables and capture only the ones that are used
4145
Map<Integer, SymbolTable.SymbolEntry> visibleVariables = ctx.symbolTable.getAllVisibleVariables();

0 commit comments

Comments
 (0)