Commit 171e491f790ffcaa8d23e85821c56c077dc103b9
1 parent
104bd7e5
pass the current return value into ReturnEventInfo ctor where possible
Showing
3 changed files
with
39 additions
and
15 deletions
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<Event> | @@ -367,7 +379,7 @@ public class Event implements Comparable<Event> | ||
| 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<Event> | @@ -390,14 +402,23 @@ public class Event implements Comparable<Event> | ||
| 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<Event> | @@ -412,18 +433,18 @@ public class Event implements Comparable<Event> | ||
| 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<S> implements Cancellable | @@ -108,10 +108,10 @@ public class EventInfo<S> 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 |