diff options
author | LayHool <23442547+layhool@users.noreply.github.com> | 2023-03-16 11:01:40 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-16 11:01:40 +0800 |
commit | e4470716576eaa37cc979c4345c7af33ec987aa7 (patch) | |
tree | dc88c3cfaccc51d9b66abe2d6418c64d8daea8ab | |
parent | 700be6f6f9546e8af049b1a763ce27f1fde5955d (diff) | |
download | javassist-e4470716576eaa37cc979c4345c7af33ec987aa7.tar.gz javassist-e4470716576eaa37cc979c4345c7af33ec987aa7.zip |
Fix issue in no-standard [new] instruction replace
A standard *new* construct bytecode will generate like:
```
new okhttp3/OkHttpClient
dup
invokespecial okhttp3/OkHttpClient <init> ()V
astore 1
```
but a few part of compiler will generate no-standard bytecode like:
```
new okhttp3/OkHttpClient
dup
astore 1
invokespecial okhttp3/OkHttpClient <init> ()V
```
which will cause javassist build stack error.
This commit will fix it
-rw-r--r-- | src/main/javassist/expr/NewExpr.java | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/main/javassist/expr/NewExpr.java b/src/main/javassist/expr/NewExpr.java index 3171fc3f..ee065167 100644 --- a/src/main/javassist/expr/NewExpr.java +++ b/src/main/javassist/expr/NewExpr.java @@ -193,6 +193,14 @@ public class NewExpr extends Expr { */ int codeSize = canReplace(); int end = pos + codeSize; + //check isStoreBeforeInit ,such as : new xx/xx ; dup;[astoreN];invokespecial xx/xx; + int beforeStoreOp = 0; + int preOp = iterator.byteAt(currentPos - 1); + if (iterator.byteAt(newPos + 3) == Opcode.DUP + && (preOp >= Opcode.ASTORE_0 + && preOp <= Opcode.ASTORE_3) && currentPos - newPos == 5) { + beforeStoreOp = preOp; + } for (int i = pos; i < end; ++i) iterator.writeByte(NOP, i); @@ -230,7 +238,12 @@ public class NewExpr extends Expr { if (codeSize > 3) // if the original code includes DUP. bytecode.addAload(retVar); - replace0(pos, bytecode, bytecodeSize); + if (beforeStoreOp >= Opcode.ASTORE_0) { + bytecode.addOpcode(beforeStoreOp); + replace0(pos - 1, bytecode, bytecodeSize + 1); + } else { + replace0(pos, bytecode, bytecodeSize); + } } catch (CompileError e) { throw new CannotCompileException(e); } catch (NotFoundException e) { throw new CannotCompileException(e); } |