OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [external/] [asm/] [org/] [objectweb/] [asm/] [tree/] [analysis/] [BasicVerifier.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/***
2
 * ASM: a very small and fast Java bytecode manipulation framework
3
 * Copyright (c) 2000-2005 INRIA, France Telecom
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 * 3. Neither the name of the copyright holders nor the names of its
15
 *    contributors may be used to endorse or promote products derived from
16
 *    this software without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28
 * THE POSSIBILITY OF SUCH DAMAGE.
29
 */
30
package org.objectweb.asm.tree.analysis;
31
 
32
import java.util.List;
33
 
34
import org.objectweb.asm.Type;
35
import org.objectweb.asm.tree.AbstractInsnNode;
36
import org.objectweb.asm.tree.FieldInsnNode;
37
import org.objectweb.asm.tree.MethodInsnNode;
38
 
39
/**
40
 * An extended {@link BasicInterpreter} that checks that bytecode instructions
41
 * are correctly used.
42
 *
43
 * @author Eric Bruneton
44
 * @author Bing Ran
45
 */
46
public class BasicVerifier extends BasicInterpreter {
47
 
48
    public Value copyOperation(final AbstractInsnNode insn, final Value value)
49
            throws AnalyzerException
50
    {
51
        Value expected;
52
        switch (insn.getOpcode()) {
53
            case ILOAD:
54
            case ISTORE:
55
                expected = BasicValue.INT_VALUE;
56
                break;
57
            case FLOAD:
58
            case FSTORE:
59
                expected = BasicValue.FLOAT_VALUE;
60
                break;
61
            case LLOAD:
62
            case LSTORE:
63
                expected = BasicValue.LONG_VALUE;
64
                break;
65
            case DLOAD:
66
            case DSTORE:
67
                expected = BasicValue.DOUBLE_VALUE;
68
                break;
69
            case ALOAD:
70
                if (!((BasicValue) value).isReference()) {
71
                    throw new AnalyzerException(null,
72
                            "an object reference",
73
                            value);
74
                }
75
                return value;
76
            case ASTORE:
77
                if (!((BasicValue) value).isReference()
78
                        && value != BasicValue.RETURNADDRESS_VALUE)
79
                {
80
                    throw new AnalyzerException(null,
81
                            "an object reference or a return address",
82
                            value);
83
                }
84
                return value;
85
            default:
86
                return value;
87
        }
88
        // type is necessarily a primitive type here,
89
        // so value must be == to expected value
90
        if (value != expected) {
91
            throw new AnalyzerException(null, expected, value);
92
        }
93
        return value;
94
    }
95
 
96
    public Value unaryOperation(final AbstractInsnNode insn, Value value)
97
            throws AnalyzerException
98
    {
99
        Value expected;
100
        switch (insn.getOpcode()) {
101
            case INEG:
102
            case IINC:
103
            case I2F:
104
            case I2L:
105
            case I2D:
106
            case I2B:
107
            case I2C:
108
            case I2S:
109
            case IFEQ:
110
            case IFNE:
111
            case IFLT:
112
            case IFGE:
113
            case IFGT:
114
            case IFLE:
115
            case TABLESWITCH:
116
            case LOOKUPSWITCH:
117
            case IRETURN:
118
            case NEWARRAY:
119
            case ANEWARRAY:
120
                expected = BasicValue.INT_VALUE;
121
                break;
122
            case FNEG:
123
            case F2I:
124
            case F2L:
125
            case F2D:
126
            case FRETURN:
127
                expected = BasicValue.FLOAT_VALUE;
128
                break;
129
            case LNEG:
130
            case L2I:
131
            case L2F:
132
            case L2D:
133
            case LRETURN:
134
                expected = BasicValue.LONG_VALUE;
135
                break;
136
            case DNEG:
137
            case D2I:
138
            case D2F:
139
            case D2L:
140
            case DRETURN:
141
                expected = BasicValue.DOUBLE_VALUE;
142
                break;
143
            case GETFIELD:
144
                expected = newValue(Type.getType("L"
145
                        + ((FieldInsnNode) insn).owner + ";"));
146
                break;
147
            case CHECKCAST:
148
                if (!((BasicValue) value).isReference()) {
149
                    throw new AnalyzerException(null,
150
                            "an object reference",
151
                            value);
152
                }
153
                return super.unaryOperation(insn, value);
154
            case ARRAYLENGTH:
155
                if (!isArrayValue(value)) {
156
                    throw new AnalyzerException(null,
157
                            "an array reference",
158
                            value);
159
                }
160
                return super.unaryOperation(insn, value);
161
            case ARETURN:
162
            case ATHROW:
163
            case INSTANCEOF:
164
            case MONITORENTER:
165
            case MONITOREXIT:
166
            case IFNULL:
167
            case IFNONNULL:
168
                if (!((BasicValue) value).isReference()) {
169
                    throw new AnalyzerException(null,
170
                            "an object reference",
171
                            value);
172
                }
173
                return super.unaryOperation(insn, value);
174
            case PUTSTATIC:
175
                expected = newValue(Type.getType(((FieldInsnNode) insn).desc));
176
                break;
177
            default:
178
                throw new RuntimeException("Internal error.");
179
        }
180
        if (!isSubTypeOf(value, expected)) {
181
            throw new AnalyzerException(null, expected, value);
182
        }
183
        return super.unaryOperation(insn, value);
184
    }
185
 
186
    public Value binaryOperation(
187
        final AbstractInsnNode insn,
188
        final Value value1,
189
        final Value value2) throws AnalyzerException
190
    {
191
        Value expected1;
192
        Value expected2;
193
        switch (insn.getOpcode()) {
194
            case IALOAD:
195
                expected1 = newValue(Type.getType("[I"));
196
                expected2 = BasicValue.INT_VALUE;
197
                break;
198
            case BALOAD:
199
                if (!isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
200
                    expected1 = newValue(Type.getType("[B"));
201
                } else {
202
                    expected1 = newValue(Type.getType("[Z"));
203
                }
204
                expected2 = BasicValue.INT_VALUE;
205
                break;
206
            case CALOAD:
207
                expected1 = newValue(Type.getType("[C"));
208
                expected2 = BasicValue.INT_VALUE;
209
                break;
210
            case SALOAD:
211
                expected1 = newValue(Type.getType("[S"));
212
                expected2 = BasicValue.INT_VALUE;
213
                break;
214
            case LALOAD:
215
                expected1 = newValue(Type.getType("[J"));
216
                expected2 = BasicValue.INT_VALUE;
217
                break;
218
            case FALOAD:
219
                expected1 = newValue(Type.getType("[F"));
220
                expected2 = BasicValue.INT_VALUE;
221
                break;
222
            case DALOAD:
223
                expected1 = newValue(Type.getType("[D"));
224
                expected2 = BasicValue.INT_VALUE;
225
                break;
226
            case AALOAD:
227
                expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
228
                expected2 = BasicValue.INT_VALUE;
229
                break;
230
            case IADD:
231
            case ISUB:
232
            case IMUL:
233
            case IDIV:
234
            case IREM:
235
            case ISHL:
236
            case ISHR:
237
            case IUSHR:
238
            case IAND:
239
            case IOR:
240
            case IXOR:
241
            case IF_ICMPEQ:
242
            case IF_ICMPNE:
243
            case IF_ICMPLT:
244
            case IF_ICMPGE:
245
            case IF_ICMPGT:
246
            case IF_ICMPLE:
247
                expected1 = BasicValue.INT_VALUE;
248
                expected2 = BasicValue.INT_VALUE;
249
                break;
250
            case FADD:
251
            case FSUB:
252
            case FMUL:
253
            case FDIV:
254
            case FREM:
255
            case FCMPL:
256
            case FCMPG:
257
                expected1 = BasicValue.FLOAT_VALUE;
258
                expected2 = BasicValue.FLOAT_VALUE;
259
                break;
260
            case LADD:
261
            case LSUB:
262
            case LMUL:
263
            case LDIV:
264
            case LREM:
265
            case LAND:
266
            case LOR:
267
            case LXOR:
268
            case LCMP:
269
                expected1 = BasicValue.LONG_VALUE;
270
                expected2 = BasicValue.LONG_VALUE;
271
                break;
272
            case LSHL:
273
            case LSHR:
274
            case LUSHR:
275
                expected1 = BasicValue.LONG_VALUE;
276
                expected2 = BasicValue.INT_VALUE;
277
                break;
278
            case DADD:
279
            case DSUB:
280
            case DMUL:
281
            case DDIV:
282
            case DREM:
283
            case DCMPL:
284
            case DCMPG:
285
                expected1 = BasicValue.DOUBLE_VALUE;
286
                expected2 = BasicValue.DOUBLE_VALUE;
287
                break;
288
            case IF_ACMPEQ:
289
            case IF_ACMPNE:
290
                expected1 = BasicValue.REFERENCE_VALUE;
291
                expected2 = BasicValue.REFERENCE_VALUE;
292
                break;
293
            case PUTFIELD:
294
                FieldInsnNode fin = (FieldInsnNode) insn;
295
                expected1 = newValue(Type.getType("L" + fin.owner + ";"));
296
                expected2 = newValue(Type.getType(fin.desc));
297
                break;
298
            default:
299
                throw new RuntimeException("Internal error.");
300
        }
301
        if (!isSubTypeOf(value1, expected1)) {
302
            throw new AnalyzerException("First argument", expected1, value1);
303
        } else if (!isSubTypeOf(value2, expected2)) {
304
            throw new AnalyzerException("Second argument", expected2, value2);
305
        }
306
        if (insn.getOpcode() == AALOAD) {
307
            return getElementValue(value1);
308
        } else {
309
            return super.binaryOperation(insn, value1, value2);
310
        }
311
    }
312
 
313
    public Value ternaryOperation(
314
        final AbstractInsnNode insn,
315
        final Value value1,
316
        final Value value2,
317
        final Value value3) throws AnalyzerException
318
    {
319
        Value expected1;
320
        Value expected3;
321
        switch (insn.getOpcode()) {
322
            case IASTORE:
323
                expected1 = newValue(Type.getType("[I"));
324
                expected3 = BasicValue.INT_VALUE;
325
                break;
326
            case BASTORE:
327
                if (!isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
328
                    expected1 = newValue(Type.getType("[B"));
329
                } else {
330
                    expected1 = newValue(Type.getType("[Z"));
331
                }
332
                expected3 = BasicValue.INT_VALUE;
333
                break;
334
            case CASTORE:
335
                expected1 = newValue(Type.getType("[C"));
336
                expected3 = BasicValue.INT_VALUE;
337
                break;
338
            case SASTORE:
339
                expected1 = newValue(Type.getType("[S"));
340
                expected3 = BasicValue.INT_VALUE;
341
                break;
342
            case LASTORE:
343
                expected1 = newValue(Type.getType("[J"));
344
                expected3 = BasicValue.LONG_VALUE;
345
                break;
346
            case FASTORE:
347
                expected1 = newValue(Type.getType("[F"));
348
                expected3 = BasicValue.FLOAT_VALUE;
349
                break;
350
            case DASTORE:
351
                expected1 = newValue(Type.getType("[D"));
352
                expected3 = BasicValue.DOUBLE_VALUE;
353
                break;
354
            case AASTORE:
355
                expected1 = value1;
356
                expected3 = BasicValue.REFERENCE_VALUE;
357
                break;
358
            default:
359
                throw new RuntimeException("Internal error.");
360
        }
361
        if (!isSubTypeOf(value1, expected1)) {
362
            throw new AnalyzerException("First argument", "a " + expected1
363
                    + " array reference", value1);
364
        } else if (value2 != BasicValue.INT_VALUE) {
365
            throw new AnalyzerException("Second argument",
366
                    BasicValue.INT_VALUE,
367
                    value2);
368
        } else if (!isSubTypeOf(value3, expected3)) {
369
            throw new AnalyzerException("Third argument", expected3, value3);
370
        }
371
        return null;
372
    }
373
 
374
    public Value naryOperation(final AbstractInsnNode insn, final List values)
375
            throws AnalyzerException
376
    {
377
        int opcode = insn.getOpcode();
378
        if (opcode == MULTIANEWARRAY) {
379
            for (int i = 0; i < values.size(); ++i) {
380
                if (values.get(i) != BasicValue.INT_VALUE) {
381
                    throw new AnalyzerException(null,
382
                            BasicValue.INT_VALUE,
383
                            (Value) values.get(i));
384
                }
385
            }
386
        } else {
387
            int i = 0;
388
            int j = 0;
389
            if (opcode != INVOKESTATIC) {
390
                String own = ((MethodInsnNode) insn).owner;
391
                if (own.charAt(0) != '[') { // can happen with JDK1.5 clone()
392
                    own = "L" + own + ";";
393
                }
394
                Type owner = Type.getType(own);
395
                if (!isSubTypeOf((Value) values.get(i++), newValue(owner))) {
396
                    throw new AnalyzerException("Method owner",
397
                            newValue(owner),
398
                            (Value) values.get(0));
399
                }
400
            }
401
            Type[] args = Type.getArgumentTypes(((MethodInsnNode) insn).desc);
402
            while (i < values.size()) {
403
                Value expected = newValue(args[j++]);
404
                Value encountered = (Value) values.get(i++);
405
                if (!isSubTypeOf(encountered, expected)) {
406
                    throw new AnalyzerException("Argument " + j,
407
                            expected,
408
                            encountered);
409
                }
410
            }
411
        }
412
        return super.naryOperation(insn, values);
413
    }
414
 
415
    protected boolean isArrayValue(final Value value) {
416
        return ((BasicValue) value).isReference();
417
    }
418
 
419
    protected Value getElementValue(final Value objectArrayValue)
420
            throws AnalyzerException
421
    {
422
        return BasicValue.REFERENCE_VALUE;
423
    }
424
 
425
    protected boolean isSubTypeOf(final Value value, final Value expected) {
426
        return value == expected;
427
    }
428
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.