List of usage examples for org.objectweb.asm MethodVisitor visitInsn
public void visitInsn(final int opcode)
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)); }/* www .j a v a 2 s. c o m*/ 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.ExpressionHandler.java
@Override public BytecodeExpression coalesce(Location loc, final List<BytecodeExpression> inputs) { List<TypeWidget> widgets = Lists.newArrayList(); for (BytecodeExpression expr : inputs) { widgets.add(expr.getType());/*from w w w . j ava2s. c om*/ } TypeWidget output = unify(widgets); return new BaseTypeExpression(output) { @Override public void generate(CodeEmitter code) { Label done = new Label(); MethodVisitor mv = code.getMethodVisitor(); boolean lastNullable = true; for (BytecodeExpression expr : inputs) { Label isNull = new Label(); code.exec(expr); if (code.cast(getType(), expr.getType(), isNull)) { mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(isNull); } else { lastNullable = false; break; } } if (lastNullable) { mv.visitInsn(Opcodes.ACONST_NULL); } mv.visitLabel(done); } }; }
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());//from www.ja v a2 s . c o 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 . jav a2 s . c o m*/ 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 www . jav a 2 s . c o 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.bytecode.types.gambit.ExpressionHandler.java
@Override public BytecodeExpression fallback(Location loc, final BytecodeExpression primary, final BytecodeExpression caught) { TypeWidget unified = unify(primary.getType(), caught.getType()); return new BaseTypeExpression(unified) { @Override/*w ww . j a va2s . co m*/ public void generate(CodeEmitter code) { MethodVisitor mv = code.getMethodVisitor(); final Label start = new Label(); final Label endCatch = new Label(); final Label handler = new Label(); Label done = new Label(); // this probably should not be catching throwable and instead should be catching Exception // or permit certain Errors through only mv.visitTryCatchBlock(start, endCatch, handler, "java/lang/Throwable"); mv.visitLabel(start); code.exec(primary); Label isNull = new Label(); boolean maybeNull = code.cast(getType(), primary.getType(), isNull); mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(endCatch); mv.visitLabel(handler); mv.visitInsn(Opcodes.POP); if (maybeNull) { mv.visitLabel(isNull); } code.exec(caught); code.cast(getType(), caught.getType()); 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 w w. j ava 2 s . c o m*/ 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.BytecodeNegateExpression.java
@Override public void generate(CodeEmitter code) { MethodVisitor mv = code.getMethodVisitor(); Label isNull = new Label(); TypeWidget mathType = getType().unboxed(); if (!mathType.isPrimitive()) { mv.visitFieldInsn(Opcodes.GETSTATIC, Type.getInternalName(Maths.class), "INSTANCE", Type.getDescriptor(Maths.class)); }//from w ww . j a va 2 s. c om boolean maybeNull = code.cast(mathType, leftExpr.getType(), isNull); // compute the result if (mathType.isPrimitive()) { mv.visitInsn(mathType.getJVMType().getOpcode(Opcodes.INEG)); } else if (mathType.getValueCoreType() == YQLCoreType.ANY) { String desc = Type.getMethodDescriptor(getType().getJVMType(), Type.getType(Maths.class), leftExpr.getType().getJVMType()); mv.visitInvokeDynamicInsn("dyn:callMethod:negate", desc, Dynamic.H_DYNALIB_BOOTSTRAP); } else { throw new ProgramCompileException(loc, "Math operation NEGATE is not defined for type %s", mathType.getJVMType()); } if (!getType().isPrimitive() && mathType.isPrimitive()) { code.box(mathType); } if (maybeNull) { Label done = new Label(); mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(isNull); 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); }// www .j a 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.CodeEmitter.java
public void swap(TypeWidget top, TypeWidget previous) { MethodVisitor mv = getMethodVisitor(); switch (top.getJVMType().getSize()) { case 1:/*from ww w. java 2 s. co m*/ switch (previous.getJVMType().getSize()) { case 1: // 1, 1 mv.visitInsn(Opcodes.SWAP); return; case 2: // 2, 1 // {value3, value2}, value1 value1, {value3, value2}, value1 mv.visitInsn(Opcodes.DUP_X2); // value1, {value3, value2} mv.visitInsn(Opcodes.POP); return; } break; case 2: switch (previous.getJVMType().getSize()) { case 1: // 1, 2 // value3, {value2, value1} {value2, value1}, value3, {value2, value1} mv.visitInsn(Opcodes.DUP2_X1); // {value2, value1}, value3 mv.visitInsn(Opcodes.POP2); return; case 2: // {value4, value3}, {value2, value1} {value2, value1}, {value4, value3}, {value2, value1} mv.visitInsn(Opcodes.DUP2_X2); // {value2, value1}, {value4, value3} mv.visitInsn(Opcodes.POP2); return; } break; } throw new UnsupportedOperationException(); }