/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.flex.abc;

import static org.apache.flex.abc.ABCConstants.CONSTANT_Multiname;
import static org.apache.flex.abc.ABCConstants.CONSTANT_MultinameA;
import static org.apache.flex.abc.ABCConstants.CONSTANT_MultinameL;
import static org.apache.flex.abc.ABCConstants.CONSTANT_MultinameLA;
import static org.apache.flex.abc.ABCConstants.CONSTANT_Qname;
import static org.apache.flex.abc.ABCConstants.CONSTANT_QnameA;
import static org.apache.flex.abc.ABCConstants.CONSTANT_RTQname;
import static org.apache.flex.abc.ABCConstants.CONSTANT_RTQnameA;
import static org.apache.flex.abc.ABCConstants.CONSTANT_RTQnameL;
import static org.apache.flex.abc.ABCConstants.CONSTANT_RTQnameLA;
import static org.apache.flex.abc.ABCConstants.CONSTANT_TypeName;
import static org.apache.flex.abc.ABCConstants.OP_applytype;
import static org.apache.flex.abc.ABCConstants.OP_astype;
import static org.apache.flex.abc.ABCConstants.OP_bkptline;
import static org.apache.flex.abc.ABCConstants.OP_call;
import static org.apache.flex.abc.ABCConstants.OP_callproperty;
import static org.apache.flex.abc.ABCConstants.OP_callproplex;
import static org.apache.flex.abc.ABCConstants.OP_callpropvoid;
import static org.apache.flex.abc.ABCConstants.OP_callstatic;
import static org.apache.flex.abc.ABCConstants.OP_callsuper;
import static org.apache.flex.abc.ABCConstants.OP_callsupervoid;
import static org.apache.flex.abc.ABCConstants.OP_coerce;
import static org.apache.flex.abc.ABCConstants.OP_construct;
import static org.apache.flex.abc.ABCConstants.OP_constructprop;
import static org.apache.flex.abc.ABCConstants.OP_constructsuper;
import static org.apache.flex.abc.ABCConstants.OP_debug;
import static org.apache.flex.abc.ABCConstants.OP_debugfile;
import static org.apache.flex.abc.ABCConstants.OP_debugline;
import static org.apache.flex.abc.ABCConstants.OP_declocal;
import static org.apache.flex.abc.ABCConstants.OP_declocal_i;
import static org.apache.flex.abc.ABCConstants.OP_deleteproperty;
import static org.apache.flex.abc.ABCConstants.OP_dxns;
import static org.apache.flex.abc.ABCConstants.OP_finddef;
import static org.apache.flex.abc.ABCConstants.OP_findproperty;
import static org.apache.flex.abc.ABCConstants.OP_findpropstrict;
import static org.apache.flex.abc.ABCConstants.OP_getdescendants;
import static org.apache.flex.abc.ABCConstants.OP_getglobalslot;
import static org.apache.flex.abc.ABCConstants.OP_getlex;
import static org.apache.flex.abc.ABCConstants.OP_getlocal;
import static org.apache.flex.abc.ABCConstants.OP_getlocal0;
import static org.apache.flex.abc.ABCConstants.OP_getproperty;
import static org.apache.flex.abc.ABCConstants.OP_getscopeobject;
import static org.apache.flex.abc.ABCConstants.OP_getslot;
import static org.apache.flex.abc.ABCConstants.OP_getsuper;
import static org.apache.flex.abc.ABCConstants.OP_hasnext2;
import static org.apache.flex.abc.ABCConstants.OP_inclocal;
import static org.apache.flex.abc.ABCConstants.OP_inclocal_i;
import static org.apache.flex.abc.ABCConstants.OP_initproperty;
import static org.apache.flex.abc.ABCConstants.OP_istype;
import static org.apache.flex.abc.ABCConstants.OP_kill;
import static org.apache.flex.abc.ABCConstants.OP_lookupswitch;
import static org.apache.flex.abc.ABCConstants.OP_newarray;
import static org.apache.flex.abc.ABCConstants.OP_newcatch;
import static org.apache.flex.abc.ABCConstants.OP_newclass;
import static org.apache.flex.abc.ABCConstants.OP_newfunction;
import static org.apache.flex.abc.ABCConstants.OP_newobject;
import static org.apache.flex.abc.ABCConstants.OP_pushbyte;
import static org.apache.flex.abc.ABCConstants.OP_pushdouble;
import static org.apache.flex.abc.ABCConstants.OP_pushint;
import static org.apache.flex.abc.ABCConstants.OP_pushnamespace;
import static org.apache.flex.abc.ABCConstants.OP_pushscope;
import static org.apache.flex.abc.ABCConstants.OP_pushshort;
import static org.apache.flex.abc.ABCConstants.OP_pushstring;
import static org.apache.flex.abc.ABCConstants.OP_pushuint;
import static org.apache.flex.abc.ABCConstants.OP_returnvoid;
import static org.apache.flex.abc.ABCConstants.OP_setglobalslot;
import static org.apache.flex.abc.ABCConstants.OP_setlocal;
import static org.apache.flex.abc.ABCConstants.OP_setproperty;
import static org.apache.flex.abc.ABCConstants.OP_setslot;
import static org.apache.flex.abc.ABCConstants.OP_setsuper;
import static org.apache.flex.abc.ABCConstants.TRAIT_Class;
import static org.apache.flex.abc.ABCConstants.TRAIT_Const;
import static org.apache.flex.abc.ABCConstants.TRAIT_Function;
import static org.apache.flex.abc.ABCConstants.TRAIT_Getter;
import static org.apache.flex.abc.ABCConstants.TRAIT_Method;
import static org.apache.flex.abc.ABCConstants.TRAIT_Setter;
import static org.apache.flex.abc.ABCConstants.TRAIT_Var;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.flex.abc.graph.IBasicBlock;
import org.apache.flex.abc.instructionlist.InstructionList;
import org.apache.flex.abc.semantics.ClassInfo;
import org.apache.flex.abc.semantics.ExceptionInfo;
import org.apache.flex.abc.semantics.InstanceInfo;
import org.apache.flex.abc.semantics.Instruction;
import org.apache.flex.abc.semantics.Label;
import org.apache.flex.abc.semantics.Metadata;
import org.apache.flex.abc.semantics.MethodBodyInfo;
import org.apache.flex.abc.semantics.MethodInfo;
import org.apache.flex.abc.semantics.Name;
import org.apache.flex.abc.semantics.Namespace;
import org.apache.flex.abc.semantics.Nsset;
import org.apache.flex.abc.semantics.PooledValue;
import org.apache.flex.abc.semantics.ScriptInfo;
import org.apache.flex.abc.semantics.Trait;
import org.apache.flex.abc.semantics.Traits;
import org.apache.flex.abc.visitors.IABCVisitor;
import org.apache.flex.abc.visitors.IClassVisitor;
import org.apache.flex.abc.visitors.IDiagnosticsVisitor;
import org.apache.flex.abc.visitors.IMetadataVisitor;
import org.apache.flex.abc.visitors.IMethodBodyVisitor;
import org.apache.flex.abc.visitors.IMethodVisitor;
import org.apache.flex.abc.visitors.IScriptVisitor;
import org.apache.flex.abc.visitors.ITraitVisitor;
import org.apache.flex.abc.visitors.ITraitsVisitor;
import org.apache.flex.abc.visitors.NilVisitors;

/**
 * The ABCEmitter is an IABCVisitor that collects information about
 * the ABC and emits it as a byte array.
 */
public final class ABCEmitter implements IABCVisitor
{
    private static final int VERSION_NONE = -1;

    //  Size of a S24 branch offset.
    private static final int SIZEOF_S24 = 3;
    
   /**
    *  Construct a new ABCEmitter, using the default
    *  diagnostics interface which ignores diagnostics.
    */
   public ABCEmitter()
    {
        this(NilVisitors.NIL_DIAGNOSTICS_VISITOR);
    }

    /**
     * Construct a new ABCEmitter using the specified diagnostics interface.
     * @param diagnosticsVisitor - a sink for diagnostics.
     */
    public ABCEmitter(IDiagnosticsVisitor diagnosticsVisitor)
    {
        this.w = new ABCWriter();
        this.lock = new ReentrantLock();
        this.visitEndCalled = false;
        this.diagnosticsVisitor = diagnosticsVisitor;
    }

    private ABCWriter w;

    /**
     * Name pool, has default zero entry.
     */
    final Pool<Name> namePool = new Pool<Name>(Pool.DefaultType.HasDefaultZero);
    
    /**
     * String pool, has default zero entry.
     */
    final Pool<String> stringPool = new Pool<String>(Pool.DefaultType.HasDefaultZero);
    
    /**
     * int pool, has default zero entry.
     */
    final Pool<Integer> intPool = new Pool<Integer>(Pool.DefaultType.HasDefaultZero);
    
    /**
     * uint pool, has default zero entry.
     */
    final Pool<Long> uintPool = new Pool<Long>(Pool.DefaultType.HasDefaultZero);
    
    /**
     * double pool, has default zero entry.
     */
    final Pool<Double> doublePool = new Pool<Double>(Pool.DefaultType.HasDefaultZero);
    
    /**
     * namespace pool, has default zero entry.
     */
    final Pool<Namespace> nsPool = new Pool<Namespace>(Pool.DefaultType.HasDefaultZero);
    
    /**
     * namespace set pool, has default zero entry.
     */
    final Pool<Nsset> nssetPool = new Pool<Nsset>(Pool.DefaultType.HasDefaultZero);
    
    /**
     * metadata pool, does not have default zero entry.
     */
    final Pool<Metadata> metadataPool = new Pool<Metadata>(Pool.DefaultType.NoDefaultZero);

    /**
     * Visitors of classes defined in this ABC.
     */
    private Collection<EmitterClassVisitor> definedClasses = new ArrayList<EmitterClassVisitor>();
    
    /**
     * MethodInfos defined in this ABC.  These are stored in a dual-indexed store
     * so the method info number of a MethodInfo can be quickly retrieved.
     */
    private final EntryOrderedStore<MethodInfo> methodInfos = new EntryOrderedStore<MethodInfo>();
    
    /**
     * Lock used to protect the method info pool stored in the
     * {@link #methodInfos} field.
     */
    private final ReadWriteLock methodInfosLock = new ReentrantReadWriteLock();

    /**
     * Method bodies defined in this ABC.
     */
    private final Vector<MethodBodyInfo> methodBodies = new Vector<MethodBodyInfo>();
    
    /**
     * Scripts defined in this ABC.  There is normally one.
     */
    private final Vector<ScriptInfo> scriptInfos = new Vector<ScriptInfo>();

    private int versionABCMajor = VERSION_NONE;
    
    private int versionABCMinor = VERSION_NONE;

    /**
     * determines whether the ABCEmitter should throw exceptions when it
     * encounters jumps to nowhere, or just try and repair and keep going.
     */
    private boolean allowBadJumps = false;

    /**
     * Should the emitter serialize method bodies to ABC as soon as possible, or
     * serialize them as it emits the final ABC?
     */
    private boolean eagerlyEmitMethodBodies = true;

    /**
     * Lock used to enforce concurrency rules of this class.
     * <p>
     * This lock is used to ensure that vistEnd calls are only made on the same
     * thread that called {@link #visit(int, int)}.
     * <p>
     * When running with asserts enabled this lock is used to cause an assertion
     * failure when the currency rules of this class are violated.
     * <p>
     * When running with asserts disabled this lock is used to cause a deadlock
     * when the currency rules of this class are violated.
     * 
     * @see #assertLockHeld()
     */
    private final ReentrantLock lock;

    /**
     * Flag set in visitEnd(), checked in verifyEmitterStatus()
     */
    private boolean visitEndCalled;

    private final IDiagnosticsVisitor diagnosticsVisitor;

    /**
     * Emit bytecode.
     * @return the ABC bytecode corresponding to the ABC structures
     * visited by this emitter or its subsidiary visitors.
     * @throws Exception if the emitter is unable to generate valid bytecode.
     */
    public byte[] emit() throws Exception
    {
        if (getMajorVersion() == VERSION_NONE || getMinorVersion() == VERSION_NONE)
            throw new IllegalStateException("No abc version specified");

        //  First sort the classes into dependency order.
        this.definedClasses = ClassDependencySort.getSorted(this.definedClasses);

        w.writeU16(getMinorVersion());
        w.writeU16(getMajorVersion());

        w.writeU30(this.intPool.getNominalSize());
        for (int x : this.intPool.getValues())
        {
            w.writeU30(x);
        }

        w.writeU30(this.uintPool.getNominalSize());
        for (long x : this.uintPool.getValues())
        {
            w.writeU30((int)x);
        }

        w.writeU30(this.doublePool.getNominalSize());
        for (double x : this.doublePool.getValues())
        {
            w.write64(Double.doubleToLongBits(x));
        }

        w.writeU30(this.stringPool.getNominalSize());
        for (String s : this.stringPool.getValues())
        {
            byte[] stringBytes = s.getBytes("UTF-8");
            w.writeU30(stringBytes.length);
            w.write(stringBytes);
        }

        w.writeU30(this.nsPool.getNominalSize());
        for (Namespace ns : this.nsPool.getValues())
        {
            emitNamespace(ns);
        }

        w.writeU30(this.nssetPool.getNominalSize());
        for (Nsset nsset : this.nssetPool.getValues())
        {
            w.writeU30(nsset.length());
            for (Namespace ns : nsset)
            {
                w.writeU30(this.nsPool.id(ns));
            }
        }

        w.writeU30(this.namePool.getNominalSize());
        for (Name n : this.namePool.getValues())
        {
            w.write(n.getKind());
            switch (n.getKind())
            {
                case CONSTANT_Qname:
                case CONSTANT_QnameA:
                {
                    w.writeU30(this.nsPool.id(n.getSingleQualifier()));
                    w.writeU30(this.stringPool.id(n.getBaseName()));
                    break;
                }
                case CONSTANT_Multiname:
                case CONSTANT_MultinameA:
                {
                    w.writeU30(this.stringPool.id(n.getBaseName()));
                    w.writeU30(this.nssetPool.id(n.getQualifiers()));
                    break;
                }
                case CONSTANT_RTQname:
                case CONSTANT_RTQnameA:
                {
                    w.writeU30(this.stringPool.id(n.getBaseName()));
                    break;
                }
                case CONSTANT_MultinameL:
                case CONSTANT_MultinameLA:
                {
                    w.writeU30(this.nssetPool.id(n.getQualifiers()));
                    break;
                }
                case CONSTANT_RTQnameL:
                case CONSTANT_RTQnameLA:
                {
                    break;
                }
                case CONSTANT_TypeName:
                {
                    w.writeU30(this.namePool.id(n.getTypeNameBase()));
                    w.writeU30(1); // only 1 type parameter is currently supposed in AVM2
                    w.writeU30(this.namePool.id(n.getTypeNameParameter()));
                    break;
                }
                default:
                {
                    assert (false) : "Unimplemented name kind " + n.getKind();
                    throw new IllegalArgumentException("Not implemented.");
                }
            }
        }

        // See the comment in EmitterMethodInfoVisitor.visit
        // to understand why we have this lock here.
        // The short answer is because multiple threads
        // need to simultaneously add method infos to the method
        // info pool.
        final Lock methodInfosReadLock = methodInfosLock.readLock();
        methodInfosReadLock.lock();
        try
        {
            w.writeU30(this.methodInfos.size());

            for (MethodInfo mi : this.methodInfos)
                emitMethodInfo(mi);
        }
        finally
        {
            methodInfosReadLock.unlock();
        }

        w.writeU30(this.metadataPool.getNominalSize());
        for (Metadata md : this.metadataPool.values)
        {
            // name
            w.writeU30(this.stringPool.id(md.getName()));

            // items count
            assert md.getKeys().length == md.getValues().length;
            w.writeU30(md.getKeys().length);

            // metadata keys
            for (final String key : md.getKeys())
            {
                final int string_index = stringPool.id(key);
                w.writeU30(string_index);
            }

            // metadata values
            for (final String value : md.getValues())
            {
                final int string_index = stringPool.id(value);
                w.writeU30(string_index);
            }
        }

        w.writeU30(this.definedClasses.size());
        for (EmitterClassVisitor clz : this.definedClasses)
        {
            InstanceInfo ii = clz.instanceInfo;

            w.writeU30(namePool.id(ii.name));
            w.writeU30(namePool.id(ii.superName));
            w.write(ii.flags);

            if (ii.hasProtectedNs())
                w.writeU30(this.nsPool.id(ii.protectedNs));
            w.writeU30(ii.interfaceNames.length);

            for (Name i : ii.interfaceNames)
                w.writeU30(this.namePool.id(i));
            w.writeU30(getMethodId(ii.iInit));

            emitTraits(clz.instanceTraits);
        }

        for (EmitterClassVisitor clz : this.definedClasses)
        {
            w.writeU30(getMethodId(clz.classInfo.cInit));
            emitTraits(clz.classTraits);
        }

        w.writeU30(this.scriptInfos.size());
        for (ScriptInfo s : this.scriptInfos)
        {
            emitScriptInfo(s);
        }

        w.writeU30(this.methodBodies.size());
        for (MethodBodyInfo mb : this.methodBodies)
        {
            emitMethodBody(mb);
        }

        return w.getDirectByteArray();
    }

    private int getMajorVersion()
    {
        return versionABCMajor;
    }

    private int getMinorVersion()
    {
        return versionABCMinor;
    }

    /**
     * Emit ABC bytes for a Traits entry.
     * 
     * @param traits - the Traits to emit.
     * @see #poolTraitValues(Traits) which puts these values into the pools.
     */
    private void emitTraits(Traits traits)
    {
        w.writeU30(traits.getTraitCount());

        for (Trait t : traits)
        {
            w.writeU30(namePool.id(t.getNameAttr("name")));
            
            //  Get the kind byte with its flags set in the high nibble.
            w.write(t.getFullKindByte());

            switch (t.getKind())
            {
                case TRAIT_Var:
                case TRAIT_Const:
                {
                    w.writeU30(t.getIntAttr(Trait.TRAIT_SLOT));
                    w.writeU30(namePool.id(t.getNameAttr(Trait.TRAIT_TYPE)));

                    //  Emit the Trait's initial value, if it has one.
                    Object trait_value = t.getAttr(Trait.SLOT_VALUE);
                    if (trait_value != null)
                    {
                        if (trait_value instanceof String)
                        {
                            w.writeU30(stringPool.id((String)trait_value));
                            w.write(ABCConstants.CONSTANT_Utf8);
                        }
                        else if (trait_value instanceof Namespace)
                        {
                            w.writeU30(nsPool.id((Namespace)trait_value));
                            w.write(ABCConstants.CONSTANT_Namespace);
                        }
                        else if (trait_value instanceof Double)
                        {
                            w.writeU30(doublePool.id((Double)trait_value));
                            w.write(ABCConstants.CONSTANT_Double);
                        }
                        else if (trait_value instanceof Integer)
                        {
                            w.writeU30(intPool.id((Integer)trait_value));
                            w.write(ABCConstants.CONSTANT_Int);
                        }
                        else if (trait_value instanceof Long)
                        {
                            w.writeU30(uintPool.id((Long)trait_value));
                            w.write(ABCConstants.CONSTANT_UInt);
                        }
                        else if (trait_value.equals(Boolean.TRUE))
                        {
                            w.writeU30(ABCConstants.CONSTANT_True);
                            w.write(ABCConstants.CONSTANT_True);
                        }
                        else if (trait_value.equals(Boolean.FALSE))
                        {
                            w.writeU30(ABCConstants.CONSTANT_False);
                            w.write(ABCConstants.CONSTANT_False);
                        }
                        else if (trait_value == ABCConstants.NULL_VALUE)
                        {
                            w.writeU30(ABCConstants.CONSTANT_Null);
                            w.write(ABCConstants.CONSTANT_Null);
                        }
                        else if (trait_value == ABCConstants.UNDEFINED_VALUE)
                        {
                            //  Undefined is a special case; it has no kind byte.
                            w.writeU30(0);
                        }
                        else
                        {
                            throw new IllegalStateException("Unrecognized initializer type: " + trait_value.getClass().toString());
                        }
                    }
                    else
                    {
                        w.writeU30(0);
                    }

                    break;
                }
                case TRAIT_Method:
                case TRAIT_Function:
                case TRAIT_Getter:
                case TRAIT_Setter:
                {
                    if (t.hasAttr(Trait.TRAIT_DISP))
                        w.writeU30(t.getIntAttr(Trait.TRAIT_DISP));
                    else
                        w.writeU30(0);

                    w.writeU30(this.getMethodId((MethodInfo)t.getAttr(Trait.TRAIT_METHOD)));
                    break;
                }
                case TRAIT_Class:
                {
                    if (t.hasAttr(Trait.TRAIT_SLOT))
                        w.writeU30(t.getIntAttr(Trait.TRAIT_SLOT));
                    else
                        w.writeU30(0);
                    w.writeU30(this.getClassId(((ClassInfo)t.getAttr(Trait.TRAIT_CLASS))));
                    break;
                }
                default:
                {
                    throw new IllegalArgumentException("Unknown trait kind " + t.getKind());
                }
            }

            if (t.hasMetadata())
            {
                Vector<Metadata> metadata = t.getMetadata();
                w.writeU30(metadata.size());
                for (Metadata m : metadata)
                {
                    w.writeU30(metadataPool.id(m));
                }
            }
        }
    }

    private int getMethodId(MethodInfo info)
    {
        Lock methodInfosReadLock = methodInfosLock.readLock();
        methodInfosReadLock.lock();
        try
        {
            return methodInfos.getId(info);
        }
        finally
        {
            methodInfosReadLock.unlock();
        }
    }

    /**
     * @return the class ID of the given ClassInfo.
     * @throws IllegalArgumentException if the class is not found.
     */
    private int getClassId(ClassInfo info)
    {
        int id_index = 0;
        for (EmitterClassVisitor candidate : this.definedClasses)
        {
            if (candidate.classInfo == info)
                return id_index;
            else
                id_index++;
        }

        throw new IllegalArgumentException("Unable to find ClassInfo index for " + info);
    }

    private void emitScriptInfo(ScriptInfo info)
    {
        final MethodInfo scriptInit = info.getInit();
        final int nRequiredArguments =
            scriptInit.getParamTypes().size() - scriptInit.getDefaultValues().size();
        if (nRequiredArguments > 0)
            diagnosticsVisitor.scriptInitWithRequiredArguments(info, scriptInit);
        w.writeU30(getMethodId(scriptInit));
        emitTraits(info.getTraits());
    }

    private void emitMethodInfo(MethodInfo info)
    {
        final Collection<Name> paramTypes = info.getParamTypes();
        final int nParamTypes = paramTypes.size();
        w.writeU30(nParamTypes);
        w.writeU30(namePool.id(info.getReturnType()));

        for (Name n : paramTypes)
        {
            w.writeU30(namePool.id(n));
        }

        w.writeU30(this.stringPool.id(info.getMethodName()));
        w.write(info.getFlags());

        if (info.hasOptional())
        {
            Collection<PooledValue> defaults = info.getDefaultValues();
            final int nDefaults = defaults.size();

            if (nDefaults > nParamTypes)
                this.diagnosticsVisitor.tooManyDefaultParameters(info);

            w.writeU30(nDefaults);
            for (PooledValue v : defaults)
            {
                w.writeU30(v.getPoolIndex());
                w.write(v.getKind());
            }
        }

        if (info.hasParamNames())
        {
            List<String> paramNames = info.getParamNames();
            final int nParamNames = paramNames.size();
            if (nParamTypes != nParamNames)
                this.diagnosticsVisitor.incorrectNumberOfParameterNames(info);

            for (String param_name : info.getParamNames())
                w.writeU30(stringPool.id(param_name));
        }
    }

    private void emitMethodBody(MethodBodyInfo f) throws Exception
    {
        MethodInfo signature = f.getMethodInfo();

        w.writeU30(getMethodId(signature));
        //  Note: computeFrameCounts() called at MethodBodyInfo.visitEnd().
        w.writeU30(f.getMaxStack());

        int max_local = f.getLocalCount();
        if (signature.getParamCount() > max_local)
            max_local = signature.getParamCount();

        w.writeU30(max_local);

        w.writeU30(f.getInitScopeDepth());
        w.writeU30(f.getMaxScopeDepth());

        if (!f.hasBytecode())
            emitCode(f);

        w.write(f.getBytecode());

        emitTraits(f.getTraits());
    }

    private void emitCode(MethodBodyInfo f) throws Exception
    {
        ABCWriter result = new ABCWriter();
        Map<IBasicBlock, ABCWriter> writers = new HashMap<IBasicBlock, ABCWriter>();

        // generate linear code sequences within the basic blocks,
        // and compute the offset of each block from the method start.
        Map<IBasicBlock, Integer> block_offsets = new HashMap<IBasicBlock, Integer>();
        int code_len = 0;

        //  First, generate code for each block.
        //  Keep a running tally of the code length,
        //  which corresponds to the starting position
        //  of each block.
        for (IBasicBlock b : f.getCfg().getBlocksInEntryOrder())
        {
            block_offsets.put(b, code_len);
            ABCWriter blockWriter = new ABCWriter();
            writers.put(b, blockWriter);

            emitBlock(b, blockWriter);

            code_len += blockWriter.size();

            //  Blocks with no instructions are
            //  valid assembly constructs.
            if (b.size() == 0)
                continue;

            //  If the last instruction in the block
            //  is a jump, leave room for the instruction,
            //  but don't emit it yet.
            Instruction last = b.get(b.size() - 1);

            if (last.isBranch())
            {
                if (last.getOpcode() == OP_lookupswitch)
                {
                    //  Switch table contains a U30 case count and S24 offsets.
                    int switch_size = 1 + sizeOfU30(last.getOperandCount()) + SIZEOF_S24 * last.getOperandCount();
                    code_len += switch_size;
                }
                else
                {
                    assert (null != last.getTarget());
                    //  Reserve space for a branch instruction.
                    code_len += 4;
                }
            }
        }

        //  Note: Can't compute code_start until we've seen
        //  how big this U30 is.
        result.writeU30(code_len);
        int code_start = result.size();

        //  Now we can resolve labels to their code offsets.
        //  Copy the linear code sequences into the main ABCWriter,
        //  and emit the branch and lookupswitch instructions.
        for (IBasicBlock b : f.getCfg().getBlocksInEntryOrder())
        {
            writers.get(b).writeTo(result);
            if (b.size() > 0)
            {
                Instruction last = b.get(b.size() - 1);

                if (last.isBranch())
                {
                    if (OP_lookupswitch == last.getOpcode())
                    {
                        emitLookupswitch(result, code_start, f, last, block_offsets);
                    }
                    else
                    {
                        assert (last.getTarget() != null);

                        emitBranch(result, last.getOpcode(), f.getBlock(last.getTarget(), !allowBadJumps), code_start, block_offsets, code_len);
                    }
                }
            }
        }

        emitExceptionInfo(f, result, block_offsets);

        f.setBytecode(result.getDirectByteArray());
    }

    private void emitBranch(ABCWriter writer, int opcode, IBasicBlock target, int code_start, Map<IBasicBlock, Integer> block_offsets, int code_len)
    {
        writer.write(opcode);
        
        //  Branch offset computed from the instruction following the branch.
        int from = writer.size() + SIZEOF_S24;
        
        //  Convert the target offset relative to the start of the ABC, as
        //  the "from" address is expressed in this fashion.
        //  if we can't determine the target then jump past the end of the method - this is to allow
        //  malformed ABCs to be successfully processed by AET.
        int to = code_start + (target != null ? block_offsets.get(target) : code_len + 1);
        
        writer.writeS24(to - from);
    }

    void emitBlock(IBasicBlock b, ABCWriter blockWriter)
    {
        for (int i = 0; i < b.size() && !b.get(i).isBranch(); i++)
        {
            Instruction insn = b.get(i);

            blockWriter.write(insn.getOpcode());
            switch (insn.getOpcode())
            {
                case OP_hasnext2:
                {
                    blockWriter.writeU30((Integer)insn.getOperand(0));
                    blockWriter.writeU30((Integer)insn.getOperand(1));
                    break;
                }
                case OP_findproperty:
                case OP_findpropstrict:
                case OP_getlex:
                case OP_getsuper:
                case OP_setsuper:
                case OP_deleteproperty:
                case OP_getdescendants:
                case OP_getproperty:
                case OP_setproperty:
                case OP_initproperty:
                case OP_istype:
                case OP_coerce:
                case OP_astype:
                case OP_finddef:
                {
                    blockWriter.writeU30(namePool.id((Name)insn.getOperand(0)));
                    break;
                }
                case OP_callproperty:
                case OP_callproplex:
                case OP_callpropvoid:
                case OP_callsuper:
                case OP_callsupervoid:
                case OP_constructprop:
                {
                    blockWriter.writeU30(namePool.id((Name)insn.getOperand(0)));
                    blockWriter.writeU30((Integer)insn.getOperand(1));
                    break;
                }
                case OP_constructsuper:
                case OP_call:
                case OP_construct:
                case OP_newarray:
                case OP_newobject:
                case OP_getlocal:
                case OP_setlocal:
                case OP_getslot:
                case OP_setslot:
                case OP_kill:
                case OP_inclocal:
                case OP_declocal:
                case OP_inclocal_i:
                case OP_declocal_i:
                case OP_newcatch:
                case OP_getglobalslot:
                case OP_setglobalslot:
                case OP_applytype:
                case OP_getscopeobject:
                case OP_pushshort:
                {
                    blockWriter.writeU30(insn.getImmediate());
                    break;
                }
                case OP_pushbyte:
                {
                    blockWriter.write(insn.getImmediate());
                    break;
                }
                case OP_newclass:
                {
                    blockWriter.writeU30(getClassId((ClassInfo)insn.getOperand(0)));
                    break;
                }
                case OP_newfunction:
                {
                    blockWriter.writeU30(getMethodId((MethodInfo)insn.getOperand(0)));
                    break;
                }
                case OP_callstatic:
                {
                    blockWriter.writeU30(getMethodId((MethodInfo)insn.getOperand(0)));
                    blockWriter.writeU30((Integer)(insn.getOperand(1)));
                    break;
                }
                case OP_pushstring:
                case OP_dxns:
                case OP_debugfile:
                {
                    blockWriter.writeU30(stringPool.id(insn.getOperand(0).toString()));
                    break;
                }
                case OP_pushnamespace:
                {
                    blockWriter.writeU30(nsPool.id((Namespace)insn.getOperand(0)));
                    break;
                }
                case OP_pushint:
                {
                    blockWriter.writeU30(intPool.id((Integer)insn.getOperand(0)));
                    break;
                }
                case OP_pushuint:
                {
                    blockWriter.writeU30(uintPool.id((Long)insn.getOperand(0)));
                    break;
                }
                case OP_pushdouble:
                {
                    blockWriter.writeU30(doublePool.id((Double)insn.getOperand(0)));
                    break;
                }
                case OP_debugline:
                case OP_bkptline:
                {
                    blockWriter.writeU30(insn.getImmediate());
                    break;
                }
                case OP_debug:
                {
                    blockWriter.write((Integer)(insn.getOperand(0)));
                    blockWriter.writeU30(stringPool.id(insn.getOperand(1).toString()));
                    blockWriter.write((Integer)insn.getOperand(2));
                    blockWriter.writeU30(0);
                    break;
                }
            }
        }
    }

    private void emitNamespace(Namespace ns)
    {
        w.write(ns.getKind());
        w.writeU30(stringPool.id(ns.getVersionedName()));
    }

    private void emitExceptionInfo(MethodBodyInfo f, ABCWriter w, Map<IBasicBlock, Integer> pos)
    {
        w.writeU30(f.getExceptions().size());

        for (ExceptionInfo ex : f.getExceptions())
        {
            if ( ex.isLive() )
            {
                w.writeU30(pos.get(f.getBlock(ex.getFrom())));
                w.writeU30(pos.get(f.getBlock(ex.getTo())));
                w.writeU30(pos.get(f.getBlock(ex.getTarget())));
                w.writeU30(namePool.id(ex.getExceptionType()));
                w.writeU30(namePool.id(ex.getCatchVar()));
            }
        }
    }

    void emitLookupswitch(ABCWriter out, int code_start, MethodBodyInfo f,
                          Instruction switch_insn, Map<IBasicBlock, Integer> block_offsets)
    {
        int case_size = switch_insn.getOperandCount() - 1; //  Last Label reserved for the default

        //  "The base location is the address of the lookupswitch instruction itself." - AVM2 
        int base_loc = out.size() - code_start;

        out.write(OP_lookupswitch);

        //  The last label is the default case.
        Label default_case = (Label)switch_insn.getOperand(case_size);
        int default_offset = (block_offsets.get(f.getBlock(default_case)) - base_loc);
        out.writeS24(default_offset);

        out.writeU30(case_size - 1);

        for (int i = 0; i < case_size; i++)
        {
            int branch_offset = (block_offsets.get(f.getBlock((Label)switch_insn.getOperand(i))) - base_loc);
            out.writeS24(branch_offset);
        }
    }

    static class ABCWriter extends ByteArrayOutputStream
    {
        void rewind(int n)
        {
            super.count -= n;
        }

        void writeU16(int i)
        {
            write(i);
            write(i >> 8);
        }

        void writeS24(int i)
        {
            writeU16(i);
            write(i >> 16);
        }

        void write64(long i)
        {
            writeS24((int)i);
            writeS24((int)(i >> 24));
            writeU16((int)(i >> 48));
        }

        void writeU30(int v)
        {
            if (v < 128 && v >= 0)
            {
                write(v);
            }
            else if (v < 16384 && v >= 0)
            {
                write(v & 0x7F | 0x80);
                write(v >> 7);
            }
            else if (v < 2097152 && v >= 0)
            {
                write(v & 0x7F | 0x80);
                write(v >> 7 | 0x80);
                write(v >> 14);
            }
            else if (v < 268435456 && v >= 0)
            {
                write(v & 0x7F | 0x80);
                write(v >> 7 | 0x80);
                write(v >> 14 | 0x80);
                write(v >> 21);
            }
            else
            {
                write(v & 0x7F | 0x80);
                write(v >> 7 | 0x80);
                write(v >> 14 | 0x80);
                write(v >> 21 | 0x80);
                write(v >>> 28);
            }
        }

        int sizeOfU30(int v)
        {
            if (v < 128 && v >= 0)
                return 1;

            else if (v < 16384 && v >= 0)
                return 2;

            else if (v < 2097152 && v >= 0)
                 return 3;

            else if (v < 268435456 && v >= 0)
                return 4;

            else
                return 5;
        }


        /**
         * Get the byte array contained within this stream.  Note: flush may need to be called
         * @return the byte array
         */
        public byte[] getDirectByteArray()
        {
            // only return the buffer directly if the length of the buffer
            // is the same as the count, as the buffer can be bigger than the
            // count, and in this case, we return an array which is larger than
            // expected, so we need to truncate it with a copy.
            if (buf.length == count)
                return buf;
            else
                return super.toByteArray();
        }

        /**
         * Ensure toByteArray() is never called.
         */
        @Override
        public byte[] toByteArray()
        {
            throw new UnsupportedOperationException();
        }
    }

    /**
     * Find all the operands in a method body and make sure they find their way
     * into the appropriate pool.
     * 
     * @param mi - the method body.
     * @post any runtime multinames have a dummy Name operand.
     */
    void poolOperands(MethodBodyInfo mbi)
    {
        for (IBasicBlock b : mbi.getCfg().getBlocksInEntryOrder())
        {
            for (Instruction insn : b.getInstructions())
            {
                switch (insn.getOpcode())
                {
                    case OP_findproperty:
                    case OP_findpropstrict:
                    case OP_getlex:
                    case OP_getdescendants:
                    case OP_initproperty:
                    case OP_istype:
                    case OP_coerce:
                    case OP_astype:
                    case OP_finddef:
                    case OP_deleteproperty:
                    case OP_getproperty:
                    case OP_setproperty:
                    case OP_getsuper:
                    case OP_setsuper:
                    {
                        visitPooledName((Name)insn.getOperand(0));
                        break;
                    }
                    case OP_callproperty:
                    case OP_callproplex:
                    case OP_callpropvoid:
                    case OP_callsuper:
                    case OP_callsupervoid:
                    case OP_constructprop:
                    {
                        visitPooledName((Name)insn.getOperand(0));
                        break;
                    }
                    case OP_pushstring:
                    case OP_dxns:
                    case OP_debugfile:
                    {
                        stringPool.add(insn.getOperand(0).toString());
                        break;
                    }
                    case OP_pushnamespace:
                    {
                        visitPooledNamespace((Namespace)insn.getOperand(0));
                        break;
                    }
                    case OP_pushint:
                    {
                        intPool.add((Integer)insn.getOperand(0));
                        break;
                    }
                    case OP_pushuint:
                    {
                        uintPool.add((Long)insn.getOperand(0));
                        break;
                    }
                    case OP_pushdouble:
                    {
                        doublePool.add((Double)insn.getOperand(0));
                        break;
                    }
                    case OP_debug:
                    {
                        stringPool.add(insn.getOperand(1).toString());
                        break;
                    }
                }
            }
        }
    }

    /**
     * Pool all the objects referenced by a Traits that need to be added to the
     * various constant pools. These objects include:
     * <ul>
     * <li>The {@link Name} object for the qualified name of each {@link Trait}.
     * </li>
     * <li>The {@link Name} object that refers to the class or interface of each
     * {@link Trait} with a type annotation.</li>
     * <li>The {@link Metadata} objects that decorate each {@link Trait}.</li>
     * <li>The {@link String}, {@link Namespace}, {@link Double},
     * {@link Integer}, or {@link Long} objects that specify the
     * initial value of each {@link Trait}.</li>
     * </ul>
     */
    private void poolTraitsConstants(Traits ts)
    {
        for (Trait t : ts)
        {
            Name traitName = t.getNameAttr(Trait.TRAIT_NAME);
            visitPooledName(traitName);

            if (t.hasAttr(Trait.TRAIT_TYPE))
                visitPooledName(t.getNameAttr(Trait.TRAIT_TYPE));

            for (Metadata md : t.getMetadata())
                visitPooledMetadata(md);

            if (t.hasAttr(Trait.SLOT_VALUE))
            {
                Object trait_value = t.getAttr(Trait.SLOT_VALUE);
                if (trait_value == null)
                {
                    //  No action required; the pool ID resolution logic
                    //  handles a null pointer by returning the nil pool value.
                }
                else if (trait_value instanceof String)
                {
                    visitPooledString((String)trait_value);
                }
                else if (trait_value instanceof Namespace)
                {
                    visitPooledNamespace((Namespace)trait_value);
                }
                else if (trait_value instanceof Double)
                {
                    visitPooledDouble((Double)trait_value);
                }
                else if (trait_value instanceof Integer)
                {
                    visitPooledInt((Integer)trait_value);
                }
                else if (trait_value instanceof Long)
                {
                    visitPooledUInt((Long)trait_value);
                }
                else if (trait_value.equals(ABCConstants.UNDEFINED_VALUE)
                         || trait_value.equals(ABCConstants.NULL_VALUE)
                         || trait_value.equals(Boolean.TRUE)
                         || trait_value.equals(Boolean.FALSE))
                {
                    // Nothing to do, predefined value.
                }
                else
                {
                    throw new IllegalStateException("Unrecognized initializer type: " + trait_value.getClass().toString());
                }
            }
        }
    }

    @Override
    public void visit(int majorVersion, int minorVersion)
    {
        verifyEmitterStatus();

        this.lock.lock();
        
        assert this.lock.getHoldCount() == 1 : "The hold count should be 1, beacuse this method should only be called once!";
        
        if (versionABCMajor == VERSION_NONE)
        {
            versionABCMajor = majorVersion;
            versionABCMinor = minorVersion;
        }
        else if (versionABCMajor != majorVersion || versionABCMinor != minorVersion)
        {
            throw new IllegalArgumentException("abc versions do not match");
        }
    }

    @Override
    public void visitEnd()
    {
        verifyEmitterStatus();
        assertLockHeld();

        this.visitEndCalled = true;
    }

    @Override
    public IClassVisitor visitClass(InstanceInfo iinfo, ClassInfo cinfo)
    {
        verifyEmitterStatus();

        EmitterClassVisitor result = new EmitterClassVisitor(iinfo, cinfo);
        result.visit();
        return result;
    }

    @Override
    public IScriptVisitor visitScript()
    {
        verifyEmitterStatus();

        return new EmitterScriptInfo();
    }

    @Override
    public IMethodVisitor visitMethod(MethodInfo minfo)
    {
        verifyEmitterStatus();

        return new EmitterMethodInfoVisitor(minfo);
    }

    @Override
    public void visitPooledDouble(Double d)
    {
        verifyEmitterStatus();

        this.doublePool.add(d);
    }

    @Override
    public void visitPooledInt(Integer i)
    {
        verifyEmitterStatus();

        this.intPool.add(i);
    }

    @Override
    public void visitPooledMetadata(Metadata md)
    {
        verifyEmitterStatus();

        this.metadataPool.add(md);

        visitPooledString(md.getName());

        for (String key : md.getKeys())
            visitPooledString(key);

        for (String value : md.getValues())
            visitPooledString(value);
    }

    @Override
    public void visitPooledName(Name n)
    {
        verifyEmitterStatus();

        if (null == n)
            return;

        final int kind = n.getKind();

        if (kind != ABCConstants.CONSTANT_TypeName)
        {
            this.namePool.add(n);

            visitPooledString(n.getBaseName());
            if ((kind == ABCConstants.CONSTANT_Qname) || (kind == ABCConstants.CONSTANT_QnameA))
                visitPooledNamespace(n.getSingleQualifier());
            else
                visitPooledNsSet(n.getQualifiers());
        }
        else
        {
            visitPooledName(n.getTypeNameBase());
            visitPooledName(n.getTypeNameParameter());
            this.namePool.add(n);
        }
    }

    @Override
    public void visitPooledNamespace(Namespace ns)
    {
        verifyEmitterStatus();

        this.nsPool.add(ns);

        if (ns != null)
            visitPooledString(ns.getVersionedName());
    }

    @Override
    public void visitPooledNsSet(Nsset nss)
    {
        verifyEmitterStatus();

        this.nssetPool.add(nss);

        if (nss != null)
        {
            for (Namespace ns : nss)
            {
                visitPooledNamespace(ns);
            }
        }
    }

    @Override
    public void visitPooledString(String s)
    {
        verifyEmitterStatus();

        this.stringPool.add(s);
    }

    @Override
    public void visitPooledUInt(Long l)
    {
        verifyEmitterStatus();

        this.uintPool.add(l);
    }

    public static int sizeOfU30(int v)
    {
        if (v < 128 && v >= 0)
            return 1;

        else if (v < 16384 && v >= 0)
            return 2;

        else if (v < 2097152 && v >= 0)
            return 3;

        else if (v < 268435456 && v >= 0)
            return 4;

        else
            return 5;

    }

    private class EmitterClassVisitor implements IClassVisitor, ClassDependencySort.IInstanceInfoProvider
    {
        EmitterClassVisitor(InstanceInfo iinfo, ClassInfo cinfo)
        {
            this.classInfo = cinfo;
            if (null == cinfo.classTraits)
                cinfo.classTraits = new Traits();
            this.classTraits = cinfo.classTraits;

            this.instanceInfo = iinfo;

            if (null == iinfo.traits)
                iinfo.traits = new Traits();
            this.instanceTraits = iinfo.traits;
            if (null == iinfo.interfaceNames)
                iinfo.interfaceNames = new Name[0];
        }

        ClassInfo classInfo;
        Traits classTraits;
        InstanceInfo instanceInfo;
        Traits instanceTraits;

        @Override
        public void visit()
        {
            verifyEmitterStatus();
        }

        @Override
        public ITraitsVisitor visitClassTraits()
        {
            verifyEmitterStatus();
            return new EmitterTraitsVisitor(this.classTraits);
        }

        @Override
        public ITraitsVisitor visitInstanceTraits()
        {
            verifyEmitterStatus();
            return new EmitterTraitsVisitor(this.instanceTraits);
        }

        @Override
        public void visitEnd()
        {
            verifyEmitterStatus();

            assertLockHeld();
            definedClasses.add(this);
            if (null == classInfo.cInit)
            {
                classInfo.cInit = new MethodInfo();
                MethodBodyInfo m_cinit = new MethodBodyInfo();
                m_cinit.setMethodInfo(classInfo.cInit);

                IMethodVisitor mv = visitMethod(classInfo.cInit);
                mv.visit();
                IMethodBodyVisitor mbv = mv.visitBody(m_cinit);
                mbv.visit();
                mbv.visitInstruction(OP_returnvoid);
                mbv.visitEnd();
                mv.visitEnd();
            }

            visitPooledName(instanceInfo.name);
            visitPooledName(instanceInfo.superName);

            if (instanceInfo.hasProtectedNs())
                visitPooledNamespace(instanceInfo.protectedNs);

            if (null == instanceInfo.iInit)
            {
                instanceInfo.iInit = new MethodInfo();
                MethodBodyInfo iinit = new MethodBodyInfo();
                iinit.setMethodInfo(instanceInfo.iInit);

                IMethodVisitor mv = visitMethod(instanceInfo.iInit);
                mv.visit();

                //  Interfaces need an instance init method, 
                //  but it doesn't have a body.
                if (0 == (instanceInfo.flags & ABCConstants.CLASS_FLAG_interface))
                {
                    IMethodBodyVisitor mbv = mv.visitBody(iinit);
                    mbv.visit();
                    mbv.visitInstruction(OP_getlocal0);
                    mbv.visitInstruction(OP_pushscope);
                    mbv.visitInstruction(OP_getlocal0);
                    mbv.visitInstruction(ABCConstants.OP_constructsuper, 0);
                    mbv.visitInstruction(OP_returnvoid);
                    mbv.visitEnd();
                }
                mv.visitEnd();
            }

            if (instanceInfo.interfaceNames != null)
            {
                for (Name interface_name : instanceInfo.interfaceNames)
                {
                    visitPooledName(interface_name);
                }
            }
        }

        @Override
        public InstanceInfo getInstanceInfo()
        {
            return this.instanceInfo;
        }
    }

    private class EmitterTraitsVisitor implements ITraitsVisitor
    {
        EmitterTraitsVisitor(Traits traits)
        {
            this.traits = traits;
        }

        Traits traits;

        @Override
        public ITraitVisitor visitClassTrait(int kind, Name name, int slot_id, ClassInfo clazz)
        {
            verifyEmitterStatus();

            Trait t = createTrait(kind, name);
            if (slot_id != 0)
                t.addAttr(Trait.TRAIT_SLOT, slot_id);
            t.addAttr(Trait.TRAIT_CLASS, clazz);

            return new EmitterTraitVisitor(t);
        }

        @Override
        public ITraitVisitor visitMethodTrait(int kind, Name name, int dispId, MethodInfo method)
        {
            verifyEmitterStatus();

            Trait t = createTrait(kind, name);
            t.addAttr(Trait.TRAIT_METHOD, method);
            if (dispId != 0)
                t.addAttr(Trait.TRAIT_DISP, dispId);
            return new EmitterTraitVisitor(t);
        }

        @Override
        public ITraitVisitor visitSlotTrait(int kind, Name name, int slotId, Name slotType, Object slotValue)
        {
            verifyEmitterStatus();

            Trait t = createTrait(kind, name);
            t.addAttr(Trait.TRAIT_SLOT, slotId);
            t.addAttr(Trait.TRAIT_TYPE, slotType);
            t.addAttr(Trait.SLOT_VALUE, slotValue);
            if (slotType != null)
                visitPooledName(slotType);
            return new EmitterTraitVisitor(t);
        }

        @Override
        public void visit()
        {
            verifyEmitterStatus();
        }

        @Override
        public void visitEnd()
        {
            verifyEmitterStatus();

            assertLockHeld();
            poolTraitsConstants(traits);
        }

        @Override
        public Traits getTraits()
        {
            return this.traits;
        }

        private Trait createTrait(int kind, Name name)
        {
            verifyEmitterStatus();

            Trait t = new Trait(kind, name);
            traits.add(t);
            return t;
        }
    }

    private class EmitterTraitVisitor implements ITraitVisitor
    {
        EmitterTraitVisitor(Trait t)
        {
            this.t = t;
        }

        Trait t;

        @Override
        public IMetadataVisitor visitMetadata(int count)
        {
            verifyEmitterStatus();

            return new IMetadataVisitor()
            {

                @Override
                public void visit(Metadata md)
                {
                    verifyEmitterStatus();

                    t.addMetadata(md);
                }
            };
        }

        @Override
        public void visitAttribute(String attr_name, Object attr_value)
        {
            verifyEmitterStatus();

            this.t.addAttr(attr_name, attr_value);
        }

        @Override
        public void visitStart()
        {
            verifyEmitterStatus();

        }

        @Override
        public void visitEnd()
        {
            verifyEmitterStatus();

            // We do not need to assert that the lock is held, because this method is empty,
            // but if this method ever started doing anything we would not want clients to
            // be broken.
            assertLockHeld();
        }
    }

    private class EmitterMethodBodyInfo implements IMethodBodyVisitor
    {
        EmitterMethodBodyInfo(MethodBodyInfo mbinfo)
        {
            this.mbi = mbinfo;
        }

        MethodBodyInfo mbi;

        @Override
        public void visit()
        {
            verifyEmitterStatus();

        }

        @Override
        public void visitEnd()
        {
            verifyEmitterStatus();

            assertLockHeld();
            poolOperands(mbi);
            methodBodies.add(mbi);

            for (ExceptionInfo exceptionInfo : mbi.getExceptions())
            {
                visitPooledName(exceptionInfo.getExceptionType());
                visitPooledName(exceptionInfo.getCatchVar());
            }
        }

        @Override
        public void visitInstruction(int opcode)
        {
            verifyEmitterStatus();

            this.mbi.insn(opcode);
        }

        @Override
        public void visitInstruction(int opcode, int immediate_operand)
        {
            verifyEmitterStatus();

            this.mbi.insn(opcode, immediate_operand);
        }

        @Override
        public void visitInstruction(int opcode, Object single_operand)
        {
            verifyEmitterStatus();

            this.mbi.insn(opcode, single_operand);
        }

        @Override
        public void visitInstruction(int opcode, Object[] operands)
        {
            verifyEmitterStatus();

            this.mbi.insn(opcode, operands);
        }

        @Override
        public void visitInstruction(Instruction insn)
        {
            verifyEmitterStatus();

            this.mbi.insn(insn);
        }

        @Override
        public ITraitsVisitor visitTraits()
        {
            verifyEmitterStatus();

            return new EmitterTraitsVisitor(this.mbi.getTraits());
        }

        @Override
        public int visitException(Label from, Label to, Label target, Name ex_type, Name ex_var)
        {
            verifyEmitterStatus();

            return mbi.addExceptionInfo(new ExceptionInfo(from, to, target, ex_type, ex_var));
        }

        @Override
        public void visitInstructionList(InstructionList new_list)
        {
            verifyEmitterStatus();

            mbi.setInstructionList(new_list);
        }

        @Override
        public void labelCurrent(Label l)
        {
            mbi.labelCurrent(l);
        }

        @Override
        public void labelNext(Label l)
        {
            mbi.labelNext(l);
        }
    }

    private class EmitterScriptInfo implements IScriptVisitor
    {
        EmitterScriptInfo()
        {
            this.si = new ScriptInfo();
        }

        final ScriptInfo si;

        @Override
        public void visit()
        {
            verifyEmitterStatus();
        }

        @Override
        public void visitEnd()
        {
            verifyEmitterStatus();
            assertLockHeld();
            scriptInfos.add(this.si);
        }

        @Override
        public void visitInit(MethodInfo init_method)
        {
            verifyEmitterStatus();

            si.setInit(init_method);
        }

        @Override
        public ITraitsVisitor visitTraits()
        {
            verifyEmitterStatus();

            return new EmitterTraitsVisitor(si.getTraits());
        }
    }

    private class EmitterMethodInfoVisitor implements IMethodVisitor
    {
        EmitterMethodInfoVisitor(MethodInfo mi)
        {
            assert (mi != null);
            this.mi = mi;
        }

        final MethodInfo mi;
        
        MethodBodyInfo mbi;

        @Override
        public void visit()
        {
            verifyEmitterStatus();

            // We need to grab a lock before adding the method
            // info to the method pool because this method ( the visit method )
            // can be called from any number of threads at the same time for the
            // same emitter.  This is the only place where we mutate emitter
            // state from a method other than visitEnd.
            //
            // We need to add the method info to the method pool here
            // so that the EmitterMethodBodyInfo.visitEnd call for other
            // methods can compute a method id for the method info
            // associated with this EmitterMethodInfoVisitor before
            // visitEnd has been called on this EmitterMethodInfoVisitor.
            final Lock methodInfosWriteLock = methodInfosLock.writeLock();
            methodInfosWriteLock.lock();
            try
            {
                methodInfos.add(mi);
            }
            finally
            {
                methodInfosWriteLock.unlock();
            }
        }

        @Override
        public IMethodBodyVisitor visitBody(MethodBodyInfo mbi)
        {
            verifyEmitterStatus();

            this.mbi = mbi;
            return new EmitterMethodBodyInfo(mbi);
        }

        @Override
        public void visitEnd()
        {
            verifyEmitterStatus();

            assertLockHeld();

            for (Name param_type_name : mi.getParamTypes())
                visitPooledName(param_type_name);

            if ((mbi != null) && (mi.isNative()))
                diagnosticsVisitor.nativeMethodWithMethodBody(mi, mbi);

            visitPooledString(mi.getMethodName());
            visitPooledName(mi.getReturnType());

            for (Name ptype : mi.getParamTypes())
            {
                visitPooledName(ptype);
            }

            if (mi.hasOptional())
            {
                for (PooledValue v : mi.getDefaultValues())
                {
                    v.setPoolIndex(visitPooledValue(v));
                }
            }

            if (mi.hasParamNames())
            {
                for (String param_name : mi.getParamNames())
                {
                    visitPooledString(param_name);
                }
            }

            //  Save the method body as compressed ABC bytecode,
            //  if so indicated.  EmitterMethodBodyInfo.visitEnd()
            //  does not do this because the method body needs the
            //  type names and default values pooled in this method.
            if (this.mbi != null)
            {
                this.mbi.computeFrameCounts(ABCEmitter.this.diagnosticsVisitor);

                //  Don't eagerly emit (to ABC blobs) method bodies that
                //  contain newclass instructions.  The class declarations
                //  are the one ABC header structure that may be sorted even
                //  without optimization (to reorder the declarations in
                //  dependency order).  If that happens then the indices
                //  in the newclass instructions would be invalid.
                if (eagerlyEmitMethodBodies && !this.mbi.hasNewclassInstruction())
                {
                    try
                    {
                        emitCode(this.mbi);
                    }
                    catch (RuntimeException uncheckedSNAFU)
                    {
                        throw uncheckedSNAFU;
                    }
                    catch (Exception checkedSNAFU)
                    {
                        //  TODO: The AET needs an error/warnings interface.
                        //  For now, "report" by rethrowing wrapped in an
                        //  unchecked exception.
                        throw new IllegalStateException(checkedSNAFU);
                    }
                }
            }
        }
    }

    /**
     * Record a PooledValue's value in the appropriate constant pool.
     * 
     * @return the pool index.
     * @see #PooledValue.setPoolIndex() which consumes the index.
     */
    private int visitPooledValue(PooledValue value)
    {
        switch (value.getKind())
        {
            case ABCConstants.CONSTANT_Int:
            {
                visitPooledInt(value.getIntegerValue());
                return this.intPool.id(value.getIntegerValue());
            }
            case ABCConstants.CONSTANT_UInt:
            {
                visitPooledUInt(value.getLongValue());
                return this.uintPool.id(value.getLongValue());
            }
            case ABCConstants.CONSTANT_Double:
            {
                visitPooledDouble(value.getDoubleValue());
                return this.doublePool.id(value.getDoubleValue());
            }
            case ABCConstants.CONSTANT_Utf8:
            {
                visitPooledString(value.getStringValue());
                return this.stringPool.id(value.getStringValue());
            }
            // The kind and index for a manifest CONSTANT are identical.
            case ABCConstants.CONSTANT_True:
            {
                return ABCConstants.CONSTANT_True;
            }
            case ABCConstants.CONSTANT_False:
            {
                return ABCConstants.CONSTANT_False;
            }
            case ABCConstants.CONSTANT_Undefined:
            {
                return ABCConstants.CONSTANT_Undefined;
            }
            case ABCConstants.CONSTANT_Null:
            {
                return ABCConstants.CONSTANT_Null;
            }
            //  All these variants of namespace are stored in the same pool.
            case ABCConstants.CONSTANT_Namespace:
            case ABCConstants.CONSTANT_PackageNs:
            case ABCConstants.CONSTANT_PackageInternalNs:
            case ABCConstants.CONSTANT_ProtectedNs:
            case ABCConstants.CONSTANT_ExplicitNamespace:
            case ABCConstants.CONSTANT_StaticProtectedNs:
            case ABCConstants.CONSTANT_PrivateNs:
            {
                visitPooledNamespace(value.getNamespaceValue());
                return this.nsPool.id(value.getNamespaceValue());
            }
            default:
            {
                throw new IllegalStateException("Unrecognized initializer type: " + value.getKind());
            }
        }
    }

    /**
     * Allow invalid jump instructions for legacy ABCs.
     * @param b - true if the caller wishes to allow bad jumps.
     */
    public void setAllowBadJumps(boolean b)
    {
        this.allowBadJumps = b;
    }

    /**
     * Lock used to enforce concurrency rules of this class.
     * <p>
     * This method is used to ensure that vistEnd calls are only made on the
     * same thread that called {@link #visit(int, int)}.
     * <p>
     * When running with asserts enabled this method will cause an assertion
     * failure when the currency rules of this class are violated.
     * <p>
     * When running with asserts disabled this method will cause a deadlock when
     * the currency rules of this class are violated.
     * 
     * @see #lock()
     */
    private void assertLockHeld()
    {
        assert this.lock.isHeldByCurrentThread() : "A visitEnd method was called from a thread other than the thread that called IABCVisitor.visit!";
        // lock immediately followed by unlock should be a NOP, unless
        // some other thread holds the lock ( which the assert above guards against when
        // running with asserts enabled ).
        lock.lock();
        lock.unlock();
    }

    /**
     * verifyEmitterStatus() verifies that the emitter has not seen a visitEnd()
     * call.
     */
    private void verifyEmitterStatus()
    {
        if (this.visitEndCalled)
            throw new IllegalStateException("An ABCEmitter can only emit once visitEnd has been called.");
    }
}
