use of org.objectweb.asm.tree.ClassNode in project drill by axbaretto.
the class AsmUtil method classFromBytes.
/**
* Create a ClassNode from bytecode.
*
* @param classBytes the bytecode
* @param asmReaderFlags flags for ASM; see {@link org.objectweb.asm.ClassReader#accept(org.objectweb.asm.ClassVisitor, int)}
* @return the ClassNode
*/
public static ClassNode classFromBytes(final byte[] classBytes, final int asmReaderFlags) {
final ClassNode classNode = new ClassNode(CompilationConfig.ASM_API_VERSION);
final ClassReader classReader = new ClassReader(classBytes);
classReader.accept(classNode, asmReaderFlags);
return classNode;
}
use of org.objectweb.asm.tree.ClassNode in project drill by axbaretto.
the class AsmUtil method logClassFromBytes.
/**
* Write a class to the log.
*
* <p>Writes at level DEBUG.
*
* @param logTag a tag to print to the log
* @param classBytes the class' bytecode
* @param logger the logger to write to
*/
public static void logClassFromBytes(final Logger logger, final String logTag, final byte[] classBytes) {
final ClassNode classNode = classFromBytes(classBytes, 0);
logClass(logger, logTag, classNode);
}
use of org.objectweb.asm.tree.ClassNode in project drill by axbaretto.
the class ClassTransformer method getImplementationClass.
public Class<?> getImplementationClass(final QueryClassLoader classLoader, final TemplateClassDefinition<?> templateDefinition, final String entireClass, final String materializedClassName) throws ClassTransformationException {
// unfortunately, this hasn't been set up at construction time, so we have to do it here
final ScalarReplacementOption scalarReplacementOption = ScalarReplacementOption.fromString(optionManager.getOption(SCALAR_REPLACEMENT_VALIDATOR));
try {
final long t1 = System.nanoTime();
final ClassSet set = new ClassSet(null, templateDefinition.getTemplateClassName(), materializedClassName);
final byte[][] implementationClasses = classLoader.getClassByteCode(set.generated, entireClass);
long totalBytecodeSize = 0;
Map<String, Pair<byte[], ClassNode>> classesToMerge = Maps.newHashMap();
for (byte[] clazz : implementationClasses) {
totalBytecodeSize += clazz.length;
final ClassNode node = AsmUtil.classFromBytes(clazz, ClassReader.EXPAND_FRAMES);
if (!AsmUtil.isClassOk(logger, "implementationClasses", node)) {
throw new IllegalStateException("Problem found with implementationClasses");
}
classesToMerge.put(node.name, Pair.of(clazz, node));
}
final LinkedList<ClassSet> names = Lists.newLinkedList();
final Set<ClassSet> namesCompleted = Sets.newHashSet();
names.add(set);
while (!names.isEmpty()) {
final ClassSet nextSet = names.removeFirst();
if (namesCompleted.contains(nextSet)) {
continue;
}
final ClassNames nextPrecompiled = nextSet.precompiled;
final byte[] precompiledBytes = byteCodeLoader.getClassByteCodeFromPath(nextPrecompiled.clazz);
final ClassNames nextGenerated = nextSet.generated;
// keeps only classes that have not be merged
Pair<byte[], ClassNode> classNodePair = classesToMerge.remove(nextGenerated.slash);
final ClassNode generatedNode;
if (classNodePair != null) {
generatedNode = classNodePair.getValue();
} else {
generatedNode = null;
}
/*
* TODO
* We're having a problem with some cases of scalar replacement, but we want to get
* the code in so it doesn't rot anymore.
*
* Here, we use the specified replacement option. The loop will allow us to retry if
* we're using TRY.
*/
MergedClassResult result = null;
boolean scalarReplace = scalarReplacementOption != ScalarReplacementOption.OFF && entireClass.length() < MAX_SCALAR_REPLACE_CODE_SIZE;
while (true) {
try {
result = MergeAdapter.getMergedClass(nextSet, precompiledBytes, generatedNode, scalarReplace);
break;
} catch (RuntimeException e) {
// if we had a problem without using scalar replacement, then rethrow
if (!scalarReplace) {
throw e;
}
// if we did try to use scalar replacement, decide if we need to retry or not
if (scalarReplacementOption == ScalarReplacementOption.ON) {
// option is forced on, so this is a hard error
throw e;
}
/*
* We tried to use scalar replacement, with the option to fall back to not using it.
* Log this failure before trying again without scalar replacement.
*/
logger.info("scalar replacement failure (retrying)\n", e);
scalarReplace = false;
}
}
for (String s : result.innerClasses) {
s = s.replace(DrillFileUtils.SEPARATOR_CHAR, '.');
names.add(nextSet.getChild(s));
}
classLoader.injectByteCode(nextGenerated.dot, result.bytes);
namesCompleted.add(nextSet);
}
// adds byte code of the classes that have not been merged to make them accessible for outer class
for (Map.Entry<String, Pair<byte[], ClassNode>> clazz : classesToMerge.entrySet()) {
classLoader.injectByteCode(clazz.getKey().replace(DrillFileUtils.SEPARATOR_CHAR, '.'), clazz.getValue().getKey());
}
Class<?> c = classLoader.findClass(set.generated.dot);
if (templateDefinition.getExternalInterface().isAssignableFrom(c)) {
logger.debug("Compiled and merged {}: bytecode size = {}, time = {} ms.", c.getSimpleName(), DrillStringUtils.readable(totalBytecodeSize), (System.nanoTime() - t1 + 500_000) / 1_000_000);
return c;
}
throw new ClassTransformationException("The requested class did not implement the expected interface.");
} catch (CompileException | IOException | ClassNotFoundException e) {
throw new ClassTransformationException(String.format("Failure generating transformation classes for value: \n %s", entireClass), e);
}
}
use of org.objectweb.asm.tree.ClassNode in project Galacticraft by micdoodle8.
the class InterfaceDependancyTransformer method transform.
@Override
public byte[] transform(String name, String tname, byte[] bytes) {
if (bytes == null) {
return null;
}
ClassNode cnode = ASMHelper.createClassNode(bytes);
boolean hasDependancyInterfaces = false;
if (cnode.visibleAnnotations != null) {
for (AnnotationNode ann : cnode.visibleAnnotations) {
if (ann.desc.equals(Type.getDescriptor(InterfaceDependancies.class))) {
hasDependancyInterfaces = true;
break;
}
}
}
if (!hasDependancyInterfaces) {
return bytes;
}
hasDependancyInterfaces = false;
for (Iterator<String> iterator = cnode.interfaces.iterator(); iterator.hasNext(); ) {
try {
Launch.classLoader.findClass(new ObfMapping(iterator.next()).toRuntime().javaClass());
} catch (ClassNotFoundException cnfe) {
iterator.remove();
hasDependancyInterfaces = true;
}
}
if (!hasDependancyInterfaces) {
return bytes;
}
return ASMHelper.createBytes(cnode, 0);
}
use of org.objectweb.asm.tree.ClassNode in project Galacticraft by micdoodle8.
the class MCPDeobfuscationTransformer method injectCallback.
private byte[] injectCallback(byte[] bytes) {
ClassNode cnode = ASMHelper.createClassNode(bytes);
MethodNode mnode = ASMHelper.findMethod(new ObfMapping(cnode.name, "<clinit>", "()V"), cnode);
mnode.instructions.insert(new MethodInsnNode(INVOKESTATIC, "codechicken/core/asm/MCPDeobfuscationTransformer", "loadCallback", "()V"));
return ASMHelper.createBytes(cnode, 0);
}
Aggregations