1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.cf.code;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.RegisterSpec;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.LocalItem;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.Constant;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Prototype;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.StdTypeList;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Base implementation of {@link Machine}.
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p><b>Note:</b> For the most part, the documentation for this class
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ignores the distinction between {@link Type} and {@link
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TypeBearer}.</p>
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class BaseMachine implements Machine {
3699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /* {@code non-null;} the prototype for the associated method */
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final Prototype prototype;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} primary arguments */
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private TypeBearer[] args;
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code >= 0;} number of primary arguments */
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int argCount;
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} type of the operation, if salient */
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Type auxType;
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** auxiliary {@code int} argument */
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int auxInt;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} auxiliary constant argument */
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Constant auxCst;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** auxiliary branch target argument */
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int auxTarget;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} auxiliary switch cases argument */
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private SwitchList auxCases;
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} auxiliary initial value list for newarray */
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ArrayList<Constant> auxInitValues;
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code >= -1;} last local accessed */
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int localIndex;
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} local target spec, if salient and calculated */
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private RegisterSpec localTarget;
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} results */
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private TypeBearer[] results;
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
7399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code >= -1;} count of the results, or {@code -1} if no results
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * have been set
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int resultCount;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance.
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
8199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param prototype {@code non-null;} the prototype for the associated method
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public BaseMachine(Prototype prototype) {
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (prototype == null) {
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("prototype == null");
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.prototype = prototype;
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        args = new TypeBearer[10];
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        results = new TypeBearer[6];
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        clearArgs();
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Prototype getPrototype() {
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return prototype;
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void clearArgs() {
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        argCount = 0;
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxType = null;
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxInt = 0;
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxCst = null;
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxTarget = 0;
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxCases = null;
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxInitValues = null;
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        localIndex = -1;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        localTarget = null;
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        resultCount = -1;
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void popArgs(Frame frame, int count) {
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ExecutionStack stack = frame.getStack();
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        clearArgs();
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (count > args.length) {
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Grow args, and add a little extra room to grow even more.
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            args = new TypeBearer[count + 10];
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = count - 1; i >= 0; i--) {
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            args[i] = stack.pop();
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        argCount = count;
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void popArgs(Frame frame, Prototype prototype) {
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StdTypeList types = prototype.getParameterTypes();
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int size = types.size();
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Use the above method to do the actual popping...
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        popArgs(frame, size);
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // ...and then verify the popped types.
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < size; i++) {
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (! Merger.isPossiblyAssignableFrom(types.getType(i), args[i])) {
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new SimException("at stack depth " + (size - 1 - i) +
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        ", expected type " + types.getType(i).toHuman() +
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        " but found " + args[i].getType().toHuman());
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void popArgs(Frame frame, Type type) {
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Use the above method to do the actual popping...
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        popArgs(frame, 1);
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // ...and then verify the popped type.
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! Merger.isPossiblyAssignableFrom(type, args[0])) {
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("expected type " + type.toHuman() +
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    " but found " + args[0].getType().toHuman());
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void popArgs(Frame frame, Type type1, Type type2) {
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Use the above method to do the actual popping...
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        popArgs(frame, 2);
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // ...and then verify the popped types.
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! Merger.isPossiblyAssignableFrom(type1, args[0])) {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("expected type " + type1.toHuman() +
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    " but found " + args[0].getType().toHuman());
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! Merger.isPossiblyAssignableFrom(type2, args[1])) {
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("expected type " + type2.toHuman() +
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    " but found " + args[1].getType().toHuman());
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void popArgs(Frame frame, Type type1, Type type2,
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Type type3) {
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Use the above method to do the actual popping...
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        popArgs(frame, 3);
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // ...and then verify the popped types.
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! Merger.isPossiblyAssignableFrom(type1, args[0])) {
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("expected type " + type1.toHuman() +
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    " but found " + args[0].getType().toHuman());
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! Merger.isPossiblyAssignableFrom(type2, args[1])) {
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("expected type " + type2.toHuman() +
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    " but found " + args[1].getType().toHuman());
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! Merger.isPossiblyAssignableFrom(type3, args[2])) {
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("expected type " + type2.toHuman() +
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    " but found " + args[2].getType().toHuman());
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void localArg(Frame frame, int idx) {
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        clearArgs();
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        args[0] = frame.getLocals().get(idx);
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        argCount = 1;
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        localIndex = idx;
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void auxType(Type type) {
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxType = type;
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void auxIntArg(int value) {
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxInt = value;
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void auxCstArg(Constant cst) {
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (cst == null) {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("cst == null");
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxCst = cst;
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void auxTargetArg(int target) {
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxTarget = target;
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void auxSwitchArg(SwitchList cases) {
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (cases == null) {
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("cases == null");
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxCases = cases;
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void auxInitValues(ArrayList<Constant> initValues) {
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        auxInitValues = initValues;
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void localTarget(int idx, Type type, LocalItem local) {
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        localTarget = RegisterSpec.makeLocalOptional(idx, type, local);
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the number of primary arguments.
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
25799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the number of primary arguments
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final int argCount() {
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return argCount;
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the width of the arguments (where a category-2 value counts as
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * two).
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
26799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the argument width
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final int argWidth() {
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int result = 0;
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < argCount; i++) {
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result += args[i].getType().getCategory();
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
28099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the {@code n}th primary argument.
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
28299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param n {@code >= 0, < argCount();} which argument
28399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the indicated argument
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final TypeBearer arg(int n) {
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (n >= argCount) {
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("n >= argCount");
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return args[n];
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ArrayIndexOutOfBoundsException ex) {
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Translate the exception.
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("n < 0");
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the type auxiliary argument.
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
30199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the salient type
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final Type getAuxType() {
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return auxType;
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
30899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the {@code int} auxiliary argument.
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the argument value
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final int getAuxInt() {
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return auxInt;
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the constant auxiliary argument.
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
31999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the argument value
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final Constant getAuxCst() {
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return auxCst;
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the branch target auxiliary argument.
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the argument value
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final int getAuxTarget() {
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return auxTarget;
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the switch cases auxiliary argument.
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
33799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the argument value
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final SwitchList getAuxCases() {
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return auxCases;
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the init values auxiliary argument.
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
34699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the argument value
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final ArrayList<Constant> getInitValues() {
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return auxInitValues;
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the last local index accessed.
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
35499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= -1;} the salient local index or {@code -1} if none
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * was set since the last time {@link #clearArgs} was called
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final int getLocalIndex() {
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return localIndex;
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the target local register spec of the current operation, if any.
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The local target spec is the combination of the values indicated
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * by a previous call to {@link #localTarget} with the type of what
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * should be the sole result set by a call to {@link #setResult} (or
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the combination {@link #clearResult} then {@link #addResult}.
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
36899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the salient register spec or {@code null} if no
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * local target was set since the last time {@link #clearArgs} was
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * called
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final RegisterSpec getLocalTarget() {
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (localTarget == null) {
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (resultCount != 1) {
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("local target with " +
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    ((resultCount == 0) ? "no" : "multiple") + " results");
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        TypeBearer result = results[0];
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Type resultType = result.getType();
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Type localType = localTarget.getType();
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (resultType == localType) {
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return localTarget;
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! Merger.isPossiblyAssignableFrom(localType, resultType)) {
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // The result and local types are inconsistent. Complain!
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throwLocalMismatch(resultType, localType);
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (localType == Type.OBJECT) {
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * The result type is more specific than the local type,
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * so use that instead.
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            localTarget = localTarget.withType(result);
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return localTarget;
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Clears the results.
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final void clearResult() {
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        resultCount = 0;
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the results list to be the given single value.
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p><b>Note:</b> If there is more than one result value, the
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * others may be added by using {@link #addResult}.</p>
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
42099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param result {@code non-null;} result value
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final void setResult(TypeBearer result) {
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (result == null) {
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("result == null");
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        results[0] = result;
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        resultCount = 1;
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds an additional element to the list of results.
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #setResult
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
43699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param result {@code non-null;} result value
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final void addResult(TypeBearer result) {
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (result == null) {
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("result == null");
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        results[resultCount] = result;
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        resultCount++;
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the count of results. This throws an exception if results were
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * never set. (Explicitly clearing the results counts as setting them.)
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
45199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the count
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final int resultCount() {
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (resultCount < 0) {
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("results never set");
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return resultCount;
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the width of the results (where a category-2 value counts as
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * two).
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
46599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the result width
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final int resultWidth() {
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int width = 0;
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < resultCount; i++) {
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            width += results[i].getType().getCategory();
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return width;
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
47899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the {@code n}th result value.
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
48099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param n {@code >= 0, < resultCount();} which result
48199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the indicated result value
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final TypeBearer result(int n) {
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (n >= resultCount) {
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("n >= resultCount");
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return results[n];
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ArrayIndexOutOfBoundsException ex) {
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Translate the exception.
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("n < 0");
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Stores the results of the latest operation into the given frame. If
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * there is a local target (see {@link #localTarget}), then the sole
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * result is stored to that target; otherwise any results are pushed
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * onto the stack.
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
50299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param frame {@code non-null;} frame to operate on
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final void storeResults(Frame frame) {
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (resultCount < 0) {
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new SimException("results never set");
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (resultCount == 0) {
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Nothing to do.
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (localTarget != null) {
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * Note: getLocalTarget() doesn't necessarily return
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * localTarget directly.
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            frame.getLocals().set(getLocalTarget());
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ExecutionStack stack = frame.getStack();
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < resultCount; i++) {
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                stack.push(results[i]);
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Throws an exception that indicates a mismatch in local variable
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * types.
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
53299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param found {@code non-null;} the encountered type
53399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param local {@code non-null;} the local variable's claimed type
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static void throwLocalMismatch(TypeBearer found,
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            TypeBearer local) {
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new SimException("local variable type mismatch: " +
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "attempt to set or access a value of type " +
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                found.toHuman() +
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                " using a local variable of type " +
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                local.toHuman() +
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ". This is symptomatic of .class transformation tools " +
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "that ignore local variable information.");
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
546