changeset 99:27104b37e259

Add the implementation of filled-new-array. Also fix a small bug in the implementation of checkcast (array of primitive should be supported).
author forax
date Mon, 28 Mar 2011 21:35:45 +0200
parents 677ddb123c91
children 8d6b719ff9a1
files src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java
diffstat 1 files changed, 46 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Mon Mar 28 16:19:59 2011 +0200
+++ b/src/main/java/org/icedrobot/daneel/rewriter/DexRewriter.java	Mon Mar 28 21:35:45 2011 +0200
@@ -451,10 +451,11 @@
             case CHECK_CAST:
                 mv.visitVarInsn(ALOAD, vsrcOrDest);
                 interpreter.load(vsrcOrDest, OBJECT_TYPE);
-                mv.visitTypeInsn(CHECKCAST, TypeUtil
-                        .convertDescToInternal(typeDesc));
+                mv.visitTypeInsn(CHECKCAST, Type.getType(typeDesc)
+                        .getInternalName());
                 mv.visitVarInsn(ASTORE, vsrcOrDest);
-                interpreter.store(vsrcOrDest, getTypeFromASMType(Type.getType(typeDesc)));
+                interpreter.store(vsrcOrDest,
+                        getTypeFromASMType(Type.getType(typeDesc)));
                 break;
             default:
                 throw newAssertionError(opcode);
@@ -973,6 +974,44 @@
         }
         
         @Override
+        public void visitInstrFilledNewArray(Opcode opcode, int num, int va,
+                int vpacked, String desc) {
+            fixStackAfterAMethodCallOrAnExceptionHandler();
+            
+            int[] registers;
+            if (opcode == Opcode.FILLED_NEW_ARRAY_RANGE) {
+                registers = null;
+            } else {
+                registers = new int[] { getRegisterD(vpacked),
+                        getRegisterE(vpacked), getRegisterF(vpacked),
+                        getRegisterG(vpacked), va };
+            }
+            
+            Type asmType = Type.getType(desc.substring(1));
+            int type = getTypeFromASMType(asmType);
+            mv.visitLdcInsn(num);   // array length
+            if (Register.isArray(type) || type == OBJECT_TYPE) {
+                mv.visitTypeInsn(ANEWARRAY, asmType.getInternalName());
+            } else {
+                mv.visitIntInsn(NEWARRAY, getNewArrayKindFromASMType(asmType));
+            }
+            
+            for (int r=0, i=0; r<num; r += asmType.getSize()) {
+                int register = registerToSlot((registers == null) ? va + r
+                        : registers[r]);
+                mv.visitInsn(DUP);     // array
+                mv.visitLdcInsn(i);    // index
+                mv.visitVarInsn(Register.getJavaOpcode(type, ILOAD), register);
+                interpreter.load(register, type);
+                mv.visitInsn(Register.getJavaOpcode(type, IASTORE));
+                
+                i++;
+            }
+            
+            returnRegisterType = Register.makeArray(type, 1);
+        }
+        
+        @Override
         public void visitInstrArray(Opcode opcode, int vsrcOrDest, int varray,
                 int vindex) {
             fixStackAfterAMethodCallOrAnExceptionHandler();
@@ -1066,6 +1105,9 @@
         }
         
         
+        
+        
+        
         // unimplemented
         
         @Override
@@ -1076,13 +1118,7 @@
             throw new UnsupportedOperationException("NYI " + opcode);
         }
 
-        @Override
-        public void visitInstrFilledNewArray(Opcode opcode, int num, int va,
-                int vpacked, String type) {
-            fixStackAfterAMethodCallOrAnExceptionHandler();
-            // don't forget to use registerToSlot
-            throw new UnsupportedOperationException("NYI " + opcode);
-        }
+