• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4 package com.android.tools.r8.code;
5 
6 import com.android.tools.r8.dex.IndexedItemCollection;
7 import com.android.tools.r8.errors.InternalCompilerError;
8 import com.android.tools.r8.graph.DexCallSite;
9 import com.android.tools.r8.graph.DexField;
10 import com.android.tools.r8.graph.DexMethod;
11 import com.android.tools.r8.graph.DexProto;
12 import com.android.tools.r8.graph.IndexedDexItem;
13 import com.android.tools.r8.graph.ObjectToOffsetMapping;
14 import com.android.tools.r8.graph.UseRegistry;
15 import com.android.tools.r8.ir.conversion.IRBuilder;
16 import com.android.tools.r8.naming.ClassNameMapper;
17 import com.android.tools.r8.utils.StringUtils;
18 import java.nio.ShortBuffer;
19 import java.util.function.BiPredicate;
20 
21 public abstract class Instruction {
22 
23   public final static int[] NO_TARGETS = null;
24   public final static int[] EXIT_TARGET = new int[]{};
25 
26   public int offset;
27 
Instruction(BytecodeStream stream)28   Instruction(BytecodeStream stream) {
29     // When this constructor is invoked, we have already read 1 ushort from the stream.
30     this.offset = stream.getOffset() - 1;
31   }
32 
Instruction()33   protected Instruction() {
34     this.offset = -1;
35   }
36 
readSigned8BitValue(BytecodeStream stream)37   static int readSigned8BitValue(BytecodeStream stream) {
38     return (byte) stream.nextByte();
39   }
40 
read8BitValue(BytecodeStream stream)41   static int read8BitValue(BytecodeStream stream) {
42     int result = stream.nextByte();
43     return result;
44   }
45 
readSigned16BitValue(BytecodeStream stream)46   static int readSigned16BitValue(BytecodeStream stream) {
47     // Convert to signed.
48     return (short) stream.nextShort();
49   }
50 
read16BitValue(BytecodeStream stream)51   static int read16BitValue(BytecodeStream stream) {
52     return stream.nextShort() & 0xffff;
53   }
54 
readSigned32BitValue(BytecodeStream stream)55   static int readSigned32BitValue(BytecodeStream stream) {
56     int low = read16BitValue(stream);
57     int high = read16BitValue(stream);
58     int result = ((high << 16) & 0xffff0000) | (low & 0xffff);
59     return result;
60   }
61 
read32BitValue(BytecodeStream stream)62   static long read32BitValue(BytecodeStream stream) {
63     long low = read16BitValue(stream);
64     long high = read16BitValue(stream);
65     long result = ((high & 0xffff) << 16) | (low & 0xffff);
66     return result;
67   }
68 
read64BitValue(BytecodeStream stream)69   static long read64BitValue(BytecodeStream stream) {
70     long low = read32BitValue(stream);
71     long high = read32BitValue(stream);
72     long result = (high << 32) | low;
73     return result;
74   }
75 
combineBytes(int high, int low)76   protected static short combineBytes(int high, int low) {
77     return (short) (((high & 0xff) << 8) | (low & 0xff));
78   }
79 
makeByte(int high, int low)80   protected static int makeByte(int high, int low) {
81     return ((high & 0xf) << 4) | low & 0xf;
82   }
83 
writeFirst(int aa, ShortBuffer dest)84   protected void writeFirst(int aa, ShortBuffer dest) {
85     dest.put((short) (((aa & 0xff) << 8) | (getOpcode() & 0xff)));
86   }
87 
writeFirst(int a, int b, ShortBuffer dest)88   protected void writeFirst(int a, int b, ShortBuffer dest) {
89     dest.put((short) (((a & 0xf) << 12) | ((b & 0xf) << 8) | (getOpcode() & 0xff)));
90   }
91 
write16BitValue(int value, ShortBuffer dest)92   protected void write16BitValue(int value, ShortBuffer dest) {
93     dest.put((short) value);
94   }
95 
write32BitValue(long value, ShortBuffer dest)96   protected void write32BitValue(long value, ShortBuffer dest) {
97     dest.put((short) (value & 0xffff));
98     dest.put((short) ((value >> 16) & 0xffff));
99   }
100 
write64BitValue(long value, ShortBuffer dest)101   protected void write64BitValue(long value, ShortBuffer dest) {
102     write32BitValue(value & 0xffffffff, dest);
103     write32BitValue((value >> 32) & 0xffffffff, dest);
104   }
105 
write16BitReference(IndexedDexItem item, ShortBuffer dest, ObjectToOffsetMapping mapping)106   protected void write16BitReference(IndexedDexItem item, ShortBuffer dest,
107       ObjectToOffsetMapping mapping) {
108     int index = item.getOffset(mapping);
109     assert index == (index & 0xffff);
110     write16BitValue(index, dest);
111   }
112 
write32BitReference(IndexedDexItem item, ShortBuffer dest, ObjectToOffsetMapping mapping)113   protected void write32BitReference(IndexedDexItem item, ShortBuffer dest,
114       ObjectToOffsetMapping mapping) {
115     write32BitValue(item.getOffset(mapping), dest);
116   }
117 
getOffset()118   public int getOffset() {
119     return offset;
120   }
121 
setOffset(int offset)122   public void setOffset(int offset) {
123     this.offset = offset;
124   }
125 
isPayload()126   public boolean isPayload() {
127     return false;
128   }
129 
isSwitchPayload()130   public boolean isSwitchPayload() {
131     return false;
132   }
133 
hasPayload()134   public boolean hasPayload() {
135     return false;
136   }
137 
isSwitch()138   public boolean isSwitch() {
139     return false;
140   }
141 
getPayloadOffset()142   public int getPayloadOffset() {
143     return 0;
144   }
145 
formatString(String left)146   String formatString(String left) {
147     StringBuilder builder = new StringBuilder();
148     StringUtils.appendLeftPadded(builder, Integer.toString(getOffset()), 6);
149     builder.append(": ");
150     StringUtils.appendRightPadded(builder, getName(), 20);
151     builder.append(left == null ? "" : left);
152     return builder.toString();
153   }
154 
formatSmaliString(String left)155   String formatSmaliString(String left) {
156     StringBuilder builder = new StringBuilder();
157     builder.append("    ");
158     if (left != null) {
159       StringUtils.appendRightPadded(builder, getSmaliName(), 20);
160       builder.append(left);
161     } else {
162       builder.append(getSmaliName());
163     }
164     return builder.toString();
165   }
166 
getTargets()167   public int[] getTargets() {
168     return NO_TARGETS;
169   }
170 
buildIR(IRBuilder builder)171   public abstract void buildIR(IRBuilder builder);
172 
getCallSite()173   public DexCallSite getCallSite() {
174     return null;
175   }
176 
getMethod()177   public DexMethod getMethod() {
178     return null;
179   }
180 
getProto()181   public DexProto getProto() {
182     return null;
183   }
184 
getField()185   public DexField getField() {
186     return null;
187   }
188 
189   @Override
equals(Object obj)190   public abstract boolean equals(Object obj);
191 
192   @Override
hashCode()193   public abstract int hashCode();
194 
getName()195   public abstract String getName();
196 
getSmaliName()197   public abstract String getSmaliName();
198 
getOpcode()199   public abstract int getOpcode();
200 
getSize()201   public abstract int getSize();
202 
toSmaliString(Instruction payloadUser)203   public String toSmaliString(Instruction payloadUser) {
204     throw new InternalCompilerError("Instruction " + payloadUser + " is not a payload user");
205   }
206 
toSmaliString(ClassNameMapper naming)207   public abstract String toSmaliString(ClassNameMapper naming);
208 
toSmaliString()209   public String toSmaliString() {
210     return toSmaliString((ClassNameMapper) null);
211   }
212 
toString(ClassNameMapper naming)213   public abstract String toString(ClassNameMapper naming);
214 
toString()215   public String toString() {
216     return toString(null);
217   }
218 
write(ShortBuffer buffer, ObjectToOffsetMapping mapping)219   public abstract void write(ShortBuffer buffer, ObjectToOffsetMapping mapping);
220 
collectIndexedItems(IndexedItemCollection indexedItems)221   public abstract void collectIndexedItems(IndexedItemCollection indexedItems);
222 
equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality)223   public boolean equals(Instruction other, BiPredicate<IndexedDexItem, IndexedDexItem> equality) {
224     // In the default case, there is nothing to substitute.
225     return this.equals(other);
226   }
227 
registerUse(UseRegistry registry)228   public void registerUse(UseRegistry registry) {
229     // Intentionally empty
230   }
231 
canThrow()232   public boolean canThrow() {
233     return false;
234   }
235 }
236