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 |