]> source.dussan.org Git - javassist.git/commitdiff
Fix issue in no-standard [new] instruction replace 448/head
authorLayHool <23442547+layhool@users.noreply.github.com>
Thu, 16 Mar 2023 03:01:40 +0000 (11:01 +0800)
committerGitHub <noreply@github.com>
Thu, 16 Mar 2023 03:01:40 +0000 (11:01 +0800)
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

src/main/javassist/expr/NewExpr.java

index 3171fc3fe80413755a5dd96863de78f72e8dde0e..ee065167c2f8403d508bb77e19e4db4f1cd9ec34 100644 (file)
@@ -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); }