Example usage for org.objectweb.asm Opcodes INVOKEVIRTUAL

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

Introduction

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

Prototype

int INVOKEVIRTUAL

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

Click Source Link

Usage

From source file:com.offbynull.coroutines.instrumenter.ContinuationPointInstructionUtils.java

License:Open Source License

static InsnList loadAndCastToOriginal(Type originalType, Variable variable) {
    Validate.notNull(originalType);// w w  w. j  a  v  a  2  s.c  o m
    Validate.notNull(variable);
    Validate.isTrue(variable.getType().equals(Type.getType(Object.class)));

    InsnList ret = new InsnList();

    switch (originalType.getSort()) {
    case Type.BOOLEAN:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Boolean"));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false));
        break;
    case Type.BYTE:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Byte"));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false));
        break;
    case Type.SHORT:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Short"));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false));
        break;
    case Type.CHAR:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Character"));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false));
        break;
    case Type.INT:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Integer"));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false));
        break;
    case Type.FLOAT:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Float"));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false));
        break;
    case Type.LONG:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Long"));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false));
        break;
    case Type.DOUBLE:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Double"));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false));
        break;
    case Type.ARRAY:
    case Type.OBJECT:
        ret.add(loadVar(variable)); // load it in to the returnValObj
        ret.add(new TypeInsnNode(Opcodes.CHECKCAST, originalType.getInternalName()));
        break;
    case Type.VOID:
        break;
    case Type.METHOD:
    default:
        throw new IllegalArgumentException();
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.generators.DebugGenerators.java

License:Open Source License

/**
 * Generates instructions for generating marker instructions. These marker instructions are meant to be is useful for debugging
 * instrumented code. For example, you can spot a specific portion of instrumented code by looking for specific markers in the assembly
 * output.//from  w  ww.j  a  v a  2 s.c  o  m
 * @param markerType marker type (determines what kind of instructions are generated)
 * @param text text to print out
 * @return instructions to call System.out.println with a string constant
 * @throws NullPointerException if any argument is {@code null}
 */
public static InsnList debugMarker(MarkerType markerType, String text) {
    Validate.notNull(markerType);
    Validate.notNull(text);

    InsnList ret = new InsnList();

    switch (markerType) {
    case NONE:
        break;
    case CONSTANT:
        ret.add(new LdcInsnNode(text));
        ret.add(new InsnNode(Opcodes.POP));
        break;
    case STDOUT:
        ret.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
        ret.add(new LdcInsnNode(text));
        ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
                "(Ljava/lang/String;)V", false));
        break;
    default:
        throw new IllegalStateException();
    }

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.generators.DebugGenerators.java

License:Open Source License

/**
 * Generates instructions for printing out a string using {@link System#out}. This is useful for debugging. For example, you
 * can print out lines around your instrumented code to make sure that what you think is being run is actually being run.
 * @param text debug text generation instruction list -- must leave a String on the stack
 * @return instructions to call System.out.println with a string constant
 * @throws NullPointerException if any argument is {@code null}
 *///from w ww.j  a v  a  2s. com
public static InsnList debugPrint(InsnList text) {
    Validate.notNull(text);

    InsnList ret = new InsnList();

    ret.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
    ret.add(text);
    ret.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V",
            false));

    return ret;
}

From source file:com.offbynull.coroutines.instrumenter.SynchronizationGenerators.java

License:Open Source License

/**
 * Generates instruction to enter a monitor (top item on the stack) and store it in the {@link LockState} object sitting in the
 * lockstate variable./*from w ww  .j  av a 2  s  . c  o m*/
 * @param markerType debug marker type
 * @param lockVars variables for lock/synchpoint functionality
 * @return instructions to enter a monitor and store it in the {@link LockState} object
 * @throws NullPointerException if any argument is {@code null}
 * @throws IllegalArgumentException if lock variables aren't set (the method doesn't contain any monitorenter/monitorexit instructions)
 */
public static InsnList enterMonitorAndStore(MarkerType markerType, LockVariables lockVars) {
    Validate.notNull(markerType);
    Validate.notNull(lockVars);

    Variable lockStateVar = lockVars.getLockStateVar();
    Validate.isTrue(lockStateVar != null);

    Type clsType = Type.getType(LOCKSTATE_ENTER_METHOD.getDeclaringClass());
    Type methodType = Type.getType(LOCKSTATE_ENTER_METHOD);
    String clsInternalName = clsType.getInternalName();
    String methodDesc = methodType.getDescriptor();
    String methodName = LOCKSTATE_ENTER_METHOD.getName();

    // NOTE: This adds to the lock state AFTER locking.
    return merge(debugMarker(markerType, "Entering monitor and storing"),
            // [obj]
            new InsnNode(Opcodes.DUP), // [obj, obj]
            new InsnNode(Opcodes.MONITORENTER), // [obj]
            new VarInsnNode(Opcodes.ALOAD, lockStateVar.getIndex()), // [obj, lockState]
            new InsnNode(Opcodes.SWAP), // [lockState, obj]
            new MethodInsnNode(Opcodes.INVOKEVIRTUAL, // []
                    clsInternalName, methodName, methodDesc, false));
}

From source file:com.offbynull.coroutines.instrumenter.SynchronizationGenerators.java

License:Open Source License

/**
 * Generates instruction to exit a monitor (top item on the stack) and remove it from the {@link LockState} object sitting in the
 * lockstate variable./*from w w w.  j av a2 s  . com*/
 * @param markerType debug marker type
 * @param lockVars variables for lock/synchpoint functionality
 * @return instructions to exit a monitor and remove it from the {@link LockState} object
 * @throws NullPointerException if any argument is {@code null}
 * @throws IllegalArgumentException if lock variables aren't set (the method doesn't contain any monitorenter/monitorexit instructions)
 */
public static InsnList exitMonitorAndDelete(MarkerType markerType, LockVariables lockVars) {
    Validate.notNull(markerType);
    Validate.notNull(lockVars);

    Variable lockStateVar = lockVars.getLockStateVar();
    Validate.isTrue(lockStateVar != null);

    Type clsType = Type.getType(LOCKSTATE_EXIT_METHOD.getDeclaringClass());
    Type methodType = Type.getType(LOCKSTATE_EXIT_METHOD);
    String clsInternalName = clsType.getInternalName();
    String methodDesc = methodType.getDescriptor();
    String methodName = LOCKSTATE_EXIT_METHOD.getName();

    // NOTE: This removes the lock AFTER unlocking.
    return merge(debugMarker(markerType, "Exiting monitor and unstoring"),
            // [obj]
            new InsnNode(Opcodes.DUP), // [obj, obj]
            new InsnNode(Opcodes.MONITOREXIT), // [obj]
            new VarInsnNode(Opcodes.ALOAD, lockStateVar.getIndex()), // [obj, lockState]
            new InsnNode(Opcodes.SWAP), // [lockState, obj]
            new MethodInsnNode(Opcodes.INVOKEVIRTUAL, // []
                    clsInternalName, methodName, methodDesc, false));
}

From source file:com.spotify.missinglink.ClassLoader.java

License:Apache License

private static void handleMethodCall(Set<CalledMethod> thisCalls, int lineNumber, MethodInsnNode insn) {
    boolean isStatic;
    switch (insn.getOpcode()) {
    case Opcodes.INVOKEVIRTUAL:
    case Opcodes.INVOKEINTERFACE:
        isStatic = false;//from  w  ww .ja v a  2s  . co  m
        break;
    case Opcodes.INVOKESPECIAL:
        isStatic = false;
        break;
    case Opcodes.INVOKESTATIC:
        isStatic = true;
        break;
    default:
        throw new RuntimeException("Unexpected method call opcode: " + insn.getOpcode());
    }
    if (insn.owner.charAt(0) != '[') {
        thisCalls.add(new CalledMethodBuilder().owner(TypeDescriptors.fromClassName(insn.owner))
                .descriptor(MethodDescriptors.fromDesc(insn.desc, insn.name)).isStatic(isStatic)
                .lineNumber(lineNumber).build());
    }
}

From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.Inlining.java

License:Open Source License

public static boolean isBuiltinInstanceMethod(ByteCodeMethodVisitor bcmv, Insn insn) {
    if (insn instanceof MethodInsn) {
        MethodInsn mi = (MethodInsn) insn;
        if ((mi.opcode == Opcodes.INVOKEVIRTUAL) && (isCompilerBuiltin(mi.owner))) {
            return true;
        }//from  w w  w.j av  a2  s .c  o  m
    }
    return false;
}

From source file:com.sun.fortress.compiler.asmbytecodeoptimizer.Inlining.java

License:Open Source License

public static boolean isLibraryInstanceMethod(ByteCodeMethodVisitor bcmv, Insn insn) {
    if (insn instanceof MethodInsn) {
        MethodInsn mi = (MethodInsn) insn;
        if ((mi.opcode == Opcodes.INVOKEVIRTUAL) && (isCompilerLibrary(mi.owner))) {
            return true;
        }/*  w ww  .  ja  va  2s. c o  m*/
    }
    return false;
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

public void printString(CodeGenMethodVisitor mv, String s) {
    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
    mv.visitLdcInsn(s);// w w w. j ava 2 s. c  o m
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
}

From source file:com.sun.fortress.compiler.codegen.CodeGen.java

License:Open Source License

public void forObjectDeclPrePass(ObjectDecl x) {
    debug("Begin forObjectDeclPrePass for ", x);
    TraitTypeHeader header = x.getHeader();
    List<TraitTypeWhere> extendsC = header.getExtendsClause();

    boolean canCompile =
            // x.getParams().isNone() &&             // no parameters
            // header.getStaticParams().isEmpty() && // no static parameter
            header.getWhereClause().isNone() && // no where clause
                    header.getThrowsClause().isNone() && // no throws clause
                    header.getContract().isNone() && // no contract
                    //            header.getDecls().isEmpty() &&        // no members
                    Modifiers.ObjectMod.containsAll(header.getMods())
    // ( extendsC.size() <= 1 ); // 0 or 1 super trait
    ;//  w w w . java 2  s  .co m

    if (!canCompile)
        throw sayWhat(x);

    // Map<String, String> xlation = new HashMap<String, String>();
    List<String> splist = new ArrayList<String>();
    final List<StaticParam> original_static_params = header.getStaticParams();
    Option<List<Param>> original_params = NodeUtil.getParams(x);

    Naming.XlationData xldata = xlationData(Naming.OBJECT_GENERIC_TAG);

    boolean savedInAnObject = inAnObject;
    inAnObject = true;
    Id classId = NodeUtil.getName(x);

    final ClassNameBundle cnb = new_ClassNameBundle(classId, original_static_params, xldata);

    String erasedSuperI = (EMIT_ERASED_GENERICS && cnb.isGeneric) ? cnb.stemClassName : "";
    String[] superInterfaces = NamingCzar.extendsClauseToInterfaces(extendsC, component.getName(),
            erasedSuperI);

    if (EMIT_ERASED_GENERICS && cnb.isGeneric) {
        emitErasedClassFor(cnb, (TraitObjectDecl) x);
    }

    String abstractSuperclass;
    if (superInterfaces.length > 0) {
        abstractSuperclass = superInterfaces[0] + NamingCzar.springBoard;
    } else {
        abstractSuperclass = NamingCzar.internalObject;
    }

    traitOrObjectName = cnb.className;
    debug("forObjectDeclPrePass ", x, " classFile = ", traitOrObjectName);

    boolean isSingletonObject = NodeUtil.getParams(x).isNone();
    List<Param> params;
    if (!isSingletonObject) {
        params = NodeUtil.getParams(x).unwrap(); //TUPLE CONSTRUCTOR PROBLEM
        String init_sig = NamingCzar.jvmSignatureFor(params, "V", thisApi());

        // Generate the factory method
        String sig = NamingCzar.jvmSignatureFor(params, cnb.classDesc, thisApi());

        String mname;

        CodeGen cg = this;
        String PCN = null;
        String PCNOuter = null;

        ArrayList<InitializedStaticField> isf_list = new ArrayList<InitializedStaticField>();

        if (cnb.isGeneric) {
            ArrowType at = FnNameInfo.typeAndParamsToArrow(NodeUtil.getSpan(x),
                    NodeFactory.makeTraitType(classId, STypesUtil.staticParamsToArgs(original_static_params)),
                    original_params.unwrap());
            String generic_arrow_type = NamingCzar.jvmTypeDesc(at, thisApi(), false);

            PCNforClosure pair = nonCollidingClosureName(generic_arrow_type, Naming.NO_SELF,
                    (IdOrOp) x.getHeader().getName(), original_static_params, this.packageAndClassName);

            PCN = pair.PCN;
            PCNOuter = pair.PCNOuter;
            xldata = pair.xldata;

            cg = new CodeGen(this);
            cg.cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, cw);

            // This creates the closure bits
            // The name is disambiguated by the class in which it appears.
            mname = InstantiatingClassloader.closureClassPrefix(PCN, cg.cw, PCN, sig, null, isf_list);
        } else {
            mname = nonCollidingSingleName(x.getHeader().getName(), sig, "");
        }

        CodeGenClassWriter cw = cg.cw;
        CodeGenMethodVisitor mv = cw.visitCGMethod(ACC_STATIC + ACC_PUBLIC, mname, sig, null, null);

        mv.visitTypeInsn(NEW, cnb.className);
        mv.visitInsn(DUP);

        // iterate, pushing parameters, beginning at zero.
        // TODO actually handle N>0 parameters.

        int numParams = params.size();
        //if only a single parameter which is a tuple, signature will give them individually
        if (numParams == 1 && (params.get(0).getIdType().unwrap() instanceof TupleType)) {
            Param p0 = params.get(0);
            TupleType tuple_type = ((TupleType) p0.getIdType().unwrap());
            List<Type> tuple_types = tuple_type.getElements();
            numParams = tuple_types.size();
        }
        for (int stack_offset = 0; stack_offset < numParams; stack_offset++) {
            // when we unbox, this will be type-dependent
            mv.visitVarInsn(ALOAD, stack_offset);
        }

        mv.visitMethodInsn(INVOKESPECIAL, cnb.className, "<init>", init_sig);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(Naming.ignoredMaxsParameter, Naming.ignoredMaxsParameter);
        mv.visitEnd();

        if (cnb.isGeneric) {
            InstantiatingClassloader.optionalStaticsAndClassInitForTO(isf_list, cg.cw);

            cg.cw.dumpClass(PCNOuter, xldata);
        }

    } else { // singleton
        params = Collections.<Param>emptyList();
    }

    CodeGenClassWriter prev = cw;

    /* Yuck, ought to allocate a new codegen here. */

    initializedStaticFields_TO = new ArrayList<InitializedStaticField>();

    cw = new CodeGenClassWriter(ClassWriter.COMPUTE_FRAMES, cw);
    cw.visitSource(NodeUtil.getSpan(x).begin.getFileName(), null);

    // Until we resolve the directory hierarchy problem.
    //            cw.visit( V1_5, ACC_PUBLIC + ACC_SUPER+ ACC_FINAL,
    //                      classFile, null, NamingCzar.internalObject, new String[] { parent });
    cw.visit(InstantiatingClassloader.JVM_BYTECODE_VERSION, ACC_PUBLIC + ACC_SUPER + ACC_FINAL, cnb.className,
            null, abstractSuperclass, superInterfaces);

    if (isSingletonObject) {

        initializedStaticFields_TO.add(new InitializedStaticField() {

            @Override
            public void forClinit(MethodVisitor imv) {
                imv.visitTypeInsn(NEW, cnb.className);
                imv.visitInsn(DUP);
                imv.visitMethodInsn(INVOKESPECIAL, cnb.className, "<init>", Naming.voidToVoid);
                imv.visitFieldInsn(PUTSTATIC, cnb.className, NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc);
            }

            @Override
            public String asmName() {
                return NamingCzar.SINGLETON_FIELD_NAME;
            }

            @Override
            public String asmSignature() {
                return cnb.classDesc;
            }

        });

        /* Used to pass splist to the static-parametered form
         * but it was always empty.  Tests work like that.
         * Bit of a WTF, keep an eye on this.
         * Repurpose splist (non-null) for the computation and
         * caching of RTTI, which also goes in a static.
         */
        addStaticVar(new VarCodeGen.StaticBinding(classId, NodeFactory.makeTraitType(classId),
                cnb.stemClassName, NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc));

        //            // Singleton; generate field in class to hold sole instance.
        //            cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,
        //                          NamingCzar.SINGLETON_FIELD_NAME, cnb.classDesc,
        //                          null /* for non-generic */, null /* instance has no value */);
    }

    currentTraitObjectDecl = x;
    //create CodeGen for init method
    // has different set of parameter variables in scope
    CodeGen initCodeGen = initializeInitMethod(params);

    initCodeGen.initializedInstanceFields_O = new ArrayList<InitializedInstanceField>();
    //        List<Binding> fieldsForEnv = new ArrayList<Binding>();
    initCodeGen.instanceFields = new InstanceFields();

    BATree<String, VarCodeGen> savedLexEnv = lexEnv.copy();

    // for each parameter
    // 1) add field to the class
    // 2) add field along with initializer to list of instance fields to put in the constructor
    // 3) add parameter to local scope of init method
    // 4) add field to scope for use in methods
    for (int i = 0; i < params.size(); i++) {
        Param p = params.get(i);

        String paramName = p.getName().getText();
        Type paramType = (Type) p.getIdType().unwrap();
        String typeDesc = NamingCzar.jvmBoxedTypeDesc(paramType, thisApi());
        Id id = NodeFactory.makeId(NodeUtil.getSpan(p.getName()), paramName);
        VarCodeGen vcg = new VarCodeGen.FieldVar(id, paramType, cnb.className, paramName, typeDesc);

        //1) add field to class
        cw.visitField(ACC_PUBLIC + ACC_FINAL, paramName, typeDesc, null /* for non-generic */,
                null /* instance has no value */);

        //2) add field with initializer as a refernce to the parameter
        initCodeGen.instanceFields.put(vcg, ExprFactory.makeVarRef(id));

        //3) add param to scope for init method only
        initCodeGen.addStaticVar(new VarCodeGen.ParamVar(id, paramType, initCodeGen));

        //4) add field to scope for method codegen
        addStaticVar(vcg);
    }

    // find declared fields in the list of decls and
    // 1) add field to the class
    // 2) add field along with initializer to list of instance fields to put in the constructor
    // 3) add field to scope for use in methods
    for (Decl d : header.getDecls()) {
        if (d instanceof VarDecl) {
            // TODO need to spot for "final" fields.  Right now we assume mutable, not final.
            final VarDecl vd = (VarDecl) d;
            final CodeGen cg = this;
            int numDecls = vd.getLhs().size();
            for (int i = 0; i < numDecls; i++) {
                LValue l = vd.getLhs().get(i);
                String fieldName = l.getName().getText();
                Type fieldType = (Type) l.getIdType().unwrap();
                String typeDesc = NamingCzar.jvmBoxedTypeDesc(fieldType, thisApi());
                Id id = NodeFactory.makeId(NodeUtil.getSpan(l.getName()), fieldName);
                VarCodeGen fieldVcg = new VarCodeGen.MutableFieldVar(id, fieldType, cnb.className, fieldName,
                        typeDesc);

                //1) add field to class
                cw.visitField(ACC_PUBLIC, fieldName, typeDesc, null /* for non-generic */,
                        null /* instance has no value */);

                //2) set up initializer
                if (vd.getInit().isNone())
                    sayWhat(vd, "no initializer for declared field(s)");
                Expr init = vd.getInit().unwrap();

                if (numDecls != 1 && init instanceof TupleExpr) {
                    List<Expr> tupleExprs = ((TupleExpr) init).getExprs();
                    if (tupleExprs.size() != numDecls)
                        sayWhat(vd, "incorrect initialization for declared fields tuple");
                    init = tupleExprs.get(i);
                }
                initCodeGen.instanceFields.put(fieldVcg, init);

                //3) add field to scope for method codegen
                addStaticVar(fieldVcg);
            }
        }
    }

    debug("Dump overloaded method chaining for ", x);
    Map<IdOrOpOrAnonymousName, MultiMap<Integer, Functional>> overloads = dumpOverloadedMethodChaining(
            superInterfaces, false);
    if (OVERLOADED_METHODS)
        typeLevelOverloadedNamesAndSigs = generateTopLevelOverloads(thisApi(), overloads, typeAnalyzer, cw,
                this, new OverloadSet.TraitOrObjectFactory(Opcodes.INVOKEVIRTUAL, cnb, this));
    debug("End of dump overloaded method chaining for ", x);

    debug("Process declarations for ", x);
    for (Decl d : header.getDecls()) {
        // This does not work yet.
        d.accept(this);
    }
    debug("End of processing declarations for ", x);

    initCodeGen.instanceInitForObject(abstractSuperclass);

    debug("Dump method chaining for ", x);
    dumpMethodChaining(superInterfaces, false);
    // dumpErasedMethodChaining(superInterfaces, false);
    debug("End of dump method chaining for ", x);

    /* RTTI stuff */
    mv = cw.visitCGMethod(Opcodes.ACC_PUBLIC, // acccess
            Naming.RTTI_GETTER, // name
            Naming.STATIC_PARAMETER_GETTER_SIG, // sig
            null, // generics sig?
            null); // exceptions
    mv.visitCode();
    mv.visitFieldInsn(GETSTATIC, cnb.className, Naming.RTTI_FIELD, Naming.RTTI_CONTAINER_DESC);

    areturnEpilogue();

    emitRttiField(cnb);
    /* end RTTI stuff */

    lexEnv = savedLexEnv;

    optionalStaticsAndClassInitForTO(classId, cnb, isSingletonObject);

    if (cnb.isGeneric) {
        cw.dumpClass(cnb.fileName, xldata.setTraitObjectTag(Naming.OBJECT_GENERIC_TAG));
    } else {
        cw.dumpClass(cnb.className);
    }
    cw = prev;
    initializedInstanceFields_O = null;
    initializedStaticFields_TO = null;
    currentTraitObjectDecl = null;

    traitOrObjectName = null;

    inAnObject = savedInAnObject;

    // Needed (above) to embed a reference to the Rtti information for this type.
    RttiClassAndInterface(x, cnb, xldata);
    debug("End forObjectDeclPrePass for ", x);
}