From c114ab3fea0841dd345c5c0228462236bdf2bc2b Mon Sep 17 00:00:00 2001 From: Techcable Date: Sat, 12 Mar 2016 09:43:39 -0700 Subject: [PATCH] Handle static methods --- .../Use-ASM-for-event-executors.patch | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/Spigot-API-Patches/Use-ASM-for-event-executors.patch b/Spigot-API-Patches/Use-ASM-for-event-executors.patch index e7e96bd01b..8264ee5cd7 100644 --- a/Spigot-API-Patches/Use-ASM-for-event-executors.patch +++ b/Spigot-API-Patches/Use-ASM-for-event-executors.patch @@ -3,7 +3,7 @@ From: Techcable 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 @@ -68,6 +68,51 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } +} +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java +@@ -0,0 +0,0 @@ ++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 eventClass; ++ private final MethodHandle handle; ++ ++ public StaticMethodHandleEventExecutor(Class 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 @@ -276,6 +321,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +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 0000000000000000000000000000000000000000..00000000000000000000000000000000 + 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 c = definer.defineClass(m.getDeclaringClass().getClassLoader(), name, classData).asSubclass(EventExecutor.class);