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.attrib;
18
19import com.android.dx.cf.code.ByteCatchList;
20import com.android.dx.cf.code.BytecodeArray;
21import com.android.dx.cf.iface.AttributeList;
22import com.android.dx.util.MutabilityException;
23
24/**
25 * Attribute class for standard {@code Code} attributes.
26 */
27public final class AttCode extends BaseAttribute {
28    /** {@code non-null;} attribute name for attributes of this type */
29    public static final String ATTRIBUTE_NAME = "Code";
30
31    /** {@code >= 0;} the stack size */
32    private final int maxStack;
33
34    /** {@code >= 0;} the number of locals */
35    private final int maxLocals;
36
37    /** {@code non-null;} array containing the bytecode per se */
38    private final BytecodeArray code;
39
40    /** {@code non-null;} the exception table */
41    private final ByteCatchList catches;
42
43    /** {@code non-null;} the associated list of attributes */
44    private final AttributeList attributes;
45
46    /**
47     * Constructs an instance.
48     *
49     * @param maxStack {@code >= 0;} the stack size
50     * @param maxLocals {@code >= 0;} the number of locals
51     * @param code {@code non-null;} array containing the bytecode per se
52     * @param catches {@code non-null;} the exception table
53     * @param attributes {@code non-null;} the associated list of attributes
54     */
55    public AttCode(int maxStack, int maxLocals, BytecodeArray code,
56                   ByteCatchList catches, AttributeList attributes) {
57        super(ATTRIBUTE_NAME);
58
59        if (maxStack < 0) {
60            throw new IllegalArgumentException("maxStack < 0");
61        }
62
63        if (maxLocals < 0) {
64            throw new IllegalArgumentException("maxLocals < 0");
65        }
66
67        if (code == null) {
68            throw new NullPointerException("code == null");
69        }
70
71        try {
72            if (catches.isMutable()) {
73                throw new MutabilityException("catches.isMutable()");
74            }
75        } catch (NullPointerException ex) {
76            // Translate the exception.
77            throw new NullPointerException("catches == null");
78        }
79
80        try {
81            if (attributes.isMutable()) {
82                throw new MutabilityException("attributes.isMutable()");
83            }
84        } catch (NullPointerException ex) {
85            // Translate the exception.
86            throw new NullPointerException("attributes == null");
87        }
88
89        this.maxStack = maxStack;
90        this.maxLocals = maxLocals;
91        this.code = code;
92        this.catches = catches;
93        this.attributes = attributes;
94    }
95
96    @Override
97    public int byteLength() {
98        return 10 + code.byteLength() + catches.byteLength() +
99            attributes.byteLength();
100    }
101
102    /**
103     * Gets the maximum stack size.
104     *
105     * @return {@code >= 0;} the maximum stack size
106     */
107    public int getMaxStack() {
108        return maxStack;
109    }
110
111    /**
112     * Gets the number of locals.
113     *
114     * @return {@code >= 0;} the number of locals
115     */
116    public int getMaxLocals() {
117        return maxLocals;
118    }
119
120    /**
121     * Gets the bytecode array.
122     *
123     * @return {@code non-null;} the bytecode array
124     */
125    public BytecodeArray getCode() {
126        return code;
127    }
128
129    /**
130     * Gets the exception table.
131     *
132     * @return {@code non-null;} the exception table
133     */
134    public ByteCatchList getCatches() {
135        return catches;
136    }
137
138    /**
139     * Gets the associated attribute list.
140     *
141     * @return {@code non-null;} the attribute list
142     */
143    public AttributeList getAttributes() {
144        return attributes;
145    }
146}
147