diff options
Diffstat (limited to 'src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java')
-rw-r--r-- | src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java | 125 |
1 files changed, 122 insertions, 3 deletions
diff --git a/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java b/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java index 1e7d34b..448c945 100644 --- a/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java +++ b/src/java/com/jogamp/gluegen/runtime/ProcAddressTable.java @@ -33,9 +33,128 @@ * in the design, construction, operation or maintenance of any nuclear * facility. */ - package com.jogamp.gluegen.runtime; -public interface ProcAddressTable { - public long getAddressFor(String functionName); +import com.jogamp.common.os.DynamicLookupHelper; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.lang.reflect.Field; +import java.security.AccessController; +import java.security.PrivilegedAction; + +/** + * Superclass for all generated ProcAddressTables. + * @author Kenneth Russel + * @author Michael Bien + * @author Sven Gothel + */ +public abstract class ProcAddressTable { + + public static final String PROCADDRESS_VAR_PREFIX = "_addressof_"; + + protected static boolean DEBUG; + protected static String DEBUG_PREFIX; + protected static int debugNum; + + private final FunctionAddressResolver resolver; + + static { + AccessController.doPrivileged(new PrivilegedAction() { + + public Object run() { + DEBUG = (System.getProperty("gluegen.debug.ProcAddressHelper") != null); + if (DEBUG) { + DEBUG_PREFIX = System.getProperty("gluegen.debug.ProcAddressHelper.prefix"); + } + return null; + } + }); + } + + public ProcAddressTable() { + this(new One2OneResolver()); + } + + public ProcAddressTable(FunctionAddressResolver resolver) { + this.resolver = resolver; + } + + /** + * Returns the address for the given function name. + * @throws RuntimeException if the Table has not been initialized yet. + */ + public abstract long getAddressFor(String functionName); + + + public void resetProcAddressTable(DynamicLookupHelper lookup) throws RuntimeException { + + Class tableClass = getClass(); + Field[] fields = tableClass.getFields(); + PrintStream dout = getDebugOutStream(); + + if (DEBUG) { + dout.println("ProcAddressHelper.resetProcAddressTable(" + getClass().getName() + ")"); + } + for (int i = 0; i < fields.length; ++i) { + String addressFieldName = fields[i].getName(); + if (!addressFieldName.startsWith(PROCADDRESS_VAR_PREFIX)) { + // not a proc address variable + continue; + } + int startOfMethodName = PROCADDRESS_VAR_PREFIX.length(); + String funcName = addressFieldName.substring(startOfMethodName); + try { + Field addressField = fields[i]; + assert (addressField.getType() == Long.TYPE); + + long newProcAddress = resolver.resolve(funcName, lookup); + + // set the current value of the proc address variable in the table object + addressField.setLong(this, newProcAddress); + if (DEBUG) { + dout.println(" " + addressField.getName() + " -> 0x" + Long.toHexString(newProcAddress)); + } + } catch (Exception e) { + throw new RuntimeException("Can not get proc address for method \"" + + funcName + "\": Couldn't set value of field \"" + addressFieldName + + "\" in class " + tableClass.getName(), e); + } + } + if (DEBUG) { + dout.flush(); + if (DEBUG_PREFIX != null) { + dout.close(); + } + } + } + + protected static PrintStream getDebugOutStream() { + PrintStream out = null; + if (DEBUG) { + if (DEBUG_PREFIX != null) { + try { + out = new PrintStream(new BufferedOutputStream(new FileOutputStream(DEBUG_PREFIX + File.separatorChar + + "procaddresshelper-" + (++debugNum) + ".txt"))); + } catch (IOException e) { + e.printStackTrace(); + out = System.err; + } + } else { + out = System.err; + } + } + return out; + } + + + private static class One2OneResolver implements FunctionAddressResolver { + public long resolve(String name, DynamicLookupHelper lookup) { + return lookup.dynamicLookupFunction(name); + } + } + + } |