Example usage for org.objectweb.asm Opcodes INVOKESPECIAL

List of usage examples for org.objectweb.asm Opcodes INVOKESPECIAL

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes INVOKESPECIAL.

Prototype

int INVOKESPECIAL

To view the source code for org.objectweb.asm Opcodes INVOKESPECIAL.

Click Source Link

Usage

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

public static byte[] compileFunc(TokenSource<RPNToken> source, String variable) throws ParsingError {
    // initialize class
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

    writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/github/rgcjonas/kuemmelgtr/jit/BogusName", null,
            CompiledClassBase.class.getName().replace('.', '/'),
            new String[] { Evaluator.Function.class.getName().replace('.', '/') });

    // create constructor
    MethodVisitor construct = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    construct.visitCode();//from   ww  w  .ja  v a2s  .co m
    construct.visitVarInsn(Opcodes.ALOAD, 0);
    construct.visitMethodInsn(Opcodes.INVOKESPECIAL, CompiledClassBase.class.getName().replace('.', '/'),
            "<init>", "()V");
    construct.visitInsn(Opcodes.RETURN);
    construct.visitMaxs(0, 0);
    construct.visitEnd();

    MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "evaluate", "(D)D", null,
            new String[] { "com/github/rgcjonas/kuemmelgtr/core/RuntimeError" });

    compileCommon(source, method, variable);

    writer.visitEnd();
    return writer.toByteArray();
}

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

public static byte[] compileBasic(TokenSource<RPNToken> source) throws ParsingError {
    // initialize class
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

    writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/github/rgcjonas/kuemmelgtr/jit/BogusName", null,
            CompiledClassBase.class.getName().replace('.', '/'),
            new String[] { Evaluator.Basic.class.getName().replace('.', '/') });

    // create constructor
    MethodVisitor construct = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    construct.visitCode();//from   w ww .jav  a2  s . c  o  m
    construct.visitVarInsn(Opcodes.ALOAD, 0);
    construct.visitMethodInsn(Opcodes.INVOKESPECIAL, CompiledClassBase.class.getName().replace('.', '/'),
            "<init>", "()V");
    construct.visitInsn(Opcodes.RETURN);
    construct.visitMaxs(0, 0);
    construct.visitEnd();

    MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "evaluate", "()D", null,
            new String[] { "com/github/rgcjonas/kuemmelgtr/core/ParsingError",
                    "com/github/rgcjonas/kuemmelgtr/core/RuntimeError" });

    compileCommon(source, method, null);

    writer.visitEnd();
    return writer.toByteArray();
}

From source file:com.google.code.jconts.instrument.gen.AsyncMethodAdapter.java

License:Apache License

@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
    checkProlog();/*from   w  w w  .java 2  s.  co m*/

    if (opcode == Opcodes.INVOKESTATIC && ASYNC_NAME.equals(owner) && ARETURN_NAME.equals(name)) {

        if (ARETURN_VOID_DESC.equals(desc)) {
            mv.visitInsn(Opcodes.ACONST_NULL);
        }

        // state variable
        target.visitVarInsn(Opcodes.ALOAD, info.isStatic() ? 0 : 1);
        mv.visitFieldInsn(Opcodes.GETFIELD, info.stateClassName, CONTINUATION_FIELD, CONTINUATION_DESC);
        mv.visitInsn(Opcodes.SWAP);
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, CONTINUATION_NAME, CONTINUATION_INVOKE_NAME,
                CONTINUATION_INVOKE_DESC);

        // Will be dropped while replacing ARETURN with RETURN.
        // FIXME: Should verify this value is NOT used.
        mv.visitInsn(Opcodes.ACONST_NULL);
        return;
    }
    if (opcode == Opcodes.INVOKESTATIC && ASYNC_NAME.equals(owner) && AWAIT_NAME.equals(name)
            && AWAIT_DESC.equals(desc)) {

        // Computation<T> is on stack

        // FIXME: ...
        // if (stack.size() != 1) {
        // throw new IllegalStateException(
        // "Stack preserving is not supported!");
        // }

        int index = dispatchTable.size();

        // Save state
        List<Type> l = new ArrayList<Type>(locals);
        if (!info.isStatic()) {
            l.remove(0);
        }

        // state.varX = locX
        String[] vars = info.tracker.stateFields(l.toArray(new Type[0]));
        for (int i = 0; i < vars.length; ++i) {
            // state variable
            target.visitVarInsn(Opcodes.ALOAD, info.isStatic() ? 0 : 1);
            mv.visitVarInsn(l.get(i).getOpcode(Opcodes.ILOAD), i + info.thisOffset);
            mv.visitFieldInsn(Opcodes.PUTFIELD, info.stateClassName, vars[i], l.get(i).getDescriptor());
        }

        // Create instance of continuation
        // new Continuation([this, ]state, index);
        mv.visitTypeInsn(Opcodes.NEW, info.continuationClassName);
        mv.visitInsn(Opcodes.DUP);

        // "this' for new Continuation([this, ]state, index)
        if (!info.isStatic()) {
            mv.visitVarInsn(Opcodes.ALOAD, 0);
        }

        // state and index
        target.visitVarInsn(Opcodes.ALOAD, 0 + info.thisOffset);
        mv.visitIntInsn(Opcodes.BIPUSH, index);

        String ctorDesc;
        if (info.isStatic()) {
            ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType, Type.INT_TYPE });
        } else {
            ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE,
                    new Type[] { Type.getObjectType(info.owner), info.stateType, Type.INT_TYPE });
        }
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, info.continuationClassName, CTOR_NAME, ctorDesc);

        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, COMPUTATION_NAME, COMPUTATION_EXECUTE_NAME,
                COMPUTATION_EXECUTE_DESC);
        super.visitInsn(Opcodes.RETURN);

        // Restore state
        // mv.visitFrame(Opcodes.F_SAME, 0, new Object[0], 0, new
        // Object[0]);
        Label label = new Label();

        int invokeIndex = dispatchTable.size();
        dispatchTable.add(label); // for invoke
        dispatchTable.add(label); // for setException
        mv.visitLabel(label);
        for (int i = 0; i < vars.length; ++i) {
            // state variable
            target.visitVarInsn(Opcodes.ALOAD, info.isStatic() ? 0 : 1);
            mv.visitFieldInsn(Opcodes.GETFIELD, info.stateClassName, vars[i], l.get(i).getDescriptor());
            mv.visitVarInsn(l.get(i).getOpcode(Opcodes.ISTORE), i + info.thisOffset);
        }

        // if (index == invokeIndex) goto invokeLabel;
        Label invokeLabel = new Label();
        target.visitVarInsn(Opcodes.ILOAD, 1 + info.thisOffset);
        mv.visitIntInsn(Opcodes.BIPUSH, invokeIndex);
        mv.visitJumpInsn(Opcodes.IF_ICMPEQ, invokeLabel);

        // Throw exception
        target.visitVarInsn(Opcodes.ALOAD, info.isStatic() ? 0 : 1);
        mv.visitFieldInsn(Opcodes.GETFIELD, info.stateClassName, "exception", THROWABLE_DESC);
        mv.visitInsn(Opcodes.ATHROW);

        // Push result value
        // invokeLabel:
        mv.visitLabel(invokeLabel);
        target.visitVarInsn(Opcodes.ALOAD, info.isStatic() ? 0 : 1);
        mv.visitFieldInsn(Opcodes.GETFIELD, info.stateClassName, "result", OBJECT_DESC);
        return;
    }
    super.visitMethodInsn(opcode, owner, name, desc);
}

From source file:com.google.code.jconts.instrument.gen.ComputationClassGenerator.java

License:Apache License

private void generateConstructor(ClassVisitor cv) {
    final String name = info.computationClassName;
    final Type outerType = Type.getObjectType(info.owner);

    // Constructor have form either <init>(OuterClass this$0, State state)
    // or <init>(State state)
    String ctorDesc;//from   w  w  w.ja  va 2 s. c om
    if (info.isStatic()) {
        ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType });
    } else {
        cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "this$0", 'L' + info.owner + ';', null, null);

        ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { outerType, info.stateType });
    }

    // Generate constructor
    MethodVisitor mv = cv.visitMethod(0, CTOR_NAME, ctorDesc, null, null);
    mv.visitCode();
    Label start = new Label();
    Label end = new Label();
    mv.visitLabel(start);

    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, OBJECT_NAME, CTOR_NAME, DEFAULT_CTOR_DESC);

    // Save state field
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitVarInsn(Opcodes.ALOAD, 1 + info.thisOffset);
    mv.visitFieldInsn(Opcodes.PUTFIELD, name, "state", stateDesc);

    // Save outer this
    if (!info.isStatic()) {
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitFieldInsn(Opcodes.PUTFIELD, name, "this$0", outerType.getDescriptor());
    }
    mv.visitInsn(Opcodes.RETURN);
    mv.visitLabel(end);

    mv.visitLocalVariable("this", 'L' + name + ';', signature, start, end, 0);
    if (!info.isStatic()) {
        mv.visitLocalVariable("this$0", outerType.getDescriptor(), null, start, end, 1);
    }
    mv.visitLocalVariable("state", stateDesc, null, start, end, 1 + info.thisOffset);

    mv.visitMaxs(2, 2 + info.thisOffset);
    mv.visitEnd();
}

From source file:com.google.code.jconts.instrument.gen.ContinuationClassGenerator.java

License:Apache License

private void generateConstructor(ClassVisitor cv) {
    final String name = info.continuationClassName;
    final Type outerType = Type.getObjectType(info.owner);

    // Constructor have form either <init>(OuterClass this$0, State state,
    // int index)
    // or <init>(State state, int index)
    String ctorDesc;/*from www  .java 2s . c o m*/
    if (info.isStatic()) {
        ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType, Type.INT_TYPE });
    } else {
        cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "this$0", 'L' + info.owner + ';', null, null);

        ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE,
                new Type[] { outerType, info.stateType, Type.INT_TYPE });
    }

    // Generate constructor
    MethodVisitor mv = cv.visitMethod(0, CTOR_NAME, ctorDesc, null, null);
    mv.visitCode();
    Label start = new Label();
    Label end = new Label();
    mv.visitLabel(start);

    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, OBJECT_NAME, CTOR_NAME, DEFAULT_CTOR_DESC);

    // Save state field
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitVarInsn(Opcodes.ALOAD, 1 + info.thisOffset);
    mv.visitFieldInsn(Opcodes.PUTFIELD, name, "state", stateDesc);

    // Save index field
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitVarInsn(Opcodes.ILOAD, 2 + info.thisOffset);
    mv.visitFieldInsn(Opcodes.PUTFIELD, name, "index", "I");

    // Save outer this
    if (!info.isStatic()) {
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitFieldInsn(Opcodes.PUTFIELD, name, "this$0", outerType.getDescriptor());
    }
    mv.visitInsn(Opcodes.RETURN);
    mv.visitLabel(end);

    mv.visitLocalVariable("this", 'L' + name + ';', signature, start, end, 0);
    if (!info.isStatic()) {
        mv.visitLocalVariable("this$0", outerType.getDescriptor(), null, start, end, 1);
    }
    mv.visitLocalVariable("state", stateDesc, null, start, end, 1 + info.thisOffset);
    mv.visitLocalVariable("index", "I", null, start, end, 2 + info.thisOffset);

    mv.visitMaxs(2, 3 + info.thisOffset);
    mv.visitEnd();
}

From source file:com.google.code.jconts.instrument.gen.CoroutineMethodAdapter.java

License:Apache License

@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
    super.visitMethodInsn(opcode, owner, name, desc);

    if (opcode == Opcodes.INVOKESPECIAL) {
        return;/*from   w  w w  .ja  v a 2  s  . c  o  m*/
    }

    if (Type.getReturnType(desc) == Type.VOID_TYPE) {
        super.visitMethodInsn(Opcodes.INVOKESTATIC, COROUTINES_NAME, COROUTINES_YIELD_NAME,
                COROUTINES_YIELD_DESC);
        super.visitMethodInsn(Opcodes.INVOKESTATIC, Constants.ASYNC_NAME, AWAIT_NAME, AWAIT_DESC);
        super.visitInsn(Opcodes.POP);
    }
}

From source file:com.google.code.jconts.instrument.gen.StateClassGenerator.java

License:Apache License

public void accept(TransformationContext context) {
    ClassVisitor cv = context.writer();/*from w  w  w .  j a  va 2  s .c  o m*/

    final String name = info.stateClassName;

    cv.visit(Opcodes.V1_6, Opcodes.ACC_FINAL /*| Opcodes.ACC_SYNTHETIC*/, name, null, OBJECT_NAME, null);

    cv.visitSource(info.ownerSource, null);
    cv.visitOuterClass(info.owner, null, null);

    cv.visitField(0/*Opcodes.ACC_SYNTHETIC*/, CONTINUATION_FIELD, CONTINUATION_DESC,
            'L' + CONTINUATION_NAME + '<' + info.valueSignature + ">;", null);

    // Local variables state
    List<String> names = info.tracker.getFieldNames();
    List<Type> types = info.tracker.getFieldTypes();
    for (int i = 0; i < names.size(); ++i) {
        cv.visitField(0/*Opcodes.ACC_SYNTHETIC*/, names.get(i), types.get(i).getDescriptor(), null, null);
    }

    // Return value variable
    cv.visitField(0/*Opcodes.ACC_SYNTHETIC*/, "result", OBJECT_DESC, null, null);
    cv.visitField(0/*Opcodes.ACC_SYNTHETIC*/, "exception", THROWABLE_DESC, null, null);

    // Generate constructor
    MethodVisitor mv = cv.visitMethod(0, CTOR_NAME, DEFAULT_CTOR_DESC, null, null);
    mv.visitCode();
    Label start = new Label();
    Label end = new Label();
    mv.visitLabel(start);
    mv.visitLineNumber(0, start);

    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, OBJECT_NAME, CTOR_NAME, DEFAULT_CTOR_DESC);
    mv.visitInsn(Opcodes.RETURN);
    mv.visitLabel(end);

    mv.visitLocalVariable("this", 'L' + name + ';', null, start, end, 0);

    mv.visitMaxs(1, 1);
    mv.visitEnd();

    cv.visitEnd();
}

From source file:com.google.code.jconts.instrument.gen.TramplineMethodGenerator.java

License:Apache License

public void accept(ClassVisitor cv) {
    MethodVisitor mv = cv.visitMethod(info.access, info.name, info.desc, info.signature, info.exceptions);
    mv.visitCode();//www  . j  ava  2  s.  c o m
    mv.visitTypeInsn(Opcodes.NEW, info.computationClassName);
    mv.visitInsn(Opcodes.DUP);

    // "this' for new Computation(this, state)
    if (!info.isStatic()) {
        mv.visitVarInsn(Opcodes.ALOAD, 0);
    }

    // new State()
    mv.visitTypeInsn(Opcodes.NEW, info.stateClassName);
    mv.visitInsn(Opcodes.DUP);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, info.stateClassName, CTOR_NAME, DEFAULT_CTOR_DESC);

    // state.varX = argX
    String[] names = info.entryLocalsVars;
    for (int i = 0; i < info.entryLocals.length; ++i) {
        mv.visitInsn(Opcodes.DUP);
        mv.visitVarInsn(info.entryLocals[i].getOpcode(Opcodes.ILOAD), i + info.thisOffset);
        mv.visitFieldInsn(Opcodes.PUTFIELD, info.stateClassName, names[i], info.entryLocals[i].getDescriptor());
    }

    // new Computation(this, state);
    String ctorDesc;
    if (info.isStatic()) {
        ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType });
    } else {
        ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE,
                new Type[] { Type.getObjectType(info.owner), info.stateType });
    }
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, info.computationClassName, CTOR_NAME, ctorDesc);

    mv.visitInsn(Opcodes.ARETURN);
    mv.visitMaxs(info.isStatic() ? 5 : 6,
            info.isStatic() ? info.entryLocals.length : info.entryLocals.length + 1);
    mv.visitEnd();
}

From source file:com.google.devtools.build.android.desugar.BytecodeTypeInference.java

License:Open Source License

@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
    if (opcode == Opcodes.INVOKESPECIAL && "<init>".equals(name)) {
        int argumentSize = (Type.getArgumentsAndReturnSizes(desc) >> 2);
        InferredType receiverType = getTypeOfOperandFromTop(argumentSize - 1);
        if (receiverType.isUninitialized()) {
            InferredType realType = InferredType.createNonUninitializedType('L' + owner + ';');
            replaceUninitializedTypeInStack(receiverType, realType);
        }/*from w w w  .java 2s  .  co  m*/
    }
    switch (opcode) {
    case Opcodes.INVOKESPECIAL:
    case Opcodes.INVOKEVIRTUAL:
    case Opcodes.INVOKESTATIC:
    case Opcodes.INVOKEINTERFACE:
        popDescriptor(desc);
        if (opcode != Opcodes.INVOKESTATIC) {
            pop(); // Pop receiver.
        }
        pushDescriptor(desc);
        break;
    default:
        throw new RuntimeException(String.format("Unhandled opcode %s, owner=%s, name=%s, desc=%s, itf=%s",
                opcode, owner, name, desc, itf));
    }
    super.visitMethodInsn(opcode, owner, name, desc, itf);
}

From source file:com.google.devtools.build.android.desugar.CoreLibrarySupport.java

License:Open Source License

/**
 * If the given invocation needs to go through a companion class of an emulated or renamed
 * core interface, this methods returns that interface.  This is a helper method for
 * {@link CoreLibraryInvocationRewriter}.
 *
 * <p>This method can only return non-{@code null} if {@code owner} is a core library type.
 * It usually returns an emulated interface, unless the given invocation is a super-call to a
 * core class's implementation of an emulated method that's being moved (other implementations
 * of emulated methods in core classes are ignored). In that case the class is returned and the
 * caller can use {@link #getMoveTarget} to find out where to redirect the invokespecial to.
 *//*from  ww  w . j av  a  2s.  c  o m*/
// TODO(kmb): Rethink this API and consider combining it with getMoveTarget().
@Nullable
public Class<?> getCoreInterfaceRewritingTarget(int opcode, String owner, String name, String desc,
        boolean itf) {
    if (looksGenerated(owner)) {
        // Regular desugaring handles generated classes, no emulation is needed
        return null;
    }
    if (!itf && opcode == Opcodes.INVOKESTATIC) {
        // Ignore static invocations on classes--they never need rewriting (unless moved but that's
        // handled separately).
        return null;
    }
    if ("<init>".equals(name)) {
        return null; // Constructors aren't rewritten
    }

    Class<?> clazz;
    if (isRenamedCoreLibrary(owner)) {
        // For renamed invocation targets we just need to do what InterfaceDesugaring does, that is,
        // only worry about invokestatic and invokespecial interface invocations; nothing to do for
        // classes and invokeinterface.  InterfaceDesugaring ignores bootclasspath interfaces,
        // so we have to do its work here for renamed interfaces.
        if (itf && (opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKESPECIAL)) {
            clazz = loadFromInternal(owner);
        } else {
            return null;
        }
    } else {
        // If not renamed, see if the owner needs emulation.
        clazz = getEmulatedCoreClassOrInterface(owner);
        if (clazz == null) {
            return null;
        }
    }
    checkArgument(itf == clazz.isInterface(), "%s expected to be interface: %s", owner, itf);

    if (opcode == Opcodes.INVOKESTATIC) {
        // Static interface invocation always goes to the given owner
        checkState(itf); // we should've bailed out above.
        return clazz;
    }

    // See if the invoked method is a default method, which will need rewriting.  For invokespecial
    // we can only get here if its a default method, and invokestatic we handled above.
    Method callee = findInterfaceMethod(clazz, name, desc);
    if (callee != null && callee.isDefault()) {
        if (isExcluded(callee)) {
            return null;
        }

        if (!itf && opcode == Opcodes.INVOKESPECIAL) {
            // See if the invoked implementation is moved; note we ignore all other overrides in classes
            Class<?> impl = clazz; // we know clazz is not an interface because !itf
            while (impl != null) {
                String implName = impl.getName().replace('.', '/');
                if (getMoveTarget(implName, name) != null) {
                    return impl;
                }
                impl = impl.getSuperclass();
            }
        }

        Class<?> result = callee.getDeclaringClass();
        if (isRenamedCoreLibrary(result.getName().replace('.', '/'))
                || emulatedInterfaces.stream().anyMatch(emulated -> emulated.isAssignableFrom(result))) {
            return result;
        }
        // We get here if the declaring class is a supertype of an emulated interface.  In that case
        // use the emulated interface instead (since we don't desugar the supertype).  Fail in case
        // there are multiple possibilities.
        Iterator<Class<?>> roots = emulatedInterfaces.stream()
                .filter(emulated -> emulated.isAssignableFrom(clazz) && result.isAssignableFrom(emulated))
                .iterator();
        checkState(roots.hasNext()); // must exist
        Class<?> substitute = roots.next();
        checkState(!roots.hasNext(), "Ambiguous emulation substitute: %s", callee);
        return substitute;
    } else {
        checkArgument(!itf || opcode != Opcodes.INVOKESPECIAL,
                "Couldn't resolve interface super call %s.super.%s : %s", owner, name, desc);
    }
    return null;
}