1e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson/* 2e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * Copyright (C) 2011 The Android Open Source Project 3e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * 4e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * you may not use this file except in compliance with the License. 6e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * You may obtain a copy of the License at 7e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * 8e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * 10e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * See the License for the specific language governing permissions and 14e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * limitations under the License. 15e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson */ 16e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 17e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilsonpackage com.android.dx.io; 18e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 19fe107fb6e3f308ac5174ebdc5a794ee880c741d9Jesse Wilsonimport com.android.dex.DexException; 20537939ca06a47668f719ee06159303bcd3175c69Dan Bornsteinimport com.android.dx.io.instructions.DecodedInstruction; 21e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 22e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson/** 23e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * Walks through a block of code and calls visitor call backs. 24e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson */ 25e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilsonpublic final class CodeReader { 26f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein private Visitor fallbackVisitor = null; 27f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein private Visitor stringVisitor = null; 28f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein private Visitor typeVisitor = null; 29f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein private Visitor fieldVisitor = null; 30f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein private Visitor methodVisitor = null; 31e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 32e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson /** 3338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein * Sets {@code visitor} as the visitor for all instructions. 3438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein */ 3538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein public void setAllVisitors(Visitor visitor) { 36f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein fallbackVisitor = visitor; 37f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein stringVisitor = visitor; 38f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein typeVisitor = visitor; 39f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein fieldVisitor = visitor; 40f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein methodVisitor = visitor; 41f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein } 42f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein 43f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein /** 44f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein * Sets {@code visitor} as the visitor for all instructions not 45f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein * otherwise handled. 46f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein */ 47f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein public void setFallbackVisitor(Visitor visitor) { 48f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein fallbackVisitor = visitor; 4938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein } 5038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein 5138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein /** 52e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * Sets {@code visitor} as the visitor for all string instructions. 53e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson */ 54e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson public void setStringVisitor(Visitor visitor) { 55f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein stringVisitor = visitor; 56e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 57e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 58e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson /** 59e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * Sets {@code visitor} as the visitor for all type instructions. 60e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson */ 61e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson public void setTypeVisitor(Visitor visitor) { 62f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein typeVisitor = visitor; 63e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 64e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 65e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson /** 66e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * Sets {@code visitor} as the visitor for all field instructions. 67e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson */ 68e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson public void setFieldVisitor(Visitor visitor) { 69f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein fieldVisitor = visitor; 70e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 71e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 72e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson /** 73e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson * Sets {@code visitor} as the visitor for all method instructions. 74e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson */ 75e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson public void setMethodVisitor(Visitor visitor) { 76f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein methodVisitor = visitor; 77e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 78e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 7938b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein public void visitAll(DecodedInstruction[] decodedInstructions) 8038b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein throws DexException { 8138b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein int size = decodedInstructions.length; 82e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 8338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein for (int i = 0; i < size; i++) { 84f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein DecodedInstruction one = decodedInstructions[i]; 85f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein if (one == null) { 86e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson continue; 87e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 88e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 89f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein callVisit(decodedInstructions, one); 90e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 91e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 92e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 9338b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein public void visitAll(short[] encodedInstructions) throws DexException { 9438b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein DecodedInstruction[] decodedInstructions = 9538b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein DecodedInstruction.decodeAll(encodedInstructions); 9638b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein visitAll(decodedInstructions); 9738b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein } 9838b861bc63b91114d52ba01e74d31fbf316a5784Dan Bornstein 99f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein private void callVisit(DecodedInstruction[] all, DecodedInstruction one) { 100f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein Visitor visitor = null; 101e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 102f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein switch (OpcodeInfo.getIndexType(one.getOpcode())) { 103f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein case STRING_REF: visitor = stringVisitor; break; 104f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein case TYPE_REF: visitor = typeVisitor; break; 105f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein case FIELD_REF: visitor = fieldVisitor; break; 106f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein case METHOD_REF: visitor = methodVisitor; break; 107e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 108e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 109f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein if (visitor == null) { 110f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein visitor = fallbackVisitor; 111e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 112e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 113f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein if (visitor != null) { 114f67b6afce08a6b9b5daf7d4d69e132fda07bc78fDan Bornstein visitor.visit(all, one); 115e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 116e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 117e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson 118e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson public interface Visitor { 119a754fbb1555f9ac2d14de0ffd0046c780732da5aDan Bornstein void visit(DecodedInstruction[] all, DecodedInstruction one); 120e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson } 121e31a42442bbd2cdc69e959f5209b793cf0aa7217Jesse Wilson} 122