From: <wme...@us...> - 2009-08-31 14:38:33
|
Revision: 6733 http://jython.svn.sourceforge.net/jython/?rev=6733&view=rev Author: wmeissner Date: 2009-08-31 14:38:24 +0000 (Mon, 31 Aug 2009) Log Message: ----------- Rework Pointer and CData a lot to make PointerCData (and hopefully ArrayCData and StructCData) easier to implement Modified Paths: -------------- branches/ctypes-jffi/CoreExposed.includes branches/ctypes-jffi/Lib/ctypes/__init__.py branches/ctypes-jffi/src/org/python/modules/jffi/CData.java branches/ctypes-jffi/src/org/python/modules/jffi/CType.java branches/ctypes-jffi/src/org/python/modules/jffi/DefaultInvokerFactory.java branches/ctypes-jffi/src/org/python/modules/jffi/DynamicLibrary.java branches/ctypes-jffi/src/org/python/modules/jffi/Function.java branches/ctypes-jffi/src/org/python/modules/jffi/MemoryOp.java branches/ctypes-jffi/src/org/python/modules/jffi/Pointer.java branches/ctypes-jffi/src/org/python/modules/jffi/ScalarCData.java branches/ctypes-jffi/src/org/python/modules/jffi/jffi.java Added Paths: ----------- branches/ctypes-jffi/src/org/python/modules/jffi/PointerCData.java Modified: branches/ctypes-jffi/CoreExposed.includes =================================================================== --- branches/ctypes-jffi/CoreExposed.includes 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/CoreExposed.includes 2009-08-31 14:38:24 UTC (rev 6733) @@ -59,7 +59,7 @@ org/python/modules/jffi/DynamicLibrary.class org/python/modules/jffi/DynamicLibrary$Symbol.class org/python/modules/jffi/Function.class -org/python/modules/jffi/Pointer.class +org/python/modules/jffi/PointerCData.class org/python/modules/jffi/ScalarCData.class org/python/modules/_threading/Condition.class org/python/modules/_threading/Lock.class Modified: branches/ctypes-jffi/Lib/ctypes/__init__.py =================================================================== --- branches/ctypes-jffi/Lib/ctypes/__init__.py 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/Lib/ctypes/__init__.py 2009-08-31 14:38:24 UTC (rev 6733) @@ -53,7 +53,7 @@ name = mod.__name__ dict["__module__"] = name - ptype = type("LP_%s" % (ctype.__name__,), (jffi.Pointer,), dict) + ptype = type("LP_%s" % (ctype.__name__,), (jffi.PointerCData,), dict) _pointer_type_cache[ctype] = ptype return ptype Modified: branches/ctypes-jffi/src/org/python/modules/jffi/CData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/CData.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/CData.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -4,9 +4,7 @@ import org.python.core.Py; import org.python.core.PyObject; import org.python.core.PyType; -import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; -import org.python.expose.ExposedSet; import org.python.expose.ExposedType; @ExposedType(name = "jffi.CData", base = PyObject.class) @@ -16,65 +14,55 @@ final MemoryOp memoryOp; final CType type; - private Memory contentMemory; - private PyObject value; + private DirectMemory referenceMemory; CData(PyType subtype, CType type, MemoryOp memoryOp) { super(subtype); this.type = type; this.memoryOp = memoryOp; - this.value = Py.None; - this.contentMemory = null; + this.referenceMemory = null; } - - @ExposedGet(name = "value") - public PyObject getValue() { - // If native memory has been allocated, read the value from there - if (contentMemory != null) { - return memoryOp.get(contentMemory, 0); - } - - return value; - } - - - @ExposedSet(name = "value") - public void setValue(PyObject value) { - this.value = value; - // If native memory has been allocated, sync the value to memory - if (contentMemory != null) { - memoryOp.put(contentMemory, 0, value); - } - } - + @ExposedMethod(names= { "byref", "pointer" }) public PyObject byref() { - return new Pointer((DirectMemory) getContentMemory(), memoryOp); + return new PointerCData(type, getReferenceMemory(), memoryOp); } - boolean hasValueMemory() { - return contentMemory != null; + final boolean hasReferenceMemory() { + return referenceMemory != null; } - void setContentMemory(Memory memory) { + final void setReferenceMemory(Memory memory) { if (!(memory instanceof DirectMemory)) { throw Py.TypeError("invalid memory"); } - this.contentMemory = memory; + this.referenceMemory = (DirectMemory) memory; } - Memory getContentMemory() { - if (contentMemory != null) { - return contentMemory; + /** + * Returns the memory used when creating a reference to this instance. + * e.g. via byref(obj) + * + * @return The reference memory for this object + */ + public final DirectMemory getReferenceMemory() { + if (referenceMemory != null) { + return referenceMemory; } - return allocateDirect(); + return allocateReferenceMemory(); } - private DirectMemory allocateDirect() { + protected DirectMemory allocateReferenceMemory() { DirectMemory m = AllocatedNativeMemory.allocate(type.size(), false); - memoryOp.put(m, 0, value); - contentMemory = m; + initReferenceMemory(m); + this.referenceMemory = m; return m; } + + public Memory getContentMemory() { + return getReferenceMemory(); + } + + protected abstract void initReferenceMemory(Memory m); } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/CType.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/CType.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/CType.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -91,7 +91,7 @@ } } - private static CType typeOf(PyObject obj) { + static CType typeOf(PyObject obj) { if (obj instanceof CType) { return (CType) obj; } @@ -192,21 +192,6 @@ return String.format("<jffi.Type.Pointer component_type=%s>", componentType.toString()); } - @Override - public PyObject __call__(PyObject value) { - if (value == Py.None) { - - return new org.python.modules.jffi.Pointer(new NullMemory(), componentMemoryOp); - - } else if (value.getType().isSubType(pyComponentType) && value instanceof CData) { - - return new org.python.modules.jffi.Pointer((DirectMemory) ((CData) value).getContentMemory(), componentMemoryOp); - - } else { - throw Py.TypeError("expected " + pyComponentType.getName() + " instead of " + value.getType().getName()); - } - } - private static final class ScalarOp extends MemoryOp { private final MemoryOp op; private final PyType type; @@ -226,8 +211,8 @@ // Point the CData to the backing memory so all value gets/sets // update the same memory this pointer points to // - if (result instanceof CData) { - ((CData) result).setContentMemory(mem); + if (result instanceof ScalarCData) { + ((ScalarCData) result).setReferenceMemory(mem); } return result; } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/DefaultInvokerFactory.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/DefaultInvokerFactory.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/DefaultInvokerFactory.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -131,6 +131,8 @@ private static final ParameterMarshaller getMarshaller(CType type) { if (type instanceof CType.Builtin) { return getMarshaller(type.getNativeType()); + } else if (type instanceof CType.Pointer) { + return PointerMarshaller.INSTANCE; } else { throw Py.RuntimeError("Unsupported parameter type: " + type); } @@ -427,7 +429,7 @@ public void marshal(HeapInvocationBuffer buffer, PyObject parameter) { if (parameter instanceof Pointer) { - buffer.putAddress(((Pointer) parameter).address); + buffer.putAddress(((Pointer) parameter).getAddress()); } else { throw Py.TypeError("expected pointer argument"); } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/DynamicLibrary.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/DynamicLibrary.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/DynamicLibrary.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -2,7 +2,6 @@ package org.python.modules.jffi; import com.kenai.jffi.Library; -import org.python.core.ClassDictInit; import org.python.core.Py; import org.python.core.PyObject; import org.python.core.PyType; @@ -43,7 +42,7 @@ @ExposedMethod public final PyObject find_symbol(PyObject name) { long address = findSymbol(name); - return new Symbol(this, name.asString(), address, new NativeMemory(address)); + return new Symbol(this, name.asString(), new NativeMemory(address)); } @ExposedMethod @@ -56,31 +55,49 @@ return new DataSymbol(this, name.asString(), findSymbol(name)); } - @ExposedType(name = "jffi.DynamicLibrary.Symbol", base = Pointer.class) - public static class Symbol extends Pointer { + @ExposedType(name = "jffi.DynamicLibrary.Symbol", base = PyObject.class) + public static class Symbol extends PyObject implements Pointer { public static final PyType TYPE = PyType.fromClass(Symbol.class); final DynamicLibrary library; + final DirectMemory memory; @ExposedGet + public final long address; + + @ExposedGet public final String name; - public Symbol(DynamicLibrary library, String name, long address, DirectMemory memory) { - super(address, memory); + public Symbol(DynamicLibrary library, String name, DirectMemory memory) { this.library = library; this.name = name; + this.memory = memory; + this.address = memory.getAddress(); } + + public final long getAddress() { + return address; + } + + public final DirectMemory getMemory() { + return memory; + } + + @Override + public boolean __nonzero__() { + return !getMemory().isNull(); + } } - public static class TextSymbol extends Symbol implements ExposeAsSuperclass { + public static final class TextSymbol extends Symbol implements ExposeAsSuperclass { public TextSymbol(DynamicLibrary lib, String name, long address) { - super(lib, name, address, new NativeMemory(address)); + super(lib, name, new NativeMemory(address)); } } - public static class DataSymbol extends Symbol implements ExposeAsSuperclass { + public static final class DataSymbol extends Symbol implements ExposeAsSuperclass { public DataSymbol(DynamicLibrary lib, String name, long address) { - super(lib, name, address, new NativeMemory(address)); + super(lib, name, new NativeMemory(address)); } } } Modified: branches/ctypes-jffi/src/org/python/modules/jffi/Function.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/Function.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/Function.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -12,8 +12,8 @@ import org.python.expose.ExposedSet; import org.python.expose.ExposedType; -@ExposedType(name = "jffi.Function", base = Pointer.class) -public class Function extends Pointer { +@ExposedType(name = "jffi.Function", base = PyObject.class) +public class Function extends PyObject implements Pointer { public static final PyType TYPE = PyType.fromClass(Function.class); private final Pointer pointer; @@ -27,37 +27,37 @@ @ExposedGet public final String name; - + @ExposedGet + public final long address; + + @ExposedGet @ExposedSet public PyObject restype; - Function(PyType type, Pointer address, DirectMemory memory) { - super(type, address.address, memory); + Function(PyType type, Pointer address) { + super(type); + this.address = address.getAddress(); this.library = null; this.name = "<anonymous>"; this.pointer = address; } - Function(PyType type, Pointer address) { - this(type, address, new NativeMemory(address.address)); + Function(PyType type, DynamicLibrary.Symbol sym) { + super(type); + this.library = sym.library; + this.name = sym.name; + this.pointer = sym; + this.address = sym.getAddress(); } - Function(PyType type, DynamicLibrary library, String name, long address) { - super(type, address, new NativeMemory(address)); - this.library = library; - this.name = name; - this.pointer = null; - } - @ExposedNew public static PyObject Function_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { if (args[0] instanceof Pointer) { if (args[0] instanceof DynamicLibrary.Symbol) { - DynamicLibrary.Symbol sym = (DynamicLibrary.Symbol) args[0]; - return new Function(subtype, sym.library, sym.name, sym.address); + return new Function(subtype, (DynamicLibrary.Symbol) args[0]); } else { return new Function(subtype, (Pointer) args[0]); } @@ -66,6 +66,14 @@ } } + public long getAddress() { + return address; + } + + public DirectMemory getMemory() { + return pointer.getMemory(); + } + @Override public PyObject fastGetDict() { return dict; @@ -125,6 +133,8 @@ @ExposedSet(name = "_jffi_argtypes") public void setParameterTypes(PyObject parameterTypes) { + this.invoker = null; // invalidate old invoker + // Removing the parameter types defaults back to varargs if (parameterTypes == Py.None) { this.parameterTypes = null; @@ -144,10 +154,13 @@ paramTypes[i] = (CType) t; } - this.invoker = null; // invalidate old invoker this.parameterTypes = paramTypes; } + @Override + public boolean __nonzero__() { + return !getMemory().isNull(); + } private final Invoker getInvoker() { if (invoker != null) { Modified: branches/ctypes-jffi/src/org/python/modules/jffi/MemoryOp.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/MemoryOp.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/MemoryOp.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -178,7 +178,7 @@ private static final class PointerOp extends MemoryOp { public final void put(Memory mem, long offset, PyObject value) { if (value instanceof Pointer) { - mem.putAddress(offset, ((Pointer) value).address); + mem.putAddress(offset, ((Pointer) value).getAddress()); } else { mem.putAddress(offset, Util.int64Value(value)); } @@ -186,7 +186,7 @@ public final PyObject get(Memory mem, long offset) { DirectMemory dm = new NativeMemory(mem.getAddress(offset)); - return new Pointer(dm.getAddress(), dm); + return new PointerCData(CType.POINTER, dm, INVALID); } } private static final class StringOp extends MemoryOp { Modified: branches/ctypes-jffi/src/org/python/modules/jffi/Pointer.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/Pointer.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/Pointer.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -1,78 +1,7 @@ package org.python.modules.jffi; -import org.python.core.Py; -import org.python.core.PyNewWrapper; -import org.python.core.PyObject; -import org.python.core.PyType; -import org.python.expose.ExposedGet; -import org.python.expose.ExposedNew; -import org.python.expose.ExposedSet; -import org.python.expose.ExposedType; - -@ExposedType(name = "jffi.Pointer", base = PyObject.class) -public class Pointer extends PyObject { - public static final PyType TYPE = PyType.fromClass(Pointer.class); - - @ExposedGet - public final long address; - - final Memory memory; - final MemoryOp componentMemoryOp; - - public Pointer(PyType type, long address, Memory memory) { - super(type); - this.address = address; - this.memory = memory; - this.componentMemoryOp = MemoryOp.INVALID; - } - - public Pointer(long address, Memory memory) { - this.address = address; - this.memory = memory; - this.componentMemoryOp = MemoryOp.INVALID; - } - - Pointer(DirectMemory memory, MemoryOp componentMemoryOp) { - this(TYPE, memory, componentMemoryOp); - } - - Pointer(PyType subtype, DirectMemory memory, MemoryOp componentMemoryOp) { - super(subtype); - this.address = memory.getAddress(); - this.memory = memory; - this.componentMemoryOp = componentMemoryOp; - } - - @ExposedNew - public static PyObject Pointer_new(PyNewWrapper new_, boolean init, PyType subtype, - PyObject[] args, String[] keywords) { - - PyObject jffi_type = subtype.__getattr__("_jffi_type"); - - if (!(jffi_type instanceof CType.Pointer)) { - throw Py.TypeError("invalid _jffi_type for " + subtype.getName()); - } - - CType.Pointer type = (CType.Pointer) jffi_type; - - if (args.length == 0) { - return new Pointer(subtype, NullMemory.INSTANCE, type.componentMemoryOp); - } - DirectMemory contents = AllocatedNativeMemory.allocate(type.componentType.size(), false); - type.componentMemoryOp.put(contents, 0, args[0]); - - return new Pointer(subtype, contents, type.componentMemoryOp); - } - - @ExposedGet(name="contents") - public PyObject contents() { - return componentMemoryOp.get(memory, 0); - } - - @ExposedSet(name="contents") - public void contents(PyObject value) { - componentMemoryOp.put(memory, 0, value); - } - +public interface Pointer { + long getAddress(); + DirectMemory getMemory(); } Added: branches/ctypes-jffi/src/org/python/modules/jffi/PointerCData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/PointerCData.java (rev 0) +++ branches/ctypes-jffi/src/org/python/modules/jffi/PointerCData.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -0,0 +1,84 @@ + +package org.python.modules.jffi; + +import org.python.core.Py; +import org.python.core.PyNewWrapper; +import org.python.core.PyObject; +import org.python.core.PyType; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedSet; +import org.python.expose.ExposedType; + +@ExposedType(name = "jffi.PointerCData", base = CData.class) +public class PointerCData extends CData implements Pointer { + public static final PyType TYPE = PyType.fromClass(PointerCData.class); + + private final DirectMemory memory; + final MemoryOp componentMemoryOp; + + PointerCData(PyType subtype, CType type, DirectMemory memory, MemoryOp componentMemoryOp) { + super(subtype, type, type.getMemoryOp()); + this.memory = memory; + this.componentMemoryOp = componentMemoryOp; + } + + PointerCData(CType type, DirectMemory memory, MemoryOp componentMemoryOp) { + this(TYPE, type, memory, componentMemoryOp); + } + + + @ExposedNew + public static PyObject PointerCData_new(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + + PyObject jffi_type = subtype.__getattr__("_jffi_type"); + + if (!(jffi_type instanceof CType.Pointer)) { + throw Py.TypeError("invalid _jffi_type for " + subtype.getName()); + } + + CType.Pointer type = (CType.Pointer) jffi_type; + + if (args.length == 0) { + return new PointerCData(subtype, type, NullMemory.INSTANCE, type.componentMemoryOp); + } + PyObject value = args[0]; + if (value instanceof CData && value.getType().isSubType(type.pyComponentType)) { + + return new PointerCData(subtype, type, ((CData) value).getReferenceMemory(), type.componentMemoryOp); + + } else { + throw Py.TypeError("expected " + type.pyComponentType.getName() + " instead of " + value.getType().getName()); + } + } + + @ExposedGet(name="contents") + public PyObject getContents() { + return componentMemoryOp.get(getMemory(), 0); + } + + @ExposedSet(name="contents") + public void setContents(PyObject value) { + componentMemoryOp.put(getMemory(), 0, value); + } + + @Override + public boolean __nonzero__() { + return !getMemory().isNull(); + } + + + protected void initReferenceMemory(Memory m) { + m.putAddress(0, memory); + } + + public final long getAddress() { + return getMemory().getAddress(); + } + + public final DirectMemory getMemory() { + return hasReferenceMemory() ? getReferenceMemory().getMemory(0) : memory; + } + +} Modified: branches/ctypes-jffi/src/org/python/modules/jffi/ScalarCData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/ScalarCData.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/ScalarCData.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -7,14 +7,18 @@ import org.python.core.PyObject; import org.python.core.PyObject.ConversionException; import org.python.core.PyType; +import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; +import org.python.expose.ExposedSet; import org.python.expose.ExposedType; @ExposedType(name = "jffi.ScalarCData", base = CData.class) public class ScalarCData extends CData { public static final PyType TYPE = PyType.fromClass(ScalarCData.class); + private PyObject value = Py.None; + @ExposedNew public static PyObject ScalarCData_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { @@ -35,8 +39,33 @@ ScalarCData(PyType pyType, CType.Builtin type) { super(pyType, type, type.getMemoryOp()); - } + } + protected final void initReferenceMemory(Memory m) { + memoryOp.put(m, 0, value); + } + + @ExposedGet(name = "value") + public PyObject getValue() { + // If native memory has been allocated, read the value from there + if (hasReferenceMemory()) { + return memoryOp.get(getReferenceMemory(), 0); + } + + return value; + } + + + @ExposedSet(name = "value") + public void setValue(PyObject value) { + this.value = value; + // If native memory has been allocated, sync the value to memory + if (hasReferenceMemory()) { + memoryOp.put(getReferenceMemory(), 0, value); + } + } + + @Override public int asInt() { return getValue().asInt(); Modified: branches/ctypes-jffi/src/org/python/modules/jffi/jffi.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/jffi.java 2009-08-31 07:40:56 UTC (rev 6732) +++ branches/ctypes-jffi/src/org/python/modules/jffi/jffi.java 2009-08-31 14:38:24 UTC (rev 6733) @@ -19,8 +19,8 @@ dict.__setitem__("__name__", Py.newString("jffi")); dict.__setitem__("DynamicLibrary", DynamicLibrary.TYPE); dict.__setitem__("Type", CType.TYPE); - dict.__setitem__("Pointer", Pointer.TYPE); dict.__setitem__("Function", Function.TYPE); + dict.__setitem__("PointerCData", PointerCData.TYPE); dict.__setitem__("ScalarCData", ScalarCData.TYPE); dict.__setitem__("FUNCFLAG_STDCALL", Py.newInteger(FUNCFLAG_STDCALL)); dict.__setitem__("FUNCFLAG_CDECL", Py.newInteger(FUNCFLAG_CDECL)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |