Improve error reporting for JIT VerifyErrors.
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/CodeBlockImpl.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/CodeBlockImpl.java
index 0dc37e2..6c0e41d 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/CodeBlockImpl.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/impl/CodeBlockImpl.java
@@ -1000,6 +1000,9 @@
 					} catch (Exception e) {
 						frame.setPc(pc);
 						throw new VMException(frame, e);
+					} catch (VerifyError e) {
+						frame.setPc(pc);
+						throw new VMException(frame, e);
 					}
 				}
 			}
diff --git a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java
index ca90522..4b15335 100644
--- a/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java
+++ b/plugins/org.eclipse.m2m.atl.emftvm/src/org/eclipse/m2m/atl/emftvm/jit/CodeBlockJIT.java
@@ -63,25 +63,9 @@
 		protected Class<?> findClass(String name) throws ClassNotFoundException {
 			if (codeBlocks.containsKey(name)) {
 				final byte[] b = internalJit(codeBlocks.get(name), name);
+				byteCode.put(name, b);
 				if (isDumpBytecode()) {
-					try {
-						final String path = name.substring(0, name.lastIndexOf('.')).replace('.', File.separatorChar);
-						final File p = new File(System.getProperty("java.io.tmpdir") + File.separatorChar + path);
-						p.mkdirs();
-						final File f = new File(p, name.substring(name.lastIndexOf('.') + 1) + ".class");
-						f.createNewFile();
-						final FileOutputStream fos = new FileOutputStream(f);
-						try {
-							fos.write(b);
-						} finally {
-							fos.close();
-						}
-						ATLLogger.info(String.format("Wrote JIT-ed code block %s to %s", 
-								codeBlocks.get(name), f.getAbsolutePath()));
-					} catch (IOException e) {
-						e.printStackTrace();
-						throw new RuntimeException(e);
-					}
+					dumpByteCode(name, b);
 				}
 				return defineClass(name, b, 0, b.length);
 			}
@@ -101,6 +85,10 @@
 	 * The execution environment to JIT for.
 	 */
 	protected final ExecEnv env;
+	/**
+	 * {@link Map} of class names to generated bytecode.
+	 */
+	protected final Map<String, byte[]> byteCode = Collections.synchronizedMap(new HashMap<String, byte[]>());
 
 	/**
 	 * Creates a new {@link CodeBlockJIT}.
@@ -129,8 +117,16 @@
 			InvocationTargetException, NoSuchMethodException {
 		final String className = getNextClassName();
 		codeBlocks.put(className, cb);
-		return (JITCodeBlock)classLoader.findClass(className)
-				.getConstructor(CodeBlock.class).newInstance(cb);
+		try {
+			return (JITCodeBlock)classLoader.findClass(className)
+					.getConstructor(CodeBlock.class).newInstance(cb);
+		} catch (VerifyError e) {
+			final byte[] b = byteCode.get(className);
+			if (b != null) {
+				dumpByteCode(className, b);
+			}
+			throw e;
+		}
 	}
 	
 	/**
@@ -385,6 +381,32 @@
 			cb.setJITCodeBlock(null);
 		}
 		codeBlocks.clear();
+		byteCode.clear();
+	}
+	
+	/**
+	 * Dumps generated bytecode to the temp directory.
+	 * @param name the class name
+	 * @param b the bytecode to dump
+	 */
+	private void dumpByteCode(String name, byte[] b) {
+		try {
+			final String path = name.substring(0, name.lastIndexOf('.')).replace('.', File.separatorChar);
+			final File p = new File(System.getProperty("java.io.tmpdir") + File.separatorChar + path);
+			p.mkdirs();
+			final File f = new File(p, name.substring(name.lastIndexOf('.') + 1) + ".class");
+			f.createNewFile();
+			final FileOutputStream fos = new FileOutputStream(f);
+			try {
+				fos.write(b);
+			} finally {
+				fos.close();
+			}
+			ATLLogger.info(String.format("Wrote JIT-ed code block %s to %s", 
+					codeBlocks.get(name), f.getAbsolutePath()));
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		}
 	}
 
 }