1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dx.cf.code;
18
19import com.android.dx.rop.type.Type;
20import com.android.dx.rop.type.TypeBearer;
21import com.android.dx.util.Hex;
22
23/**
24 * Representation of a subroutine return address. In Java verification,
25 * somewhat counterintuitively, the salient bit of information you need to
26 * know about a return address is the <i>start address</i> of the subroutine
27 * being returned from, not the address being returned <i>to</i>, so that's
28 * what instances of this class hang onto.
29 */
30public final class ReturnAddress implements TypeBearer {
31    /** {@code >= 0;} the start address of the subroutine being returned from */
32    private final int subroutineAddress;
33
34    /**
35     * Constructs an instance.
36     *
37     * @param subroutineAddress {@code >= 0;} the start address of the
38     * subroutine being returned from
39     */
40    public ReturnAddress(int subroutineAddress) {
41        if (subroutineAddress < 0) {
42            throw new IllegalArgumentException("subroutineAddress < 0");
43        }
44
45        this.subroutineAddress = subroutineAddress;
46    }
47
48    /** {@inheritDoc} */
49    @Override
50    public String toString() {
51        return ("<addr:" + Hex.u2(subroutineAddress) + ">");
52    }
53
54    /** {@inheritDoc} */
55    public String toHuman() {
56        return toString();
57    }
58
59    /** {@inheritDoc} */
60    public Type getType() {
61        return Type.RETURN_ADDRESS;
62    }
63
64    /** {@inheritDoc} */
65    public TypeBearer getFrameType() {
66        return this;
67    }
68
69    /** {@inheritDoc} */
70    public int getBasicType() {
71        return Type.RETURN_ADDRESS.getBasicType();
72    }
73
74    /** {@inheritDoc} */
75    public int getBasicFrameType() {
76        return Type.RETURN_ADDRESS.getBasicFrameType();
77    }
78
79    /** {@inheritDoc} */
80    public boolean isConstant() {
81        return false;
82    }
83
84    /** {@inheritDoc} */
85    @Override
86    public boolean equals(Object other) {
87        if (!(other instanceof ReturnAddress)) {
88            return false;
89        }
90
91        return subroutineAddress == ((ReturnAddress) other).subroutineAddress;
92    }
93
94    /** {@inheritDoc} */
95    @Override
96    public int hashCode() {
97        return subroutineAddress;
98    }
99
100    /**
101     * Gets the subroutine address.
102     *
103     * @return {@code >= 0;} the subroutine address
104     */
105    public int getSubroutineAddress() {
106        return subroutineAddress;
107    }
108}
109