public Object invoke (Object target, Object[] args) throws IllegalAccessException, InvocationTargetException { try { return methodAccess.invoke(target, methodAccessIndex, args); } catch (Exception ex) { throw new InvocationTargetException(ex); } } }
ReflectASMFieldAccessor(Class<T> ownerType, Field field, Class<U> fieldType) throws InaccessibleFieldException { methodAccess = MethodAccess.get(ownerType); Method getter = ReflectionUtil.findGetter(field); if (getter != null) { getterIndex = methodAccess.getIndex(getter.getName()); } Method setter = ReflectionUtil.findSetter(field); if (setter != null) { setterIndex = methodAccess.getIndex(setter.getName()); } if (getterIndex == NO_METHOD || setterIndex == NO_METHOD) { fieldAccess = FieldAccess.get(ownerType); try { fieldIndex = fieldAccess.getIndex(field.getName()); } catch (IllegalArgumentException e) { throw new InaccessibleFieldException("Failed to create accessor for field '" + field.getName() + "' of type '" + ownerType.getName() + "'", e); } } }
ByteCodeEventHandlerInfo(ComponentSystem handler, Method method, int priority, String activity, Collection<Class<? extends Component>> filterComponents, Collection<Class<? extends Component>> componentParams) { this.handler = handler; this.activity = activity; this.methodAccess = MethodAccess.get(handler.getClass()); methodIndex = methodAccess.getIndex(method.getName(), method.getParameterTypes()); this.filterComponents = ImmutableList.copyOf(filterComponents); this.componentParams = ImmutableList.copyOf(componentParams); this.priority = priority; }
Class<?> defineClass (String name, byte[] bytes) throws ClassFormatError { try { // Attempt to load the access class in the same loader, which makes protected and default access members accessible. return (Class<?>)getDefineClassMethod().invoke(getParent(), new Object[] {name, bytes, Integer.valueOf(0), Integer.valueOf(bytes.length), getClass().getProtectionDomain()}); } catch (Exception ignored) { // continue with the definition in the current loader (won't have access to protected and package-protected members) } return defineClass(name, bytes, 0, bytes.length, getClass().getProtectionDomain()); }
@Override public Object newInstance () { try { return access.newInstance(); } catch (Exception ex) { throw new KryoException("Error constructing instance of class: " + className(type), ex); } } };
static AccessClassLoader get (Class type) { ClassLoader parent = getParentClassLoader(type); // 1. fast-path: if (selfContextParentClassLoader.equals(parent)) { if (selfContextAccessClassLoader == null) { synchronized (accessClassLoaders) { // DCL with volatile semantics if (selfContextAccessClassLoader == null) selfContextAccessClassLoader = new AccessClassLoader(selfContextParentClassLoader); } } return selfContextAccessClassLoader; } // 2. normal search: synchronized (accessClassLoaders) { WeakReference<AccessClassLoader> ref = accessClassLoaders.get(parent); if (ref != null) { AccessClassLoader accessClassLoader = ref.get(); if (accessClassLoader != null) return accessClassLoader; else accessClassLoaders.remove(parent); // the value has been GC-reclaimed, but still not the key (defensive sanity) } AccessClassLoader accessClassLoader = new AccessClassLoader(parent); accessClassLoaders.put(parent, new WeakReference<AccessClassLoader>(accessClassLoader)); return accessClassLoader; } }
static private void recursiveAddInterfaceMethodsToList (Class interfaceType, ArrayList<Method> methods) { addDeclaredMethodsToList(interfaceType, methods); for (Class nextInterface : interfaceType.getInterfaces()) recursiveAddInterfaceMethodsToList(nextInterface, methods); } }
Class defineAccessClass (String name, byte[] bytes) throws ClassFormatError { localClassNames.add(name); return defineClass(name, bytes); }
/** Returns null if the access class has not yet been defined. */ Class loadAccessClass (String name) { // No need to check the parent class loader if the access class hasn't been defined yet. if (localClassNames.contains(name)) { try { return loadClass(name, false); } catch (ClassNotFoundException ex) { throw new RuntimeException(ex); // Should not happen, since we know the class has been defined. } } return null; }
ByteCodeEventHandlerInfo(ComponentSystem handler, Method method, int priority, String activity, Collection<Class<? extends Component>> filterComponents, Collection<Class<? extends Component>> componentParams) { this.handler = handler; this.activity = activity; this.methodAccess = MethodAccess.get(handler.getClass()); methodIndex = methodAccess.getIndex(method.getName(), method.getParameterTypes()); this.filterComponents = ImmutableList.copyOf(filterComponents); this.componentParams = ImmutableList.copyOf(componentParams); this.priority = priority; }
@Override public void invoke(EntityRef entity, Event event) { try { Object[] params = new Object[2 + componentParams.size()]; params[0] = event; params[1] = entity; for (int i = 0; i < componentParams.size(); ++i) { params[i + 2] = entity.getComponent(componentParams.get(i)); } if (!activity.isEmpty()) { PerformanceMonitor.startActivity(activity); } try { methodAccess.invoke(handler, methodIndex, params); } finally { if (!activity.isEmpty()) { PerformanceMonitor.endActivity(); } } } catch (Exception ex) { logger.error("Failed to invoke event", ex); } }
@Override public Object newInstance () { try { return access.newInstance(); } catch (Exception ex) { throw new KryoException("Error constructing instance of class: " + className(type), ex); } } };
if (asm && !Util.isAndroid && Modifier.isPublic(type.getModifiers())) methodAccess = MethodAccess.get(type); try { AsmCachedMethod asmCachedMethod = new AsmCachedMethod(); asmCachedMethod.methodAccessIndex = ((MethodAccess)methodAccess).getIndex(method.getName(), parameterTypes); asmCachedMethod.methodAccess = (MethodAccess)methodAccess; cachedMethod = asmCachedMethod;
@Override public void invoke(EntityRef entity, Event event) { try { Object[] params = new Object[2 + componentParams.size()]; params[0] = event; params[1] = entity; for (int i = 0; i < componentParams.size(); ++i) { params[i + 2] = entity.getComponent(componentParams.get(i)); } if (!activity.isEmpty()) { PerformanceMonitor.startActivity(activity); } try { methodAccess.invoke(handler, methodIndex, params); } finally { if (!activity.isEmpty()) { PerformanceMonitor.endActivity(); } } } catch (Exception ex) { logger.error("Failed to invoke event", ex); } }