Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2012 RoboVM AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.robovm.objc;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.robovm.rt.VM;
import org.robovm.rt.bro.Bro;
import org.robovm.rt.bro.Runtime;
import org.robovm.rt.bro.Struct;
import org.robovm.rt.bro.annotation.Bridge;
import org.robovm.rt.bro.annotation.ByVal;
import org.robovm.rt.bro.annotation.Library;
import org.robovm.rt.bro.annotation.Pointer;
import org.robovm.rt.bro.annotation.StructRet;
import org.robovm.rt.bro.ptr.BytePtr;
/**
*
*/
@Library("objc")
public class ObjCRuntime {
private static final Map, Integer> structSizes = new HashMap, Integer>();
static {
Bro.bind(ObjCRuntime.class);
}
public static void bind() {
Class> caller = VM.getStackClasses(0, 1)[0];
bind(caller);
}
public static void bind(Class> c) {
for (Method method : c.getDeclaredMethods()) {
Bridge bridge = method.getAnnotation(Bridge.class);
if (bridge != null && (bridge.symbol() == null || "".equals(bridge.symbol()))) {
Class>[] paramTypes = method.getParameterTypes();
if (paramTypes.length >= 2) {
// An ObjC method takes at least 2 parameters (self, selector)
// or (super, selector).
if (paramTypes[1] == Selector.class) {
String symbol = null;
if (paramTypes[0] == ObjCSuper.class) {
symbol = "objc_msgSendSuper";
} else if (ObjCObject.class.isAssignableFrom(paramTypes[0])) {
// self should be an instance of ObjCObject
symbol = "objc_msgSend";
} else if (paramTypes[0] == long.class) {
// Also allow @Pointer long as type of self
Annotation[] paramAnnos = method.getParameterAnnotations()[0];
for (Annotation a : paramAnnos) {
if (a.annotationType() == Pointer.class) {
symbol = "objc_msgSend";
break;
}
}
}
if (symbol != null) {
// So this is a bridge to an ObjC method. If the method
// returns a struct by value we may have to use the
// special stret versions of objc_msgSend/objc_msgSendSuper.
if (isStret(method)) {
symbol += "_stret";
}
long f = Runtime.resolveBridge("objc", symbol, method);
VM.bindBridgeMethod(method, f);
}
}
}
}
}
Bro.bind(c);
}
static boolean isStret(Method method) {
Class> returnType = method.getReturnType();
if (returnType.getSuperclass() == Struct.class
&& (method.getAnnotation(ByVal.class) != null
|| returnType.getAnnotation(ByVal.class) != null)) {
int structSize = getStructSize(returnType);
if (Bro.IS_X86 && Bro.IS_32BIT) {
if (structSize > 2 && structSize != 4 && structSize != 8) {
// On x86 stret has to be used for all structs except
// of size 1, 2, 4 and 8 bytes.
return true;
}
} else if (Bro.IS_X86 && Bro.IS_64BIT) {
if (structSize > 16) {
return true;
}
} else if (Bro.IS_ARM && Bro.IS_32BIT) {
if (structSize > 4) {
// On ARM stret has to be used for structs
// larger than 4 bytes
return true;
}
} else if (Bro.IS_ARM && Bro.IS_64BIT) {
// iOS ARM64 doesn't have objc_msgSend_stret
return false;
} else {
throw new Error("Unsupported architecture");
}
}
return false;
}
static synchronized int getStructSize(Class> cls) {
Integer size = structSizes.get(cls);
if (size == null) {
try {
Method sizeOf = cls.getMethod("sizeOf");
size = (Integer) sizeOf.invoke(null);
} catch (Exception e) {
throw new Error(e);
}
structSizes.put(cls, size);
}
return size;
}
/* selector */
@Bridge
public static native BytePtr sel_getName(Selector sel);
@Bridge
public static native Selector sel_registerName(BytePtr str);
/* objc */
@Bridge
public static native @Pointer long objc_getClass(@Pointer long name);
@Bridge
public static native @Pointer long objc_getMetaClass(@Pointer long name);
@Bridge
public static native @Pointer long objc_allocateClassPair(@Pointer long superclass, @Pointer long name, @Pointer long extraBytes);
@Bridge
public static native void objc_registerClassPair(@Pointer long cls);
@Bridge
public static native @Pointer long objc_getProtocol(@Pointer long name);
@Bridge
public static native @Pointer long objc_allocateProtocol(@Pointer long name);
@Bridge
public static native void objc_registerProtocol(@Pointer long protocol);
@Bridge
public static native void objc_setAssociatedObject(@Pointer long object, @Pointer long key, @Pointer long value, int policy);
@Bridge
public static native @Pointer long objc_getAssociatedObject(@Pointer long object, @Pointer long key);
@Bridge
public static native @Pointer long objc_copyProtocolList (@Pointer long outCount);
/* object */
@Bridge
public static native @Pointer long object_getClass(@Pointer long object);
@Bridge
public static native @Pointer long object_setClass(@Pointer long object, @Pointer long cls);
@Bridge
public static native @Pointer long object_getClassName(@Pointer long object);
@Bridge
public static native @Pointer long object_dispose(@Pointer long object);
@Bridge
public static native @Pointer long object_getIvar(@Pointer long object, @Pointer long ivar);
@Bridge
public static native void object_setIvar(@Pointer long object, @Pointer long ivar, @Pointer long value);
/* class */
@Bridge
public static native @Pointer long class_getSuperclass(@Pointer long cls);
@Bridge
public static native @Pointer long class_isMetaClass(@Pointer long cls);
@Bridge
public static native @Pointer long class_getName(@Pointer long cls);
@Bridge
public static native @Pointer long class_getInstanceMethod(@Pointer long aClass, @Pointer long aSelector);
@Bridge
public static native @Pointer long class_getClassMethod(@Pointer long aClass, @Pointer long aSelector);
@Bridge
public static native boolean class_addProtocol(@Pointer long cls, @Pointer long protocol);
@Bridge
public static native boolean class_conformsToProtocol(@Pointer long cls, @Pointer long protocol);
@Bridge
public static native @Pointer long class_copyProtocolList(@Pointer long cls, @Pointer long outCount);
@Bridge
public static native @Pointer long class_copyMethodList(@Pointer long cls, @Pointer long outCount);
@Bridge
public static native @Pointer long class_copyPropertyList(@Pointer long cls, @Pointer long outCount);
@Bridge
public static native boolean class_addMethod(@Pointer long cls, @Pointer long name, @Pointer long imp, @Pointer long types);
@Bridge
public static native @Pointer long class_replaceMethod(@Pointer long cls, @Pointer long name, @Pointer long imp, @Pointer long types);
@Bridge
public static native @Pointer long class_getMethodImplementation(@Pointer long cls, @Pointer long name);
@Bridge
public static native boolean class_addIvar(@Pointer long cls, @Pointer long name, int size, byte alignment, @Pointer long types);
@Bridge
public static native @Pointer long class_getInstanceVariable(@Pointer long cls, @Pointer long name);
@Bridge
public static native @Pointer long class_getClassVariable(@Pointer long cls, @Pointer long name);
@Bridge
public static native @Pointer long class_getIvarLayout(@Pointer long cls);
@Bridge
public static native void class_setIvarLayout(@Pointer long cls, @Pointer long layout);
@Bridge
public static native @Pointer long class_getProperty(@Pointer long cls, @Pointer long name);
@Bridge
public static native boolean class_respondsToSelector(@Pointer long cls, @Pointer long sel);
/* protocol */
@Bridge
public static native @Pointer long protocol_getName(@Pointer long protocol);
@Bridge
public static native void protocol_addProtocol(@Pointer long protocol, @Pointer long addition);
@Bridge
public static native boolean protocol_conformsToProtocol(@Pointer long protocol, @Pointer long other);
@Bridge
public static native @Pointer long protocol_getProperty(@Pointer long protocol, @Pointer long name, boolean isRequiredProperty, boolean isInstanceProperty);
@Bridge
public static native @Pointer long protocol_copyProtocolList(@Pointer long protocol, @Pointer long outCount);
/* ivar */
@Bridge
public static native @Pointer long ivar_getName(@Pointer long ivar);
@Bridge
public static native @Pointer long ivar_getTypeEncoding(@Pointer long ivar);
@Bridge
public static native int ivar_getOffset(@Pointer long ivar);
/* method */
@Bridge
public static native @Pointer long method_getName(@Pointer long m);
@Bridge
public static native @Pointer long method_copyReturnType(@Pointer long m);
@Bridge
public static native @Pointer long method_copyArgumentType(@Pointer long m, int index);
@Bridge
public static native int method_getNumberOfArguments(@Pointer long m);
@Bridge
public static native @Pointer long method_getTypeEncoding(@Pointer long method);
@Bridge
public static native @Pointer long method_getImplementation(@Pointer long method);
@Bridge
public static native @Pointer long method_setImplementation(@Pointer long m, @Pointer long imp);
@Bridge
public static native void method_exchangeImplementations(@Pointer long m1, @Pointer long m2);
/* property */
@Bridge
public static native @Pointer long property_getName(@Pointer long property);
@Bridge
public static native BytePtr property_getAttributes(@Pointer long property);
@Bridge
public static native BytePtr property_copyAttributeValue(@Pointer long property, BytePtr attributeName);
/* message */
@Bridge(symbol = "objc_msgSend")
public static native @Pointer long ptr_objc_msgSend(@Pointer long receiver, @Pointer long selector);
@Bridge(symbol = "objc_msgSendSuper")
public static native @Pointer long ptr_objc_msgSendSuper(@Pointer long zuper, @Pointer long selector);
@Bridge(symbol = "objc_msgSend")
public static native void void_objc_msgSend(@Pointer long receiver, @Pointer long selector);
@Bridge(symbol = "objc_msgSendSuper")
public static native void void_objc_msgSendSuper(@Pointer long zuper, @Pointer long selector);
@Bridge(symbol = "objc_msgSend")
public static native boolean boolean_objc_msgSend(@Pointer long receiver, @Pointer long selector);
@Bridge(symbol = "objc_msgSend")
public static native void void_objc_msgSend_ptr(@Pointer long receiver, @Pointer long selector, @Pointer long ptr);
@Bridge(symbol = "objc_msgSend")
public static native void void_objc_msgSend_boolean(@Pointer long receiver, @Pointer long selector, boolean b);
@Bridge(symbol = "objc_msgSend")
public static native int int_objc_msgSend(@Pointer long receiver, @Pointer long selector);
@Bridge(symbol = "objc_msgSend")
public static native @Pointer long ptr_objc_msgSend_ptr(@Pointer long receiver, @Pointer long selector, @Pointer long ptr);
@Bridge(symbol = "objc_msgSend")
public static native @Pointer long ptr_objc_msgSend_int(@Pointer long receiver, @Pointer long selector, int i);
@Bridge(symbol = "objc_msgSend")
public static native @Pointer long ptr_objc_msgSend_long(@Pointer long receiver, @Pointer long selector, long l);
@Bridge(symbol = "objc_msgSend")
public static native char char_objc_msgSend_int(@Pointer long receiver, @Pointer long selector, int i);
@Bridge(symbol = "objc_msgSend_stret", optional = true) // Optional since it's not available on iOS ARM64
public static native void objc_msgSend_stret(@StructRet @Pointer long ret, @Pointer long receiver, @Pointer long selector);
}