use of org.apache.drill.exec.compile.bytecode.ValueHolderReplacementVisitor in project drill by apache.
the class MergeAdapter method getMergedClass.
public static MergedClassResult getMergedClass(final ClassSet set, final byte[] precompiledClass, ClassNode generatedClass, final boolean scalarReplace) {
if (verifyBytecode) {
if (!AsmUtil.isClassBytesOk(logger, "precompiledClass", precompiledClass)) {
throw new IllegalStateException("Problem found in precompiledClass");
}
if ((generatedClass != null) && !AsmUtil.isClassOk(logger, "generatedClass", generatedClass)) {
throw new IllegalStateException("Problem found in generatedClass");
}
}
/*
* Setup adapters for merging, remapping class names and class writing. This is done in
* reverse order of how they will be evaluated.
*/
final RemapClasses re = new RemapClasses(set);
try {
if (scalarReplace && generatedClass != null) {
if (logger.isDebugEnabled()) {
AsmUtil.logClass(logger, "generated " + set.generated.dot, generatedClass);
}
final ClassNode generatedMerged = new ClassNode();
ClassVisitor mergeGenerator = generatedMerged;
if (verifyBytecode) {
mergeGenerator = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, generatedMerged), true);
}
/*
* Even though we're effectively transforming-creating a new class in mergeGenerator,
* there's no way to pass in ClassWriter.COMPUTE_MAXS, which would save us from having
* to figure out stack size increases on our own. That gets handled by the
* InstructionModifier (from inside ValueHolderReplacement > ScalarReplacementNode).
*/
generatedClass.accept(new ValueHolderReplacementVisitor(mergeGenerator, verifyBytecode));
if (verifyBytecode) {
if (!AsmUtil.isClassOk(logger, "generatedMerged", generatedMerged)) {
throw new IllegalStateException("Problem found with generatedMerged");
}
}
generatedClass = generatedMerged;
}
final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
ClassVisitor writerVisitor = writer;
if (verifyBytecode) {
writerVisitor = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, writerVisitor), true);
}
ClassVisitor remappingAdapter = new RemappingClassAdapter(writerVisitor, re);
if (verifyBytecode) {
remappingAdapter = new DrillCheckClassAdapter(CompilationConfig.ASM_API_VERSION, new CheckClassVisitorFsm(CompilationConfig.ASM_API_VERSION, remappingAdapter), true);
}
ClassVisitor visitor = remappingAdapter;
if (generatedClass != null) {
visitor = new MergeAdapter(set, remappingAdapter, generatedClass);
}
ClassReader tReader = new ClassReader(precompiledClass);
tReader.accept(visitor, ClassReader.SKIP_FRAMES);
byte[] outputClass = writer.toByteArray();
if (logger.isDebugEnabled()) {
AsmUtil.logClassFromBytes(logger, "merged " + set.generated.dot, outputClass);
}
return new MergedClassResult(outputClass, re.getInnerClasses());
} catch (Error | RuntimeException e) {
logger.error("Failure while merging classes.", e);
AsmUtil.logClass(logger, "generatedClass", generatedClass);
throw e;
}
}
Aggregations