Commit 171e491f790ffcaa8d23e85821c56c077dc103b9

Authored by Mumfrey
1 parent 104bd7e5

pass the current return value into ReturnEventInfo ctor where possible

java/common/com/mumfrey/liteloader/transformers/event/Event.java
@@ -345,18 +345,30 @@ public class Event implements Comparable<Event> @@ -345,18 +345,30 @@ public class Event implements Comparable<Event>
345 LiteLoaderLogger.debug("Event %s is spawning handler %s in class %s", this.name, handler.name, Event.getActiveProxyRef()); 345 LiteLoaderLogger.debug("Event %s is spawning handler %s in class %s", this.name, handler.name, Event.getActiveProxyRef());
346 346
347 int ctorMAXS = 0, invokeMAXS = arguments.length + (doCaptureLocals ? locals.length - initialFrameSize : 0); 347 int ctorMAXS = 0, invokeMAXS = arguments.length + (doCaptureLocals ? locals.length - initialFrameSize : 0);
348 - int eventInfoVar = this.method.maxLocals++; 348 + int marshallVar = this.method.maxLocals++;
349 349
350 InsnList insns = new InsnList(); 350 InsnList insns = new InsnList();
351 351
  352 + boolean pushReturnValue = false;
  353 +
  354 + // If this is a ReturnEventInfo AND we are right before a RETURN opcode (so we can expect the *original* return
  355 + // value to be on the stack, then we dup the return value into a local var so we can push it later when we invoke
  356 + // the ReturnEventInfo ctor
  357 + if (injectionPoint instanceof InsnNode && injectionPoint.getOpcode() >= Opcodes.IRETURN && injectionPoint.getOpcode() < Opcodes.RETURN)
  358 + {
  359 + pushReturnValue = true;
  360 + insns.add(new InsnNode(Opcodes.DUP));
  361 + insns.add(new VarInsnNode(this.methodReturnType.getOpcode(Opcodes.ISTORE), marshallVar));
  362 + }
  363 +
352 // Instance the EventInfo for this event 364 // Instance the EventInfo for this event
353 insns.add(new TypeInsnNode(Opcodes.NEW, this.eventInfoClass)); ctorMAXS++; 365 insns.add(new TypeInsnNode(Opcodes.NEW, this.eventInfoClass)); ctorMAXS++;
354 insns.add(new InsnNode(Opcodes.DUP)); ctorMAXS++; invokeMAXS++; 366 insns.add(new InsnNode(Opcodes.DUP)); ctorMAXS++; invokeMAXS++;
355 - ctorMAXS += this.invokeEventInfoConstructor(insns, cancellable);  
356 - insns.add(new VarInsnNode(Opcodes.ASTORE, eventInfoVar)); 367 + ctorMAXS += this.invokeEventInfoConstructor(insns, cancellable, pushReturnValue, marshallVar);
  368 + insns.add(new VarInsnNode(Opcodes.ASTORE, marshallVar));
357 369
358 // Call the event handler method in the proxy 370 // Call the event handler method in the proxy
359 - insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar)); 371 + insns.add(new VarInsnNode(Opcodes.ALOAD, marshallVar));
360 ByteCodeUtilities.loadArgs(arguments, insns, this.methodIsStatic ? 0 : 1); 372 ByteCodeUtilities.loadArgs(arguments, insns, this.methodIsStatic ? 0 : 1);
361 if (doCaptureLocals) 373 if (doCaptureLocals)
362 { 374 {
@@ -367,7 +379,7 @@ public class Event implements Comparable&lt;Event&gt; @@ -367,7 +379,7 @@ public class Event implements Comparable&lt;Event&gt;
367 if (cancellable) 379 if (cancellable)
368 { 380 {
369 // Inject the if (e.isCancelled()) return e.getReturnValue(); 381 // Inject the if (e.isCancelled()) return e.getReturnValue();
370 - this.injectCancellationCode(insns, injectionPoint, eventInfoVar); 382 + this.injectCancellationCode(insns, injectionPoint, marshallVar);
371 } 383 }
372 384
373 // Inject our generated code into the method 385 // Inject our generated code into the method
@@ -390,14 +402,23 @@ public class Event implements Comparable&lt;Event&gt; @@ -390,14 +402,23 @@ public class Event implements Comparable&lt;Event&gt;
390 return eventDescriptor + ")V"; 402 return eventDescriptor + ")V";
391 } 403 }
392 404
393 - protected int invokeEventInfoConstructor(InsnList insns, boolean cancellable) 405 + protected int invokeEventInfoConstructor(InsnList insns, boolean cancellable, boolean pushReturnValue, int marshallVar)
394 { 406 {
395 int ctorMAXS = 0; 407 int ctorMAXS = 0;
396 408
397 insns.add(new LdcInsnNode(this.name)); ctorMAXS++; 409 insns.add(new LdcInsnNode(this.name)); ctorMAXS++;
398 insns.add(this.methodIsStatic ? new InsnNode(Opcodes.ACONST_NULL) : new VarInsnNode(Opcodes.ALOAD, 0)); ctorMAXS++; 410 insns.add(this.methodIsStatic ? new InsnNode(Opcodes.ACONST_NULL) : new VarInsnNode(Opcodes.ALOAD, 0)); ctorMAXS++;
399 insns.add(new InsnNode(cancellable ? Opcodes.ICONST_1 : Opcodes.ICONST_0)); ctorMAXS++; 411 insns.add(new InsnNode(cancellable ? Opcodes.ICONST_1 : Opcodes.ICONST_0)); ctorMAXS++;
400 - insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, this.eventInfoClass, Obf.constructor.name, EventInfo.getConstructorDescriptor(), false)); 412 +
  413 + if (pushReturnValue)
  414 + {
  415 + insns.add(new VarInsnNode(this.methodReturnType.getOpcode(Opcodes.ILOAD), marshallVar));
  416 + insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, this.eventInfoClass, Obf.constructor.name, EventInfo.getConstructorDescriptor(this.methodReturnType), false));
  417 + }
  418 + else
  419 + {
  420 + insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, this.eventInfoClass, Obf.constructor.name, EventInfo.getConstructorDescriptor(), false));
  421 + }
401 422
402 return ctorMAXS; 423 return ctorMAXS;
403 } 424 }
@@ -412,18 +433,18 @@ public class Event implements Comparable&lt;Event&gt; @@ -412,18 +433,18 @@ public class Event implements Comparable&lt;Event&gt;
412 * 433 *
413 * @param insns 434 * @param insns
414 * @param injectionPoint 435 * @param injectionPoint
415 - * @param eventInfoVar 436 + * @param marshallVar
416 */ 437 */
417 - protected void injectCancellationCode(final InsnList insns, final AbstractInsnNode injectionPoint, int eventInfoVar) 438 + protected void injectCancellationCode(final InsnList insns, final AbstractInsnNode injectionPoint, int marshallVar)
418 { 439 {
419 - insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar)); 440 + insns.add(new VarInsnNode(Opcodes.ALOAD, marshallVar));
420 insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, this.eventInfoClass, EventInfo.getIsCancelledMethodName(), EventInfo.getIsCancelledMethodSig(), false)); 441 insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, this.eventInfoClass, EventInfo.getIsCancelledMethodName(), EventInfo.getIsCancelledMethodSig(), false));
421 442
422 LabelNode notCancelled = new LabelNode(); 443 LabelNode notCancelled = new LabelNode();
423 insns.add(new JumpInsnNode(Opcodes.IFEQ, notCancelled)); 444 insns.add(new JumpInsnNode(Opcodes.IFEQ, notCancelled));
424 445
425 // If this is a void method, just injects a RETURN opcode, otherwise we need to get the return value from the EventInfo 446 // If this is a void method, just injects a RETURN opcode, otherwise we need to get the return value from the EventInfo
426 - this.injectReturnCode(insns, injectionPoint, eventInfoVar); 447 + this.injectReturnCode(insns, injectionPoint, marshallVar);
427 448
428 insns.add(notCancelled); 449 insns.add(notCancelled);
429 } 450 }
java/common/com/mumfrey/liteloader/transformers/event/EventInfo.java
@@ -108,10 +108,10 @@ public class EventInfo&lt;S&gt; implements Cancellable @@ -108,10 +108,10 @@ public class EventInfo&lt;S&gt; implements Cancellable
108 108
109 if (returnType.getSort() == Type.OBJECT) 109 if (returnType.getSort() == Type.OBJECT)
110 { 110 {
111 - return String.format("(%s%s%sZ)V", EventInfo.STRING, EventInfo.OBJECT, EventInfo.OBJECT); 111 + return String.format("(%s%sZ%s)V", EventInfo.STRING, EventInfo.OBJECT, EventInfo.OBJECT);
112 } 112 }
113 113
114 - return String.format("(%s%s%sZ)V", EventInfo.STRING, EventInfo.OBJECT, returnType.getDescriptor()); 114 + return String.format("(%s%sZ%s)V", EventInfo.STRING, EventInfo.OBJECT, returnType.getDescriptor());
115 } 115 }
116 116
117 public static String getConstructorDescriptor() 117 public static String getConstructorDescriptor()
java/common/com/mumfrey/liteloader/transformers/event/inject/BeforeInvoke.java
@@ -223,9 +223,12 @@ public class BeforeInvoke extends InjectionPoint @@ -223,9 +223,12 @@ public class BeforeInvoke extends InjectionPoint
223 if (this.methodOwners[i] != null) this.methodOwners[i] = this.methodOwners[i].replace('.', '/'); 223 if (this.methodOwners[i] != null) this.methodOwners[i] = this.methodOwners[i].replace('.', '/');
224 } 224 }
225 225
226 - for (int i = 0; i < this.methodSignatures.length; i++) 226 + if (this.methodSignatures != null)
227 { 227 {
228 - if (this.methodSignatures[i] != null) this.methodSignatures[i] = this.methodSignatures[i].replace('.', '/'); 228 + for (int i = 0; i < this.methodSignatures.length; i++)
  229 + {
  230 + if (this.methodSignatures[i] != null) this.methodSignatures[i] = this.methodSignatures[i].replace('.', '/');
  231 + }
229 } 232 }
230 } 233 }
231 234