use of org.objectweb.asm.ClassVisitor in project elasticsearch by elastic.
the class SSource method write.
public void write() {
// Create the ClassWriter.
int classFrames = ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS;
int classAccess = Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL;
String classBase = BASE_CLASS_TYPE.getInternalName();
String className = CLASS_TYPE.getInternalName();
String[] classInterfaces = new String[] { Type.getType(scriptInterface.getInterface()).getInternalName() };
ClassWriter writer = new ClassWriter(classFrames);
ClassVisitor visitor = writer;
// if picky is enabled, turn on some checks. instead of VerifyError at the end, you get a helpful stacktrace.
if (settings.isPicky()) {
visitor = new SimpleChecksAdapter(visitor);
}
if (debugStream != null) {
visitor = new TraceClassVisitor(visitor, debugStream, null);
}
visitor.visit(WriterConstants.CLASS_VERSION, classAccess, className, null, classBase, classInterfaces);
visitor.visitSource(Location.computeSourceName(name, source), null);
// Write the constructor:
MethodWriter constructor = new MethodWriter(Opcodes.ACC_PUBLIC, CONSTRUCTOR, visitor, globals.getStatements(), settings);
constructor.visitCode();
constructor.loadThis();
constructor.loadArgs();
constructor.invokeConstructor(BASE_CLASS_TYPE, CONSTRUCTOR);
constructor.returnValue();
constructor.endMethod();
// Write the method defined in the interface:
MethodWriter executeMethod = new MethodWriter(Opcodes.ACC_PUBLIC, scriptInterface.getExecuteMethod(), visitor, globals.getStatements(), settings);
executeMethod.visitCode();
write(executeMethod, globals);
executeMethod.endMethod();
// Write all functions:
for (SFunction function : functions) {
function.write(visitor, settings, globals);
}
// Write all synthetic functions. Note that this process may add more :)
while (!globals.getSyntheticMethods().isEmpty()) {
List<SFunction> current = new ArrayList<>(globals.getSyntheticMethods().values());
globals.getSyntheticMethods().clear();
for (SFunction function : current) {
function.write(visitor, settings, globals);
}
}
// Write the constants
if (false == globals.getConstantInitializers().isEmpty()) {
Collection<Constant> inits = globals.getConstantInitializers().values();
// Fields
for (Constant constant : inits) {
visitor.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC, constant.name, constant.type.getDescriptor(), null, null).visitEnd();
}
// Initialize the constants in a static initializer
final MethodWriter clinit = new MethodWriter(Opcodes.ACC_STATIC, WriterConstants.CLINIT, visitor, globals.getStatements(), settings);
clinit.visitCode();
for (Constant constant : inits) {
constant.initializer.accept(clinit);
clinit.putStatic(CLASS_TYPE, constant.name, constant.type);
}
clinit.returnValue();
clinit.endMethod();
}
// Write any uses$varName methods for used variables
for (org.objectweb.asm.commons.Method usesMethod : scriptInterface.getUsesMethods()) {
MethodWriter ifaceMethod = new MethodWriter(Opcodes.ACC_PUBLIC, usesMethod, visitor, globals.getStatements(), settings);
ifaceMethod.visitCode();
ifaceMethod.push(reserved.getUsedVariables().contains(usesMethod.getName().substring("uses$".length())));
ifaceMethod.returnValue();
ifaceMethod.endMethod();
}
// End writing the class and store the generated bytes.
visitor.visitEnd();
bytes = writer.toByteArray();
}
use of org.objectweb.asm.ClassVisitor in project bazel by bazelbuild.
the class Desugar method main.
public static void main(String[] args) throws Exception {
// LambdaClassMaker generates lambda classes for us, but it does so by essentially simulating
// the call to LambdaMetafactory that the JVM would make when encountering an invokedynamic.
// LambdaMetafactory is in the JDK and its implementation has a property to write out ("dump")
// generated classes, which we take advantage of here. Set property before doing anything else
// since the property is read in the static initializer; if this breaks we can investigate
// setting the property when calling the tool.
Path dumpDirectory = Files.createTempDirectory("lambdas");
System.setProperty(LambdaClassMaker.LAMBDA_METAFACTORY_DUMPER_PROPERTY, dumpDirectory.toString());
deleteTreeOnExit(dumpDirectory);
if (args.length == 1 && args[0].startsWith("@")) {
args = Files.readAllLines(Paths.get(args[0].substring(1)), ISO_8859_1).toArray(new String[0]);
}
OptionsParser optionsParser = OptionsParser.newOptionsParser(Options.class);
optionsParser.setAllowResidue(false);
optionsParser.parseAndExitUponError(args);
Options options = optionsParser.getOptions(Options.class);
checkState(!options.inputJars.isEmpty(), "--input is required");
checkState(options.inputJars.size() == options.outputJars.size(), "Desugar requires the same number of inputs and outputs to pair them");
checkState(!options.bootclasspath.isEmpty() || options.allowEmptyBootclasspath, "At least one --bootclasspath_entry is required");
if (options.verbose) {
System.out.printf("Lambda classes will be written under %s%n", dumpDirectory);
}
CoreLibraryRewriter rewriter = new CoreLibraryRewriter(options.coreLibrary ? "__desugar__/" : "");
boolean allowDefaultMethods = options.minSdkVersion >= 24;
boolean allowCallsToObjectsNonNull = options.minSdkVersion >= 19;
LambdaClassMaker lambdas = new LambdaClassMaker(dumpDirectory);
// Process each input separately
for (InputOutputPair inputOutputPair : toInputOutputPairs(options)) {
Path inputJar = inputOutputPair.getInput();
IndexedJars appIndexedJar = new IndexedJars(ImmutableList.of(inputJar));
IndexedJars appAndClasspathIndexedJars = new IndexedJars(options.classpath, appIndexedJar);
ClassLoader loader = createClassLoader(rewriter, options.bootclasspath, appAndClasspathIndexedJars);
try (ZipFile in = new ZipFile(inputJar.toFile());
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(inputOutputPair.getOutput())))) {
ClassReaderFactory readerFactory = new ClassReaderFactory((options.copyBridgesFromClasspath && !allowDefaultMethods) ? appAndClasspathIndexedJars : appIndexedJar, rewriter);
ImmutableSet.Builder<String> interfaceLambdaMethodCollector = ImmutableSet.builder();
// Process input Jar, desugaring as we go
for (Enumeration<? extends ZipEntry> entries = in.entries(); entries.hasMoreElements(); ) {
ZipEntry entry = entries.nextElement();
try (InputStream content = in.getInputStream(entry)) {
// danger of accidentally uncompressed resources ending up in an .apk.
if (entry.getName().endsWith(".class")) {
ClassReader reader = rewriter.reader(content);
CoreLibraryRewriter.UnprefixingClassWriter writer = rewriter.writer(ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = writer;
if (!options.onlyDesugarJavac9ForLint) {
if (!allowDefaultMethods) {
visitor = new Java7Compatibility(visitor, readerFactory);
}
visitor = new LambdaDesugaring(visitor, loader, lambdas, interfaceLambdaMethodCollector, allowDefaultMethods);
}
if (!allowCallsToObjectsNonNull) {
visitor = new ObjectsRequireNonNullMethodInliner(visitor);
}
reader.accept(visitor, 0);
writeStoredEntry(out, entry.getName(), writer.toByteArray());
} else {
// TODO(bazel-team): Avoid de- and re-compressing resource files
ZipEntry destEntry = new ZipEntry(entry);
destEntry.setCompressedSize(-1);
out.putNextEntry(destEntry);
ByteStreams.copy(content, out);
out.closeEntry();
}
}
}
ImmutableSet<String> interfaceLambdaMethods = interfaceLambdaMethodCollector.build();
checkState(!allowDefaultMethods || interfaceLambdaMethods.isEmpty(), "Desugaring with default methods enabled moved interface lambdas");
// Write out the lambda classes we generated along the way
ImmutableMap<Path, LambdaInfo> lambdaClasses = lambdas.drain();
checkState(!options.onlyDesugarJavac9ForLint || lambdaClasses.isEmpty(), "There should be no lambda classes generated: %s", lambdaClasses.keySet());
for (Map.Entry<Path, LambdaInfo> lambdaClass : lambdaClasses.entrySet()) {
try (InputStream bytecode = Files.newInputStream(dumpDirectory.resolve(lambdaClass.getKey()))) {
ClassReader reader = rewriter.reader(bytecode);
CoreLibraryRewriter.UnprefixingClassWriter writer = rewriter.writer(ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = writer;
if (!allowDefaultMethods) {
// null ClassReaderFactory b/c we don't expect to need it for lambda classes
visitor = new Java7Compatibility(visitor, (ClassReaderFactory) null);
}
visitor = new LambdaClassFixer(visitor, lambdaClass.getValue(), readerFactory, interfaceLambdaMethods, allowDefaultMethods);
// Send lambda classes through desugaring to make sure there's no invokedynamic
// instructions in generated lambda classes (checkState below will fail)
visitor = new LambdaDesugaring(visitor, loader, lambdas, null, allowDefaultMethods);
if (!allowCallsToObjectsNonNull) {
// Not sure whether there will be implicit null check emitted by javac, so we rerun
// the inliner again
visitor = new ObjectsRequireNonNullMethodInliner(visitor);
}
reader.accept(visitor, 0);
String filename = rewriter.unprefix(lambdaClass.getValue().desiredInternalName()) + ".class";
writeStoredEntry(out, filename, writer.toByteArray());
}
}
Map<Path, LambdaInfo> leftBehind = lambdas.drain();
checkState(leftBehind.isEmpty(), "Didn't process %s", leftBehind);
}
}
}
use of org.objectweb.asm.ClassVisitor in project robovm by robovm.
the class ObjCBlockPlugin method createBlockMarshaler.
private String createBlockMarshaler(Config config, Clazz clazz, final SootMethod targetMethod, Type[] actualGenericTypes, soot.Type[] actualRawTypes, soot.Type[] unboxedTypes, Map<String, Integer> blockTypeIds, String[][] targetMethodAnnotations) throws IOException {
if (targetMethod.getDeclaringClass().getName().equals("java.lang.Runnable") && targetMethod.getName().equals("run")) {
return RUNNABLE_AS_OBJC_BLOCK_MARSHALER;
}
String targetMethodKey = getTargetMethodKey(targetMethod, actualRawTypes, targetMethodAnnotations);
Integer id = blockTypeIds.get(targetMethodKey);
if (id != null) {
// Already generated
return getBlockMarshalerName(clazz, id);
}
id = blockTypeIds.size();
blockTypeIds.put(targetMethodKey, id);
final String blockMarshalerName = getBlockMarshalerName(clazz, id);
final String targetInterfaceName = Types.getInternalName(targetMethod.getDeclaringClass());
// We use RunnableAsObjCBlockMarshaler as template
Clazz templateMarshaler = config.getClazzes().load(RUNNABLE_AS_OBJC_BLOCK_MARSHALER);
final Set<String> usedBoxMethods = new HashSet<>();
final Set<String> usedUnboxMethods = new HashSet<>();
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
generateTargetMethod(blockMarshalerName, targetMethod, actualGenericTypes, actualRawTypes, unboxedTypes, usedBoxMethods, usedUnboxMethods, cw);
generateBridgeMethod(actualGenericTypes, unboxedTypes, targetMethodAnnotations, cw);
generateCallbackMethod(blockMarshalerName, targetMethod, actualGenericTypes, actualRawTypes, unboxedTypes, usedBoxMethods, usedUnboxMethods, targetMethodAnnotations, cw);
ClassReader classReader = new ClassReader(templateMarshaler.getBytes());
classReader.accept(new ClassVisitor(ASM4, cw) {
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, blockMarshalerName, signature, superName, new String[] { targetInterfaceName });
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
// Ignore
}
@Override
public void visitSource(String source, String debug) {
// Ignore
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
switch(name) {
case "run":
case "invoke":
case "invoked":
// Skip all these
return null;
case "box":
if (!usedBoxMethods.contains(desc)) {
return null;
}
break;
case "unbox":
if (!usedUnboxMethods.contains(desc)) {
return null;
}
break;
}
desc = desc.replace("java/lang/Runnable", targetInterfaceName);
signature = null;
// RunnableAsObjCBlockMarshaler to the blockMarshalerName
return new MethodVisitor(ASM4, super.visitMethod(access, name, desc, signature, exceptions)) {
@Override
public void visitLdcInsn(Object cst) {
if (cst instanceof org.objectweb.asm.Type) {
if (((org.objectweb.asm.Type) cst).getSort() == org.objectweb.asm.Type.OBJECT) {
String internalName = ((org.objectweb.asm.Type) cst).getInternalName();
if (RUNNABLE_AS_OBJC_BLOCK_MARSHALER.equals(internalName)) {
cst = org.objectweb.asm.Type.getObjectType(blockMarshalerName);
}
}
}
super.visitLdcInsn(cst);
}
@Override
public void visitTypeInsn(int opcode, String type) {
if (RUNNABLE_AS_OBJC_BLOCK_MARSHALER.equals(type)) {
type = blockMarshalerName;
} else if ("java/lang/Runnable".equals(type)) {
type = targetInterfaceName;
}
super.visitTypeInsn(opcode, type);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (RUNNABLE_AS_OBJC_BLOCK_MARSHALER.equals(owner)) {
owner = blockMarshalerName;
}
super.visitFieldInsn(opcode, owner, name, desc);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
if (RUNNABLE_AS_OBJC_BLOCK_MARSHALER.equals(owner)) {
owner = blockMarshalerName;
}
super.visitMethodInsn(opcode, owner, name, desc);
}
@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
// Ignored
}
@Override
public void visitLineNumber(int line, Label start) {
// Ignored
}
};
}
}, 0);
cw.visitInnerClass(blockMarshalerName, clazz.getInternalName(), blockMarshalerName.substring(clazz.getInternalName().length() + 1), ACC_PUBLIC + ACC_STATIC);
cw.visitEnd();
File f = clazz.getPath().getGeneratedClassFile(blockMarshalerName);
FileUtils.writeByteArrayToFile(f, cw.toByteArray());
// The marshaler class is created after the class is compiled.
// This prevents the triggering of a recompile of the class.
f.setLastModified(clazz.lastModified());
return blockMarshalerName;
}
use of org.objectweb.asm.ClassVisitor in project byte-buddy by raphw.
the class AbstractDynamicTypeBuilderTest method testWriterHint.
@Test
@SuppressWarnings("unchecked")
public void testWriterHint() throws Exception {
AsmVisitorWrapper asmVisitorWrapper = mock(AsmVisitorWrapper.class);
when(asmVisitorWrapper.wrap(any(TypeDescription.class), any(ClassVisitor.class), any(Implementation.Context.class), any(TypePool.class), any(FieldList.class), any(MethodList.class), anyInt(), anyInt())).then(new Answer<ClassVisitor>() {
@Override
public ClassVisitor answer(InvocationOnMock invocationOnMock) throws Throwable {
return new ClassVisitor(Opcodes.ASM5, (ClassVisitor) invocationOnMock.getArguments()[1]) {
@Override
public void visitEnd() {
MethodVisitor mv = visitMethod(Opcodes.ACC_PUBLIC, FOO, "()Ljava/lang/String;", null, null);
mv.visitCode();
mv.visitLdcInsn(FOO);
mv.visitInsn(Opcodes.ARETURN);
mv.visitMaxs(-1, -1);
mv.visitEnd();
}
};
}
});
when(asmVisitorWrapper.mergeWriter(0)).thenReturn(ClassWriter.COMPUTE_MAXS);
Class<?> type = createPlain().visit(asmVisitorWrapper).make().load(ClassLoadingStrategy.BOOTSTRAP_LOADER, ClassLoadingStrategy.Default.WRAPPER).getLoaded();
assertThat(type.getDeclaredMethod(FOO).invoke(type.getDeclaredConstructor().newInstance()), is((Object) FOO));
verify(asmVisitorWrapper).mergeWriter(0);
verify(asmVisitorWrapper, atMost(1)).mergeReader(0);
verify(asmVisitorWrapper).wrap(any(TypeDescription.class), any(ClassVisitor.class), any(Implementation.Context.class), any(TypePool.class), any(FieldList.class), any(MethodList.class), anyInt(), anyInt());
verifyNoMoreInteractions(asmVisitorWrapper);
}
use of org.objectweb.asm.ClassVisitor in project byte-buddy by raphw.
the class TypeConstantAdjustmentTest method testInstrumentationLegacyClassOtherType.
@Test
public void testInstrumentationLegacyClassOtherType() throws Exception {
ClassVisitor classVisitor = TypeConstantAdjustment.INSTANCE.wrap(mock(TypeDescription.class), this.classVisitor, mock(Implementation.Context.class), mock(TypePool.class), new FieldList.Empty<FieldDescription.InDefinedShape>(), new MethodList.Empty<MethodDescription>(), IGNORED, IGNORED);
classVisitor.visit(ClassFileVersion.JAVA_V4.getMinorMajorVersion(), FOOBAR, FOO, BAR, QUX, new String[] { BAZ });
MethodVisitor methodVisitor = classVisitor.visitMethod(FOOBAR, FOO, BAR, QUX, new String[] { BAZ });
assertThat(methodVisitor, not(this.methodVisitor));
methodVisitor.visitLdcInsn(FOO);
verify(this.classVisitor).visit(ClassFileVersion.JAVA_V4.getMinorMajorVersion(), FOOBAR, FOO, BAR, QUX, new String[] { BAZ });
verify(this.classVisitor).visitMethod(FOOBAR, FOO, BAR, QUX, new String[] { BAZ });
verifyNoMoreInteractions(this.classVisitor);
verify(this.methodVisitor).visitLdcInsn(FOO);
verifyNoMoreInteractions(this.methodVisitor);
}
Aggregations