mirror of
https://github.com/revanced/smali.git
synced 2025-05-04 16:44:25 +02:00
Add support for the throw-verification-error opcode
This commit is contained in:
parent
cb3e0ea38a
commit
bbe539f2d2
@ -31,6 +31,7 @@ package org.jf.baksmali.Adaptors.Format;
|
|||||||
import org.jf.baksmali.Adaptors.MethodItem;
|
import org.jf.baksmali.Adaptors.MethodItem;
|
||||||
import org.jf.baksmali.Adaptors.ReferenceFormatter;
|
import org.jf.baksmali.Adaptors.ReferenceFormatter;
|
||||||
import org.jf.baksmali.Adaptors.RegisterFormatter;
|
import org.jf.baksmali.Adaptors.RegisterFormatter;
|
||||||
|
import org.jf.dexlib.Code.Format.Instruction20bc;
|
||||||
import org.jf.util.IndentingWriter;
|
import org.jf.util.IndentingWriter;
|
||||||
import org.jf.baksmali.Renderers.LongRenderer;
|
import org.jf.baksmali.Renderers.LongRenderer;
|
||||||
import org.jf.dexlib.Code.*;
|
import org.jf.dexlib.Code.*;
|
||||||
@ -84,6 +85,13 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
|
|||||||
writer.write(", ");
|
writer.write(", ");
|
||||||
writeSecondRegister(writer);
|
writeSecondRegister(writer);
|
||||||
return true;
|
return true;
|
||||||
|
case Format20bc:
|
||||||
|
writeOpcode(writer);
|
||||||
|
writer.write(' ');
|
||||||
|
writeVerificationErrorType(writer);
|
||||||
|
writer.write(", ");
|
||||||
|
writeReference(writer);
|
||||||
|
return true;
|
||||||
case Format20t:
|
case Format20t:
|
||||||
case Format30t:
|
case Format30t:
|
||||||
writeOpcode(writer);
|
writeOpcode(writer);
|
||||||
@ -305,4 +313,9 @@ public class InstructionMethodItem<T extends Instruction> extends MethodItem {
|
|||||||
Item item = ((InstructionWithReference)instruction).getReferencedItem();
|
Item item = ((InstructionWithReference)instruction).getReferencedItem();
|
||||||
ReferenceFormatter.writeReference(writer, item);
|
ReferenceFormatter.writeReference(writer, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void writeVerificationErrorType(IndentingWriter writer) throws IOException {
|
||||||
|
VerificationErrorType validationErrorType = ((Instruction20bc)instruction).getValidationErrorType();
|
||||||
|
writer.write(validationErrorType.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ public enum Format {
|
|||||||
Format11n(Instruction11n.Factory, 2),
|
Format11n(Instruction11n.Factory, 2),
|
||||||
Format11x(Instruction11x.Factory, 2),
|
Format11x(Instruction11x.Factory, 2),
|
||||||
Format12x(Instruction12x.Factory, 2),
|
Format12x(Instruction12x.Factory, 2),
|
||||||
|
Format20bc(Instruction20bc.Factory, 4),
|
||||||
Format20t(Instruction20t.Factory, 4),
|
Format20t(Instruction20t.Factory, 4),
|
||||||
Format21c(Instruction21c.Factory, 4),
|
Format21c(Instruction21c.Factory, 4),
|
||||||
Format21h(Instruction21h.Factory, 4),
|
Format21h(Instruction21h.Factory, 4),
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2011 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code.Format;
|
||||||
|
|
||||||
|
import org.jf.dexlib.*;
|
||||||
|
import org.jf.dexlib.Code.*;
|
||||||
|
import org.jf.dexlib.Util.AnnotatedOutput;
|
||||||
|
import org.jf.dexlib.Util.NumberUtils;
|
||||||
|
|
||||||
|
public class Instruction20bc extends InstructionWithReference {
|
||||||
|
public static final Instruction.InstructionFactory Factory = new Factory();
|
||||||
|
|
||||||
|
private VerificationErrorType validationErrorType;
|
||||||
|
|
||||||
|
public Instruction20bc(Opcode opcode, VerificationErrorType validationErrorType, Item referencedItem) {
|
||||||
|
super(opcode, referencedItem, getReferenceType(referencedItem));
|
||||||
|
|
||||||
|
this.validationErrorType = validationErrorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReferenceType getReferenceType(Item item) {
|
||||||
|
if (item instanceof TypeIdItem) {
|
||||||
|
return ReferenceType.type;
|
||||||
|
}
|
||||||
|
if (item instanceof FieldIdItem) {
|
||||||
|
return ReferenceType.field;
|
||||||
|
}
|
||||||
|
if (item instanceof MethodIdItem) {
|
||||||
|
return ReferenceType.method;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instruction20bc(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
super(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
|
||||||
|
short val = NumberUtils.decodeUnsignedByte(buffer[bufferIndex+1]);
|
||||||
|
validationErrorType = VerificationErrorType.getValidationErrorType(val & 0x3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ReferenceType readReferenceType(Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
short val = NumberUtils.decodeUnsignedByte(buffer[bufferIndex+1]);
|
||||||
|
short referenceType = (short)(val >> 6);
|
||||||
|
return ReferenceType.fromValidationErrorReferenceType(referenceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Format getFormat() {
|
||||||
|
return Format.Format20bc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeInstruction(AnnotatedOutput out, int currentCodeAddress) {
|
||||||
|
if(opcode == Opcode.CONST_STRING && getReferencedItem().getIndex() > 0xFFFF) {
|
||||||
|
throw new RuntimeException("String offset is too large for const-string. Use string-const/jumbo instead.");
|
||||||
|
}
|
||||||
|
|
||||||
|
out.writeByte(opcode.value);
|
||||||
|
out.writeByte((this.getReferenceType().getValidationErrorReferenceType() << 6) &
|
||||||
|
validationErrorType.getValue());
|
||||||
|
|
||||||
|
out.writeShort(getReferencedItem().getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
public VerificationErrorType getValidationErrorType() {
|
||||||
|
return validationErrorType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Factory implements Instruction.InstructionFactory {
|
||||||
|
public Instruction makeInstruction(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
return new Instruction20bc(dexFile, opcode, buffer, bufferIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -33,17 +33,27 @@ import org.jf.dexlib.Util.NumberUtils;
|
|||||||
|
|
||||||
public abstract class InstructionWithReference extends Instruction {
|
public abstract class InstructionWithReference extends Instruction {
|
||||||
private Item referencedItem;
|
private Item referencedItem;
|
||||||
|
private ReferenceType referenceType;
|
||||||
|
|
||||||
protected InstructionWithReference(Opcode opcode, Item referencedItem) {
|
protected InstructionWithReference(Opcode opcode, Item referencedItem) {
|
||||||
super(opcode);
|
super(opcode);
|
||||||
this.referencedItem = referencedItem;
|
this.referencedItem = referencedItem;
|
||||||
|
this.referenceType = opcode.referenceType;
|
||||||
|
checkReferenceType();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected InstructionWithReference(Opcode opcode, Item referencedItem, ReferenceType referenceType) {
|
||||||
|
super(opcode);
|
||||||
|
this.referencedItem = referencedItem;
|
||||||
|
this.referenceType = referenceType;
|
||||||
checkReferenceType();
|
checkReferenceType();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected InstructionWithReference(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
protected InstructionWithReference(DexFile dexFile, Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
super(opcode);
|
super(opcode);
|
||||||
|
|
||||||
int itemIndex = getReferencedItemIndex(buffer, bufferIndex);
|
this.referenceType = readReferenceType(opcode, buffer, bufferIndex);
|
||||||
|
int itemIndex = getReferencedItemIndex(buffer, bufferIndex);
|
||||||
lookupReferencedItem(dexFile, opcode, itemIndex);
|
lookupReferencedItem(dexFile, opcode, itemIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,12 +61,20 @@ public abstract class InstructionWithReference extends Instruction {
|
|||||||
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
|
return NumberUtils.decodeUnsignedShort(buffer, bufferIndex + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReferenceType getReferenceType() {
|
||||||
|
return referenceType;
|
||||||
|
}
|
||||||
|
|
||||||
public Item getReferencedItem() {
|
public Item getReferencedItem() {
|
||||||
return referencedItem;
|
return referencedItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ReferenceType readReferenceType(Opcode opcode, byte[] buffer, int bufferIndex) {
|
||||||
|
return opcode.referenceType;
|
||||||
|
}
|
||||||
|
|
||||||
private void lookupReferencedItem(DexFile dexFile, Opcode opcode, int itemIndex) {
|
private void lookupReferencedItem(DexFile dexFile, Opcode opcode, int itemIndex) {
|
||||||
switch (opcode.referenceType) {
|
switch (referenceType) {
|
||||||
case field:
|
case field:
|
||||||
referencedItem = dexFile.FieldIdsSection.getItemByIndex(itemIndex);
|
referencedItem = dexFile.FieldIdsSection.getItemByIndex(itemIndex);
|
||||||
return;
|
return;
|
||||||
@ -73,7 +91,7 @@ public abstract class InstructionWithReference extends Instruction {
|
|||||||
|
|
||||||
|
|
||||||
private void checkReferenceType() {
|
private void checkReferenceType() {
|
||||||
switch (opcode.referenceType) {
|
switch (referenceType) {
|
||||||
case field:
|
case field:
|
||||||
if (!(referencedItem instanceof FieldIdItem)) {
|
if (!(referencedItem instanceof FieldIdItem)) {
|
||||||
throw new RuntimeException(referencedItem.getClass().getSimpleName() +
|
throw new RuntimeException(referencedItem.getClass().getSimpleName() +
|
||||||
|
@ -263,6 +263,7 @@ public enum Opcode
|
|||||||
SGET_WIDE_VOLATILE((byte)0xea, "sget-wide-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
SGET_WIDE_VOLATILE((byte)0xea, "sget-wide-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||||
SPUT_WIDE_VOLATILE((byte)0xeb, "sput-wide-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
SPUT_WIDE_VOLATILE((byte)0xeb, "sput-wide-volatile", ReferenceType.field, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||||
|
|
||||||
|
THROW_VERIFICATION_ERROR((byte)0xed, "throw-verification-error", ReferenceType.none, Format.Format20bc, Opcode.ODEX_ONLY | Opcode.CAN_THROW),
|
||||||
EXECUTE_INLINE((byte)0xee, "execute-inline", ReferenceType.none, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
EXECUTE_INLINE((byte)0xee, "execute-inline", ReferenceType.none, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
EXECUTE_INLINE_RANGE((byte)0xef, "execute-inline/range", ReferenceType.none, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
EXECUTE_INLINE_RANGE((byte)0xef, "execute-inline/range", ReferenceType.none, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
INVOKE_DIRECT_EMPTY((byte)0xf0, "invoke-direct-empty", ReferenceType.method, Format.Format35s, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
INVOKE_DIRECT_EMPTY((byte)0xf0, "invoke-direct-empty", ReferenceType.method, Format.Format35s, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||||
|
@ -32,11 +32,17 @@ import org.jf.dexlib.*;
|
|||||||
|
|
||||||
public enum ReferenceType
|
public enum ReferenceType
|
||||||
{
|
{
|
||||||
string,
|
string(-1),
|
||||||
type,
|
type(0),
|
||||||
field,
|
field(1),
|
||||||
method,
|
method(2),
|
||||||
none;
|
none(-1);
|
||||||
|
|
||||||
|
private int validationErrorReferenceType;
|
||||||
|
|
||||||
|
private ReferenceType(int validationErrorReferenceType) {
|
||||||
|
this.validationErrorReferenceType = validationErrorReferenceType;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean checkItem(Item item) {
|
public boolean checkItem(Item item) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
@ -48,9 +54,27 @@ public enum ReferenceType
|
|||||||
return item instanceof FieldIdItem;
|
return item instanceof FieldIdItem;
|
||||||
case method:
|
case method:
|
||||||
return item instanceof MethodIdItem;
|
return item instanceof MethodIdItem;
|
||||||
case none:
|
|
||||||
return item == null;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ReferenceType fromValidationErrorReferenceType(int validationErrorReferenceType) {
|
||||||
|
switch (validationErrorReferenceType) {
|
||||||
|
case 0:
|
||||||
|
return type;
|
||||||
|
case 1:
|
||||||
|
return field;
|
||||||
|
case 2:
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValidationErrorReferenceType() {
|
||||||
|
if (validationErrorReferenceType == -1) {
|
||||||
|
throw new RuntimeException("This reference type cannot be referenced from a throw-validation-error" +
|
||||||
|
" instruction");
|
||||||
|
}
|
||||||
|
return validationErrorReferenceType;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* [The "BSD licence"]
|
||||||
|
* Copyright (c) 2011 Ben Gruver
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.dexlib.Code;
|
||||||
|
|
||||||
|
public enum VerificationErrorType {
|
||||||
|
None(0, "no-error"),
|
||||||
|
Generic(1, "generic-error"),
|
||||||
|
NoClass(2, "no-such-class"),
|
||||||
|
NoField(3, "no-such-field"),
|
||||||
|
NoMethod(4, "no-such-method"),
|
||||||
|
AccessClass(5, "illegal-class-access"),
|
||||||
|
AccessField(6, "illegal-field-access"),
|
||||||
|
AccessMethod(7, "illegal-method-access"),
|
||||||
|
ClassChange(8, "class-change-error"),
|
||||||
|
Instantiation(9, "instantiation-error");
|
||||||
|
|
||||||
|
private int value;
|
||||||
|
private String name;
|
||||||
|
private VerificationErrorType(int value, String name) {
|
||||||
|
this.value = value;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VerificationErrorType getValidationErrorType(int validationErrorType) {
|
||||||
|
switch (validationErrorType) {
|
||||||
|
case 0:
|
||||||
|
return None;
|
||||||
|
case 1:
|
||||||
|
return Generic;
|
||||||
|
case 2:
|
||||||
|
return NoClass;
|
||||||
|
case 3:
|
||||||
|
return NoField;
|
||||||
|
case 4:
|
||||||
|
return NoMethod;
|
||||||
|
case 5:
|
||||||
|
return AccessClass;
|
||||||
|
case 6:
|
||||||
|
return AccessField;
|
||||||
|
case 7:
|
||||||
|
return AccessMethod;
|
||||||
|
case 8:
|
||||||
|
return ClassChange;
|
||||||
|
case 9:
|
||||||
|
return Instantiation;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -331,6 +331,18 @@ ACCESS_SPEC
|
|||||||
| 'volatile'
|
| 'volatile'
|
||||||
| 'transient';
|
| 'transient';
|
||||||
|
|
||||||
|
VERIFICATION_ERROR_TYPE
|
||||||
|
: 'no-error'
|
||||||
|
| 'generic-error'
|
||||||
|
| 'no-such-class'
|
||||||
|
| 'no-such-field'
|
||||||
|
| 'no-such-method'
|
||||||
|
| 'illegal-class-access'
|
||||||
|
| 'illegal-field-access'
|
||||||
|
| 'illegal-method-access'
|
||||||
|
| 'class-change-error'
|
||||||
|
| 'instantiation-error';
|
||||||
|
|
||||||
VTABLE_OFFSET
|
VTABLE_OFFSET
|
||||||
: 'vtable@0x' HEX_DIGIT+;
|
: 'vtable@0x' HEX_DIGIT+;
|
||||||
|
|
||||||
@ -434,6 +446,9 @@ INSTRUCTION_FORMAT12x
|
|||||||
| 'div-double/2addr'
|
| 'div-double/2addr'
|
||||||
| 'rem-double/2addr';
|
| 'rem-double/2addr';
|
||||||
|
|
||||||
|
INSTRUCTION_FORMAT20bc
|
||||||
|
: 'throw-verification-error';
|
||||||
|
|
||||||
INSTRUCTION_FORMAT20t
|
INSTRUCTION_FORMAT20t
|
||||||
: 'goto/16';
|
: 'goto/16';
|
||||||
|
|
||||||
|
@ -419,6 +419,7 @@ the indicated type OR an identifier, depending on the context*/
|
|||||||
simple_name
|
simple_name
|
||||||
: SIMPLE_NAME
|
: SIMPLE_NAME
|
||||||
| ACCESS_SPEC -> SIMPLE_NAME[$ACCESS_SPEC]
|
| ACCESS_SPEC -> SIMPLE_NAME[$ACCESS_SPEC]
|
||||||
|
| VERIFICATION_ERROR_TYPE -> SIMPLE_NAME[$VERIFICATION_ERROR_TYPE]
|
||||||
| POSITIVE_INTEGER_LITERAL -> SIMPLE_NAME[$POSITIVE_INTEGER_LITERAL]
|
| POSITIVE_INTEGER_LITERAL -> SIMPLE_NAME[$POSITIVE_INTEGER_LITERAL]
|
||||||
| NEGATIVE_INTEGER_LITERAL -> SIMPLE_NAME[$NEGATIVE_INTEGER_LITERAL]
|
| NEGATIVE_INTEGER_LITERAL -> SIMPLE_NAME[$NEGATIVE_INTEGER_LITERAL]
|
||||||
| INTEGER_LITERAL -> SIMPLE_NAME[$INTEGER_LITERAL]
|
| INTEGER_LITERAL -> SIMPLE_NAME[$INTEGER_LITERAL]
|
||||||
@ -684,6 +685,11 @@ instruction returns [int size]
|
|||||||
| //e.g. move v1 v2
|
| //e.g. move v1 v2
|
||||||
instruction_format12x REGISTER COMMA REGISTER {$size = Format.Format12x.size;}
|
instruction_format12x REGISTER COMMA REGISTER {$size = Format.Format12x.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT12x[$start, "I_STATEMENT_FORMAT12x"] instruction_format12x REGISTER REGISTER)
|
-> ^(I_STATEMENT_FORMAT12x[$start, "I_STATEMENT_FORMAT12x"] instruction_format12x REGISTER REGISTER)
|
||||||
|
| //e.g. throw-verification-error generic-error, Lsome/class;
|
||||||
|
INSTRUCTION_FORMAT20bc VERIFICATION_ERROR_TYPE COMMA (CLASS_DESCRIPTOR | fully_qualified_field | fully_qualified_method)
|
||||||
|
{
|
||||||
|
throwOdexedInstructionException(input, $INSTRUCTION_FORMAT20bc.text);
|
||||||
|
}
|
||||||
| //e.g. goto/16 endloop:
|
| //e.g. goto/16 endloop:
|
||||||
INSTRUCTION_FORMAT20t label_ref_or_offset {$size = Format.Format20t.size;}
|
INSTRUCTION_FORMAT20t label_ref_or_offset {$size = Format.Format20t.size;}
|
||||||
-> ^(I_STATEMENT_FORMAT20t[$start, "I_STATEMENT_FORMAT20t"] INSTRUCTION_FORMAT20t label_ref_or_offset)
|
-> ^(I_STATEMENT_FORMAT20t[$start, "I_STATEMENT_FORMAT20t"] INSTRUCTION_FORMAT20t label_ref_or_offset)
|
||||||
|
@ -364,6 +364,11 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor}
|
|||||||
return newToken(ACCESS_SPEC);
|
return newToken(ACCESS_SPEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"no-error" | "generic-error" | "no-such-class" | "no-such-field" | "no-such-method" | "illegal-class-access" |
|
||||||
|
"illegal-field-access" | "illegal-method-access" | "class-change-error" | "instantiation-error" {
|
||||||
|
return newToken(VERIFICATION_ERROR_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
"vtable@0x" {HexDigit}+ { return newToken(VTABLE_OFFSET); }
|
"vtable@0x" {HexDigit}+ { return newToken(VTABLE_OFFSET); }
|
||||||
"field@0x" {HexDigit}+ { return newToken(FIELD_OFFSET); }
|
"field@0x" {HexDigit}+ { return newToken(FIELD_OFFSET); }
|
||||||
|
|
||||||
@ -407,6 +412,10 @@ Type = {PrimitiveType} | {ClassDescriptor} | {ArrayDescriptor}
|
|||||||
return newToken(INSTRUCTION_FORMAT12x);
|
return newToken(INSTRUCTION_FORMAT12x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"throw-verification-error" {
|
||||||
|
return newToken(INSTRUCTION_FORMAT20bc);
|
||||||
|
}
|
||||||
|
|
||||||
"goto/16" {
|
"goto/16" {
|
||||||
return newToken(INSTRUCTION_FORMAT20t);
|
return newToken(INSTRUCTION_FORMAT20t);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user