1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/*
2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project
3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License.
6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at
7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson *
10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software
11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and
14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License.
15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */
16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.dex.code;
18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.io.Opcodes;
20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.Constant;
21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.rop.cst.CstBaseMethodRef;
22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.AnnotatedOutput;
23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.ExceptionWithContext;
24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.FixedSizeList;
25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.IndentingWriter;
26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.IOException;
28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.OutputStream;
29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.OutputStreamWriter;
30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.io.Writer;
31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.ArrayList;
32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/**
34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * List of {@link DalvInsn} instances.
35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */
36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class DalvInsnList extends FixedSizeList {
37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * The amount of register space, in register units, required for this
40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * code block. This may be greater than the largest observed register+
41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * category because the method this code block exists in may
42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * specify arguments that are unused by the method.
43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    private final int regCount;
45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Constructs and returns an immutable instance whose elements are
48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * identical to the ones in the given list, in the same order.
49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param list {@code non-null;} the list to use for elements
51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param regCount count, in register-units, of the number of registers
52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * this code block requires.
53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} an appropriately-constructed instance of this
54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * class
55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public static DalvInsnList makeImmutable(ArrayList<DalvInsn> list,
57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            int regCount) {
58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int size = list.size();
59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        DalvInsnList result = new DalvInsnList(size, regCount);
60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        for (int i = 0; i < size; i++) {
62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            result.set(i, list.get(i));
63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        result.setImmutable();
66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return result;
67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Constructs an instance. All indices initially contain {@code null}.
71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param size the size of the list
73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public DalvInsnList(int size, int regCount) {
75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        super(size);
76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        this.regCount = regCount;
77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the element at the given index. It is an error to call
81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * this with the index for an element which was never set; if you
82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * do that, this will throw {@code NullPointerException}.
83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param n {@code >= 0, < size();} which index
85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code non-null;} element at that index
86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public DalvInsn get(int n) {
88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return (DalvInsn) get0(n);
89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Sets the instruction at the given index.
93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param n {@code >= 0, < size();} which index
95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param insn {@code non-null;} the instruction to set at {@code n}
96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void set(int n, DalvInsn insn) {
98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        set0(n, insn);
99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the size of this instance, in 16-bit code units. This will only
103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * return a meaningful result if the instructions in this instance all
104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * have valid addresses.
105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code >= 0;} the size
107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public int codeSize() {
109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int sz = size();
110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (sz == 0) {
112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            return 0;
113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        DalvInsn last = get(sz - 1);
116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return last.getNextAddress();
117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Writes all the instructions in this instance to the given output
121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * destination.
122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param out {@code non-null;} where to write to
124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void writeTo(AnnotatedOutput out) {
126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int startCursor = out.getCursor();
127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int sz = size();
128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (out.annotates()) {
130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            boolean verbose = out.isVerbose();
131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            for (int i = 0; i < sz; i++) {
133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                DalvInsn insn = (DalvInsn) get0(i);
134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                int codeBytes = insn.codeSize() * 2;
135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                String s;
136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                if ((codeBytes != 0) || verbose) {
138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    s = insn.listingString("  ", out.getAnnotationWidth(),
139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                            true);
140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                } else {
141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    s = null;
142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                }
143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                if (s != null) {
145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    out.annotate(codeBytes, s);
146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                } else if (codeBytes != 0) {
147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    out.annotate(codeBytes, "");
148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                }
149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        for (int i = 0; i < sz; i++) {
153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            DalvInsn insn = (DalvInsn) get0(i);
154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            try {
155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                insn.writeTo(out);
156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            } catch (RuntimeException ex) {
157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                throw ExceptionWithContext.withContext(ex,
158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                        "...while writing " + insn);
159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        // Sanity check of the amount written.
163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int written = (out.getCursor() - startCursor) / 2;
164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        if (written != codeSize()) {
165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            throw new RuntimeException("write length mismatch; expected " +
166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    codeSize() + " but actually wrote " + written);
167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the minimum required register count implied by this
172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * instance.  This includes any unused parameters that could
173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * potentially be at the top of the register space.
174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code >= 0;} the required registers size
175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public int getRegistersSize() {
177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return regCount;
178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Gets the size of the outgoing arguments area required by this
182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * method. This is equal to the largest argument word count of any
183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * method referred to by this instance.
184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @return {@code >= 0;} the required outgoing arguments size
186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public int getOutsSize() {
188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int sz = size();
189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int result = 0;
190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        for (int i = 0; i < sz; i++) {
192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            DalvInsn insn = (DalvInsn) get0(i);
193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (!(insn instanceof CstInsn)) {
195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                continue;
196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            Constant cst = ((CstInsn) insn).getConstant();
199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (!(cst instanceof CstBaseMethodRef)) {
201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                continue;
202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            boolean isStatic =
205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                (insn.getOpcode().getFamily() == Opcodes.INVOKE_STATIC);
206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            int count =
207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                ((CstBaseMethodRef) cst).getParameterWordCount(isStatic);
208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            if (count > result) {
210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                result = count;
211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        return result;
215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Does a human-friendly dump of this instance.
219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param out {@code non-null;} where to dump
221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param prefix {@code non-null;} prefix to attach to each line of output
222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param verbose whether to be verbose; verbose output includes
223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * lines for zero-size instructions and explicit constant pool indices
224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void debugPrint(Writer out, String prefix, boolean verbose) {
226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        IndentingWriter iw = new IndentingWriter(out, 0, prefix);
227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        int sz = size();
228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        try {
230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            for (int i = 0; i < sz; i++) {
231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                DalvInsn insn = (DalvInsn) get0(i);
232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                String s;
233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                if ((insn.codeSize() != 0) || verbose) {
235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    s = insn.listingString("", 0, verbose);
236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                } else {
237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    s = null;
238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                }
239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                if (s != null) {
241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                    iw.write(s);
242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson                }
243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            }
244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            iw.flush();
246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        } catch (IOException ex) {
247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            throw new RuntimeException(ex);
248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    /**
252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * Does a human-friendly dump of this instance.
253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     *
254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param out {@code non-null;} where to dump
255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param prefix {@code non-null;} prefix to attach to each line of output
256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * @param verbose whether to be verbose; verbose output includes
257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     * lines for zero-size instructions
258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson     */
259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    public void debugPrint(OutputStream out, String prefix, boolean verbose) {
260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        Writer w = new OutputStreamWriter(out);
261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        debugPrint(w, prefix, verbose);
262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson
263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        try {
264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            w.flush();
265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        } catch (IOException ex) {
266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson            throw new RuntimeException(ex);
267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson        }
268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson    }
269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson}
270