@@ -498,39 +498,41 @@ public Void visitFunction(FunctionExpression expression) {
498498 final JavaClass thisClass = javaWriter .method .class_ ;
499499 final String lambdaName = this .javaMangler .mangleLambdaMethod (javaWriter .method .compiled .name , interfaces [0 ]);
500500 final LambdaClosureInfo closureInfo = LambdaClosureInfo .from (context , expression .closure , thisClass );
501- final String lambdaDescriptor = calcFunctionDescriptor (thisClass , closureInfo , expression .header );
501+ final String lambdaDescriptor = calcFunctionDescriptor (closureInfo , expression .header );
502502 final JavaNativeMethod lambdaMethod = JavaNativeMethod .getStatic (thisClass , lambdaName , lambdaDescriptor , Opcodes .ACC_PRIVATE | Opcodes .ACC_STATIC );
503503 final JavaCompilingMethod lambdaMethodCompiling = JavaMemberVisitor .compileBridgeableMethodNoSideEffect (lambdaMethod , lambdaDescriptor ); // TODO("Restore signatures")
504504 final JavaWriter lambdaWriter = new JavaWriter (context .logger , expression .position , javaWriter .clazzVisitor , lambdaMethodCompiling , null );
505505 final CapturedExpressionVisitor <Void > lambdaCapturesVisitor = new JavaCapturedExpressionVisitorLocalRedirectionVisitor (lambdaWriter , expression , closureInfo );
506- final JavaCompiledModule lambdaModule = new ShiftingJavaCompiledModule (module , closureInfo , context );
507- final JavaExpressionVisitor lambdaExpressionVisitor = new JavaExpressionVisitor (context , lambdaModule , lambdaWriter , javaMangler , lambdaCapturesVisitor );
506+ final JavaExpressionVisitor lambdaExpressionVisitor = new JavaExpressionVisitor (context , module , lambdaWriter , javaMangler , lambdaCapturesVisitor );
508507 final JavaStatementVisitor lambdaStatementVisitor = new JavaStatementVisitor (context , lambdaExpressionVisitor , javaMangler );
509508
510509 lambdaWriter .start ();
511510 expression .body .accept (lambdaStatementVisitor );
512511 lambdaWriter .ret ();
513512 lambdaWriter .end ();
514513
515- if (java .lang .reflect .Modifier .isStatic (javaWriter .method .compiled .modifiers ) || thisClass .kind == JavaClass .Kind .EXPANSION ) {
516- javaWriter .aConstNull ();
517- } else {
518- javaWriter .loadObject (0 );
514+ final JavaLoadThisOnIndyCapturedExpressionVisitor thisVisitor = new JavaLoadThisOnIndyCapturedExpressionVisitor (this );
515+ final JavaLoadCapturesOnIndyCapturedExpressionVisitor othersVisitor = new JavaLoadCapturesOnIndyCapturedExpressionVisitor (this );
516+
517+ boolean hasLoadedThis = false ;
518+ for (final CapturedExpression capture : expression .closure .captures ) {
519+ // Note: we want this to be |= to ensure NO short-circuiting behavior
520+ hasLoadedThis |= capture .accept (thisVisitor );
519521 }
520522
521- if (closureInfo .isDifferentThis ()) {
522- for (final CapturedExpression capture : expression .closure .captures ) {
523- capture .accept (new JavaCapturedExpressionVisitorLoadIndyCapturesVisitor (this , true ));
524- }
523+ // If no this was loaded, then we don't care about its value; just load null
524+ if (!hasLoadedThis ) {
525+ javaWriter .aConstNull ();
525526 }
527+
526528 for (final CapturedExpression capture : expression .closure .captures ) {
527- capture .accept (new JavaCapturedExpressionVisitorLoadIndyCapturesVisitor ( this , false ) );
529+ capture .accept (othersVisitor );
528530 }
529531
530532 // TODO("Have this in JavaWriter")
531533 javaWriter .getVisitor ().visitInvokeDynamicInsn (
532534 methodInfo .name ,
533- calcIndyDescriptor (thisClass , closureInfo , interfaces [0 ]),
535+ calcIndyDescriptor (closureInfo , interfaces [0 ]),
534536 new org .objectweb .asm .Handle (
535537 Opcodes .H_INVOKESTATIC ,
536538 Type .getInternalName (org .openzen .zenscript .javart .factory .LambdaFactory .class ),
@@ -555,14 +557,14 @@ public Void visitFunction(FunctionExpression expression) {
555557 false
556558 ),
557559 Type .getMethodType (JavaMemberVisitor .compileBridgeableMethodNoSideEffect (methodInfo , context .getMethodDescriptor (expression .header )).compiled .descriptor ),
558- org .openzen .zenscript .javart .factory .LambdaFactory .FLAG_GENERATE_BRIDGE | ( closureInfo . isDifferentThis ()? org . openzen . zenscript . javart . factory . LambdaFactory . FLAG_DIFFERENTIATE_RECEIVER : 0 ) ,
560+ org .openzen .zenscript .javart .factory .LambdaFactory .FLAG_GENERATE_BRIDGE ,
559561 Type .getMethodType (methodInfo .descriptor )
560562 );
561563
562564 return null ;
563565 }
564566
565- private String calcFunctionDescriptor (final JavaClass thisClass , final LambdaClosureInfo closureInfo , final FunctionHeader header ) {
567+ private String calcFunctionDescriptor (final LambdaClosureInfo closureInfo , final FunctionHeader header ) {
566568 final StringJoiner joiner = new StringJoiner ("" );
567569 for (final CapturedExpression capture : closureInfo .closure ().captures ) {
568570 if (!(capture instanceof CapturedThisExpression )) {
@@ -571,19 +573,21 @@ private String calcFunctionDescriptor(final JavaClass thisClass, final LambdaClo
571573 }
572574 }
573575
574- final String thisDescriptor = closureInfo . isDifferentThis ()? context . getDescriptor ( closureInfo . thisType ()) : "" ;
575-
576+ // TODO("Remove null check: the method should always return non-null")
577+ final String thisType = closureInfo . thisType () == null ? "Ljava/lang/Void;" : context . getDescriptor ( closureInfo . thisType ());
576578 final StringBuilder builder = new StringBuilder (context .getMethodDescriptor (header ));
577- builder .insert (builder .indexOf ("(" ) + 1 , 'L' + thisClass . internalName + ';' + thisDescriptor );
579+ builder .insert (builder .indexOf ("(" ) + 1 , thisType );
578580 builder .insert (builder .lastIndexOf (")" ), joiner );
579581 return builder .toString ();
580582 }
581583
582- private String calcIndyDescriptor (final JavaClass thisClass , final LambdaClosureInfo closureInfo , final String targetInterface ) {
583- final StringBuilder builder = new StringBuilder ("(L" );
584- builder .append (thisClass .internalName ).append (';' );
584+ private String calcIndyDescriptor (final LambdaClosureInfo closureInfo , final String targetInterface ) {
585+ final StringBuilder builder = new StringBuilder ("(" );
585586
586- if (closureInfo .isDifferentThis ()) {
587+ // TODO("Remove null check as this method should never return null")
588+ if (closureInfo .thisType () == null ) {
589+ builder .append ("Ljava/lang/Void;" );
590+ } else {
587591 builder .append (context .getDescriptor (closureInfo .thisType ()));
588592 }
589593
0 commit comments