/*
 * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.java.util.jar.pack;

import java.io.*;
import java.util.*;
import com.sun.java.util.jar.pack.Package.Class;
import java.lang.reflect.Modifier;

/**
 * Represents a chunk of bytecodes.
 * @author John Rose
 */
class Code extends Attribute.Holder implements Constants {
    Class.Method m;

    public Code(Class.Method m) {
        this.m = m;
    }

    public Class.Method getMethod() {
        return m;
    }
    public Class thisClass() {
        return m.thisClass();
    }
    public Package getPackage() {
        return m.thisClass().getPackage();
    }

    public ConstantPool.Entry[] getCPMap() {
        return m.getCPMap();
    }

    static private final ConstantPool.Entry[] noRefs = ConstantPool.noRefs;

    // The following fields are used directly by the ClassReader, etc.
    int max_stack;
    int max_locals;

    ConstantPool.Entry handler_class[] = noRefs;
    int handler_start[] = noInts;
    int handler_end[] = noInts;
    int handler_catch[] = noInts;

    byte[] bytes;
    Fixups fixups;  // reference relocations, if any are required
    Object insnMap; // array of instruction boundaries

    int getLength() { return bytes.length; }

    int getMaxStack() {
        return max_stack;
    }
    void setMaxStack(int ms) {
        max_stack = ms;
    }

    int getMaxNALocals() {
        int argsize = m.getArgumentSize();
        return max_locals - argsize;
    }
    void setMaxNALocals(int ml) {
        int argsize = m.getArgumentSize();
        max_locals = argsize + ml;
    }

    int getHandlerCount() {
        assert(handler_class.length == handler_start.length);
        assert(handler_class.length == handler_end.length);
        assert(handler_class.length == handler_catch.length);
        return handler_class.length;
    }
    void setHandlerCount(int h) {
        if (h > 0) {
            handler_class = new ConstantPool.Entry[h];
            handler_start = new int[h];
            handler_end   = new int[h];
            handler_catch = new int[h];
            // caller must fill these in ASAP
        }
    }

    void setBytes(byte[] bytes) {
        this.bytes = bytes;
        if (fixups != null)
            fixups.setBytes(bytes);
    }

    void setInstructionMap(int[] insnMap, int mapLen) {
        //int[] oldMap = null;
        //assert((oldMap = getInstructionMap()) != null);
        this.insnMap = allocateInstructionMap(insnMap, mapLen);
        //assert(Arrays.equals(oldMap, getInstructionMap()));
    }
    void setInstructionMap(int[] insnMap) {
        setInstructionMap(insnMap, insnMap.length);
    }

    int[] getInstructionMap() {
        return expandInstructionMap(getInsnMap());
    }

    void addFixups(Collection moreFixups) {
        if (fixups == null) {
            fixups = new Fixups(bytes);
        }
        assert(fixups.getBytes() == bytes);
        fixups.addAll(moreFixups);
    }

    public void trimToSize() {
        if (fixups != null) {
            fixups.trimToSize();
            if (fixups.size() == 0)
                fixups = null;
        }
        super.trimToSize();
    }

    protected void visitRefs(int mode, Collection refs) {
        int verbose = getPackage().verbose;
        if (verbose > 2)
            System.out.println("Reference scan "+this);
        Class cls = thisClass();
        Package pkg = cls.getPackage();
        for (int i = 0; i < handler_class.length; i++) {
            refs.add(handler_class[i]);
        }
        if (fixups != null) {
            fixups.visitRefs(refs);
        } else {
            // References (to a local cpMap) are embedded in the bytes.
            ConstantPool.Entry[] cpMap = getCPMap();
            for (Instruction i = instructionAt(0); i != null; i = i.next()) {
                if (verbose > 4)
                    System.out.println(i);
                int cpref = i.getCPIndex();
                if (cpref >= 0) {
                    refs.add(cpMap[cpref]);
                }
            }
        }
        // Handle attribute list:
        super.visitRefs(mode, refs);
    }

    // Since bytecodes are the single largest contributor to
    // package size, it's worth a little bit of trouble
    // to reduce the per-bytecode memory footprint.
    // In the current scheme, half of the bulk of these arrays
    // due to bytes, and half to shorts.  (Ints are insignificant.)
    // Given an average of 1.8 bytes per instruction, this means
    // instruction boundary arrays are about a 75% overhead--tolerable.
    // (By using bytes, we get 33% savings over just shorts and ints.
    // Using both bytes and shorts gives 66% savings over just ints.)
    static final boolean shrinkMaps = true;

    private Object allocateInstructionMap(int[] insnMap, int mapLen) {
        int PClimit = getLength();
        if (shrinkMaps && PClimit <= Byte.MAX_VALUE - Byte.MIN_VALUE) {
            byte[] map = new byte[mapLen+1];
            for (int i = 0; i < mapLen; i++) {
                map[i] = (byte)(insnMap[i] + Byte.MIN_VALUE);
            }
            map[mapLen] = (byte)(PClimit + Byte.MIN_VALUE);
            return map;
        } else if (shrinkMaps && PClimit < Short.MAX_VALUE - Short.MIN_VALUE) {
            short[] map = new short[mapLen+1];
            for (int i = 0; i < mapLen; i++) {
                map[i] = (short)(insnMap[i] + Short.MIN_VALUE);
            }
            map[mapLen] = (short)(PClimit + Short.MIN_VALUE);
            return map;
        } else {
            int[] map = new int[mapLen+1];
            for (int i = 0; i < mapLen; i++) {
                map[i] = (int) insnMap[i];
            }
            map[mapLen] = (int) PClimit;
            return map;
        }
    }
    private int[] expandInstructionMap(Object map0) {
        int[] imap;
        if (map0 instanceof byte[]) {
            byte[] map = (byte[]) map0;
            imap = new int[map.length-1];
            for (int i = 0; i < imap.length; i++) {
                imap[i] = map[i] - Byte.MIN_VALUE;
            }
        } else if (map0 instanceof short[]) {
            short[] map = (short[]) map0;
            imap = new int[map.length-1];
            for (int i = 0; i < imap.length; i++) {
                imap[i] = map[i] - Byte.MIN_VALUE;
            }
        } else {
            int[] map = (int[]) map0;
            imap = new int[map.length-1];
            for (int i = 0; i < imap.length; i++) {
                imap[i] = map[i];
            }
        }
        return imap;
    }

    Object getInsnMap() {
        // Build a map of instruction boundaries.
        if (insnMap != null) {
            return insnMap;
        }
        int[] map = new int[getLength()];
        int fillp = 0;
        for (Instruction i = instructionAt(0); i != null; i = i.next()) {
            map[fillp++] = i.getPC();
        }
        // Make it byte[], short[], or int[] according to the max BCI.
        insnMap = allocateInstructionMap(map, fillp);
        //assert(assertBCICodingsOK());
        return insnMap;
    }

    /** Encode the given BCI as an instruction boundary number.
     *  For completeness, irregular (non-boundary) BCIs are
     *  encoded compactly immediately after the boundary numbers.
     *  This encoding is the identity mapping outside 0..length,
     *  and it is 1-1 everywhere.  All by itself this technique
     *  improved zipped rt.jar compression by 2.6%.
     */
    public int encodeBCI(int bci) {
        if (bci <= 0 || bci > getLength())  return bci;
        Object map0 = getInsnMap();
        int i, len;
        if (shrinkMaps && map0 instanceof byte[]) {
            byte[] map = (byte[]) map0;
            len = map.length;
            i = Arrays.binarySearch(map, (byte)(bci + Byte.MIN_VALUE));
        } else if (shrinkMaps && map0 instanceof short[]) {
            short[] map = (short[]) map0;
            len = map.length;
            i = Arrays.binarySearch(map, (short)(bci + Short.MIN_VALUE));
        } else {
            int[] map = (int[]) map0;
            len = map.length;
            i = Arrays.binarySearch(map, (int)bci);
        }
        assert(i != -1);
        assert(i != 0);
        assert(i != len);
        assert(i != -len-1);
        return (i >= 0) ? i : len + bci - (-i-1);
    }
    public int decodeBCI(int bciCode) {
        if (bciCode <= 0 || bciCode > getLength())  return bciCode;
        Object map0 = getInsnMap();
        int i, len;
        // len == map.length
        // If bciCode < len, result is map[bciCode], the common and fast case.
        // Otherwise, let map[i] be the smallest map[*] larger than bci.
        // Then, required by the return statement of encodeBCI:
        //   bciCode == len + bci - i
        // Thus:
        //   bci-i == bciCode-len
        //   map[i]-adj-i == bciCode-len ; adj in (0..map[i]-map[i-1])
        // We can solve this by searching for adjacent entries
        // map[i-1], map[i] such that:
        //   map[i-1]-(i-1) <= bciCode-len < map[i]-i
        // This can be approximated by searching map[i] for bciCode and then
        // linear searching backward.  Given the right i, we then have:
        //   bci == bciCode-len + i
        // This linear search is at its worst case for indexes in the beginning
        // of a large method, but it's not clear that this is a problem in
        // practice, since BCIs are usually on instruction boundaries.
        if (shrinkMaps && map0 instanceof byte[]) {
            byte[] map = (byte[]) map0;
            len = map.length;
            if (bciCode < len)
                return map[bciCode] - Byte.MIN_VALUE;
            i = Arrays.binarySearch(map, (byte)(bciCode + Byte.MIN_VALUE));
            if (i < 0)  i = -i-1;
            int key = bciCode-len + Byte.MIN_VALUE;
            for (;; i--) {
                if (map[i-1]-(i-1) <= key)  break;
            }
        } else if (shrinkMaps && map0 instanceof short[]) {
            short[] map = (short[]) map0;
            len = map.length;
            if (bciCode < len)
                return map[bciCode] - Short.MIN_VALUE;
            i = Arrays.binarySearch(map, (short)(bciCode + Short.MIN_VALUE));
            if (i < 0)  i = -i-1;
            int key = bciCode-len + Short.MIN_VALUE;
            for (;; i--) {
                if (map[i-1]-(i-1) <= key)  break;
            }
        } else {
            int[] map = (int[]) map0;
            len = map.length;
            if (bciCode < len)
                return map[bciCode];
            i = Arrays.binarySearch(map, (int)bciCode);
            if (i < 0)  i = -i-1;
            int key = bciCode-len;
            for (;; i--) {
                if (map[i-1]-(i-1) <= key)  break;
            }
        }
        return bciCode-len + i;
    }

    public void finishRefs(ConstantPool.Index ix) {
        if (fixups != null) {
            fixups.finishRefs(ix);
            fixups = null;
        }
        // Code attributes are finished in ClassWriter.writeAttributes.
    }

    Instruction instructionAt(int pc) {
        return Instruction.at(bytes, pc);
    }

    static boolean flagsRequireCode(int flags) {
        // A method's flags force it to have a Code attribute,
        // if the flags are neither native nor abstract.
        return (flags & (Modifier.NATIVE | Modifier.ABSTRACT)) == 0;
    }

    public String toString() {
        return m+".Code";
    }

    /// Fetching values from my own array.
    public int getInt(int pc)    { return Instruction.getInt(bytes, pc); }
    public int getShort(int pc)  { return Instruction.getShort(bytes, pc); }
    public int getByte(int pc)   { return Instruction.getByte(bytes, pc); }
    void setInt(int pc, int x)   { Instruction.setInt(bytes, pc, x); }
    void setShort(int pc, int x) { Instruction.setShort(bytes, pc, x); }
    void setByte(int pc, int x)  { Instruction.setByte(bytes, pc, x); }

/* TEST CODE ONLY
    private boolean assertBCICodingsOK() {
        boolean ok = true;
        int len = java.lang.reflect.Array.getLength(insnMap);
        int base = 0;
        if (insnMap.getClass().getComponentType() == Byte.TYPE)
            base = Byte.MIN_VALUE;
        if (insnMap.getClass().getComponentType() == Short.TYPE)
            base = Short.MIN_VALUE;
        for (int i = -1, imax = getLength()+1; i <= imax; i++) {
            int bci = i;
            int enc = Math.min(-999, bci-1);
            int dec = enc;
            try {
                enc = encodeBCI(bci);
                dec = decodeBCI(enc);
            } catch (RuntimeException ee) {
                ee.printStackTrace();
            }
            if (dec == bci) {
                //System.out.println("BCI="+bci+(enc<len?"":"   ")+" enc="+enc);
                continue;
            }
            if (ok) {
                for (int q = 0; q <= 1; q++) {
                    StringBuffer sb = new StringBuffer();
                    sb.append("bci "+(q==0?"map":"del")+"["+len+"] = {");
                    for (int j = 0; j < len; j++) {
                        int mapi = ((Number)java.lang.reflect.Array.get(insnMap, j)).intValue() - base;
                        mapi -= j*q;
                        sb.append(" "+mapi);
                    }
                    sb.append(" }");
                    System.out.println("*** "+sb);
                }
            }
            System.out.println("*** BCI="+bci+" enc="+enc+" dec="+dec);
            ok = false;
        }
        return ok;
    }
//*/
}
