Example usage for org.objectweb.asm MethodVisitor visitInsn

List of usage examples for org.objectweb.asm MethodVisitor visitInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitInsn.

Prototype

public void visitInsn(final int opcode) 

Source Link

Document

Visits a zero operand instruction.

Usage

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();
}