Commit 11504037 authored by Lubomir Bulej's avatar Lubomir Bulej
Browse files

ExtendThread: take the output directory as an argument.

parent 6081a78c
...@@ -26,9 +26,10 @@ ...@@ -26,9 +26,10 @@
</target> </target>
<target name="prepare-extendedthread" depends="compile-tlvinserter"> <target name="prepare-extendedthread" depends="compile-tlvinserter">
<mkdir dir="bin-thread/java/lang" /> <mkdir dir="bin-thread" />
<java fork="true" classname="ch.usi.dag.disl.utilinstr.tlvinserter.ExtendThread"> <java fork="true" classname="ch.usi.dag.disl.utilinstr.tlvinserter.ExtendThread">
<classpath refid="buildpath" /> <classpath refid="buildpath" />
<arg value="${basedir}/bin-thread" />
</java> </java>
<mkdir dir="${build}" /> <mkdir dir="${build}" />
<jar basedir="bin-thread" destfile="${extendedthread.path}" /> <jar basedir="bin-thread" destfile="${extendedthread.path}" />
......
package ch.usi.dag.disl.utilinstr.tlvinserter; package ch.usi.dag.disl.utilinstr.tlvinserter;
import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
...@@ -11,52 +13,76 @@ import org.objectweb.asm.ClassWriter; ...@@ -11,52 +13,76 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import ch.usi.dag.disl.localvar.ThreadLocalVar; import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.Constants;
/** /**
* This is just a utility class for disl compilation * Extends {@link Thread} with a "bypass" variable and writes its new bytecode
* to a class file in a given directory. This is required to compile DiSL bypass
* code, which checks the state of the "bypass" variable.
*/ */
public final class ExtendThread { public final class ExtendThread {
private static final String THREAD_BIN_DIR = "./bin-thread/"; public static void main (final String ... args) throws Exception {
public static void main(String[] args) throws Exception { if (args.length < 1) {
System.err.println ("usage: ExtendThread <output-directory>");
Class<?> tc = Thread.class; System.exit (1);
}
// get thread class as resource
InputStream tis = tc.getResourceAsStream("Thread.class"); final File outputDir = new File (args [0]);
if (!outputDir.isDirectory ()) {
// prepare dynamic bypass variable System.err.printf ("error: %s does not exist or is not a directory!\n", outputDir);
ThreadLocalVar tlv = new ThreadLocalVar(null, "bypass", System.exit (1);
Type.getType(boolean.class), false); }
tlv.setDefaultValue(0);
//
// Define a thread-local non-inheritable boolean variable named
// "bypass", with a default value of false,
//
final ThreadLocalVar tlBypass = new ThreadLocalVar (
null, "bypass", Type.getType (boolean.class), false
);
tlBypass.setDefaultValue (0);
//
// Extend Thread with a "bypass" variable and dump the new Thread
// bytecode into given directory.
//
__writeThread (outputDir, __extendThread (tlBypass));
}
// prepare Set with dynamic bypass
Set<ThreadLocalVar> tlvs = new HashSet<ThreadLocalVar>();
tlvs.add(tlv);
// parse Thread in ASM private static byte [] __extendThread (
ClassReader cr = new ClassReader(tis); final ThreadLocalVar ... tlvs
ClassWriter cw = new ClassWriter(cr, 0); ) throws IOException {
final InputStream is = Thread.class.getResourceAsStream ("Thread.class");
final ClassReader cr = new ClassReader (is);
final ClassWriter cw = new ClassWriter (cr, 0);
final Set <ThreadLocalVar> vars = new HashSet <ThreadLocalVar> (Arrays.asList (tlvs));
cr.accept (new TLVInserter (cw, vars), 0);
return cw.toByteArray ();
}
// put dynamic bypass into Thread using TLVInserter
cr.accept(new TLVInserter(cw, tlvs), 0);
// prepare Thread file name private static void __writeThread (
String threadFileName = tc.getName(); final File baseDir, final byte [] bytes
threadFileName = threadFileName.replace( ) throws IOException {
Constants.PACKAGE_STD_DELIM, Constants.PACKAGE_INTERN_DELIM); final Class <Thread> tc = Thread.class;
threadFileName += Constants.CLASS_EXT; final String pkgName = tc.getPackage ().getName ();
final String dirName = pkgName.replace ('.', File.separatorChar);
// output Thread code into special thread bin directory final File outputDir = new File (baseDir, dirName);
write(THREAD_BIN_DIR + threadFileName, cw.toByteArray()); outputDir.mkdirs ();
}
final String fileName = String.format ("%s.class", tc.getSimpleName ());
final File outputFile = new File (outputDir, fileName);
private static void write(String outputFile, byte[] data) throws IOException { final FileOutputStream fos = new FileOutputStream (outputFile);
FileOutputStream fos = new FileOutputStream(outputFile); try {
fos.write(data); fos.write (bytes);
fos.close(); } finally {
fos.close ();
}
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment