Merge pull request #78 from Techcable/feature/asm-executors

Handle static event methods
This commit is contained in:
Zach 2016-03-12 12:20:35 -06:00
commit c231a1b9e9
2 changed files with 58 additions and 11 deletions

View file

@ -1,9 +1,9 @@
From 7e35c9c03a1fe023e8da7de1718f60e00298c6b5 Mon Sep 17 00:00:00 2001
From c1dc52ffb0997b633a552eb4fc6341de01a50e40 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@outlook.com>
Date: Thu, 3 Mar 2016 13:20:33 -0700
Subject: [PATCH] Use ASM for event executors.
Uses method handles for private methods.
Uses method handles for private or static methods.
diff --git a/pom.xml b/pom.xml
index 0b615b4..1ad108e 100644
@ -68,6 +68,51 @@ index 0000000..9ff99e3
+ }
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
new file mode 100644
index 0000000..f60f010
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
@@ -0,0 +1,39 @@
+package com.destroystokyo.paper.event.executor;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import com.google.common.base.Preconditions;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.EventException;
+import org.bukkit.event.Listener;
+import org.bukkit.plugin.EventExecutor;
+
+public class StaticMethodHandleEventExecutor implements EventExecutor {
+ private final Class<? extends Event> eventClass;
+ private final MethodHandle handle;
+
+ public StaticMethodHandleEventExecutor(Class<? extends Event> eventClass, Method m) {
+ Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
+ this.eventClass = eventClass;
+ try {
+ m.setAccessible(true);
+ this.handle = MethodHandles.lookup().unreflect(m);
+ } catch (IllegalAccessException e) {
+ throw new AssertionError("Unable to set accessible", e);
+ }
+ }
+
+ @Override
+ public void execute(Listener listener, Event event) throws EventException {
+ if (!eventClass.isInstance(event)) return;
+ try {
+ handle.invoke(event);
+ } catch (Throwable t) {
+ throw new EventException(t);
+ }
+ }
+}
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java
new file mode 100644
index 0000000..45c2330
@ -264,10 +309,10 @@ index 0000000..62acbf8
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/EventExecutor.java b/src/main/java/org/bukkit/plugin/EventExecutor.java
index 3b2c99e..7b92ce0 100644
index 3b2c99e..f9316d6 100644
--- a/src/main/java/org/bukkit/plugin/EventExecutor.java
+++ b/src/main/java/org/bukkit/plugin/EventExecutor.java
@@ -4,9 +4,53 @@ import org.bukkit.event.Event;
@@ -4,9 +4,55 @@ import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.Listener;
@ -276,6 +321,7 @@ index 3b2c99e..7b92ce0 100644
+import java.lang.reflect.Modifier;
+
+import com.destroystokyo.paper.event.executor.MethodHandleEventExecutor;
+import com.destroystokyo.paper.event.executor.StaticMethodHandleEventExecutor;
+import com.destroystokyo.paper.event.executor.asm.ASMEventExecutorGenerator;
+import com.destroystokyo.paper.event.executor.asm.ClassDefiner;
+import com.google.common.base.Preconditions;
@ -292,9 +338,10 @@ index 3b2c99e..7b92ce0 100644
+ Preconditions.checkNotNull(m, "Null method");
+ Preconditions.checkArgument(m.getParameterCount() != 0, "Incorrect number of arguments %s", m.getParameterCount());
+ Preconditions.checkArgument(m.getParameterTypes()[0] == eventClass, "First parameter %s doesn't match event class %s", m.getParameterTypes()[0], eventClass);
+ Preconditions.checkArgument(!Modifier.isStatic(m.getModifiers()), "Static method %s", m.getName());
+ ClassDefiner definer = ClassDefiner.getInstance();
+ if (definer.isBypassAccessChecks() || Modifier.isPublic(m.getDeclaringClass().getModifiers()) && Modifier.isPublic(m.getModifiers())) {
+ if (Modifier.isStatic(m.getModifiers())) {
+ return new StaticMethodHandleEventExecutor(eventClass, m);
+ } if (definer.isBypassAccessChecks() || Modifier.isPublic(m.getDeclaringClass().getModifiers()) && Modifier.isPublic(m.getModifiers())) {
+ String name = ASMEventExecutorGenerator.generateName();
+ byte[] classData = ASMEventExecutorGenerator.generateEventExecutor(m, name);
+ Class<? extends EventExecutor> c = definer.defineClass(m.getDeclaringClass().getClassLoader(), name, classData).asSubclass(EventExecutor.class);

View file

@ -1,4 +1,4 @@
From e6a7755229623e86993c9082866072172ce1801e Mon Sep 17 00:00:00 2001
From a069652a3ba0866cac4c632565af03258a99c17b Mon Sep 17 00:00:00 2001
From: DoctorDark <doctordark11@gmail.com>
Date: Wed, 2 Mar 2016 01:17:06 -0600
Subject: [PATCH] Configurable end credits when leaving the end
@ -20,10 +20,10 @@ index 5504cfe..6dc7e4c 100644
+ }
}
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index df58d6c..45b1ed8 100644
index 2ec82a2..59ea36d 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -526,9 +526,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
@@ -525,9 +525,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public Entity c(int i) {
this.cj = true;
@ -37,7 +37,7 @@ index df58d6c..45b1ed8 100644
this.viewingCredits = true;
if (this.a(AchievementList.D)) {
this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, 0.0F));
@@ -546,7 +548,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
@@ -545,7 +547,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
} else {
this.b((Statistic) AchievementList.y);
}
@ -47,7 +47,7 @@ index df58d6c..45b1ed8 100644
// CraftBukkit start
TeleportCause cause = (this.dimension == 1 || i == 1) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL;
this.server.getPlayerList().changeDimension(this, i, cause); // PAIL: check all this
@@ -557,6 +561,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
@@ -556,6 +560,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
this.cb = -1;
return this;
}