org.robovm.objc.ObjCBlock Maven / Gradle / Ivy
/*
* Copyright (C) 2013 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.reflect.Field;
import java.lang.reflect.Method;
import java.util.IdentityHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.robovm.objc.annotation.TypeEncoding;
import org.robovm.objc.block.VoidBooleanBlock;
import org.robovm.rt.VM;
import org.robovm.rt.bro.Struct;
import org.robovm.rt.bro.annotation.Callback;
import org.robovm.rt.bro.annotation.MachineSizedUInt;
import org.robovm.rt.bro.annotation.Pointer;
import org.robovm.rt.bro.annotation.StructMember;
import org.robovm.rt.bro.ptr.BytePtr;
/**
* {@link Struct} mapping the {@code Block_literal} struct used internally by
* the Objective-C runtime. This class is only for internal use. See the
* source code of the block interfaces in the {@link org.robovm.objc.block}
* package (e.g. {@link VoidBooleanBlock} for examples on how to marshal
* Objective-C block types.
* The Block ABI
* documentation has more information on how blocks are implemented in
* Objective-C.
*/
public final class ObjCBlock extends Struct {
@StructMember(0)
public native @Pointer long isa();
@StructMember(0)
public native ObjCBlock isa(@Pointer long isa);
@StructMember(1)
public native int flags();
@StructMember(1)
public native ObjCBlock flags(int flags);
@StructMember(2)
public native int reserved();
@StructMember(2)
public native ObjCBlock reserved(int reserved);
@StructMember(3)
public native @Pointer long invoke();
@StructMember(3)
public native ObjCBlock invoke(@Pointer long invoke);
@StructMember(4)
public native Descriptor descriptor();
@StructMember(4)
public native ObjCBlock descriptor(Descriptor descriptor);
@StructMember(5)
public native @Pointer long object_addr();
@StructMember(5)
public native ObjCBlock object_addr(@Pointer long object_addr);
@StructMember(6)
public native @Pointer long wrapper_addr();
@StructMember(6)
public native ObjCBlock wrapper_addr(@Pointer long wrapper_addr);
public static void setHandle(ObjCBlock block, long handle) {
block.setHandle(handle);
}
public Object object() {
return VM.castAddressToObject(object_addr());
}
public ObjCBlock object(Object o) {
object_addr(VM.getObjectAddress(o));
return this;
}
public Wrapper wrapper() {
return (Wrapper) VM.castAddressToObject(wrapper_addr());
}
public ObjCBlock wrapper(Wrapper o) {
wrapper_addr(VM.getObjectAddress(o));
return this;
}
public boolean hasObject() {
return descriptor().getHandle() == Wrapper.DESCRIPTOR.getHandle();
}
public static final class Descriptor extends Struct {
@StructMember(0)
public native @MachineSizedUInt long reserved();
@StructMember(0)
public native Descriptor reserved(@MachineSizedUInt long reserved);
@StructMember(1)
public native @MachineSizedUInt long literal_size();
@StructMember(1)
public native Descriptor literal_size(@MachineSizedUInt long literal_size);
@StructMember(2)
public native @Pointer long copy_helper();
@StructMember(2)
public native Descriptor copy_helper(@Pointer long copy_helper);
@StructMember(3)
public native @Pointer long dispose_helper();
@StructMember(3)
public native Descriptor dispose_helper(@Pointer long dispose_helper);
@StructMember(4)
public native BytePtr signature();
@StructMember(4)
public native Descriptor signature(BytePtr value);
}
public static final class Wrapper {
private static final Descriptor DESCRIPTOR;
private static final long NSStackBlock;
private static final int BLOCK_HAS_COPY_DISPOSE = (1 << 25);
private static final int BLOCK_HAS_STRET = (1 << 29);
private static final int BLOCK_HAS_SIGNATURE = (1 << 30);
static {
try {
long copyImpl = VM.getCallbackMethodImpl(
Wrapper.class.getDeclaredMethod("copy", ObjCBlock.class, ObjCBlock.class));
long disposeImpl = VM.getCallbackMethodImpl(
Wrapper.class.getDeclaredMethod("dispose", ObjCBlock.class));
DESCRIPTOR = new Descriptor()
.literal_size(ObjCBlock.sizeOf())
.copy_helper(copyImpl)
.dispose_helper(disposeImpl)
.signature(null);
} catch (Exception e) {
throw new Error(e);
}
NSStackBlock =
ObjCRuntime.objc_getClass(VM.getStringUTFChars("__NSStackBlock__"));
if (NSStackBlock == 0L) {
throw new Error("Objective-C class __NSStackBlock__ not found");
}
}
private final long callbackImpl;
private final int flags;
private final IdentityHashMap