Fork of Apache Harmony's Pack200 implementation
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pack200/src/test/java/org/apache/harmony/unpack200/tests/CodeAttributeTest.java

203 lines
7.2 KiB

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.unpack200.tests;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.apache.harmony.unpack200.CpBands;
import org.apache.harmony.unpack200.Segment;
import org.apache.harmony.unpack200.SegmentConstantPool;
import org.apache.harmony.unpack200.bytecode.ByteCode;
import org.apache.harmony.unpack200.bytecode.CPFieldRef;
import org.apache.harmony.unpack200.bytecode.CPMethodRef;
import org.apache.harmony.unpack200.bytecode.CPString;
import org.apache.harmony.unpack200.bytecode.CPUTF8;
import org.apache.harmony.unpack200.bytecode.CodeAttribute;
import org.apache.harmony.unpack200.bytecode.LocalVariableTableAttribute;
import org.apache.harmony.unpack200.bytecode.OperandManager;
/**
* Tests for CodeAttribute
*/
public class CodeAttributeTest extends TestCase {
public class MockCodeAttribute extends CodeAttribute {
public MockCodeAttribute(int maxStack, int maxLocals,
byte[] codePacked, Segment segment,
OperandManager operandManager, List exceptionTable) {
super(maxStack, maxLocals, codePacked, segment, operandManager,
exceptionTable);
}
public int getLength() {
return super.getLength();
}
}
public class MockCpBands extends CpBands {
public MockCpBands(Segment segment) {
super(segment);
}
public CPFieldRef cpFieldValue(int index) {
return null;
}
public CPString cpStringValue(int index) {
return new CPString(new CPUTF8("Hello"), -1);
}
public CPMethodRef cpMethodValue(int index) {
return null;
}
}
public class MockOperandManager extends OperandManager {
public MockOperandManager() {
super(new int[] {}, // bcCaseCount
new int[] {}, // bcCaseValues
new int[] {}, // bcByte
new int[] {}, // bcShort
new int[] {}, // bcLocal
new int[] {}, // bcLabel
new int[] {}, // bcIntRef
new int[] {}, // bcFloatRef
new int[] {}, // bcLongRef
new int[] {}, // bcDoubleRef
new int[] { 0, 1, 2, 3, 4 }, // bcStringRef
new int[] {}, // bcClassRef
new int[] {}, // bcFieldRef
new int[] {}, // bcMethodRef
new int[] {}, // bcIMethodRef
new int[] { 0, 0, 0, 0, 0, 0 }, // bcThisField
new int[] {}, // bcSuperField
new int[] { 0 }, // bcThisMethod
new int[] {}, // bcSuperMethod
new int[] {} // bcInitRef
, null);
}
}
public class MockSegment extends Segment {
public SegmentConstantPool getConstantPool() {
return new MockSegmentConstantPool(cpBands);
}
}
public class MockSegmentConstantPool extends SegmentConstantPool {
public MockSegmentConstantPool(CpBands bands) {
super(bands);
}
protected int matchSpecificPoolEntryIndex(String[] nameArray,
String compareString, int desiredIndex) {
return 1;
}
}
Segment segment = new MockSegment();
CpBands cpBands = new MockCpBands(segment);
public byte[] mixedByteArray = { -47, // aload_0_getstatic_this 0, 1
-46, // aload_0_putstatic_this 4, 5
1, // aconst_null 8
-45, // aload_0_getfield_this 9, 10
// Should always end with a multibyte
// instruction
-44, // aload_0_putfield_this (int) 13, 14
};
public byte[] singleByteArray = { 42, // aload_0 0
1, // aconst_null 1
18, // ldc 2
-49, // return 4
};
public void testLength() {
OperandManager operandManager = new MockOperandManager();
operandManager.setSegment(segment);
operandManager.setCurrentClass("java/lang/Foo");
MockCodeAttribute attribute = new MockCodeAttribute(3, // maxStack
2, // maxLocals
mixedByteArray, // codePacked
segment, // segment
operandManager, // operandManager
new ArrayList());
assertEquals(29, attribute.getLength());
attribute.attributes.add(new LocalVariableTableAttribute(0, null, null,
null, null, null));
assertEquals(37, attribute.getLength());
}
public void testMixedByteCodes() {
OperandManager operandManager = new MockOperandManager();
operandManager.setSegment(segment);
operandManager.setCurrentClass("java/lang/Foo");
CodeAttribute attribute = new CodeAttribute(3, // maxStack
2, // maxLocals
mixedByteArray, // codePacked
segment, // segment
operandManager, // operandManager
new ArrayList());
assertEquals(2, attribute.maxLocals);
assertEquals(3, attribute.maxStack);
assertEquals("aload_0_putfield_this", ((ByteCode) attribute.byteCodes
.get(4)).toString());
int expectedLabels[] = new int[] { 0, 1, 4, 5, 8, 9, 10, 13, 14 };
for (int index = 0; index < expectedLabels.length; index++) {
assertEquals(expectedLabels[index],
((Integer) attribute.byteCodeOffsets.get(index)).intValue());
}
}
public void testSingleByteCodes() {
OperandManager operandManager = new MockOperandManager();
operandManager.setSegment(segment);
operandManager.setCurrentClass("java/lang/Foo");
CodeAttribute attribute = new CodeAttribute(4, // maxStack
3, // maxLocals
singleByteArray, // codePacked
segment, // segment
operandManager, // operandManager
new ArrayList());
assertEquals(3, attribute.maxLocals);
assertEquals(4, attribute.maxStack);
assertEquals("invokespecial_this", ((ByteCode) attribute.byteCodes
.get(3)).toString());
int expectedLabels[] = new int[] { 0, 1, 2, 4 };
for (int index = 0; index < expectedLabels.length; index++) {
assertEquals(expectedLabels[index],
((Integer) attribute.byteCodeOffsets.get(index)).intValue());
}
}
}