diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderInstruction.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderInstruction.java new file mode 100644 index 00000000..63f1a68d --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderInstruction.java @@ -0,0 +1,69 @@ +/* + * Copyright 2012, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.jf.dexlib2.builder; + +import org.jf.dexlib2.Format; +import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.iface.instruction.Instruction; +import org.jf.dexlib2.util.Preconditions; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public abstract class BuilderInstruction implements Instruction { + @Nonnull protected final Opcode opcode; + + @Nullable MethodLocation location; + + protected BuilderInstruction(@Nonnull Opcode opcode) { + Preconditions.checkFormat(opcode, getFormat()); + this.opcode = opcode; + } + + @Nonnull public Opcode getOpcode() { + return opcode; + } + + public abstract Format getFormat(); + + public int getCodeUnits() { + return getFormat().size / 2; + } + + public MethodLocation getLocation() { + if (location == null) { + throw new IllegalStateException("Cannot get the location of an instruction that hasn't been added to a " + + "method."); + } + return location; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderSwitchPayload.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderSwitchPayload.java new file mode 100644 index 00000000..e8112528 --- /dev/null +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/BuilderSwitchPayload.java @@ -0,0 +1,24 @@ +package org.jf.dexlib2.builder; + +import org.jf.dexlib2.Opcode; +import org.jf.dexlib2.iface.instruction.SwitchPayload; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public abstract class BuilderSwitchPayload extends BuilderInstruction implements SwitchPayload { + @Nullable + MethodLocation referrer; + + protected BuilderSwitchPayload(@Nonnull Opcode opcode) { + super(opcode); + } + + @Nonnull + public MethodLocation getReferrer() { + if (referrer == null) { + throw new IllegalStateException("The referrer has not been set yet"); + } + return referrer; + } +} diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodImplementationBuilder.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodImplementationBuilder.java index 5508977a..ee714516 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodImplementationBuilder.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodImplementationBuilder.java @@ -1,7 +1,6 @@ package org.jf.dexlib2.builder; -import org.jf.dexlib2.Opcode; -import org.jf.dexlib2.iface.reference.Reference; +import org.jf.dexlib2.iface.MethodImplementation; import org.jf.dexlib2.iface.reference.StringReference; import org.jf.dexlib2.iface.reference.TypeReference; import org.jf.dexlib2.writer.builder.BuilderStringReference; @@ -9,22 +8,25 @@ import org.jf.dexlib2.writer.builder.BuilderStringReference; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.HashMap; -import java.util.List; -public class MethodImplementationBuilder { +public class MethodImplementationBuilder { // Contains all named labels - both placed and unplaced private final HashMap labels = new HashMap(); @Nonnull - private final MutableMethodImplementation impl; + private final MutableMethodImplementation impl; private MethodLocation currentLocation; public MethodImplementationBuilder() { - this.impl = new MutableMethodImplementation(); + this.impl = new MutableMethodImplementation(); this.currentLocation = impl.instructionList.get(0); } + public MethodImplementation buildMethodImplementation() { + return impl.buildMethodImplementation(); + } + /** * Adds a new named label at the current location. * @@ -114,147 +116,8 @@ public class MethodImplementationBuilder { currentLocation.addSetSourceFile(sourceFile); } - public void addInstruction10t(@Nonnull Opcode opcode, - @Nonnull Label label) { - } - - public void addInstruction10x(@Nonnull Opcode opcode) { - } - - public void addInstruction11n(@Nonnull Opcode opcode, - int registerA, - int literal) { - } - - public void addInstruction11x(@Nonnull Opcode opcode, - int registerA) { - } - - public void addInstruction12x(@Nonnull Opcode opcode, - int registerA, - int registerB) { - } - - public void addInstruction20bc(@Nonnull Opcode opcode, - int verificationError, - @Nonnull ReferenceType reference) { - } - - public void addInstruction20t(@Nonnull Opcode opcode, - @Nonnull Label label) { - } - - public void addInstruction21c(@Nonnull Opcode opcode, - int registerA, - @Nonnull ReferenceType reference) { - } - - public void addInstruction21ih(@Nonnull Opcode opcode, - int registerA, - int literal) { - } - - public void addInstruction21lh(@Nonnull Opcode opcode, - int registerA, - long literal) { - } - - public void addInstruction21s(@Nonnull Opcode opcode, - int registerA, - int literal) { - } - - public void addInstruction21t(@Nonnull Opcode opcode, - int registerA, - @Nonnull Label label) { - } - - public void addInstruction22b(@Nonnull Opcode opcode, - int registerA, - int registerB, - int literal) { - } - - public void addInstruction22c(@Nonnull Opcode opcode, - int registerA, - int registerB, - @Nonnull ReferenceType reference) { - } - - public void addInstruction22s(@Nonnull Opcode opcode, - int registerA, - int registerB, - int literal) { - } - - public void addInstruction22t(@Nonnull Opcode opcode, - int registerA, - int registerB, - @Nonnull Label labelMethodItem) { - } - - public void addInstruction22x(@Nonnull Opcode opcode, - int registerA, - int registerB) { - } - - public void addInstruction23x(@Nonnull Opcode opcode, - int registerA, - int registerB, - int registerC) { - } - - public void addInstruction30t(@Nonnull Opcode opcode, - @Nonnull Label label) { - } - - public void addInstruction31c(@Nonnull Opcode opcode, - int registerA, - @Nonnull ReferenceType reference) { - } - - public void addInstruction31i(@Nonnull Opcode opcode, - int registerA, - int literal) { - } - - public void addInstruction31t(@Nonnull Opcode opcode, - int registerA, - @Nonnull Label label) { - } - - public void addInstruction32x(@Nonnull Opcode opcode, - int registerA, - int registerB) { - } - - public void addInstruction35c(@Nonnull Opcode opcode, - int registerCount, - int registerC, - int registerD, - int registerE, - int registerF, - int registerG, - @Nonnull ReferenceType reference) { - } - - public void addInstruction3rc(@Nonnull Opcode opcode, - int startRegister, - int registerCount, - @Nonnull ReferenceType reference) { - } - - public void addInstruction51l(@Nonnull Opcode opcode, - int registerA, - long literal) { - } - - public void addPackedSwitchPayload(int startKey, @Nullable List switchElements) { - } - - public void addSparseSwitchPayload(@Nullable List switchElements) { - } - - public void addArrayPayload(int elementWidth, @Nullable List arrayElements) { + public void addInstruction(@Nullable BuilderInstruction instruction) { + impl.addInstruction(instruction); + currentLocation = impl.instructionList.get(impl.instructionList.size()-1); } } diff --git a/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodLocation.java b/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodLocation.java index 700a8157..cf14caa0 100644 --- a/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodLocation.java +++ b/dexlib2/src/main/java/org/jf/dexlib2/builder/MethodLocation.java @@ -9,17 +9,20 @@ import org.jf.dexlib2.writer.builder.BuilderStringReference; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.*; +import java.util.AbstractSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; public class MethodLocation { - @Nullable Instruction instruction; + @Nullable BuilderInstruction instruction; int codeAddress; int index; private List