mirror of
https://github.com/revanced/smali.git
synced 2025-05-14 13:17:06 +02:00
Implement try blocks for the method builder
This commit is contained in:
parent
160fc1cdba
commit
897832aa15
@ -0,0 +1,58 @@
|
|||||||
|
package org.jf.dexlib2.builder;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.base.BaseExceptionHandler;
|
||||||
|
import org.jf.dexlib2.iface.ExceptionHandler;
|
||||||
|
import org.jf.dexlib2.iface.reference.TypeReference;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
class BuilderExceptionHandler {
|
||||||
|
static ExceptionHandler newExceptionHandler(@Nullable final TypeReference exceptionType,
|
||||||
|
@Nonnull final LabelMethodItem handler) {
|
||||||
|
if (exceptionType == null) {
|
||||||
|
return newExceptionHandler(handler);
|
||||||
|
}
|
||||||
|
return new BaseExceptionHandler() {
|
||||||
|
@Nullable @Override public String getExceptionType() {
|
||||||
|
return exceptionType.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getHandlerCodeAddress() {
|
||||||
|
return handler.getCodeAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable @Override public TypeReference getExceptionTypeReference() {
|
||||||
|
return exceptionType;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ExceptionHandler newExceptionHandler(@Nonnull final LabelMethodItem handler) {
|
||||||
|
return new BaseExceptionHandler() {
|
||||||
|
@Nullable @Override public String getExceptionType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getHandlerCodeAddress() {
|
||||||
|
return handler.getCodeAddress();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static ExceptionHandler newExceptionHandler(@Nullable final String exceptionType,
|
||||||
|
@Nonnull final LabelMethodItem handler) {
|
||||||
|
if (exceptionType == null) {
|
||||||
|
return newExceptionHandler(handler);
|
||||||
|
}
|
||||||
|
return new BaseExceptionHandler() {
|
||||||
|
@Nullable @Override public String getExceptionType() {
|
||||||
|
return exceptionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getHandlerCodeAddress() {
|
||||||
|
return handler.getCodeAddress();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package org.jf.dexlib2.builder;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.jf.dexlib2.base.BaseTryBlock;
|
||||||
|
import org.jf.dexlib2.iface.ExceptionHandler;
|
||||||
|
import org.jf.dexlib2.iface.reference.TypeReference;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class BuilderTryBlock extends BaseTryBlock<ExceptionHandler> {
|
||||||
|
// We only ever have one exception handler per try block. They are later merged as needed in TryListBuilder
|
||||||
|
@Nonnull public final ExceptionHandler exceptionHandler;
|
||||||
|
@Nonnull public final LabelMethodItem start;
|
||||||
|
// The end location is exclusive, it should point to the codeAddress of the instruction immediately after the last
|
||||||
|
// covered instruction.
|
||||||
|
@Nonnull public final LabelMethodItem end;
|
||||||
|
|
||||||
|
public BuilderTryBlock(@Nonnull LabelMethodItem start, @Nonnull LabelMethodItem end,
|
||||||
|
@Nullable String exceptionType, @Nonnull LabelMethodItem handler) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
this.exceptionHandler = BuilderExceptionHandler.newExceptionHandler(exceptionType, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BuilderTryBlock(@Nonnull LabelMethodItem start, @Nonnull LabelMethodItem end,
|
||||||
|
@Nullable TypeReference exceptionType, @Nonnull LabelMethodItem handler) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
this.exceptionHandler = BuilderExceptionHandler.newExceptionHandler(exceptionType, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BuilderTryBlock(@Nonnull LabelMethodItem start, @Nonnull LabelMethodItem end,
|
||||||
|
@Nonnull LabelMethodItem handler) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
this.exceptionHandler = BuilderExceptionHandler.newExceptionHandler(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getStartCodeAddress() {
|
||||||
|
return start.getCodeAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getCodeUnitCount() {
|
||||||
|
return end.getCodeAddress() - start.getCodeAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull @Override public List<? extends ExceptionHandler> getExceptionHandlers() {
|
||||||
|
return ImmutableList.of(exceptionHandler);
|
||||||
|
}
|
||||||
|
}
|
@ -7,4 +7,8 @@ public class LabelMethodItem extends MethodItem {
|
|||||||
LabelMethodItem(MethodLocation location) {
|
LabelMethodItem(MethodLocation location) {
|
||||||
this.location = location;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getCodeAddress() {
|
||||||
|
return getLocation().getCodeAddress();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,11 +18,11 @@ public class MethodImplementationBuilder<ReferenceType extends Reference> {
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
private final MutableMethodImplementation<ReferenceType> impl;
|
private final MutableMethodImplementation<ReferenceType> impl;
|
||||||
|
|
||||||
// the current instruction index
|
private MethodLocation currentLocation;
|
||||||
private int currentIndex;
|
|
||||||
|
|
||||||
public MethodImplementationBuilder(@Nonnull MutableMethodImplementation<ReferenceType> impl) {
|
public MethodImplementationBuilder() {
|
||||||
this.impl = impl;
|
this.impl = new MutableMethodImplementation<ReferenceType>();
|
||||||
|
this.currentLocation = impl.instructionList.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,18 +35,16 @@ public class MethodImplementationBuilder<ReferenceType extends Reference> {
|
|||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public LabelMethodItem addLabel(@Nonnull String name) {
|
public LabelMethodItem addLabel(@Nonnull String name) {
|
||||||
MethodLocation location = impl.instructionList.get(currentIndex);
|
|
||||||
|
|
||||||
LabelMethodItem label = labels.get(name);
|
LabelMethodItem label = labels.get(name);
|
||||||
|
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
if (label.isPlaced()) {
|
if (label.isPlaced()) {
|
||||||
throw new IllegalArgumentException("There is already a label with that name.");
|
throw new IllegalArgumentException("There is already a label with that name.");
|
||||||
} else {
|
} else {
|
||||||
location.addLabel(label);
|
currentLocation.addLabel(label);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
label = location.addNewLabel();
|
label = currentLocation.addNewLabel();
|
||||||
labels.put(name, label);
|
labels.put(name, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,13 +73,16 @@ public class MethodImplementationBuilder<ReferenceType extends Reference> {
|
|||||||
|
|
||||||
public void addCatch(@Nullable TypeReference type, @Nonnull LabelMethodItem from,
|
public void addCatch(@Nullable TypeReference type, @Nonnull LabelMethodItem from,
|
||||||
@Nonnull LabelMethodItem to, @Nonnull LabelMethodItem handler) {
|
@Nonnull LabelMethodItem to, @Nonnull LabelMethodItem handler) {
|
||||||
|
impl.addCatch(type, from, to, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCatch(@Nullable String type, @Nonnull LabelMethodItem from, @Nonnull LabelMethodItem to,
|
public void addCatch(@Nullable String type, @Nonnull LabelMethodItem from, @Nonnull LabelMethodItem to,
|
||||||
@Nonnull LabelMethodItem handler) {
|
@Nonnull LabelMethodItem handler) {
|
||||||
|
impl.addCatch(type, from, to, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCatch(@Nonnull LabelMethodItem from, @Nonnull LabelMethodItem to, @Nonnull LabelMethodItem handler) {
|
public void addCatch(@Nonnull LabelMethodItem from, @Nonnull LabelMethodItem to, @Nonnull LabelMethodItem handler) {
|
||||||
|
impl.addCatch(from, to, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLineNumber(int lineNumber) {
|
public void addLineNumber(int lineNumber) {
|
||||||
|
@ -3,13 +3,17 @@ package org.jf.dexlib2.builder;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.jf.dexlib2.iface.MethodImplementation;
|
import org.jf.dexlib2.iface.MethodImplementation;
|
||||||
import org.jf.dexlib2.iface.reference.Reference;
|
import org.jf.dexlib2.iface.reference.Reference;
|
||||||
|
import org.jf.dexlib2.iface.reference.TypeReference;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MutableMethodImplementation<ReferenceType extends Reference> {
|
public class MutableMethodImplementation<ReferenceType extends Reference> {
|
||||||
final ArrayList<MethodLocation> instructionList = Lists.newArrayList(new MethodLocation(null, 0, 0));
|
final ArrayList<MethodLocation> instructionList = Lists.newArrayList(new MethodLocation(null, 0, 0));
|
||||||
|
private final ArrayList<BuilderTryBlock> tryBlocks = Lists.newArrayList();
|
||||||
|
|
||||||
public MutableMethodImplementation() {
|
public MutableMethodImplementation() {
|
||||||
}
|
}
|
||||||
@ -21,4 +25,18 @@ public class MutableMethodImplementation<ReferenceType extends Reference> {
|
|||||||
public List<MethodLocation> getInstruction() {
|
public List<MethodLocation> getInstruction() {
|
||||||
return Collections.unmodifiableList(instructionList);
|
return Collections.unmodifiableList(instructionList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addCatch(@Nullable TypeReference type, @Nonnull LabelMethodItem from,
|
||||||
|
@Nonnull LabelMethodItem to, @Nonnull LabelMethodItem handler) {
|
||||||
|
tryBlocks.add(new BuilderTryBlock(from, to, type, handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCatch(@Nullable String type, @Nonnull LabelMethodItem from, @Nonnull LabelMethodItem to,
|
||||||
|
@Nonnull LabelMethodItem handler) {
|
||||||
|
tryBlocks.add(new BuilderTryBlock(from, to, type, handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCatch(@Nonnull LabelMethodItem from, @Nonnull LabelMethodItem to, @Nonnull LabelMethodItem handler) {
|
||||||
|
tryBlocks.add(new BuilderTryBlock(from, to, handler));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user