use of org.objectweb.asm.Type in project cdap by caskdata.
the class SparkClassRewriter method rewriteClient.
/**
* Defines the org.apache.spark.deploy.yarn.Client class with rewriting of the createConfArchive method to
* workaround the SPARK-13441 bug.
*/
@Nullable
private byte[] rewriteClient(InputStream byteCodeStream) throws IOException {
// We only need to rewrite if listing either HADOOP_CONF_DIR or YARN_CONF_DIR return null.
boolean needRewrite = false;
for (String env : ImmutableList.of("HADOOP_CONF_DIR", "YARN_CONF_DIR")) {
String value = System.getenv(env);
if (value != null) {
File path = new File(value);
if (path.isDirectory() && path.listFiles() == null) {
needRewrite = true;
break;
}
}
}
// If rewrite is not needed
if (!needRewrite) {
return null;
}
ClassReader cr = new ClassReader(byteCodeStream);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cr.accept(new ClassVisitor(Opcodes.ASM5, cw) {
@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
// Only rewrite the createConfArchive method
if (!"createConfArchive".equals(name)) {
return mv;
}
// Check if it's a recognizable return type.
// Spark 1.5+ return type is File
boolean isReturnFile = Type.getReturnType(desc).equals(Type.getType(File.class));
Type optionType = Type.getObjectType("scala/Option");
if (!isReturnFile) {
// Spark 1.4 return type is Option<File>
if (!Type.getReturnType(desc).equals(optionType)) {
// Unknown type. Not going to modify the code.
return mv;
}
}
// Generate this for Spark 1.5+
// return SparkRuntimeUtils.createConfArchive(this.sparkConf, SPARK_CONF_FILE,
// LOCALIZED_CONF_DIR, LOCALIZED_CONF_DIR_ZIP);
// Generate this for Spark 1.4
// return Option.apply(SparkRuntimeUtils.createConfArchive(this.sparkConf, SPARK_CONF_FILE,
// LOCALIZED_CONF_DIR, LOCALIZED_CONF_DIR_ZIP));
GeneratorAdapter mg = new GeneratorAdapter(mv, access, name, desc);
// load this.sparkConf to the stack
mg.loadThis();
mg.getField(Type.getObjectType("org/apache/spark/deploy/yarn/Client"), "sparkConf", SPARK_CONF_TYPE);
// push three constants to the stack
mg.visitLdcInsn(SPARK_CONF_FILE);
mg.visitLdcInsn(LOCALIZED_CONF_DIR);
mg.visitLdcInsn(LOCALIZED_CONF_DIR_ZIP);
// call SparkRuntimeUtils.createConfArchive, return a File and leave it in stack
Type stringType = Type.getType(String.class);
mg.invokeStatic(SPARK_RUNTIME_UTILS_TYPE, new Method("createConfArchive", Type.getType(File.class), new Type[] { SPARK_CONF_TYPE, stringType, stringType, stringType }));
if (isReturnFile) {
// Spark 1.5+ return type is File, hence just return the File from the stack
mg.returnValue();
mg.endMethod();
} else {
// Spark 1.4 return type is Option<File>
// return Option.apply(<file from stack>);
// where the file is actually just popped from the stack
mg.invokeStatic(optionType, new Method("apply", optionType, new Type[] { Type.getType(Object.class) }));
mg.checkCast(optionType);
mg.returnValue();
mg.endMethod();
}
return null;
}
}, ClassReader.EXPAND_FRAMES);
return cw.toByteArray();
}
use of org.objectweb.asm.Type in project sling by apache.
the class GenerateAdapterMetadataMojo method parseAdapterAnnotation.
@SuppressWarnings("unchecked")
private void parseAdapterAnnotation(final AnnotationNode annotation, final ClassNode annotatedClass, final Map<String, Object> adaptableDescription) throws JsonException {
String condition = null;
List<Type> adapterClasses = null;
final List<?> values = annotation.values;
final Iterator<?> it = values.iterator();
while (it.hasNext()) {
final Object name = it.next();
final Object value = it.next();
if (StringUtils.isEmpty(condition)) {
condition = String.format(DEFAULT_CONDITION, getSimpleName(annotatedClass));
}
if ("condition".equals(name)) {
condition = (String) value;
} else if ("value".equals(name)) {
adapterClasses = (List<Type>) value;
}
}
if (adapterClasses == null) {
throw new IllegalArgumentException("Adapter annotation is malformed. Expecting a list of adapter classes");
}
for (final Type adapterClass : adapterClasses) {
JsonSupport.accumulate(adaptableDescription, condition, adapterClass.getClassName());
}
}
use of org.objectweb.asm.Type in project android_frameworks_base by crdroidandroid.
the class DelegateMethodAdapter method generateDelegateCode.
/**
* Generates the new code for the method.
* <p/>
* For native methods, this must be invoked directly by {@link DelegateClassAdapter}
* (since they have no code to visit).
* <p/>
* Otherwise for non-native methods the {@link DelegateClassAdapter} simply needs to
* return this instance of {@link DelegateMethodAdapter} and let the normal visitor pattern
* invoke it as part of the {@link ClassReader#accept(ClassVisitor, int)} workflow and then
* this method will be invoked from {@link MethodVisitor#visitEnd()}.
*/
public void generateDelegateCode() {
/*
* The goal is to generate a call to a static delegate method.
* If this method is non-static, the first parameter will be 'this'.
* All the parameters must be passed and then the eventual return type returned.
*
* Example, let's say we have a method such as
* public void myMethod(int a, Object b, ArrayList<String> c) { ... }
*
* We'll want to create a body that calls a delegate method like this:
* TheClass_Delegate.myMethod(this, a, b, c);
*
* If the method is non-static and the class name is an inner class (e.g. has $ in its
* last segment), we want to push the 'this' of the outer class first:
* OuterClass_InnerClass_Delegate.myMethod(
* OuterClass.this,
* OuterClass$InnerClass.this,
* a, b, c);
*
* Only one level of inner class is supported right now, for simplicity and because
* we don't need more.
*
* The generated class name is the current class name with "_Delegate" appended to it.
* One thing to realize is that we don't care about generics -- since generic types
* are erased at build time, they have no influence on the method name being called.
*/
// Add our annotation
AnnotationVisitor aw = mDelWriter.visitAnnotation(Type.getObjectType(Type.getInternalName(LayoutlibDelegate.class)).toString(), // visible at runtime
true);
if (aw != null) {
aw.visitEnd();
}
mDelWriter.visitCode();
if (mDelegateLineNumber != null) {
Object[] p = mDelegateLineNumber;
mDelWriter.visitLineNumber((Integer) p[0], (Label) p[1]);
}
ArrayList<Type> paramTypes = new ArrayList<>();
String delegateClassName = mClassName + DELEGATE_SUFFIX;
boolean pushedArg0 = false;
int maxStack = 0;
// Check if the last segment of the class name has inner an class.
// Right now we only support one level of inner classes.
Type outerType = null;
int slash = mClassName.lastIndexOf('/');
int dol = mClassName.lastIndexOf('$');
if (dol != -1 && dol > slash && dol == mClassName.indexOf('$')) {
String outerClass = mClassName.substring(0, dol);
outerType = Type.getObjectType(outerClass);
// Change a delegate class name to "com/foo/Outer_Inner_Delegate"
delegateClassName = delegateClassName.replace('$', '_');
}
// by the 'this' of any outer class, if any.
if (!mIsStatic) {
if (outerType != null && !mIsStaticInnerClass) {
// The first-level inner class has a package-protected member called 'this$0'
// that points to the outer class.
// Push this.getField("this$0") on the call stack.
// var 0 = this
mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
mDelWriter.visitFieldInsn(Opcodes.GETFIELD, // class where the field is defined
mClassName, // field name
"this$0", // type of the field
outerType.getDescriptor());
maxStack++;
paramTypes.add(outerType);
}
// Push "this" for the instance method, which is always ALOAD 0
mDelWriter.visitVarInsn(Opcodes.ALOAD, 0);
maxStack++;
pushedArg0 = true;
paramTypes.add(Type.getObjectType(mClassName));
}
// Push all other arguments. Start at arg 1 if we already pushed 'this' above.
Type[] argTypes = Type.getArgumentTypes(mDesc);
int maxLocals = pushedArg0 ? 1 : 0;
for (Type t : argTypes) {
int size = t.getSize();
mDelWriter.visitVarInsn(t.getOpcode(Opcodes.ILOAD), maxLocals);
maxLocals += size;
maxStack += size;
paramTypes.add(t);
}
// Construct the descriptor of the delegate based on the parameters
// we pushed on the call stack. The return type remains unchanged.
String desc = Type.getMethodDescriptor(Type.getReturnType(mDesc), paramTypes.toArray(new Type[paramTypes.size()]));
// Invoke the static delegate
mDelWriter.visitMethodInsn(Opcodes.INVOKESTATIC, delegateClassName, mMethodName, desc, false);
Type returnType = Type.getReturnType(mDesc);
mDelWriter.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
mDelWriter.visitMaxs(maxStack, maxLocals);
mDelWriter.visitEnd();
// For debugging now. Maybe we should collect these and store them in
// a text file for helping create the delegates. We could also compare
// the text file to a golden and break the build on unsupported changes
// or regressions. Even better we could fancy-print something that looks
// like the expected Java method declaration.
mLog.debug("Delegate: %1$s # %2$s %3$s", delegateClassName, mMethodName, desc);
}
use of org.objectweb.asm.Type in project android_frameworks_base by crdroidandroid.
the class AbstractClassAdapter method renameMethodDesc.
/**
* Renames a method descriptor, i.e. applies renameType to all arguments and to the
* return value.
*/
String renameMethodDesc(String desc) {
if (desc == null) {
return null;
}
Type[] args = Type.getArgumentTypes(desc);
StringBuilder sb = new StringBuilder("(");
for (Type arg : args) {
String name = renameType(arg);
sb.append(name);
}
sb.append(')');
Type ret = Type.getReturnType(desc);
String name = renameType(ret);
sb.append(name);
return sb.toString();
}
use of org.objectweb.asm.Type in project bytecode-viewer by Konloch.
the class Remapper method mapMethodDesc.
public String mapMethodDesc(String desc) {
if ("()V".equals(desc)) {
return desc;
}
Type[] args = Type.getArgumentTypes(desc);
StringBuilder sb = new StringBuilder("(");
for (int i = 0; i < args.length; i++) {
sb.append(mapDesc(args[i].getDescriptor()));
}
Type returnType = Type.getReturnType(desc);
if (returnType == Type.VOID_TYPE) {
sb.append(")V");
return sb.toString();
}
sb.append(')').append(mapDesc(returnType.getDescriptor()));
return sb.toString();
}
Aggregations