Skip to content

Commit 80bea9b

Browse files
committed
Expressions: Avoid creating a dynamic constant with BSM if MethodHandle descriptor can be used
1 parent c87f022 commit 80bea9b

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

lucene/expressions/src/java/org/apache/lucene/expressions/js/JavascriptCompiler.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.lang.classfile.instruction.BranchInstruction;
3232
import java.lang.classfile.instruction.OperatorInstruction;
3333
import java.lang.constant.ClassDesc;
34+
import java.lang.constant.ConstantDesc;
3435
import java.lang.constant.ConstantDescs;
3536
import java.lang.constant.DynamicConstantDesc;
3637
import java.lang.constant.MethodTypeDesc;
@@ -379,10 +380,10 @@ public Void visitNumeric(JavascriptParser.NumericContext ctx) {
379380

380381
@Override
381382
public Void visitExternal(JavascriptParser.ExternalContext ctx) {
382-
String text = ctx.VARIABLE().getText();
383-
int arguments = ctx.expression().size();
384-
boolean parens = ctx.LP() != null && ctx.RP() != null;
385-
MethodHandle mh = parens ? functions.get(text) : null;
383+
final String text = ctx.VARIABLE().getText();
384+
final int arguments = ctx.expression().size();
385+
final boolean parens = ctx.LP() != null && ctx.RP() != null;
386+
final MethodHandle mh = parens ? functions.get(text) : null;
386387

387388
if (mh != null) {
388389
final int arity = mh.type().parameterCount();
@@ -401,15 +402,19 @@ public Void visitExternal(JavascriptParser.ExternalContext ctx) {
401402
ctx.start.getStartIndex());
402403
}
403404

404-
// place dynamic constant with MethodHandle on top of stack
405-
final int index = constantsMap.computeIfAbsent(text, _ -> constantsMap.size());
406-
final var constantDesc =
407-
DynamicConstantDesc.ofNamed(
408-
ConstantDescs.BSM_CLASS_DATA_AT,
409-
ConstantDescs.DEFAULT_NAME,
410-
ConstantDescs.CD_MethodHandle,
411-
index);
412-
gen.loadConstant(constantDesc);
405+
// place reference to direct MethodHandle (usually if it is direct and reachable by system
406+
// classloader) or a dynamic constant using BSM for classdata on stack:
407+
final ConstantDesc constant =
408+
mh.describeConstable()
409+
.map(ConstantDesc.class::cast)
410+
.orElseGet(
411+
() ->
412+
DynamicConstantDesc.ofNamed(
413+
ConstantDescs.BSM_CLASS_DATA_AT,
414+
ConstantDescs.DEFAULT_NAME,
415+
ConstantDescs.CD_MethodHandle,
416+
constantsMap.computeIfAbsent(text, _ -> constantsMap.size())));
417+
gen.loadConstant(constant);
413418

414419
// add arguments:
415420
typeStack.push(TypeKind.DOUBLE);
@@ -426,8 +431,8 @@ public Void visitExternal(JavascriptParser.ExternalContext ctx) {
426431

427432
gen.conversion(TypeKind.DOUBLE, typeStack.peek());
428433
} else if (!parens || arguments == 0 && text.contains(".")) {
429-
text = normalizeQuotes(ctx.getText());
430-
final int index = externalsMap.computeIfAbsent(text, _ -> externalsMap.size());
434+
final String var = normalizeQuotes(ctx.getText());
435+
final int index = externalsMap.computeIfAbsent(var, _ -> externalsMap.size());
431436

432437
gen.aload(gen.parameterSlot(0));
433438
gen.loadConstant(index);

0 commit comments

Comments
 (0)