Browse Source

fixed JASSIST-175

git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@675 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
tags/rel_3_17_1_ga
chiba 11 years ago
parent
commit
705c3c6621

+ 1
- 1
Readme.html View File

@@ -284,7 +284,7 @@ see javassist.Dump.
<p>-version 3.17
<ul>
<li>OSGi bundle info is now included in the jar file.
<li>JIRA JASSIST-160, 163, 166, 168, 170, 171, 174 have been fixed.
<li>JIRA JASSIST-160, 163, 166, 168, 170, 171, 174, 175 have been fixed.
</ul>

<p>-version 3.16.1 on March 6, 2012

BIN
javassist.jar View File


+ 6
- 0
src/main/javassist/bytecode/BadBytecode.java View File

@@ -31,4 +31,10 @@ public class BadBytecode extends Exception {
public BadBytecode(String msg, Throwable cause) {
super(msg, cause);
}

public BadBytecode(MethodInfo minfo, Throwable cause) {
super(minfo.toString() + " in "
+ minfo.getConstPool().getClassName()
+ ": " + cause.getMessage(), cause);
}
}

+ 45
- 10
src/main/javassist/bytecode/stackmap/MapMaker.java View File

@@ -96,7 +96,13 @@ public class MapMaker extends Tracer {
return null;

MapMaker mm = new MapMaker(classes, minfo, ca);
mm.make(blocks, ca.getCode());
try {
mm.make(blocks, ca.getCode());
}
catch (BadBytecode bb) {
throw new BadBytecode(minfo, bb);
}

return mm.toStackMap(blocks);
}

@@ -117,7 +123,12 @@ public class MapMaker extends Tracer {
return null;

MapMaker mm = new MapMaker(classes, minfo, ca);
mm.make(blocks, ca.getCode());
try {
mm.make(blocks, ca.getCode());
}
catch (BadBytecode bb) {
throw new BadBytecode(minfo, bb);
}
return mm.toStackMap2(minfo.getConstPool(), blocks);
}

@@ -137,7 +148,7 @@ public class MapMaker extends Tracer {
{
make(code, blocks[0]);
try {
fixTypes(blocks);
fixTypes(code, blocks);
} catch (NotFoundException e) {
throw new BadBytecode("failed to resolve types", e);
}
@@ -276,22 +287,40 @@ public class MapMaker extends Tracer {
* Since SCCs are found in the topologically sorted order,
* their types are also fixed when they are found.
*/
private void fixTypes(TypedBlock[] blocks) throws NotFoundException {
private void fixTypes(byte[] code, TypedBlock[] blocks) throws NotFoundException, BadBytecode {
ArrayList preOrder = new ArrayList();
int len = blocks.length;
int index = 0;
for (int i = 0; i < len; i++) {
TypedBlock block = blocks[i];
int n = block.localsTypes.length;
for (int j = 0; j < n; j++)
index = block.localsTypes[j].dfs(preOrder, index, classPool);
if (block.localsTypes == null) // if block is dead code
fixDeadcode(code, block);
else {
int n = block.localsTypes.length;
for (int j = 0; j < n; j++)
index = block.localsTypes[j].dfs(preOrder, index, classPool);

n = block.stackTop;
for (int j = 0; j < n; j++)
index = block.stackTypes[j].dfs(preOrder, index, classPool);
n = block.stackTop;
for (int j = 0; j < n; j++)
index = block.stackTypes[j].dfs(preOrder, index, classPool);
}
}
}

private void fixDeadcode(byte[] code, TypedBlock block) throws BadBytecode {
int pos = block.position;
int len = block.length - 3;
if (len < 0)
throw new BadBytecode("dead code detected at " + pos
+ ". No stackmap table generated.");

for (int k = 0; k < len; k++)
code[pos + k] = Bytecode.NOP;

code[pos + len] = (byte)Bytecode.GOTO;
ByteArray.write16bit(-len, code, pos + len + 1);
}

// Phase 3

public StackMapTable toStackMap(TypedBlock[] blocks) {
@@ -314,6 +343,12 @@ public class MapMaker extends Tracer {
offsetDelta = bb.length - 1;
prev = bb;
}
else if (bb.incoming == 0) {
// dead code.
writer.sameFrame(offsetDelta);
offsetDelta = bb.length - 1;
prev = bb;
}
else
offsetDelta += bb.length;
}

+ 60
- 0
src/test/javassist/bytecode/StackMapTest.java View File

@@ -647,6 +647,66 @@ public class StackMapTest extends TestCase {
}
}

public void testJIRA175() throws Exception {
CtClass cc = loader.get("javassist.bytecode.StackMapTest$C5");
cc.getDeclaredMethod("setter").instrument(new javassist.expr.ExprEditor() {
@Override
public void edit(javassist.expr.FieldAccess f) throws javassist.CannotCompileException {
if (!f.where().getMethodInfo().isMethod())
return;

f.replace("{ $_ = $proceed($$); if (false) return $_;}");
}
});
cc.writeFile();
Object t1 = make(cc.getName());
assertEquals(3, invoke(t1, "test"));
}

public static class C5 {
String value;
int ivalue;
public int test() {
setter("foo");
return value.length();
}

public void setter(String s) {
value = s;
ivalue = s.length();
}
}

public void testJIRA175b() throws Exception {
CtClass cc = loader.get("javassist.bytecode.StackMapTest$C6");
try {
cc.getDeclaredMethod("setter").instrument(new javassist.expr.ExprEditor() {
public void edit(javassist.expr.FieldAccess f) throws javassist.CannotCompileException {
if (!f.where().getMethodInfo().isMethod())
return;

f.replace("{ $_ = $proceed($$); return $_;}");
}
});
fail("deadcode detection");
}
catch (javassist.CannotCompileException e) {}
}

public static class C6 {
String value;
int ivalue;
public int test() {
setter("foo");
return value.length();
}

public void setter(String s) {
value = s;
ivalue = s.length();
}
}

public void tstCtClassType() throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass cc = cp.get("javassist.CtClassType");

Loading…
Cancel
Save