下面列出了org.objectweb.asm.Opcodes# ANEWARRAY 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void visitTypeInsn(final int opcode, final String type) {
Type objectType = Type.getObjectType(type);
switch (opcode) {
case Opcodes.NEW:
anew(objectType);
break;
case Opcodes.ANEWARRAY:
newarray(objectType);
break;
case Opcodes.CHECKCAST:
checkcast(objectType);
break;
case Opcodes.INSTANCEOF:
instanceOf(objectType);
break;
default:
throw new IllegalArgumentException();
}
}
public void visitTypeInsn(int opcode, String type) {
if (firstInstruction)
addInc();
super.visitTypeInsn(opcode, type);
// we deal with Opcodes.NEW through the constructors
if (opcode == Opcodes.ANEWARRAY) {
int siteId = getNextSiteId();
addLog(true, siteId);
} else if (DO_NEW_INVOKESPECIAL_SEQUENCE && opcode == Opcodes.NEW) {
super.visitInsn(Opcodes.DUP);
Triplet p = new Triplet();
p.type = type;
p.var = this.localsBase + 1 + newTypeStack.size();
p.siteId = getNextSiteId();
if (this.maxLocals < p.var) {
this.maxLocals = p.var;
methodToLargestLocal.put(this.encodedName, new Integer(
p.var));
}
super.setLocalType(p.var, JAVA_LANG_OBJECT_TYPE); // super.newLocal(OBJECT_TYPE);
newTypeStack.addLast(p);
super.visitVarInsn(Opcodes.ASTORE, p.var);
}
}
@Override
public void visitTypeInsn(final int opcode, final String type) {
Type objectType = Type.getObjectType(type);
switch (opcode) {
case Opcodes.NEW:
anew(objectType);
break;
case Opcodes.ANEWARRAY:
newarray(objectType);
break;
case Opcodes.CHECKCAST:
checkcast(objectType);
break;
case Opcodes.INSTANCEOF:
instanceOf(objectType);
break;
default:
throw new IllegalArgumentException();
}
}
private boolean isSmokeMethod(MethodNode method)
{
boolean containsArray = false;
int putstatic = 0;
int getstatic = 0;
for(AbstractInsnNode ain : method.instructions.toArray())
if(ain.getOpcode() == Opcodes.ANEWARRAY)
containsArray = true;
else if(ain.getOpcode() == Opcodes.PUTSTATIC || ain.getOpcode() == Opcodes.GETSTATIC)
if(((FieldInsnNode)ain).desc.equals("[Ljava/lang/String;"))
{
if(ain.getOpcode() == Opcodes.PUTSTATIC)
putstatic++;
else
getstatic++;
}
return containsArray && putstatic == 2 && getstatic == 2;
}
/**
* new and anewarray bytecodes take a String operand for the type of the object or array element
* so we hook them here. Note that new doesn't actually result in any instrumentation here; we
* just do a bit of book-keeping and do the instrumentation following the constructor call
* (because we're not allowed to touch the object until it is initialized).
*/
@Override
public void visitTypeInsn(int opcode, String typeName) {
if (opcode == Opcodes.NEW) {
// We can't actually tag this object right after allocation because it
// must be initialized with a ctor before we can touch it (Verifier
// enforces this). Instead, we just note it and tag following
// initialization.
super.visitTypeInsn(opcode, typeName);
++outstandingAllocs;
} else if (opcode == Opcodes.ANEWARRAY) {
super.visitInsn(Opcodes.DUP);
super.visitTypeInsn(opcode, typeName);
invokeRecordAllocation(typeName);
} else {
super.visitTypeInsn(opcode, typeName);
}
}
@Override
public void visitTypeInsn(final int opcode, final String type) {
Type objectType = Type.getObjectType(type);
switch (opcode) {
case Opcodes.NEW:
anew(objectType);
break;
case Opcodes.ANEWARRAY:
newarray(objectType);
break;
case Opcodes.CHECKCAST:
checkcast(objectType);
break;
case Opcodes.INSTANCEOF:
instanceOf(objectType);
break;
default:
throw new IllegalArgumentException();
}
}
@Override
public void visitTypeInsn(final int opcode, final String type) {
Type objectType = Type.getObjectType(type);
switch (opcode) {
case Opcodes.NEW:
anew(objectType);
break;
case Opcodes.ANEWARRAY:
newarray(objectType);
break;
case Opcodes.CHECKCAST:
checkcast(objectType);
break;
case Opcodes.INSTANCEOF:
instanceOf(objectType);
break;
default:
throw new IllegalArgumentException();
}
}
@Override
public void visitTypeInsn(int opcode, String type) {
String descriptor = convertToDescriptor(type);
switch (opcode) {
case Opcodes.NEW:
// This should be UNINITIALIZED(label). Okay for type inference.
pushDescriptor(descriptor);
break;
case Opcodes.ANEWARRAY:
pop();
pushDescriptor('[' + descriptor);
break;
case Opcodes.CHECKCAST:
pop();
pushDescriptor(descriptor);
break;
case Opcodes.INSTANCEOF:
pop();
push(InferredType.INT);
break;
default:
throw new RuntimeException("Unhandled opcode " + opcode);
}
super.visitTypeInsn(opcode, type);
}
/**
* @param opcode
* @param type
* @param s
*/
static void handleJVMTypeInsn ( int opcode, String type, JVMStackState s ) {
BaseType o;
switch ( opcode ) {
case Opcodes.NEW:
s.push(new ObjectReferenceConstant(false, Type.getObjectType(type), type.replace('/', '.')));
break;
case Opcodes.ANEWARRAY:
s.pop();
if ( type.charAt(0) == '[' ) {
s.push(new BasicVariable(Type.getObjectType("[" + type), "array", false)); //$NON-NLS-1$//$NON-NLS-2$
}
else {
s.push(new BasicVariable(Type.getObjectType("[L" + type + ";"), "array", false)); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
}
break;
case Opcodes.CHECKCAST:
if ( log.isDebugEnabled() ) {
log.debug("Checkcast " + type); //$NON-NLS-1$
}
o = s.pop();
if ( o != null ) {
o.addAlternativeType(Type.getObjectType(type));
s.push(o);
}
else {
s.clear();
}
break;
case Opcodes.INSTANCEOF:
o = s.pop();
if ( o != null ) {
o.addAlternativeType(Type.getObjectType(type));
}
s.push(new BasicConstant(Type.BOOLEAN_TYPE, "typeof " + o + " = " + type, ! ( o != null ) || o.isTainted())); //$NON-NLS-1$ //$NON-NLS-2$
break;
}
}
@Override
public AbstractInsnNode tryMatch(InstructionMatcher matcher, AbstractInsnNode now) {
if (now.getOpcode() != Opcodes.ANEWARRAY) {
return null;
}
TypeInsnNode typeInsnNode = (TypeInsnNode) now;
if (!(basic ? TransformerHelper.basicType(typeInsnNode.desc) : typeInsnNode.desc).equals(type)) {
return null;
}
return now.getNext();
}
@Override
public void visitCode()
{
super.visitCode();
if(methodData.hasHookAt(HookPosition.METHOD_START))
{
HookData hookData = methodData.getHook(HookPosition.METHOD_START);
super.visitLdcInsn(className + "." + methodName + "|start");
if(hookData.collectsParams())
{
super.visitIntInsn(Opcodes.BIPUSH, paramCount);
super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
for(byte i = 0; i < paramCount; i++)
{
super.visitInsn(Opcodes.DUP);
super.visitIntInsn(Opcodes.BIPUSH, i);
super.visitVarInsn(Opcodes.ALOAD, i);
super.visitInsn(Opcodes.AASTORE);
}
}
// TODO: Custom class path
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"tk/wurst_client/hooks/HookManager", "hook",
"(Ljava/lang/String;"
+ (hookData.collectsParams() ? "[Ljava/lang/Object;" : "")
+ ")V", false);
}
}
@Override
public void visitInsn(int opcode)
{
if(methodData.hasHookAt(HookPosition.METHOD_END) && opcode >= 172
&& opcode <= 177)
{
HookData hookData = methodData.getHook(HookPosition.METHOD_END);
super.visitLdcInsn(className + "." + methodName + "|end");
if(hookData.collectsParams())
{
super.visitIntInsn(Opcodes.BIPUSH, paramCount);
super.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
for(byte i = 0; i < paramCount; i++)
{
super.visitInsn(Opcodes.DUP);
super.visitIntInsn(Opcodes.BIPUSH, i);
super.visitVarInsn(Opcodes.ALOAD, i);
super.visitInsn(Opcodes.AASTORE);
}
}
// TODO: Custom class path
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"tk/wurst_client/hooks/HookManager", "hook",
"(Ljava/lang/String;"
+ (hookData.collectsParams() ? "[Ljava/lang/Object;" : "")
+ ")V", false);
}
super.visitInsn(opcode);
}
@Override
public void addDependencies(List<String> dependencyList) {
String t = type.replace('.', '_').replace('/', '_').replace('$', '_');
t = unarray(t);
actualType = t;
if(t != null && !dependencyList.contains(t)) {
dependencyList.add(t);
}
if(actualType == null) {
// primitive array
switch(type.charAt(type.length() - 1)) {
case 'I':
actualType = "JAVA_INT";
break;
case 'J':
actualType = "JAVA_LONG";
break;
case 'B':
actualType = "JAVA_BYTE";
break;
case 'S':
actualType = "JAVA_SHORT";
break;
case 'F':
actualType = "JAVA_FLOAT";
break;
case 'D':
actualType = "JAVA_DOUBLE";
break;
case 'Z':
actualType = "JAVA_BOOLEAN";
break;
case 'C':
actualType = "JAVA_CHAR";
break;
}
}
if(opcode == Opcodes.ANEWARRAY) {
if(type.startsWith("[")) {
int dim = 2;
String tt = type.substring(1);
while(tt.startsWith("[")) {
tt = tt.substring(1);
dim++;
}
ByteCodeClass.addArrayType(actualType, dim);
return;
}
ByteCodeClass.addArrayType(actualType, 1);
}
}
@Override
public void appendInstruction(StringBuilder b, List<Instruction> l) {
type = type.replace('.', '_').replace('/', '_').replace('$', '_');
b.append(" ");
switch(opcode) {
case Opcodes.NEW:
b.append("PUSH_POINTER(__NEW_");
b.append(type);
b.append("(threadStateData)); /* NEW */\n");
break;
case Opcodes.ANEWARRAY:
if(type.startsWith("[")) {
int dim = 2;
String t = type.substring(1);
while(t.startsWith("[")) {
t = t.substring(1);
dim++;
}
b.append(" SP--;\n PUSH_POINTER(allocArray(threadStateData, (*SP).data.i, &class_array");
b.append(dim);
b.append("__");
b.append(actualType);
b.append(", sizeof(JAVA_OBJECT), ");
b.append(dim);
b.append("));\n SP[-1].data.o->__codenameOneParentClsReference = &class_array");
b.append(dim);
b.append("__");
b.append(actualType);
b.append("; /* ANEWARRAY multi */\n");
break;
}
b.append("SP--;\n PUSH_POINTER(__NEW_ARRAY_");
b.append(actualType);
b.append("(threadStateData, SP[0].data.i));\n");
break;
case Opcodes.CHECKCAST:
b.append("BC_CHECKCAST(");
b.append(type);
b.append(");\n");
break;
case Opcodes.INSTANCEOF:
int pos = type.indexOf('[');
if(pos > -1) {
int count = 1;
while(type.charAt(pos + 1) == '[') {
count++;
pos++;
}
b.append("BC_INSTANCEOF(cn1_array_");
b.append(count);
b.append("_id_");
b.append(actualType);
} else {
b.append("BC_INSTANCEOF(cn1_class_id_");
b.append(actualType);
}
b.append(");\n");
break;
}
}