@SuppressWarnings("unchecked") private static ObjCClass toObjCClass(Class<?>[] array, int index) { return array.length > index ? ObjCClass.getByType((Class<? extends ObjCObject>) array[index]) : null; }
@MarshalsPointer public static Class<? extends ObjCObject> toObject(Class<ObjCClass> cls, long handle, long flags) { ObjCClass o = ObjCClass.toObjCClass(handle); if (o == null) { return null; } return o.getType(); } @MarshalsPointer
private static void logRetainRelease(long cls, long self, int count, boolean isRetain) { String className = ObjCClass.getFromObject(cls).getType().getName(); System.err.println(String.format("[Debug] %s %s@0x%s, retain count: %d", isRetain ? "Retained" : "Released", className, Long.toHexString(self), isRetain ? count + 1 : count - 1)); } }
@SuppressWarnings("unchecked") private static ObjCClass register(Class<? extends ObjCObject> type, String name) { ObjCClass superclass = getByType((Class<? extends ObjCObject>) type.getSuperclass()); long handle = ObjCRuntime.objc_allocateClassPair(superclass.getHandle(), VM.getStringUTFChars(name), 0); if (handle == 0L) { throw new ObjCClassNotFoundException("Failed to create custom Objective-C class for Java class: " + type); for (Entry<String, Method> entry : getCallbacks(type).entrySet()) { String selName = entry.getKey(); Method method = entry.getValue(); } else { long methodPtr = isClassMethod ? ObjCRuntime.class_getClassMethod(superclass.getHandle(), selector.getHandle()) : ObjCRuntime.class_getInstanceMethod(superclass.getHandle(), selector.getHandle()); if (methodPtr != 0L) { long encodingPtr = ObjCRuntime.method_getTypeEncoding(methodPtr); return new ObjCClass(handle, type, name, !isObjCProxy(type), false);
return (T) ObjCClass.toObjCClass(handle); return createInstance(ObjCClass.getByType(cls), handle, afterMarshaledFlags, false); if (ObjCClass.isObjCProxy(cls)) { expectedType = cls.getInterfaces()[0]; if (o != null && o.getHandle() != 0) { if (!expectedType.isAssignableFrom(o.getClass())) { if (ObjCClass.isObjCProxy(o.getClass())) { } else if (ObjCClass.isObjCProxy(cls)) { return createInstance(ObjCClass.getByType(cls), handle, afterMarshaledFlags, false); } else { ObjCClass objCClass = ObjCClass.getFromObject(handle); if (!expectedType.isAssignableFrom(objCClass.getType())) { objCClass = ObjCClass.getByType(cls);
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(); }
ObjCClass c = ObjCObject.getPeerObject(classPtr); if (c == null) { c = getByNameNotLoaded(VM.newStringUTF(ObjCRuntime.class_getName(classPtr))); for (String protocol : getProtocols(classPtr, false)) { Class<? extends ObjCObject> cls = allNativeProtocolProxies.get(protocol); if (cls != null) { c = getByType(cls); break; c = ObjCObject.getPeerObject(classPtr); if (c == null) { c = getByNameNotLoaded(VM.newStringUTF(ObjCRuntime.class_getName(classPtr))); if (c == null) { for (String protocol : getProtocols(classPtr, false)) { Class<? extends ObjCObject> cls = allNativeProtocolProxies.get(protocol); if (cls != null) { c = getByType(cls); break;
@SuppressWarnings("unchecked") protected ObjCSuper getSuper() { if (zuper == null) { Class<? extends ObjCObject> javaClass = (Class<? extends ObjCObject>) getClass().getSuperclass(); ObjCClass objCClass = ObjCClass.getByType(javaClass); while (objCClass.isCustom()) { javaClass = (Class<? extends ObjCObject>) javaClass.getSuperclass(); objCClass = ObjCClass.getByType(javaClass); } zuper = new ObjCSuper(this, objCClass); } return zuper; }
static long alloc(ObjCClass c) { long h = ObjCRuntime.ptr_objc_msgSend(c.getHandle(), alloc.getHandle()); if (h == 0L) { throw new OutOfMemoryError(); } return h; }
long classPtr = ObjCRuntime.objc_getClass(VM.getStringUTFChars(name)); if (classPtr != 0L) { c = new ObjCClass(classPtr, type, name, false, false); long protocolPtr = ObjCRuntime.objc_getProtocol(VM.getStringUTFChars(name)); if (protocolPtr != 0L) { c = new ObjCClass(protocolPtr, type, name, false, true); name = getCustomClassName(type); c = register(type, name);
/** * Creates a new instance of the specified {@link ObjCClass}. If * {@code makePeer == true} this method MUST be called while the * {@link #objcBridgeLock} is held. */ @SuppressWarnings("unchecked") private static <T extends ObjCObject> T createInstance(ObjCClass objCClass, long handle, int afterMarshaledFlags, boolean makePeer) { Class<T> c = (Class<T>) objCClass.getType(); T o = VM.allocateObject(c); o.setHandle(handle); if (makePeer) { setPeerObject(handle, o); } if (objCClass.isCustom()) { VM.setBoolean(VM.getObjectAddress(o) + CUSTOM_CLASS_OFFSET, true); } o.afterMarshaled(afterMarshaledFlags); return o; }
/** * Preloads classes added during compilation, if any. */ private static void preloadClasses() throws UnsupportedEncodingException { byte[] data = VM.getRuntimeData(UIApplication.class.getName() + ".preloadClasses"); if (data != null) { String[] customClasses = new String(data, "UTF8").split(","); for (String customClass : customClasses) { try { // Register class. @SuppressWarnings("unchecked") Class<? extends ObjCClass> cls = (Class<? extends ObjCClass>) Class.forName(customClass); ObjCClass.registerCustomClass(cls); } catch (Throwable t) { Foundation.log("Failed to preload class " + customClass + ": " + t.getMessage()); t.printStackTrace(); } } } }
@Callback private static String parseClassName(ObjCClass self, @Pointer long selector) { Class<?> clazz = self.getType(); ParseClassName annotation = clazz.getAnnotation(ParseClassName.class); return annotation.value(); }
private static Map<String, Method> getCallbacks(Class<?> type) { Map<String, Method> callbacks = new HashMap<String, Method>(); findCallbacks(type, callbacks); return callbacks; }
public static ObjCClass getByName(String objcClassName) { synchronized (objcBridgeLock) { ObjCClass c = nameToClass.get(objcClassName); if (c == null) { c = getByNameNotLoaded(objcClassName); if (c == null) { throw new ObjCClassNotFoundException("Could not find Java class corresponding to Objective-C class: " + objcClassName); } } return c; } }
@SuppressWarnings("unchecked") private static ObjCClass register(Class<? extends ObjCObject> type, String name) { ObjCClass superclass = getByType((Class<? extends ObjCObject>) type.getSuperclass()); long handle = ObjCRuntime.objc_allocateClassPair(superclass.getHandle(), VM.getStringUTFChars(name), 0); if (handle == 0L) { throw new ObjCClassNotFoundException("Failed to create custom Objective-C class for Java class: " + type); for (Entry<String, Method> entry : getCallbacks(type).entrySet()) { String selName = entry.getKey(); Method method = entry.getValue(); } else { long methodPtr = isClassMethod ? ObjCRuntime.class_getClassMethod(superclass.getHandle(), selector.getHandle()) : ObjCRuntime.class_getInstanceMethod(superclass.getHandle(), selector.getHandle()); if (methodPtr != 0L) { long encodingPtr = ObjCRuntime.method_getTypeEncoding(methodPtr); return new ObjCClass(handle, type, name, !isObjCProxy(type), false);
return (T) ObjCClass.toObjCClass(handle); return createInstance(ObjCClass.getByType(cls), handle, afterMarshaledFlags, false); if (ObjCClass.isObjCProxy(cls)) { expectedType = cls.getInterfaces()[0]; if (o != null && o.getHandle() != 0) { if (!expectedType.isAssignableFrom(o.getClass())) { if (ObjCClass.isObjCProxy(o.getClass())) { } else if (ObjCClass.isObjCProxy(cls)) { return createInstance(ObjCClass.getByType(cls), handle, afterMarshaledFlags, false); } else { ObjCClass objCClass = ObjCClass.getFromObject(handle); if (!expectedType.isAssignableFrom(objCClass.getType())) { objCClass = ObjCClass.getByType(cls);
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(); }