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 345 LiteLoaderLogger.debug("Event %s is spawning handler %s in class %s", this.name, handler.name, Event.getActiveProxyRef());
346 346  
347 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 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 364 // Instance the EventInfo for this event
353 365 insns.add(new TypeInsnNode(Opcodes.NEW, this.eventInfoClass)); ctorMAXS++;
354 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 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 372 ByteCodeUtilities.loadArgs(arguments, insns, this.methodIsStatic ? 0 : 1);
361 373 if (doCaptureLocals)
362 374 {
... ... @@ -367,7 +379,7 @@ public class Event implements Comparable&lt;Event&gt;
367 379 if (cancellable)
368 380 {
369 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 385 // Inject our generated code into the method
... ... @@ -390,14 +402,23 @@ public class Event implements Comparable&lt;Event&gt;
390 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 407 int ctorMAXS = 0;
396 408  
397 409 insns.add(new LdcInsnNode(this.name)); ctorMAXS++;
398 410 insns.add(this.methodIsStatic ? new InsnNode(Opcodes.ACONST_NULL) : new VarInsnNode(Opcodes.ALOAD, 0)); ctorMAXS++;
399 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 423 return ctorMAXS;
403 424 }
... ... @@ -412,18 +433,18 @@ public class Event implements Comparable&lt;Event&gt;
412 433 *
413 434 * @param insns
414 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 441 insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, this.eventInfoClass, EventInfo.getIsCancelledMethodName(), EventInfo.getIsCancelledMethodSig(), false));
421 442  
422 443 LabelNode notCancelled = new LabelNode();
423 444 insns.add(new JumpInsnNode(Opcodes.IFEQ, notCancelled));
424 445  
425 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 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 108  
109 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 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 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  
... ...