1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/*
2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project
3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License");
5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License.
6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at
7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *      http://www.apache.org/licenses/LICENSE-2.0
9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software
11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS,
12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and
14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License.
15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.rop.code;
18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.FixedSizeList;
20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/**
22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * List of {@link Insn} instances.
23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class InsnList
25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        extends FixedSizeList {
26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs an instance. All indices initially contain {@code null}.
28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param size the size of the list
30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public InsnList(int size) {
32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        super(size);
33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the element at the given index. It is an error to call
37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * this with the index for an element which was never set; if you
38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * do that, this will throw {@code NullPointerException}.
39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param n {@code >= 0, < size();} which index
41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} element at that index
42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public Insn get(int n) {
44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return (Insn) get0(n);
45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Sets the instruction at the given index.
49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param n {@code >= 0, < size();} which index
51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param insn {@code non-null;} the instruction to set at {@code n}
52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public void set(int n, Insn insn) {
54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        set0(n, insn);
55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Gets the last instruction. This is just a convenient shorthand for
59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * {@code get(size() - 1)}.
60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} the last instruction
62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public Insn getLast() {
64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return get(size() - 1);
65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Visits each instruction in the list, in order.
69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param visitor {@code non-null;} visitor to use
71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public void forEach(Insn.Visitor visitor) {
73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int sz = size();
74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < sz; i++) {
76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            get(i).accept(visitor);
77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Compares the contents of this {@code InsnList} with another.
82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * The blocks must have the same number of insns, and each Insn must
83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * also return true to {@code Insn.contentEquals()}.
84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param b to compare
86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return true in the case described above.
87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public boolean contentEquals(InsnList b) {
89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (b == null) return false;
90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int sz = size();
92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (sz != b.size()) return false;
94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < sz; i++) {
96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (!get(i).contentEquals(b.get(i))) {
97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                return false;
98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return true;
102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Returns an instance that is identical to this one, except that
106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * the registers in each instruction are offset by the given
107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * amount. Mutability of the result is inherited from the
108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * original.
109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     *
110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @param delta the amount to offset register numbers by
111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * @return {@code non-null;} an appropriately-constructed instance
112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public InsnList withRegisterOffset(int delta) {
114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int sz = size();
115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        InsnList result = new InsnList(sz);
116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < sz; i++) {
118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            Insn one = (Insn) get0(i);
119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            if (one != null) {
120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                result.set0(i, one.withRegisterOffset(delta));
121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            }
122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (isImmutable()) {
125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            result.setImmutable();
126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return result;
129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul}
131