下面列出了org.objectweb.asm.Opcodes# ACONST_NULL 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static AbstractInsnNode getDefaultValue(Type type) {
switch (type.getSort()) {
case Type.BOOLEAN:
case Type.CHAR:
case Type.BYTE:
case Type.SHORT:
case Type.INT:
return ASMUtils.getNumberInsn(0);
case Type.FLOAT:
return ASMUtils.getNumberInsn(0f);
case Type.LONG:
return ASMUtils.getNumberInsn(0L);
case Type.DOUBLE:
return ASMUtils.getNumberInsn(0d);
case Type.OBJECT:
return new InsnNode(Opcodes.ACONST_NULL);
default:
throw new AssertionError();
}
}
public static AbstractInsnNode getRandomValue(Type type) {
switch (type.getSort()) {
case Type.BOOLEAN:
return ASMUtils.getNumberInsn(RandomUtils.getRandomInt(0, 2));
case Type.CHAR:
return ASMUtils.getNumberInsn(RandomUtils.getRandomInt(Character.MIN_VALUE, Character.MAX_VALUE));
case Type.BYTE:
return ASMUtils.getNumberInsn(RandomUtils.getRandomInt(Byte.MIN_VALUE, Byte.MAX_VALUE));
case Type.SHORT:
return ASMUtils.getNumberInsn(RandomUtils.getRandomInt(Short.MIN_VALUE, Short.MAX_VALUE));
case Type.INT:
return ASMUtils.getNumberInsn(RandomUtils.getRandomInt());
case Type.FLOAT:
return ASMUtils.getNumberInsn(RandomUtils.getRandomFloat());
case Type.LONG:
return ASMUtils.getNumberInsn(RandomUtils.getRandomLong());
case Type.DOUBLE:
return ASMUtils.getNumberInsn(RandomUtils.getRandomDouble());
case Type.ARRAY:
case Type.OBJECT:
return new InsnNode(Opcodes.ACONST_NULL);
default:
throw new AssertionError();
}
}
private void insert() {
InsnList trInsns = transformerNode.instructions;
AbstractInsnNode node = trInsns.getLast();
while (true) {
if (node == null)
break;
if (node instanceof LabelNode) {
node = node.getPrevious();
continue;
} else if (node.getOpcode() == Opcodes.RETURN) {
trInsns.remove(node);
} else if (node.getOpcode() == Opcodes.ATHROW && node.getPrevious().getOpcode() == Opcodes.ACONST_NULL) {
AbstractInsnNode prev = node.getPrevious();
trInsns.remove(node);
trInsns.remove(prev);
}
break;
}
resultNode.instructions.insert(trInsns);
}
private void dupStackElementBeforeSignatureArgs(final String sig) {
final Label beginScopeLabel = new Label();
final Label endScopeLabel = new Label();
super.visitLabel(beginScopeLabel);
Type[] argTypes = Type.getArgumentTypes(sig);
int[] args = new int[argTypes.length];
for (int i = argTypes.length - 1; i >= 0; --i) {
args[i] = newLocal(argTypes[i], beginScopeLabel, endScopeLabel);
super.visitVarInsn(argTypes[i].getOpcode(Opcodes.ISTORE), args[i]);
}
super.visitInsn(Opcodes.DUP);
for (int i = 0; i < argTypes.length; ++i) {
int op = argTypes[i].getOpcode(Opcodes.ILOAD);
super.visitVarInsn(op, args[i]);
if (op == Opcodes.ALOAD) {
super.visitInsn(Opcodes.ACONST_NULL);
super.visitVarInsn(Opcodes.ASTORE, args[i]);
}
}
super.visitLabel(endScopeLabel);
}
@Override
public boolean isConstant() {
switch (opcode) {
case Opcodes.ACONST_NULL:
case Opcodes.ICONST_0:
case Opcodes.ICONST_1:
case Opcodes.ICONST_2:
case Opcodes.ICONST_3:
case Opcodes.ICONST_4:
case Opcodes.ICONST_5:
case Opcodes.ICONST_M1:
case Opcodes.FCONST_0:
case Opcodes.FCONST_1:
case Opcodes.FCONST_2:
case Opcodes.DCONST_0:
case Opcodes.DCONST_1:
case Opcodes.LCONST_0:
case Opcodes.LCONST_1:
case Opcodes.LDC:
return true;
}
return super.isConstant();
}
protected void onMethodEnter() {
if (done || ! isSynchronized()) return;
has_monitor_operation = true;
super.visitInsn(Opcodes.ACONST_NULL);
super.pop();
methodStartLabel = super.mark();
super.visitMethodInsn(Opcodes.INVOKESTATIC, className, LOG_INTERNAL_ENTER_METHOD, LOG_CLASS_SIGNATURE);
}
@Override
public void generate(CodeEmitter code) {
// VOID, BOOLEAN, CHAR, BYTE, SHORT, INT, FLOAT, LONG, DOUBLE, ARRAY, OBJECT or METHOD.
int opcode;
switch (getType().getJVMType().getSort()) {
case Type.VOID:
case Type.METHOD:
throw new UnsupportedOperationException("Unsupported NullExpr type: " + getType());
case Type.BOOLEAN:
case Type.SHORT:
case Type.INT:
case Type.CHAR:
opcode = Opcodes.ICONST_0;
break;
case Type.FLOAT:
opcode = Opcodes.FCONST_0;
break;
case Type.LONG:
opcode = Opcodes.LCONST_0;
break;
case Type.DOUBLE:
opcode = Opcodes.DCONST_0;
break;
case Type.ARRAY:
case Type.OBJECT:
opcode = Opcodes.ACONST_NULL;
break;
default:
throw new UnsupportedOperationException("Unknown NullExpr type: " + getType());
}
code.getMethodVisitor().visitInsn(opcode);
if (opcode == Opcodes.ACONST_NULL) {
code.cast(getType(), AnyTypeWidget.getInstance());
}
}
public InsnValue createConstant(AbstractInsnNode insn) throws AnalyzerException {
switch (insn.getOpcode()) {
case Opcodes.ACONST_NULL:
return InsnValue.NULL_REFERENCE_VALUE;
case Opcodes.ICONST_M1:
case Opcodes.ICONST_0:
case Opcodes.ICONST_1:
case Opcodes.ICONST_2:
case Opcodes.ICONST_3:
case Opcodes.ICONST_4:
case Opcodes.ICONST_5:
case Opcodes.BIPUSH:
case Opcodes.SIPUSH:
return InsnValue.intValue(insn);
case Opcodes.LCONST_0:
case Opcodes.LCONST_1:
return InsnValue.longValue(insn.getOpcode());
case Opcodes.FCONST_0:
case Opcodes.FCONST_1:
case Opcodes.FCONST_2:
return InsnValue.floatValue(insn.getOpcode());
case Opcodes.DCONST_0:
case Opcodes.DCONST_1:
return InsnValue.doubleValue(insn.getOpcode());
case Opcodes.LDC:
Object obj = ((LdcInsnNode) insn).cst;
if (obj instanceof Type) {
return new InsnValue((Type) obj);
} else {
Type t = Type.getType(obj.getClass());
int sort = t.getSort();
// Non-included types:
// Type.ARRAY
// Type.VOID
// Type.METHOD
switch (sort) {
case Type.BOOLEAN:
return InsnValue.intValue((int) obj);
case Type.CHAR:
return InsnValue.charValue((char) obj);
case Type.BYTE:
return InsnValue.byteValue((byte) obj);
case Type.SHORT:
return InsnValue.shortValue((short) obj);
case Type.INT:
return InsnValue.intValue((int) obj);
case Type.FLOAT:
return InsnValue.floatValue((float) obj);
case Type.LONG:
return InsnValue.longValue((long) obj);
case Type.DOUBLE:
return InsnValue.doubleValue((double) obj);
case Type.OBJECT:
return new InsnValue(t, obj);
}
return new InsnValue(t);
}
case Opcodes.NEW:
return new InsnValue(Type.getType(((TypeInsnNode) insn).desc));
case Opcodes.JSR:
// TODO: IDK if this is right.
return InsnValue.REFERENCE_VALUE;
}
return null;
}
private static boolean isParameterSetToNull(AbstractInsnNode node) throws IllegalArgumentException {
if (node instanceof InsnNode && Opcodes.ACONST_NULL == node.getOpcode()) {
throw new IllegalArgumentException("Parameter set as Null");
}
return false;
}
/**
* Returns whether a given instruction can be used to push argument of {@code type} on stack.
*/
private /* static */ boolean isPushForType(AbstractInsnNode insn, Type type) {
int opcode = insn.getOpcode();
if (opcode == type.getOpcode(Opcodes.ILOAD)) {
return true;
}
// b/62060793: AsyncAwait rewrites bytecode to convert java methods into state machine with
// support of lambdas. Constant zero values are pushed on stack for all yet uninitialized
// local variables. And SIPUSH instruction is used to advance an internal state of a state
// machine.
switch (type.getSort()) {
case Type.BOOLEAN:
return opcode == Opcodes.ICONST_0 || opcode == Opcodes.ICONST_1;
case Type.BYTE:
case Type.CHAR:
case Type.SHORT:
case Type.INT:
return opcode == Opcodes.SIPUSH
|| opcode == Opcodes.ICONST_0
|| opcode == Opcodes.ICONST_1
|| opcode == Opcodes.ICONST_2
|| opcode == Opcodes.ICONST_3
|| opcode == Opcodes.ICONST_4
|| opcode == Opcodes.ICONST_5
|| opcode == Opcodes.ICONST_M1;
case Type.LONG:
return opcode == Opcodes.LCONST_0 || opcode == Opcodes.LCONST_1;
case Type.FLOAT:
return opcode == Opcodes.FCONST_0
|| opcode == Opcodes.FCONST_1
|| opcode == Opcodes.FCONST_2;
case Type.DOUBLE:
return opcode == Opcodes.DCONST_0 || opcode == Opcodes.DCONST_1;
case Type.OBJECT:
case Type.ARRAY:
return opcode == Opcodes.ACONST_NULL;
default:
// Support for BIPUSH and LDC* opcodes is not implemented as there is no known use case.
return false;
}
}