31
31
import java .lang .classfile .instruction .BranchInstruction ;
32
32
import java .lang .classfile .instruction .OperatorInstruction ;
33
33
import java .lang .constant .ClassDesc ;
34
+ import java .lang .constant .ConstantDesc ;
34
35
import java .lang .constant .ConstantDescs ;
35
36
import java .lang .constant .DynamicConstantDesc ;
36
37
import java .lang .constant .MethodTypeDesc ;
@@ -379,10 +380,10 @@ public Void visitNumeric(JavascriptParser.NumericContext ctx) {
379
380
380
381
@ Override
381
382
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 ;
386
387
387
388
if (mh != null ) {
388
389
final int arity = mh .type ().parameterCount ();
@@ -401,15 +402,19 @@ public Void visitExternal(JavascriptParser.ExternalContext ctx) {
401
402
ctx .start .getStartIndex ());
402
403
}
403
404
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 );
413
418
414
419
// add arguments:
415
420
typeStack .push (TypeKind .DOUBLE );
@@ -426,8 +431,8 @@ public Void visitExternal(JavascriptParser.ExternalContext ctx) {
426
431
427
432
gen .conversion (TypeKind .DOUBLE , typeStack .peek ());
428
433
} 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 ());
431
436
432
437
gen .aload (gen .parameterSlot (0 ));
433
438
gen .loadConstant (index );
0 commit comments