java-gobject-introspection r106 - trunk/src/org/gnome/gir/compiler
- From: walters svn gnome org
- To: svn-commits-list gnome org
- Subject: java-gobject-introspection r106 - trunk/src/org/gnome/gir/compiler
- Date: Thu, 23 Oct 2008 12:32:23 +0000 (UTC)
Author: walters
Date: Thu Oct 23 12:32:22 2008
New Revision: 106
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=106&view=rev
Log:
Split up compiler
Added:
trunk/src/org/gnome/gir/compiler/LocalVariable.java
trunk/src/org/gnome/gir/compiler/LocalVariableTable.java
trunk/src/org/gnome/gir/compiler/NameMap.java
trunk/src/org/gnome/gir/compiler/TypeMap.java
Modified:
trunk/src/org/gnome/gir/compiler/CodeFactory.java
Modified: trunk/src/org/gnome/gir/compiler/CodeFactory.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/CodeFactory.java (original)
+++ trunk/src/org/gnome/gir/compiler/CodeFactory.java Thu Oct 23 12:32:22 2008
@@ -52,13 +52,9 @@
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -66,21 +62,16 @@
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.gnome.gir.gobject.GErrorException;
import org.gnome.gir.gobject.GErrorStruct;
-import org.gnome.gir.gobject.GList;
import org.gnome.gir.gobject.GObjectAPI;
-import org.gnome.gir.gobject.GSList;
import org.gnome.gir.gobject.GType;
import org.gnome.gir.gobject.GlibAPI;
import org.gnome.gir.gobject.GlibRuntime;
-import org.gnome.gir.gobject.UnmappedPointer;
import org.gnome.gir.gobject.annotation.Return;
import org.gnome.gir.repository.ArgInfo;
import org.gnome.gir.repository.BaseInfo;
@@ -119,22 +110,15 @@
import com.sun.jna.Callback;
import com.sun.jna.Function;
-import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Pointer;
import com.sun.jna.TypeMapper;
-import com.sun.jna.ptr.ByteByReference;
-import com.sun.jna.ptr.DoubleByReference;
-import com.sun.jna.ptr.FloatByReference;
-import com.sun.jna.ptr.IntByReference;
-import com.sun.jna.ptr.LongByReference;
import com.sun.jna.ptr.PointerByReference;
-import com.sun.jna.ptr.ShortByReference;
@SuppressWarnings("serial")
public class CodeFactory {
- private static final Logger logger = Logger.getLogger("org.gnome.gir.Compiler");
+ static final Logger logger = Logger.getLogger("org.gnome.gir.Compiler");
private static final Set<String> GOBJECT_METHOD_BLACKLIST = new HashSet<String>() {
{
@@ -143,242 +127,6 @@
}
};
- public static Type toJava(TypeTag tag) {
- if (tag == TypeTag.LONG || tag == TypeTag.ULONG ||
- tag == TypeTag.SSIZE || tag == TypeTag.SIZE)
- return Type.getType(Long.class);
- if (tag == TypeTag.ARRAY)
- return Type.getType(List.class);
- if (tag == TypeTag.GLIST)
- return Type.getType(GList.class);
- if (tag == TypeTag.GSLIST)
- return Type.getType(GSList.class);
- if (tag == TypeTag.GHASH)
- return Type.getType(Map.class);
- return toTypeBase(tag);
- }
-
- private Type typeFromInfo(TypeInfo info) {
- BaseInfo base = info.getInterface();
- return typeFromInfo(base);
- }
-
- private Type typeFromInfo(BaseInfo info) {
- /* Unfortunately, flags are best mapped as plain Integer for now */
- if (info instanceof FlagsInfo)
- return Type.getObjectType("java/lang/Integer");
- String internalName = GType.getInternalNameMapped(info.getNamespace(), info.getName());
- if (internalName != null)
- return Type.getObjectType(internalName);
- return null;
- }
-
- public Type toJavaArray(TypeInfo containedType) {
- Type result = toJava(containedType);
- if (result == null)
- return null;
- String descriptor = result.getDescriptor();
- return Type.getType("[" + descriptor);
- }
-
- public Type toJava(TypeInfo type) {
- //Transfer transfer = arg.getOwnershipTransfer();
- TypeTag tag = type.getTag();
-
- if (tag.equals(TypeTag.VOID)) {
- // FIXME - for now we change random Voids into Pointer, but this seems to
- // be a G-I bug
- return Type.getType(Pointer.class);
- } else if (tag.equals(TypeTag.INTERFACE)) {
- return typeFromInfo(type.getInterface());
- } else if (tag.equals(TypeTag.ARRAY)) {
- return toJavaArray(type.getParamType(0));
- } else if (!type.isPointer() || (tag.equals(TypeTag.UTF8) || tag.equals(TypeTag.FILENAME))) {
- return toTypeBase(tag);
- } else if (type.isPointer()) {
- return toJavaRef(tag);
- } else {
- return toTypeBase(tag);
- }
- }
-
- public Type toJava(FieldInfo arg) {
- TypeInfo type = arg.getType();
- if (type.getTag().equals(TypeTag.INTERFACE)) {
- BaseInfo iface = arg.getType().getInterface();
- /* Special case structure/union members; we need to use the
- * $ByReference tag if the member is actually a pointer.
- */
- if (iface instanceof StructInfo || iface instanceof UnionInfo) {
- boolean hasFields;
- if (iface instanceof StructInfo)
- hasFields = ((StructInfo) iface).getFields().length > 0;
- else
- hasFields = ((UnionInfo) iface).getFields().length > 0;
- if (!hasFields)
- return Type.getType(Pointer.class);
- String internalName = getInternalNameMapped(iface);
- if (type.isPointer() && internalName.startsWith(GType.dynamicNamespace))
- internalName += "$ByReference";
- return Type.getObjectType(internalName);
- } else if (iface instanceof InterfaceInfo || iface instanceof ObjectInfo ||
- iface instanceof BoxedInfo) {
- /* Interfaces/Objects/Boxed are always Pointer for now
- */
- return Type.getType(Pointer.class);
- }
- }
- Type result = toJava(type);
- if (result == null) {
- logger.warning(String.format("Unhandled field type %s (type %s)", result, type));
- }
- return result;
- }
-
- public Type toJava(ArgInfo arg) {
- if (arg.getDirection() == Direction.IN) {
- return toJava(arg.getType());
- } else {
- return toJavaRef(arg.getType().getTag());
- }
- }
-
- public static Type toJavaRef(TypeTag tag) {
- Type t = toJava(tag);
- if (t == null)
- return null;
- if (t.equals(Type.INT_TYPE))
- return Type.getType(IntByReference.class);
- if (t.equals(Type.LONG_TYPE))
- return Type.getType(LongByReference.class);
- if (t.equals(Type.BOOLEAN_TYPE))
- return Type.getType(IntByReference.class);
- if (t.equals(Type.BYTE_TYPE))
- return Type.getType(ByteByReference.class);
- if (t.equals(Type.SHORT_TYPE))
- return Type.getType(ShortByReference.class);
- if (t.equals(Type.FLOAT_TYPE))
- return Type.getType(FloatByReference.class);
- if (t.equals(Type.DOUBLE_TYPE))
- return Type.getType(DoubleByReference.class);
- if (t.equals(Type.getType(String.class)) || t.equals(Type.getType(File.class)))
- return Type.getType(PointerByReference.class);
- return Type.getType(UnmappedPointer.class);
- }
-
- private static Type toTypeBase(TypeTag tag) {
- if (tag == TypeTag.VOID)
- return Type.VOID_TYPE;
- if (tag == TypeTag.BOOLEAN)
- return Type.BOOLEAN_TYPE;
- if (tag == TypeTag.INT8 || tag == TypeTag.UINT8)
- return Type.BYTE_TYPE;
- if (tag == TypeTag.INT16 || tag == TypeTag.UINT16)
- return Type.SHORT_TYPE;
- if (tag == TypeTag.INT32 || tag == TypeTag.UINT32 ||
- tag == TypeTag.INT || tag == TypeTag.UINT)
- return Type.INT_TYPE;
- if (tag == TypeTag.INT64 || tag == TypeTag.UINT64
- || tag == TypeTag.SIZE || tag == TypeTag.SSIZE)
- return Type.LONG_TYPE;
- if (tag == TypeTag.LONG) {
- if (Native.LONG_SIZE == 8)
- return Type.LONG_TYPE;
- else
- return Type.INT_TYPE;
- }
- if (tag == TypeTag.FLOAT)
- return Type.FLOAT_TYPE;
- if (tag == TypeTag.DOUBLE)
- return Type.DOUBLE_TYPE;
- if (tag == TypeTag.TIMET)
- return Type.getType(Date.class);
- if (tag == TypeTag.GTYPE)
- return Type.getType(GType.class);
- if (tag == TypeTag.UTF8)
- return Type.getType(String.class);
- if (tag == TypeTag.FILENAME)
- return Type.getType(File.class);
- return null;
- }
-
- private Type getCallableReturn(CallableInfo callable) {
- TypeInfo info = callable.getReturnType();
- if (info.getTag().equals(TypeTag.INTERFACE)) {
- return typeFromInfo(info);
- }
- return toJava(info.getTag());
- }
-
- private Class<?> getPrimitiveBox(Type type) {
- if (type.equals(Type.BOOLEAN_TYPE))
- return Boolean.class;
- if (type.equals(Type.BYTE_TYPE))
- return Byte.class;
- if (type.equals(Type.CHAR_TYPE))
- return Character.class;
- if (type.equals(Type.SHORT_TYPE))
- return Short.class;
- if (type.equals(Type.INT_TYPE))
- return Integer.class;
- if (type.equals(Type.LONG_TYPE))
- return Long.class;
- if (type.equals(Type.FLOAT_TYPE))
- return Float.class;
- if (type.equals(Type.DOUBLE_TYPE))
- return Double.class;
- return null;
- }
-
- public boolean introspectionImplements(ObjectInfo obj, InterfaceInfo iface) {
- while (!(obj.getNamespace().equals("GObject") && obj.getName().equals("Object"))) {
- List<InterfaceInfo> ifaces = Arrays.asList(obj.getInterfaces());
- for (InterfaceInfo possible : ifaces) {
- if (isAssignableFrom(iface, possible))
- return true;
- }
- obj = obj.getParent();
- }
- return false;
- }
-
- public List<InterfaceInfo> getUniqueInterfaces(ObjectInfo obj) {
- List<InterfaceInfo> ifaces = Arrays.asList(obj.getInterfaces());
- return getUniqueInterfaces(ifaces);
- }
-
- private boolean isAssignableFrom(InterfaceInfo lhs, InterfaceInfo rhs) {
- if (lhs.equals(rhs))
- return true;
- List<InterfaceInfo> prereqs = Arrays.asList(lhs.getPrerequisites());
- for (InterfaceInfo iface : prereqs) {
- if (isAssignableFrom(iface, rhs))
- return true;
- }
- return false;
- }
-
- public List<InterfaceInfo> getUniqueInterfaces(List<InterfaceInfo> ifaces) {
- boolean hit = true;
- ifaces = new ArrayList<InterfaceInfo>(ifaces);
- while (hit) {
- hit = false;
- for (Iterator<InterfaceInfo> it = ifaces.iterator(); it.hasNext();) {
- InterfaceInfo possible = it.next();
- for (InterfaceInfo iface : ifaces) {
- if (iface == possible)
- continue;
- if (isAssignableFrom(possible, iface)) {
- it.remove();
- hit = true;
- break;
- }
- }
- }
- }
- return ifaces;
- }
-
private static abstract class ClassCompilation {
String namespace;
String nsversion;
@@ -545,32 +293,10 @@
return GType.getInternalName(info.getNamespace(), info.getName());
}
- private static String getInternalNameMapped(BaseInfo info) {
+ static String getInternalNameMapped(BaseInfo info) {
return GType.getInternalNameMapped(info.getNamespace(), info.getName());
}
- private static final Pattern allNumeric = Pattern.compile("[0-9]+");
- private static final Pattern firstNumericUscore = Pattern.compile("([0-9]+)_");
- private static final Pattern replaceFirstNumeric = Pattern.compile("([0-9]+)([A-Za-z]+)");
- private String fixIdentifier(String base, String ident) {
- Matcher match = firstNumericUscore.matcher(ident);
- if (match.lookingAt()) {
- return base + ident;
- }
- match = replaceFirstNumeric.matcher(ident);
- if (!match.lookingAt()) {
- if (allNumeric.matcher(ident).matches()) {
- return base + ident;
- }
- return ident;
- }
- return match.replaceFirst("$2$1");
- }
-
- private String enumNameToUpper(String base, String nick) {
- return fixIdentifier(base, nick.replace("-", "_")).toUpperCase();
- }
-
public boolean isDestroyNotify(ArgInfo arg) {
TypeInfo type = arg.getType();
if (!type.getTag().equals(TypeTag.INTERFACE))
@@ -591,7 +317,7 @@
null);
ValueInfo[] values = info.getValueInfo();
for (ValueInfo valueInfo : values) {
- String name = enumNameToUpper(info.getName(), valueInfo.getName());
+ String name = NameMap.enumNameToUpper(info.getName(), valueInfo.getName());
FieldVisitor fv = compilation.writer.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM,
name, "L" + compilation.internalName + ";", null, null);
fv.visitEnd();
@@ -626,7 +352,7 @@
mv.visitLabel(l0);
int i = 0;
for (ValueInfo valueInfo : values) {
- String name = enumNameToUpper(info.getName(), valueInfo.getName());
+ String name = NameMap.enumNameToUpper(info.getName(), valueInfo.getName());
mv.visitTypeInsn(NEW, compilation.internalName);
mv.visitInsn(DUP);
mv.visitLdcInsn(name);
@@ -640,7 +366,7 @@
mv.visitTypeInsn(ANEWARRAY, compilation.internalName);
i = 0;
for (ValueInfo valueInfo : values) {
- String name = enumNameToUpper(info.getName(), valueInfo.getName());
+ String name = NameMap.enumNameToUpper(info.getName(), valueInfo.getName());
mv.visitInsn(DUP);
mv.visitIntInsn(BIPUSH, i);
i++;
@@ -748,7 +474,7 @@
ValueInfo[] values = info.getValueInfo();
for (ValueInfo valueInfo : values) {
FieldVisitor fv = compilation.writer.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC,
- enumNameToUpper(info.getName(), valueInfo.getName()), "J", null, valueInfo.getValue());
+ NameMap.enumNameToUpper(info.getName(), valueInfo.getName()), "J", null, valueInfo.getValue());
fv.visitEnd();
}
compilation.close();
@@ -1048,13 +774,13 @@
PropertyInfo[] props, Set<String> sigs,
boolean isInterfaceSource, boolean isInterfaceTarget) {
for (PropertyInfo prop : props) {
- Type type = toJava(prop.getType());
+ Type type = TypeMap.toJava(prop.getType());
if (type == null) {
logger.warning(String.format("Skipping unhandled property type %s of %s", prop.getName(), compilation.internalName));
continue;
}
int propFlags = prop.getFlags();
- Class<?> propBox = getPrimitiveBox(type);
+ Class<?> propBox = TypeMap.getPrimitiveBox(type);
Type propTypeBox;
if (propBox != null)
propTypeBox = Type.getType(propBox);
@@ -1198,7 +924,7 @@
parentInternalName = getInternalNameMapped(parent);
String[] interfaces = null;
- List<InterfaceInfo> giInterfaces = getUniqueInterfaces(info);
+ List<InterfaceInfo> giInterfaces = TypeMap.getUniqueInterfaces(info);
if (giInterfaces.size() > 0) {
interfaces = new String[giInterfaces.size()];
}
@@ -1229,7 +955,7 @@
if (ctx == null)
continue;
// Insert the object as first parameter
- ctx.argTypes.add(0, typeFromInfo(info));
+ ctx.argTypes.add(0, TypeMap.typeFromInfo(info));
compileSignal(compilation, ctx, sig, false, false);
}
@@ -1299,7 +1025,7 @@
writeCallable(ACC_PUBLIC, compilation, fi, ctx);
}
for (InterfaceInfo iface : giInterfaces) {
- if (introspectionImplements(info.getParent(), iface))
+ if (TypeMap.introspectionImplements(info.getParent(), iface))
continue;
for (FunctionInfo fi: iface.getMethods()) {
CallableCompilationContext ctx = tryCompileCallable(fi, iface, true, false, sigs);
@@ -1309,7 +1035,7 @@
ctx.targetInterface = iface;
writeCallable(ACC_PUBLIC, compilation, fi, ctx);
}
- Type ifaceType = typeFromInfo(iface);
+ Type ifaceType = TypeMap.typeFromInfo(iface);
for (SignalInfo sig : iface.getSignals()) {
CallableCompilationContext ctx = tryCompileCallable(sig, null);
if (ctx == null)
@@ -1335,7 +1061,7 @@
new String[] { "org/gnome/gir/gobject/GObject$GObjectProxy" });
globals.interfaceTypes.put(internalName, info.getTypeInit());
- Type ifaceType = typeFromInfo(info);
+ Type ifaceType = TypeMap.typeFromInfo(info);
for (SignalInfo sig : info.getSignals()) {
CallableCompilationContext ctx = tryCompileCallable(sig, null);
if (ctx == null)
@@ -1379,7 +1105,7 @@
compilation.close();
}
- private static final class CallableCompilationContext {
+ static final class CallableCompilationContext {
CallableInfo info;
boolean isMethod;
boolean isConstructor;
@@ -1463,11 +1189,11 @@
ctx.args = si.getArgs();
if (ctx.isConstructor) {
ctx.returnType = Type.VOID_TYPE;
- ctx.thisType = getCallableReturn(si);
+ ctx.thisType = TypeMap.getCallableReturn(si);
} else {
if (ctx.isMethod && thisType != null)
ctx.thisType = Type.getObjectType(getInternalNameMapped(thisType));
- ctx.returnType = getCallableReturn(si);
+ ctx.returnType = TypeMap.getCallableReturn(si);
}
if (ctx.returnType == null) {
logger.warning("Skipping callable with unhandled return signature: "+ si.getIdentifier());
@@ -1515,7 +1241,7 @@
ctx.arrayToLengthIndices.put(argOffset, lenIdx);
}
}
- t = toJava(arg);
+ t = TypeMap.toJava(arg);
if (t == null) {
logger.warning(String.format("Unhandled argument %s in callable %s", arg, si.getIdentifier()));
return null;
@@ -1558,7 +1284,7 @@
}
private Type writeLoadArgument(MethodVisitor mv, int loadOffset, Type argType) {
- Class<?> box = getPrimitiveBox(argType);
+ Class<?> box = TypeMap.getPrimitiveBox(argType);
mv.visitVarInsn(argType.getOpcode(ILOAD), loadOffset);
if (box != null) {
Type boxedType = Type.getType(box);
@@ -1569,90 +1295,6 @@
return argType;
}
- private static final class LocalVariable {
- String name;
- int offset;
- Type type;
- public LocalVariable(String name, int offset, Type type) {
- super();
- this.name = name;
- this.offset = offset;
- this.type = type;
- }
- }
-
- private static final class LocalVariableTable {
- private Map<String,LocalVariable> locals;
- private int lastOffset;
-
- public LocalVariableTable(Type thisType, List<Type> args, List<String> argNames) {
- lastOffset = 0;
- locals = new LinkedHashMap<String,LocalVariable>();
- if (thisType != null) {
- locals.put("this", new LocalVariable("this", 0, thisType));
- lastOffset += thisType.getSize();
- }
- int i = 0;
- if (args == null)
- return;
- for (Type arg: args) {
- String name;
- if (argNames != null)
- name = argNames.get(i);
- else
- name = "arg" + i;
- locals.put(name, new LocalVariable(name, lastOffset, arg));
- lastOffset += arg.getSize();
- i++;
- }
- }
-
- public LocalVariableTable(CallableCompilationContext ctx) {
- this(ctx.thisType, ctx.argTypes, ctx.argNames);
- }
-
- public LocalVariable add(String name, Type type) {
- LocalVariable ret = new LocalVariable(name, lastOffset, type);
- lastOffset += type.getSize();
- locals.put(name, ret);
- return ret;
- }
-
- public int allocTmp(String name, Type type) {
- return add("tmp_" + name, type).offset;
- }
-
- public Collection<LocalVariable> getAll() {
- return locals.values();
- }
-
- public LocalVariable get(int index) {
- int i = 0;
- for (LocalVariable variable : locals.values()) {
- if (i == index)
- return variable;
- i++;
- }
- throw new IllegalArgumentException(String.format("Index %d is out of range (max %d)", index, locals.size()-1));
- }
-
- public int getOffset(String name) {
- LocalVariable var = locals.get(name);
- return var.offset;
- }
-
- private void writeLocals(MethodVisitor mv, Label start, Label end) {
- for (LocalVariable var : getAll()) {
- mv.visitLocalVariable(var.name, var.type.getDescriptor(), null, start, end, var.offset);
- }
- }
-
- @Override
- public String toString() {
- return String.format("<locals lastOffset=%s table=%s>", lastOffset, locals);
- }
- }
-
private void writeCallable(int accessFlags, ClassCompilation compilation, FunctionInfo fi,
CallableCompilationContext ctx) {
String descriptor = ctx.getDescriptor();
@@ -1676,7 +1318,7 @@
String globalInternalsName = getInternals(fi);
String symbol = fi.getSymbol();
- Class<?> returnBox = getPrimitiveBox(ctx.returnType);
+ Class<?> returnBox = TypeMap.getPrimitiveBox(ctx.returnType);
Type returnTypeBox;
if (returnBox != null)
returnTypeBox = Type.getType(returnBox);
@@ -2002,8 +1644,8 @@
args.add(Type.getObjectType(compilation.internalName));
boolean allArgsPrimitive = true;
for (FieldInfo field : fields) {
- Type argType = toJava(field);
- if (argType == null || getPrimitiveBox(argType) == null) {
+ Type argType = TypeMap.toJava(field);
+ if (argType == null || TypeMap.getPrimitiveBox(argType) == null) {
allArgsPrimitive = false;
break;
}
@@ -2051,7 +1693,7 @@
}
for (FieldInfo fi : fields) {
String name = ucaseToCamel(fi.getName());
- Type fieldType = toJava(fi);
+ Type fieldType = TypeMap.toJava(fi);
if (fieldType.equals(Type.VOID_TYPE)) // FIXME Temporary hack for GdkAtom
fieldType = Type.getType(Pointer.class);
FieldVisitor fv = compilation.writer.visitField(ACC_PUBLIC, name, fieldType.getDescriptor(), null, null);
@@ -2100,12 +1742,12 @@
private void compile(ConstantInfo info) {
GlobalsCompilation globals = getGlobals(info.getNamespace());
InnerClassCompilation compilation = globals.getConstants();
- Type type = toJava(info.getType());
+ Type type = TypeMap.toJava(info.getType());
if (type == null) {
logger.warning("Unhandled constant type " + type);
return;
}
- String fieldName = fixIdentifier("n", info.getName());
+ String fieldName = NameMap.fixIdentifier("n", info.getName());
FieldVisitor fv = compilation.writer.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,
fieldName, type.getDescriptor(), null, null);
fv.visitEnd();
Added: trunk/src/org/gnome/gir/compiler/LocalVariable.java
==============================================================================
--- (empty file)
+++ trunk/src/org/gnome/gir/compiler/LocalVariable.java Thu Oct 23 12:32:22 2008
@@ -0,0 +1,18 @@
+/**
+ *
+ */
+package org.gnome.gir.compiler;
+
+import org.objectweb.asm.Type;
+
+final class LocalVariable {
+ String name;
+ int offset;
+ Type type;
+ public LocalVariable(String name, int offset, Type type) {
+ super();
+ this.name = name;
+ this.offset = offset;
+ this.type = type;
+ }
+}
\ No newline at end of file
Added: trunk/src/org/gnome/gir/compiler/LocalVariableTable.java
==============================================================================
--- (empty file)
+++ trunk/src/org/gnome/gir/compiler/LocalVariableTable.java Thu Oct 23 12:32:22 2008
@@ -0,0 +1,86 @@
+/**
+ *
+ */
+package org.gnome.gir.compiler;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.gnome.gir.compiler.CodeFactory.CallableCompilationContext;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+
+final class LocalVariableTable {
+ private Map<String,LocalVariable> locals;
+ private int lastOffset;
+
+ public LocalVariableTable(Type thisType, List<Type> args, List<String> argNames) {
+ lastOffset = 0;
+ locals = new LinkedHashMap<String,LocalVariable>();
+ if (thisType != null) {
+ locals.put("this", new LocalVariable("this", 0, thisType));
+ lastOffset += thisType.getSize();
+ }
+ int i = 0;
+ if (args == null)
+ return;
+ for (Type arg: args) {
+ String name;
+ if (argNames != null)
+ name = argNames.get(i);
+ else
+ name = "arg" + i;
+ locals.put(name, new LocalVariable(name, lastOffset, arg));
+ lastOffset += arg.getSize();
+ i++;
+ }
+ }
+
+ public LocalVariableTable(CallableCompilationContext ctx) {
+ this(ctx.thisType, ctx.argTypes, ctx.argNames);
+ }
+
+ public LocalVariable add(String name, Type type) {
+ LocalVariable ret = new LocalVariable(name, lastOffset, type);
+ lastOffset += type.getSize();
+ locals.put(name, ret);
+ return ret;
+ }
+
+ public int allocTmp(String name, Type type) {
+ return add("tmp_" + name, type).offset;
+ }
+
+ public Collection<LocalVariable> getAll() {
+ return locals.values();
+ }
+
+ public LocalVariable get(int index) {
+ int i = 0;
+ for (LocalVariable variable : locals.values()) {
+ if (i == index)
+ return variable;
+ i++;
+ }
+ throw new IllegalArgumentException(String.format("Index %d is out of range (max %d)", index, locals.size()-1));
+ }
+
+ public int getOffset(String name) {
+ LocalVariable var = locals.get(name);
+ return var.offset;
+ }
+
+ void writeLocals(MethodVisitor mv, Label start, Label end) {
+ for (LocalVariable var : getAll()) {
+ mv.visitLocalVariable(var.name, var.type.getDescriptor(), null, start, end, var.offset);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("<locals lastOffset=%s table=%s>", lastOffset, locals);
+ }
+}
\ No newline at end of file
Added: trunk/src/org/gnome/gir/compiler/NameMap.java
==============================================================================
--- (empty file)
+++ trunk/src/org/gnome/gir/compiler/NameMap.java Thu Oct 23 12:32:22 2008
@@ -0,0 +1,29 @@
+package org.gnome.gir.compiler;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class NameMap {
+
+ private static final Pattern allNumeric = Pattern.compile("[0-9]+");
+ private static final Pattern firstNumericUscore = Pattern.compile("([0-9]+)_");
+ private static final Pattern replaceFirstNumeric = Pattern.compile("([0-9]+)([A-Za-z]+)");
+ public static String fixIdentifier(String base, String ident) {
+ Matcher match = firstNumericUscore.matcher(ident);
+ if (match.lookingAt()) {
+ return base + ident;
+ }
+ match = replaceFirstNumeric.matcher(ident);
+ if (!match.lookingAt()) {
+ if (allNumeric.matcher(ident).matches()) {
+ return base + ident;
+ }
+ return ident;
+ }
+ return match.replaceFirst("$2$1");
+ }
+
+ public static String enumNameToUpper(String base, String nick) {
+ return fixIdentifier(base, nick.replace("-", "_")).toUpperCase();
+ }
+}
Added: trunk/src/org/gnome/gir/compiler/TypeMap.java
==============================================================================
--- (empty file)
+++ trunk/src/org/gnome/gir/compiler/TypeMap.java Thu Oct 23 12:32:22 2008
@@ -0,0 +1,278 @@
+package org.gnome.gir.compiler;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.gnome.gir.gobject.GList;
+import org.gnome.gir.gobject.GSList;
+import org.gnome.gir.gobject.GType;
+import org.gnome.gir.gobject.UnmappedPointer;
+import org.gnome.gir.repository.ArgInfo;
+import org.gnome.gir.repository.BaseInfo;
+import org.gnome.gir.repository.BoxedInfo;
+import org.gnome.gir.repository.CallableInfo;
+import org.gnome.gir.repository.Direction;
+import org.gnome.gir.repository.FieldInfo;
+import org.gnome.gir.repository.FlagsInfo;
+import org.gnome.gir.repository.InterfaceInfo;
+import org.gnome.gir.repository.ObjectInfo;
+import org.gnome.gir.repository.StructInfo;
+import org.gnome.gir.repository.TypeInfo;
+import org.gnome.gir.repository.TypeTag;
+import org.gnome.gir.repository.UnionInfo;
+import org.objectweb.asm.Type;
+
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.ptr.ByteByReference;
+import com.sun.jna.ptr.DoubleByReference;
+import com.sun.jna.ptr.FloatByReference;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.LongByReference;
+import com.sun.jna.ptr.PointerByReference;
+import com.sun.jna.ptr.ShortByReference;
+
+public class TypeMap {
+
+ public static Type toJava(TypeTag tag) {
+ if (tag == TypeTag.LONG || tag == TypeTag.ULONG ||
+ tag == TypeTag.SSIZE || tag == TypeTag.SIZE)
+ return Type.getType(Long.class);
+ if (tag == TypeTag.ARRAY)
+ return Type.getType(List.class);
+ if (tag == TypeTag.GLIST)
+ return Type.getType(GList.class);
+ if (tag == TypeTag.GSLIST)
+ return Type.getType(GSList.class);
+ if (tag == TypeTag.GHASH)
+ return Type.getType(Map.class);
+ return toTypeBase(tag);
+ }
+
+ public static Type toJavaRef(TypeTag tag) {
+ Type t = toJava(tag);
+ if (t == null)
+ return null;
+ if (t.equals(Type.INT_TYPE))
+ return Type.getType(IntByReference.class);
+ if (t.equals(Type.LONG_TYPE))
+ return Type.getType(LongByReference.class);
+ if (t.equals(Type.BOOLEAN_TYPE))
+ return Type.getType(IntByReference.class);
+ if (t.equals(Type.BYTE_TYPE))
+ return Type.getType(ByteByReference.class);
+ if (t.equals(Type.SHORT_TYPE))
+ return Type.getType(ShortByReference.class);
+ if (t.equals(Type.FLOAT_TYPE))
+ return Type.getType(FloatByReference.class);
+ if (t.equals(Type.DOUBLE_TYPE))
+ return Type.getType(DoubleByReference.class);
+ if (t.equals(Type.getType(String.class)) || t.equals(Type.getType(File.class)))
+ return Type.getType(PointerByReference.class);
+ return Type.getType(UnmappedPointer.class);
+ }
+
+ static Type toTypeBase(TypeTag tag) {
+ if (tag == TypeTag.VOID)
+ return Type.VOID_TYPE;
+ if (tag == TypeTag.BOOLEAN)
+ return Type.BOOLEAN_TYPE;
+ if (tag == TypeTag.INT8 || tag == TypeTag.UINT8)
+ return Type.BYTE_TYPE;
+ if (tag == TypeTag.INT16 || tag == TypeTag.UINT16)
+ return Type.SHORT_TYPE;
+ if (tag == TypeTag.INT32 || tag == TypeTag.UINT32 ||
+ tag == TypeTag.INT || tag == TypeTag.UINT)
+ return Type.INT_TYPE;
+ if (tag == TypeTag.INT64 || tag == TypeTag.UINT64
+ || tag == TypeTag.SIZE || tag == TypeTag.SSIZE)
+ return Type.LONG_TYPE;
+ if (tag == TypeTag.LONG) {
+ if (Native.LONG_SIZE == 8)
+ return Type.LONG_TYPE;
+ else
+ return Type.INT_TYPE;
+ }
+ if (tag == TypeTag.FLOAT)
+ return Type.FLOAT_TYPE;
+ if (tag == TypeTag.DOUBLE)
+ return Type.DOUBLE_TYPE;
+ if (tag == TypeTag.TIMET)
+ return Type.getType(Date.class);
+ if (tag == TypeTag.GTYPE)
+ return Type.getType(GType.class);
+ if (tag == TypeTag.UTF8)
+ return Type.getType(String.class);
+ if (tag == TypeTag.FILENAME)
+ return Type.getType(File.class);
+ return null;
+ }
+
+ static Class<?> getPrimitiveBox(Type type) {
+ if (type.equals(Type.BOOLEAN_TYPE))
+ return Boolean.class;
+ if (type.equals(Type.BYTE_TYPE))
+ return Byte.class;
+ if (type.equals(Type.CHAR_TYPE))
+ return Character.class;
+ if (type.equals(Type.SHORT_TYPE))
+ return Short.class;
+ if (type.equals(Type.INT_TYPE))
+ return Integer.class;
+ if (type.equals(Type.LONG_TYPE))
+ return Long.class;
+ if (type.equals(Type.FLOAT_TYPE))
+ return Float.class;
+ if (type.equals(Type.DOUBLE_TYPE))
+ return Double.class;
+ return null;
+ }
+
+ static Type getCallableReturn(CallableInfo callable) {
+ TypeInfo info = callable.getReturnType();
+ if (info.getTag().equals(TypeTag.INTERFACE)) {
+ return TypeMap.typeFromInfo(info);
+ }
+ return toJava(info.getTag());
+ }
+
+ public static Type toJava(ArgInfo arg) {
+ if (arg.getDirection() == Direction.IN) {
+ return TypeMap.toJava(arg.getType());
+ } else {
+ return toJavaRef(arg.getType().getTag());
+ }
+ }
+
+ public static Type toJava(FieldInfo arg) {
+ TypeInfo type = arg.getType();
+ if (type.getTag().equals(TypeTag.INTERFACE)) {
+ BaseInfo iface = arg.getType().getInterface();
+ /* Special case structure/union members; we need to use the
+ * $ByReference tag if the member is actually a pointer.
+ */
+ if (iface instanceof StructInfo || iface instanceof UnionInfo) {
+ boolean hasFields;
+ if (iface instanceof StructInfo)
+ hasFields = ((StructInfo) iface).getFields().length > 0;
+ else
+ hasFields = ((UnionInfo) iface).getFields().length > 0;
+ if (!hasFields)
+ return Type.getType(Pointer.class);
+ String internalName = CodeFactory.getInternalNameMapped(iface);
+ if (type.isPointer() && internalName.startsWith(GType.dynamicNamespace))
+ internalName += "$ByReference";
+ return Type.getObjectType(internalName);
+ } else if (iface instanceof InterfaceInfo || iface instanceof ObjectInfo ||
+ iface instanceof BoxedInfo) {
+ /* Interfaces/Objects/Boxed are always Pointer for now
+ */
+ return Type.getType(Pointer.class);
+ }
+ }
+ Type result = TypeMap.toJava(type);
+ if (result == null) {
+ CodeFactory.logger.warning(String.format("Unhandled field type %s (type %s)", result, type));
+ }
+ return result;
+ }
+
+ public static Type toJava(TypeInfo type) {
+ //Transfer transfer = arg.getOwnershipTransfer();
+ TypeTag tag = type.getTag();
+
+ if (tag.equals(TypeTag.VOID)) {
+ // FIXME - for now we change random Voids into Pointer, but this seems to
+ // be a G-I bug
+ return Type.getType(Pointer.class);
+ } else if (tag.equals(TypeTag.INTERFACE)) {
+ return TypeMap.typeFromInfo(type.getInterface());
+ } else if (tag.equals(TypeTag.ARRAY)) {
+ return TypeMap.toJavaArray(type.getParamType(0));
+ } else if (!type.isPointer() || (tag.equals(TypeTag.UTF8) || tag.equals(TypeTag.FILENAME))) {
+ return toTypeBase(tag);
+ } else if (type.isPointer()) {
+ return toJavaRef(tag);
+ } else {
+ return toTypeBase(tag);
+ }
+ }
+
+ public static Type toJavaArray(TypeInfo containedType) {
+ Type result = toJava(containedType);
+ if (result == null)
+ return null;
+ String descriptor = result.getDescriptor();
+ return Type.getType("[" + descriptor);
+ }
+
+ static Type typeFromInfo(BaseInfo info) {
+ /* Unfortunately, flags are best mapped as plain Integer for now */
+ if (info instanceof FlagsInfo)
+ return Type.getObjectType("java/lang/Integer");
+ String internalName = GType.getInternalNameMapped(info.getNamespace(), info.getName());
+ if (internalName != null)
+ return Type.getObjectType(internalName);
+ return null;
+ }
+
+ static Type typeFromInfo(TypeInfo info) {
+ BaseInfo base = info.getInterface();
+ return typeFromInfo(base);
+ }
+
+ public static List<InterfaceInfo> getUniqueInterfaces(List<InterfaceInfo> ifaces) {
+ boolean hit = true;
+ ifaces = new ArrayList<InterfaceInfo>(ifaces);
+ while (hit) {
+ hit = false;
+ for (Iterator<InterfaceInfo> it = ifaces.iterator(); it.hasNext();) {
+ InterfaceInfo possible = it.next();
+ for (InterfaceInfo iface : ifaces) {
+ if (iface == possible)
+ continue;
+ if (TypeMap.isAssignableFrom(possible, iface)) {
+ it.remove();
+ hit = true;
+ break;
+ }
+ }
+ }
+ }
+ return ifaces;
+ }
+
+ public static List<InterfaceInfo> getUniqueInterfaces(ObjectInfo obj) {
+ List<InterfaceInfo> ifaces = Arrays.asList(obj.getInterfaces());
+ return getUniqueInterfaces(ifaces);
+ }
+
+ public static boolean introspectionImplements(ObjectInfo obj, InterfaceInfo iface) {
+ while (!(obj.getNamespace().equals("GObject") && obj.getName().equals("Object"))) {
+ List<InterfaceInfo> ifaces = Arrays.asList(obj.getInterfaces());
+ for (InterfaceInfo possible : ifaces) {
+ if (TypeMap.isAssignableFrom(iface, possible))
+ return true;
+ }
+ obj = obj.getParent();
+ }
+ return false;
+ }
+
+ static boolean isAssignableFrom(InterfaceInfo lhs, InterfaceInfo rhs) {
+ if (lhs.equals(rhs))
+ return true;
+ List<InterfaceInfo> prereqs = Arrays.asList(lhs.getPrerequisites());
+ for (InterfaceInfo iface : prereqs) {
+ if (isAssignableFrom(iface, rhs))
+ return true;
+ }
+ return false;
+ }
+
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]