private static long getNativeSuper(final long cls) { /* * We cannot just assume that cls is a custom class that has an * entry in customClassToNativeSuper. The Obj-C runtime will * sometimes subclass our custom classes (e.g. when doing key-value * observing) which means that retain()/release() in this class may * be called with instances of such subclasses. We must walk the * class hierarchy to find the actual custom class. */ long c = cls; synchronized (customClassToNativeSuper) { while (c != 0) { long nativeSuper = customClassToNativeSuper.get(c, ZERO_LONG); if (nativeSuper != 0) { return nativeSuper; } c = ObjCRuntime.class_getSuperclass(c); } } List<String> classHierarchy = new ArrayList<>(); c = cls; while (c != 0) { classHierarchy.add(VM.newStringUTF(ObjCRuntime.class_getName(c))); c = ObjCRuntime.class_getSuperclass(c); } throw new Error("Failed to find a custom class to native super class " + "mapping for class hierarchy " + classHierarchy); } }
public String toDebugString() { StringBuilder sb = new StringBuilder(); sb.append("@interface ").append(getName()); long superclass = ObjCRuntime.class_getSuperclass(getHandle()); if (superclass != 0) { sb.append(" : ").append(VM.newStringUTF(ObjCRuntime.class_getName(superclass))); } IntPtr outCount = new IntPtr(); long protocols = ObjCRuntime.class_copyProtocolList(getHandle(), outCount.getHandle()); if (outCount.get() > 0) { sb.append(" <"); for (int i = 0; i < outCount.get(); i++) { if (i > 0) { sb.append(", "); } sb.append(VM.newStringUTF(ObjCRuntime.protocol_getName(VM.getPointer(protocols)))); protocols += (Bro.IS_64BIT ? 8 : 4); } sb.append('>'); } sb.append('\n'); sb.append("@end"); return sb.toString(); }
private static void registerCallbackMethod(long cls, long selector, long newSelector, Method method) { long superMethod = ObjCRuntime.class_getInstanceMethod(cls, selector); long typeEncoding = ObjCRuntime.method_getTypeEncoding(superMethod); if (!ObjCRuntime.class_addMethod(cls, selector, VM.getCallbackMethodImpl(method), typeEncoding)) { throw new Error( "Failed to register callback method on the ObjectOwnershipHelper: class_addMethod(...) failed"); } // find the super class that is a native class and cache it long superClass = ObjCRuntime.class_getSuperclass(cls); long nativeSuper = 0; while (superClass != 0) { ObjCClass objCClass = ObjCClass.toObjCClass(superClass); if (!objCClass.isCustom()) { nativeSuper = superClass; break; } superClass = ObjCRuntime.class_getSuperclass(superClass); } if (nativeSuper == 0) { throw new Error("Couldn't find native super class for " + VM.newStringUTF(ObjCRuntime.class_getName(cls))); } synchronized (customClassToNativeSuper) { customClassToNativeSuper.put(cls, nativeSuper); } }
classPtr = ObjCRuntime.class_getSuperclass(classPtr); c = ObjCObject.getPeerObject(classPtr); if (c == null) {
private static long getNativeSuper(final long cls) { /* * We cannot just assume that cls is a custom class that has an * entry in customClassToNativeSuper. The Obj-C runtime will * sometimes subclass our custom classes (e.g. when doing key-value * observing) which means that retain()/release() in this class may * be called with instances of such subclasses. We must walk the * class hierarchy to find the actual custom class. */ long c = cls; synchronized (customClassToNativeSuper) { while (c != 0) { long nativeSuper = customClassToNativeSuper.get(c, ZERO_LONG); if (nativeSuper != 0) { return nativeSuper; } c = ObjCRuntime.class_getSuperclass(c); } } List<String> classHierarchy = new ArrayList<>(); c = cls; while (c != 0) { classHierarchy.add(VM.newStringUTF(ObjCRuntime.class_getName(c))); c = ObjCRuntime.class_getSuperclass(c); } throw new Error("Failed to find a custom class to native super class " + "mapping for class hierarchy " + classHierarchy); } }
public String toDebugString() { StringBuilder sb = new StringBuilder(); sb.append("@interface ").append(getName()); long superclass = ObjCRuntime.class_getSuperclass(getHandle()); if (superclass != 0) { sb.append(" : ").append(VM.newStringUTF(ObjCRuntime.class_getName(superclass))); } IntPtr outCount = new IntPtr(); long protocols = ObjCRuntime.class_copyProtocolList(getHandle(), outCount.getHandle()); if (outCount.get() > 0) { sb.append(" <"); for (int i = 0; i < outCount.get(); i++) { if (i > 0) { sb.append(", "); } sb.append(VM.newStringUTF(ObjCRuntime.protocol_getName(VM.getPointer(protocols)))); protocols += (Bro.IS_64BIT ? 8 : 4); } sb.append('>'); } sb.append('\n'); sb.append("@end"); return sb.toString(); }
private static void registerCallbackMethod(long cls, long selector, long newSelector, Method method) { long superMethod = ObjCRuntime.class_getInstanceMethod(cls, selector); long typeEncoding = ObjCRuntime.method_getTypeEncoding(superMethod); if (!ObjCRuntime.class_addMethod(cls, selector, VM.getCallbackMethodImpl(method), typeEncoding)) { throw new Error( "Failed to register callback method on the ObjectOwnershipHelper: class_addMethod(...) failed"); } // find the super class that is a native class and cache it long superClass = ObjCRuntime.class_getSuperclass(cls); long nativeSuper = 0; while (superClass != 0) { ObjCClass objCClass = ObjCClass.toObjCClass(superClass); if (!objCClass.isCustom()) { nativeSuper = superClass; break; } superClass = ObjCRuntime.class_getSuperclass(superClass); } if (nativeSuper == 0) { throw new Error("Couldn't find native super class for " + VM.newStringUTF(ObjCRuntime.class_getName(cls))); } synchronized (customClassToNativeSuper) { customClassToNativeSuper.put(cls, nativeSuper); } }
classPtr = ObjCRuntime.class_getSuperclass(classPtr); c = ObjCObject.getPeerObject(classPtr); if (c == null) {