001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.drlvm.tests.regression.h3067;
019:
020: import junit.framework.TestCase;
021:
022: /**
023: * Loads class and tries to invoke a method which should fail
024: * verification.
025: *
026: * <code>wide</code> bytecode should be followed by an instruction
027: * which uses local variables. We patch WIDE_CLASS class, so <code>wide</code>
028: * is followed by <code>goto</code>. This should fail verification.
029: */
030: public class Test extends TestCase {
031: public static void main(String args[]) {
032: (new Test()).test();
033: }
034:
035: final static int NOPS = 20;
036: final static String PACKAGE_NAME = Test.class.getPackage()
037: .getName();
038: final static String WIDE_CLASS = PACKAGE_NAME + ".WideGoto";
039: final static int OPCODE_WIDE = 0xC4;
040:
041: public void test() {
042: final Loader loader = new Loader();
043: try {
044: Class c = loader.loadClass(WIDE_CLASS);
045: ((Test) c.newInstance()).test();
046: } catch (VerifyError ve) {
047: return;
048: } catch (Exception e) {
049: }
050: fail("A method of SupClass class should throw VerifyError");
051: }
052:
053: class Loader extends ClassLoader {
054: final static int LENGTH = 50000;
055:
056: public Class loadClass(String name)
057: throws ClassNotFoundException {
058: if (!name.equals(WIDE_CLASS)) {
059: return getParent().loadClass(name);
060: }
061: final String path = name.replace('.', '/') + ".class";
062: java.io.InputStream is = ClassLoader
063: .getSystemResourceAsStream(path);
064: if (is == null) {
065: System.out.println("Cannot find " + path);
066: return null;
067: }
068: int offset, nops = 0;
069: byte[] buffer = new byte[LENGTH];
070: for (offset = 0;; offset++) {
071: int b;
072: try {
073: b = is.read();
074: } catch (java.io.IOException ioe) {
075: return null;
076: }
077: if (b == -1) {
078: break;
079: }
080: if (offset == LENGTH) {
081: System.out
082: .println("Class too big, please increase LENGTH = "
083: + LENGTH);
084: return null;
085: }
086:
087: if (b == 0) {
088: nops++;
089: if (nops == NOPS) {
090: b = OPCODE_WIDE;
091: }
092: } else {
093: nops = 0;
094: }
095: buffer[offset] = (byte) b;
096: }
097: try {
098: return defineClass(name, buffer, 0, offset);
099: } catch (Exception e) {
100: return null;
101: }
102:
103: }
104: }
105: }
|