List of usage examples for org.objectweb.asm MethodVisitor visitMethodInsn
public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor, final boolean isInterface)
From source file:com.tencent.tinker.build.auxiliaryclass.AuxiliaryClassInjectAdapter.java
License:Open Source License
@Override public void visitEnd() { // If method <clinit> and <init> are not found, we should generate a <clinit>. if (!this.isClInitExists && !this.isInitExists) { MethodVisitor mv = super.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode();/*from w w w.ja va2 s. co m*/ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "lineSeparator", "()Ljava/lang/String;", false); Label lblSkipInvalidInsn = new Label(); mv.visitJumpInsn(Opcodes.IFNONNULL, lblSkipInvalidInsn); mv.visitLdcInsn(Type.getType(this.auxiliaryClassDesc)); mv.visitVarInsn(Opcodes.ASTORE, 0); mv.visitLabel(lblSkipInvalidInsn); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } super.visitEnd(); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.DynamicBootstrapUnit.java
public void init() { ProgramValueTypeAdapter types = environment.getValueTypeAdapter(); BytecodeExpression classSource = types.constant(getEnvironment()); TypeWidget dynamicLinker = types.adaptInternal(DynamicLinker.class); FieldDefinition field = createField(dynamicLinker, "bootstrap"); field.addModifier(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL); MethodGenerator sl = createMethod("<clinit>"); sl.setModifier(Opcodes.ACC_STATIC);//www .ja v a 2s . c o m sl.add(classSource); sl.add(new BytecodeSequence() { @Override public void generate(CodeEmitter code) { final MethodVisitor mv = code.getMethodVisitor(); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Dynamic.class), "createDynamicLinker", MethodType.methodType(DynamicLinker.class, ASMClassSource.class).toMethodDescriptorString(), false); mv.visitFieldInsn(Opcodes.PUTSTATIC, Dynamic.DYNAMIC_INTERNAL_NAME, "bootstrap", Type.getDescriptor(DynamicLinker.class)); mv.visitInsn(Opcodes.RETURN); } }); MethodGenerator mgen = createStaticMethod(Dynamic.DYNAMIC_BOOTSTRAP_METHOD); TypeWidget callSite = types.adaptInternal(CallSite.class); TypeWidget lookup = types.adaptInternal(MethodHandles.Lookup.class); TypeWidget methodType = types.adaptInternal(MethodType.class); mgen.setReturnType(callSite); AssignableValue lu = mgen.addArgument("lookup", lookup); AssignableValue name = mgen.addArgument("name", BaseTypeAdapter.STRING); AssignableValue sig = mgen.addArgument("sig", methodType); final String desc = MethodType.methodType(CallSite.class, // ...that will return a CallSite object, ... MethodHandles.Lookup.class, // ... when given a lookup object, ... String.class, // ... the operation name, ... MethodType.class, // ... and the signature at the call site. DynamicLinker.class).toMethodDescriptorString(); mgen.add(lu.read()); mgen.add(name.read()); mgen.add(sig.read()); mgen.add(new BytecodeSequence() { @Override public void generate(CodeEmitter code) { final MethodVisitor mv = code.getMethodVisitor(); mv.visitFieldInsn(Opcodes.GETSTATIC, Dynamic.DYNAMIC_INTERNAL_NAME, "bootstrap", Type.getDescriptor(DynamicLinker.class)); mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(Dynamic.class), "link", desc, false); mv.visitInsn(Opcodes.ARETURN); } }); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ConstructInvocation.java
@Override protected void generate(Location loc, CodeEmitter code, List<BytecodeExpression> args) { Preconditions.checkArgument(args.size() == getArgumentTypes().size(), "exactInvoker argument length mismatch: %s != expected %s", args.size(), getArgumentTypes().size()); MethodVisitor mv = code.getMethodVisitor(); List<BytecodeExpression> pre = Lists.newArrayListWithCapacity(args.size()); CodeEmitter scope = code.createScope(); for (BytecodeExpression arg : args) { pre.add(scope.evaluateOnce(arg)); }/*from w w w . j av a 2 s. com*/ mv.visitTypeInsn(Opcodes.NEW, ownerInternalName); mv.visitInsn(Opcodes.DUP); for (BytecodeExpression arg : pre) { arg.generate(scope); } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, ownerInternalName, "<init>", desc, false); scope.endScope(); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ConstructorAdapter.java
@Override public void invokeSpecial(final Class<?> clazz, final List<BytecodeExpression> arguments) { final Type[] args = new Type[arguments.size()]; for (int i = 0; i < arguments.size(); ++i) { args[i] = arguments.get(i).getType().getJVMType(); }// w ww. j a v a2s.com unit.setSuperInit(new BytecodeSequence() { @Override public void generate(CodeEmitter code) { code.exec(code.getLocal("this")); for (BytecodeExpression e : arguments) { code.exec(e); } MethodVisitor mv = code.getMethodVisitor(); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(clazz), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, args), false); } }); }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression list(Location loc, final List<BytecodeExpression> args) { List<TypeWidget> types = Lists.newArrayList(); for (BytecodeExpression e : args) { types.add(e.getType());/*www. j a v a2 s . co m*/ } final TypeWidget unified = unify(types).boxed(); final ListTypeWidget out = new ListTypeWidget(NotNullableTypeWidget.create(unified)); return new BaseTypeExpression(out) { @Override public void generate(CodeEmitter code) { MethodVisitor mv = code.getMethodVisitor(); code.exec(out.construct(constant(args.size()))); for (BytecodeExpression expr : args) { Label skip = new Label(); mv.visitInsn(Opcodes.DUP); code.exec(expr); final TypeWidget type = expr.getType(); boolean nullable = code.cast(unified, type, skip); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Collection.class), "add", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Object.class)), true); if (nullable) { // we're either going to POP the DUPed List OR the result of add mv.visitLabel(skip); } mv.visitInsn(Opcodes.POP); } } }; }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression matches(Location loc, final BytecodeExpression left, final BytecodeExpression right) { return new BaseTypeExpression(BaseTypeAdapter.BOOLEAN) { @Override/*from w w w . j av a2s . c om*/ public void generate(CodeEmitter code) { Label done = new Label(); Label anyIsNull = new Label(); CodeEmitter.BinaryCoercion coerce = code.binaryCoercion(right, Pattern.class, left, CharSequence.class, anyIsNull, anyIsNull, anyIsNull); MethodVisitor mv = code.getMethodVisitor(); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Pattern.class), "matcher", Type.getMethodDescriptor(Type.getType(Matcher.class), Type.getType(CharSequence.class)), false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Matcher.class), "matches", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false); if (coerce.leftNullable || coerce.rightNullable) { mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(anyIsNull); mv.visitInsn(Opcodes.ICONST_0); mv.visitLabel(done); } } }; }
From source file:com.yahoo.yqlplus.engine.internal.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression in(Location loc, final BytecodeExpression left, final BytecodeExpression right) { return new BaseTypeExpression(BaseTypeAdapter.BOOLEAN) { @Override/*from ww w. j a v a 2 s . co m*/ public void generate(CodeEmitter code) { Label done = new Label(); Label anyIsNull = new Label(); CodeEmitter.BinaryCoercion coerce = code.binaryCoercion(right, Collection.class, left, Object.class, anyIsNull, anyIsNull, anyIsNull); MethodVisitor mv = code.getMethodVisitor(); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Collection.class), "contains", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Object.class)), true); if (coerce.leftNullable || coerce.rightNullable) { mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(anyIsNull); mv.visitInsn(Opcodes.ICONST_0); mv.visitLabel(done); } } }; }
From source file:com.yahoo.yqlplus.engine.internal.compiler.BytecodeArithmeticExpression.java
@Override public void generate(CodeEmitter code) { MethodVisitor mv = code.getMethodVisitor(); Label isNull = new Label(); TypeWidget mathType = getType().unboxed(); if (!mathType.isPrimitive() || op == ArithmeticOperation.POW) { mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(Maths.class), "INSTANCE", Type.getDescriptor(Maths.class)); mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(ArithmeticOperation.class), op.name(), Type.getDescriptor(ArithmeticOperation.class)); }/*w ww. j a va2 s . c om*/ CodeEmitter.Unification out = code.unifyAs(mathType, leftExpr, rightExpr, isNull, isNull, isNull); // now we have both sides unified as (if possible) a primitive type // compute the result if (mathType.isPrimitive()) { switch (op) { case ADD: mv.visitInsn(mathType.getJVMType().getOpcode(Opcodes.IADD)); break; case SUB: mv.visitInsn(mathType.getJVMType().getOpcode(Opcodes.ISUB)); break; case MULT: mv.visitInsn(mathType.getJVMType().getOpcode(Opcodes.IMUL)); break; case DIV: mv.visitInsn(mathType.getJVMType().getOpcode(Opcodes.IDIV)); break; case MOD: mv.visitInsn(mathType.getJVMType().getOpcode(Opcodes.IREM)); break; case POW: mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Maths.class), "binaryMath", Type.getMethodDescriptor(mathType.getJVMType(), Type.getType(ArithmeticOperation.class), mathType.getJVMType(), mathType.getJVMType()), false); break; default: throw new ProgramCompileException(loc, "Unknown BinaryMath operation: " + op); } } else if (mathType.getValueCoreType() == YQLCoreType.ANY) { String desc = Type.getMethodDescriptor(getType().getJVMType(), Type.getType(Maths.class), Type.getType(ArithmeticOperation.class), leftExpr.getType().boxed().getJVMType(), rightExpr.getType().boxed().getJVMType()); mv.visitInvokeDynamicInsn("dyn:callMethod:binaryMath", desc, Dynamic.H_DYNALIB_BOOTSTRAP); } else { throw new ProgramCompileException(loc, "Math operation %s is not defined for type %s", op, mathType.getJVMType()); } if (!getType().isPrimitive() && mathType.isPrimitive()) { code.box(mathType); } if (out.nullPossible) { Label done = new Label(); mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(isNull); if (!mathType.isPrimitive() || op == ArithmeticOperation.POW) { mv.visitInsn(Opcodes.POP2); } mv.visitInsn(Opcodes.ACONST_NULL); mv.visitLabel(done); } }
From source file:com.yahoo.yqlplus.engine.internal.compiler.CodeEmitter.java
public void emitStringSwitch(Map<String, Label> labels, Label defaultCase, boolean caseInsensitive) { MethodVisitor mv = getMethodVisitor(); if (caseInsensitive) { mv.visitFieldInsn(GETSTATIC, "java/util/Locale", "ENGLISH", "Ljava/util/Locale;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "toUpperCase", "(Ljava/util/Locale;)Ljava/lang/String;", false); }/* w w w.ja v a 2 s. c o m*/ mv.visitInsn(DUP); AssignableValue tmp = allocate(String.class); tmp.write(BaseTypeAdapter.STRING).generate(this); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "hashCode", "()I", false); Multimap<Integer, SwitchLabel> keys = ArrayListMultimap.create(); for (Map.Entry<String, Label> e : labels.entrySet()) { String name = e.getKey(); if (caseInsensitive) { name = name.toUpperCase(Locale.ENGLISH); } keys.put(name.hashCode(), new SwitchLabel(name, e.getValue())); } List<Integer> codes = Lists.newArrayList(keys.keySet()); Collections.sort(codes); int[] k = new int[codes.size()]; Label[] kl = new Label[codes.size()]; for (int i = 0; i < k.length; ++i) { k[i] = codes.get(i); kl[i] = new Label(); } mv.visitLookupSwitchInsn(defaultCase, k, kl); for (int i = 0; i < k.length; ++i) { mv.visitLabel(kl[i]); for (SwitchLabel switchLabel : keys.get(k[i])) { mv.visitLdcInsn(switchLabel.name); tmp.read().generate(this); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); mv.visitJumpInsn(IFNE, switchLabel.label); } mv.visitJumpInsn(GOTO, defaultCase); } }
From source file:com.yahoo.yqlplus.engine.internal.compiler.CompareExpression.java
@Override public void generate(CodeEmitter code) { // a bit of a hack; should not need to go to dynamic invocation for this unless one arg is ANY Label done = new Label(); MethodVisitor mv = code.getMethodVisitor(); Label leftNull = new Label(); Label rightNull = new Label(); Label bothNull = new Label(); CodeEmitter.Unification unified = code.unifiedEmit(leftExpr, rightExpr, leftNull, rightNull, bothNull); if (unified.type.isPrimitive()) { emitPrimitiveCompare(code, unified.type); } else {//from w w w. j a v a 2s. c o m // TODO: statically determine if the unified type is Comparable -- for now treat them all like "any" CodeEmitter scope = code.createScope(); MethodVisitor mv2 = scope.getMethodVisitor(); AssignableValue right = scope.allocate(unified.type); AssignableValue left = scope.allocate(unified.type); scope.exec(right.write(unified.type)); scope.exec(left.write(unified.type)); scope.exec(left.read()); Label leftIsNotComparable = new Label(); scope.emitInstanceCheck(unified.type, Comparable.class, leftIsNotComparable); scope.exec(right.read()); mv2.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Comparable.class), "compareTo", Type.getMethodDescriptor(Type.INT_TYPE, Type.getType(Object.class)), true); scope.gotoExitScope(); mv2.visitLabel(leftIsNotComparable); scope.exec(scope.getLocal("$program").read()); scope.exec(left.read()); scope.emitIntConstant((loc != null) ? loc.getLineNumber() : -1); scope.emitIntConstant((loc != null) ? loc.getCharacterOffset() : 0); mv2.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(ProgramInvocation.class), "notComparable", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object.class), Type.INT_TYPE, Type.INT_TYPE), false); // this bit is not reachable, notComparable throws mv2.visitInsn(Opcodes.ICONST_0); mv2.visitJumpInsn(Opcodes.GOTO, done); scope.endScope(); } if (unified.nullPossible) { mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(leftNull); mv.visitInsn(Opcodes.ICONST_M1); mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(rightNull); mv.visitInsn(Opcodes.ICONST_1); mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(bothNull); mv.visitInsn(Opcodes.ICONST_0); } mv.visitLabel(done); }