use of org.objectweb.asm.ClassWriter in project presto by prestodb.
the class CompilerUtils method defineClasses.
private static Map<String, Class<?>> defineClasses(List<ClassDefinition> classDefinitions, DynamicClassLoader classLoader) {
ClassInfoLoader classInfoLoader = ClassInfoLoader.createClassInfoLoader(classDefinitions, classLoader);
if (DUMP_BYTE_CODE_TREE) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DumpBytecodeVisitor dumpBytecode = new DumpBytecodeVisitor(new PrintStream(out));
for (ClassDefinition classDefinition : classDefinitions) {
dumpBytecode.visitClass(classDefinition);
}
System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8));
}
Map<String, byte[]> bytecodes = new LinkedHashMap<>();
for (ClassDefinition classDefinition : classDefinitions) {
ClassWriter cw = new SmartClassWriter(classInfoLoader);
try {
classDefinition.visit(ADD_FAKE_LINE_NUMBER ? new AddFakeLineNumberClassVisitor(cw) : cw);
} catch (IndexOutOfBoundsException | NegativeArraySizeException e) {
Printer printer = new Textifier();
StringWriter stringWriter = new StringWriter();
TraceClassVisitor tcv = new TraceClassVisitor(null, printer, new PrintWriter(stringWriter));
classDefinition.visit(tcv);
throw new IllegalArgumentException("An error occurred while processing classDefinition:" + System.lineSeparator() + stringWriter.toString(), e);
}
try {
byte[] bytecode = cw.toByteArray();
if (RUN_ASM_VERIFIER) {
ClassReader reader = new ClassReader(bytecode);
CheckClassAdapter.verify(reader, classLoader, true, new PrintWriter(System.out));
}
bytecodes.put(classDefinition.getType().getJavaClassName(), bytecode);
} catch (RuntimeException e) {
throw new CompilationException("Error compiling class " + classDefinition.getName(), e);
}
}
String dumpClassPath = DUMP_CLASS_FILES_TO.get();
if (dumpClassPath != null) {
for (Map.Entry<String, byte[]> entry : bytecodes.entrySet()) {
File file = new File(dumpClassPath, ParameterizedType.typeFromJavaClassName(entry.getKey()).getClassName() + ".class");
try {
log.debug("ClassFile: " + file.getAbsolutePath());
Files.createParentDirs(file);
Files.write(entry.getValue(), file);
} catch (IOException e) {
log.error(e, "Failed to write generated class file to: %s" + file.getAbsolutePath());
}
}
}
if (DUMP_BYTE_CODE_RAW) {
for (byte[] bytecode : bytecodes.values()) {
ClassReader classReader = new ClassReader(bytecode);
classReader.accept(new TraceClassVisitor(new PrintWriter(System.err)), ClassReader.EXPAND_FRAMES);
}
}
Map<String, Class<?>> classes = classLoader.defineClasses(bytecodes);
try {
for (Class<?> clazz : classes.values()) {
Reflection.initialize(clazz);
}
} catch (VerifyError e) {
throw new RuntimeException(e);
}
return classes;
}
use of org.objectweb.asm.ClassWriter in project bazel by bazelbuild.
the class RClassGenerator method write.
/** Builds the bytecode and writes out the R.class file, and R$inner.class files. */
public void write() throws IOException {
Iterable<String> folders = PACKAGE_SPLITTER.split(packageName);
Path packageDir = outFolder;
for (String folder : folders) {
packageDir = packageDir.resolve(folder);
}
// At least create the outFolder that was requested. However, if there are no symbols, don't
// create the R.class and inner class files (no need to have an empty class).
Files.createDirectories(packageDir);
if (initializers.isEmpty()) {
return;
}
Path rClassFile = packageDir.resolve(SdkConstants.FN_COMPILED_RESOURCE_CLASS);
String packageWithSlashes = packageName.replaceAll("\\.", "/");
String rClassName = packageWithSlashes.isEmpty() ? "R" : (packageWithSlashes + "/R");
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classWriter.visit(JAVA_VERSION, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER, rClassName, null, /* signature */
SUPER_CLASS, null);
classWriter.visitSource(SdkConstants.FN_RESOURCE_CLASS, null);
writeConstructor(classWriter);
// Build the R.class w/ the inner classes, then later build the individual R$inner.class.
for (ResourceType resourceType : initializers.keySet()) {
String innerClassName = rClassName + "$" + resourceType;
classWriter.visitInnerClass(innerClassName, rClassName, resourceType.toString(), Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC);
}
classWriter.visitEnd();
Files.write(rClassFile, classWriter.toByteArray());
// Now generate the R$inner.class files.
for (Map.Entry<ResourceType, List<FieldInitializer>> entry : initializers.entrySet()) {
writeInnerClass(entry.getValue(), packageDir, rClassName, entry.getKey().toString());
}
}
use of org.objectweb.asm.ClassWriter in project bazel by bazelbuild.
the class GenZipWithEntries method dump.
public static byte[] dump(String name) {
ClassWriter cw = new ClassWriter(0);
cw.visit(52, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, name, null, "java/lang/Object", null);
{
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
use of org.objectweb.asm.ClassWriter in project platform_frameworks_base by android.
the class DelegateClassAdapterTest method testConstructorsNotSupported.
/**
* {@link DelegateMethodAdapter} does not support overriding constructors yet,
* so this should fail with an {@link UnsupportedOperationException}.
*
* Although not tested here, the message of the exception should contain the
* constructor signature.
*/
@Test(expected = UnsupportedOperationException.class)
public void testConstructorsNotSupported() throws IOException {
ClassWriter cw = new ClassWriter(0);
String internalClassName = NATIVE_CLASS_NAME.replace('.', '/');
HashSet<String> delegateMethods = new HashSet<>();
delegateMethods.add("<init>");
DelegateClassAdapter cv = new DelegateClassAdapter(mLog, cw, internalClassName, delegateMethods);
ClassReader cr = new ClassReader(NATIVE_CLASS_NAME);
cr.accept(cv, 0);
}
use of org.objectweb.asm.ClassWriter in project platform_frameworks_base by android.
the class DelegateClassAdapterTest method testDelegateInner.
@Test
public void testDelegateInner() throws Throwable {
// We'll delegate the "get" method of both the inner and outer class.
HashSet<String> delegateMethods = new HashSet<>();
delegateMethods.add("get");
delegateMethods.add("privateMethod");
// Generate the delegate for the outer class.
ClassWriter cwOuter = new ClassWriter(0);
String outerClassName = OUTER_CLASS_NAME.replace('.', '/');
DelegateClassAdapter cvOuter = new DelegateClassAdapter(mLog, cwOuter, outerClassName, delegateMethods);
ClassReader cr = new ClassReader(OUTER_CLASS_NAME);
cr.accept(cvOuter, 0);
// Generate the delegate for the inner class.
ClassWriter cwInner = new ClassWriter(0);
String innerClassName = INNER_CLASS_NAME.replace('.', '/');
DelegateClassAdapter cvInner = new DelegateClassAdapter(mLog, cwInner, innerClassName, delegateMethods);
cr = new ClassReader(INNER_CLASS_NAME);
cr.accept(cvInner, 0);
// Load the generated classes in a different class loader and try them
ClassLoader2 cl2 = null;
try {
cl2 = new ClassLoader2() {
@Override
public void testModifiedInstance() throws Exception {
// Check the outer class
Class<?> outerClazz2 = loadClass(OUTER_CLASS_NAME);
Object o2 = outerClazz2.newInstance();
assertNotNull(o2);
// The original Outer.get returns 1+10+20,
// but the delegate makes it return 4+10+20
assertEquals(4 + 10 + 20, callGet(o2, 10, 20));
assertEquals(1 + 10 + 20, callGet_Original(o2, 10, 20));
// The original Outer has a private method,
// so by default we can't access it.
boolean gotIllegalAccessException = false;
try {
callMethod(o2, "privateMethod", false);
} catch (IllegalAccessException e) {
gotIllegalAccessException = true;
}
assertTrue(gotIllegalAccessException);
// The private method from original Outer has been
// delegated. The delegate generated should have the
// same access.
gotIllegalAccessException = false;
try {
assertEquals("outerPrivateMethod", callMethod(o2, "privateMethod_Original", false));
} catch (IllegalAccessException e) {
gotIllegalAccessException = true;
}
assertTrue(gotIllegalAccessException);
// Check the inner class. Since it's not a static inner class, we need
// to use the hidden constructor that takes the outer class as first parameter.
Class<?> innerClazz2 = loadClass(INNER_CLASS_NAME);
Constructor<?> innerCons = innerClazz2.getConstructor(outerClazz2);
Object i2 = innerCons.newInstance(o2);
assertNotNull(i2);
// The original Inner.get returns 3+10+20,
// but the delegate makes it return 6+10+20
assertEquals(6 + 10 + 20, callGet(i2, 10, 20));
assertEquals(3 + 10 + 20, callGet_Original(i2, 10, 20));
}
};
cl2.add(OUTER_CLASS_NAME, cwOuter.toByteArray());
cl2.add(INNER_CLASS_NAME, cwInner.toByteArray());
cl2.testModifiedInstance();
} catch (Throwable t) {
throw dumpGeneratedClass(t, cl2);
}
}
Aggregations