mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 12:20:11 +02:00
Implement some of the initial .register and register reference stuff
This commit is contained in:
parent
3048a6c897
commit
12b3579577
@ -287,7 +287,7 @@ simple_name
|
|||||||
| DOUBLE_LITERAL_OR_ID
|
| DOUBLE_LITERAL_OR_ID
|
||||||
| BOOL_LITERAL
|
| BOOL_LITERAL
|
||||||
| NULL_LITERAL
|
| NULL_LITERAL
|
||||||
| REGISTER
|
| register
|
||||||
| param_list_or_id
|
| param_list_or_id
|
||||||
| PRIMITIVE_TYPE
|
| PRIMITIVE_TYPE
|
||||||
| VOID_TYPE
|
| VOID_TYPE
|
||||||
@ -536,11 +536,11 @@ label_ref
|
|||||||
finally { marker.done(SmaliElementTypes.LABEL_REFERENCE); }
|
finally { marker.done(SmaliElementTypes.LABEL_REFERENCE); }
|
||||||
|
|
||||||
register_list
|
register_list
|
||||||
: REGISTER (COMMA REGISTER)*
|
: register (COMMA register)*
|
||||||
| /* epsilon */;
|
| /* epsilon */;
|
||||||
|
|
||||||
register_range
|
register_range
|
||||||
: (REGISTER (DOTDOT REGISTER)?)?;
|
: (register (DOTDOT register)?)?;
|
||||||
|
|
||||||
verification_error_reference
|
verification_error_reference
|
||||||
: class_descriptor | fully_qualified_field | fully_qualified_method;
|
: class_descriptor | fully_qualified_field | fully_qualified_method;
|
||||||
@ -560,12 +560,17 @@ or method annotations until we determine if there is an .end parameter directive
|
|||||||
the annotations. If it turns out that they are parameter annotations, we include them in the I_PARAMETER AST. Otherwise, we
|
the annotations. If it turns out that they are parameter annotations, we include them in the I_PARAMETER AST. Otherwise, we
|
||||||
add them to the $statements_and_directives::methodAnnotations list*/
|
add them to the $statements_and_directives::methodAnnotations list*/
|
||||||
parameter_directive
|
parameter_directive
|
||||||
: PARAMETER_DIRECTIVE REGISTER (COMMA string_literal)?
|
: PARAMETER_DIRECTIVE register (COMMA string_literal)?
|
||||||
({input.LA(1) == ANNOTATION_DIRECTIVE}? annotation)*
|
({input.LA(1) == ANNOTATION_DIRECTIVE}? annotation)*
|
||||||
( END_PARAMETER_DIRECTIVE
|
( END_PARAMETER_DIRECTIVE
|
||||||
| /*epsilon*/
|
| /*epsilon*/
|
||||||
);
|
);
|
||||||
|
|
||||||
|
register
|
||||||
|
@init { Marker marker = mark(); }
|
||||||
|
: REGISTER;
|
||||||
|
finally { marker.done(SmaliElementTypes.REGISTER_REFERENCE); }
|
||||||
|
|
||||||
debug_directive
|
debug_directive
|
||||||
: line_directive
|
: line_directive
|
||||||
| local_directive
|
| local_directive
|
||||||
@ -582,18 +587,18 @@ line_directive
|
|||||||
|
|
||||||
local_directive
|
local_directive
|
||||||
@init { Marker marker = mark(); }
|
@init { Marker marker = mark(); }
|
||||||
: LOCAL_DIRECTIVE REGISTER (COMMA (null_literal | string_literal) COLON (void_type | nonvoid_type_descriptor)
|
: LOCAL_DIRECTIVE register (COMMA (null_literal | string_literal) COLON (void_type | nonvoid_type_descriptor)
|
||||||
(COMMA string_literal)? )?;
|
(COMMA string_literal)? )?;
|
||||||
finally { marker.done(SmaliElementTypes.LOCAL_DEBUG_STATEMENT); }
|
finally { marker.done(SmaliElementTypes.LOCAL_DEBUG_STATEMENT); }
|
||||||
|
|
||||||
end_local_directive
|
end_local_directive
|
||||||
@init { Marker marker = mark(); }
|
@init { Marker marker = mark(); }
|
||||||
: END_LOCAL_DIRECTIVE REGISTER;
|
: END_LOCAL_DIRECTIVE register;
|
||||||
finally { marker.done(SmaliElementTypes.END_LOCAL_DEBUG_STATEMENT); }
|
finally { marker.done(SmaliElementTypes.END_LOCAL_DEBUG_STATEMENT); }
|
||||||
|
|
||||||
restart_local_directive
|
restart_local_directive
|
||||||
@init { Marker marker = mark(); }
|
@init { Marker marker = mark(); }
|
||||||
: RESTART_LOCAL_DIRECTIVE REGISTER;
|
: RESTART_LOCAL_DIRECTIVE register;
|
||||||
finally { marker.done(SmaliElementTypes.RESTART_LOCAL_DEBUG_STATEMENT); }
|
finally { marker.done(SmaliElementTypes.RESTART_LOCAL_DEBUG_STATEMENT); }
|
||||||
|
|
||||||
prologue_directive
|
prologue_directive
|
||||||
@ -686,15 +691,15 @@ insn_format10x_odex
|
|||||||
|
|
||||||
insn_format11n
|
insn_format11n
|
||||||
: //e.g. const/4 v0, 5
|
: //e.g. const/4 v0, 5
|
||||||
INSTRUCTION_FORMAT11n REGISTER COMMA integral_literal;
|
INSTRUCTION_FORMAT11n register COMMA integral_literal;
|
||||||
|
|
||||||
insn_format11x
|
insn_format11x
|
||||||
: //e.g. move-result-object v1
|
: //e.g. move-result-object v1
|
||||||
INSTRUCTION_FORMAT11x REGISTER;
|
INSTRUCTION_FORMAT11x register;
|
||||||
|
|
||||||
insn_format12x
|
insn_format12x
|
||||||
: //e.g. move v1 v2
|
: //e.g. move v1 v2
|
||||||
instruction_format12x REGISTER COMMA REGISTER;
|
instruction_format12x register COMMA register;
|
||||||
|
|
||||||
insn_format20bc
|
insn_format20bc
|
||||||
: //e.g. throw-verification-error generic-error, Lsome/class;
|
: //e.g. throw-verification-error generic-error, Lsome/class;
|
||||||
@ -706,71 +711,71 @@ insn_format20t
|
|||||||
|
|
||||||
insn_format21c_field
|
insn_format21c_field
|
||||||
: //e.g. sget-object v0, java/lang/System/out LJava/io/PrintStream;
|
: //e.g. sget-object v0, java/lang/System/out LJava/io/PrintStream;
|
||||||
INSTRUCTION_FORMAT21c_FIELD REGISTER COMMA fully_qualified_field;
|
INSTRUCTION_FORMAT21c_FIELD register COMMA fully_qualified_field;
|
||||||
|
|
||||||
insn_format21c_field_odex
|
insn_format21c_field_odex
|
||||||
: //e.g. sget-object-volatile v0, java/lang/System/out LJava/io/PrintStream;
|
: //e.g. sget-object-volatile v0, java/lang/System/out LJava/io/PrintStream;
|
||||||
INSTRUCTION_FORMAT21c_FIELD_ODEX REGISTER COMMA fully_qualified_field;
|
INSTRUCTION_FORMAT21c_FIELD_ODEX register COMMA fully_qualified_field;
|
||||||
|
|
||||||
insn_format21c_string
|
insn_format21c_string
|
||||||
: //e.g. const-string v1, "Hello World!"
|
: //e.g. const-string v1, "Hello World!"
|
||||||
INSTRUCTION_FORMAT21c_STRING REGISTER COMMA string_literal;
|
INSTRUCTION_FORMAT21c_STRING register COMMA string_literal;
|
||||||
|
|
||||||
insn_format21c_type
|
insn_format21c_type
|
||||||
: //e.g. const-class v2, Lorg/jf/HelloWorld2/HelloWorld2;
|
: //e.g. const-class v2, Lorg/jf/HelloWorld2/HelloWorld2;
|
||||||
INSTRUCTION_FORMAT21c_TYPE REGISTER COMMA nonvoid_type_descriptor;
|
INSTRUCTION_FORMAT21c_TYPE register COMMA nonvoid_type_descriptor;
|
||||||
|
|
||||||
insn_format21ih
|
insn_format21ih
|
||||||
: //e.g. const/high16 v1, 1234
|
: //e.g. const/high16 v1, 1234
|
||||||
INSTRUCTION_FORMAT21ih REGISTER COMMA fixed_32bit_literal;
|
INSTRUCTION_FORMAT21ih register COMMA fixed_32bit_literal;
|
||||||
|
|
||||||
insn_format21lh
|
insn_format21lh
|
||||||
: //e.g. const-wide/high16 v1, 1234
|
: //e.g. const-wide/high16 v1, 1234
|
||||||
INSTRUCTION_FORMAT21lh REGISTER COMMA fixed_32bit_literal;
|
INSTRUCTION_FORMAT21lh register COMMA fixed_32bit_literal;
|
||||||
|
|
||||||
insn_format21s
|
insn_format21s
|
||||||
: //e.g. const/16 v1, 1234
|
: //e.g. const/16 v1, 1234
|
||||||
INSTRUCTION_FORMAT21s REGISTER COMMA integral_literal;
|
INSTRUCTION_FORMAT21s register COMMA integral_literal;
|
||||||
|
|
||||||
insn_format21t
|
insn_format21t
|
||||||
: //e.g. if-eqz v0, endloop:
|
: //e.g. if-eqz v0, endloop:
|
||||||
INSTRUCTION_FORMAT21t REGISTER COMMA label_ref;
|
INSTRUCTION_FORMAT21t register COMMA label_ref;
|
||||||
|
|
||||||
insn_format22b
|
insn_format22b
|
||||||
: //e.g. add-int v0, v1, 123
|
: //e.g. add-int v0, v1, 123
|
||||||
INSTRUCTION_FORMAT22b REGISTER COMMA REGISTER COMMA integral_literal;
|
INSTRUCTION_FORMAT22b register COMMA register COMMA integral_literal;
|
||||||
|
|
||||||
insn_format22c_field
|
insn_format22c_field
|
||||||
: //e.g. iput-object v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
: //e.g. iput-object v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
||||||
INSTRUCTION_FORMAT22c_FIELD REGISTER COMMA REGISTER COMMA fully_qualified_field;
|
INSTRUCTION_FORMAT22c_FIELD register COMMA register COMMA fully_qualified_field;
|
||||||
|
|
||||||
insn_format22c_field_odex
|
insn_format22c_field_odex
|
||||||
: //e.g. iput-object-volatile v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
: //e.g. iput-object-volatile v1, v0 org/jf/HelloWorld2/HelloWorld2.helloWorld Ljava/lang/String;
|
||||||
INSTRUCTION_FORMAT22c_FIELD_ODEX REGISTER COMMA REGISTER COMMA fully_qualified_field;
|
INSTRUCTION_FORMAT22c_FIELD_ODEX register COMMA register COMMA fully_qualified_field;
|
||||||
|
|
||||||
insn_format22c_type
|
insn_format22c_type
|
||||||
: //e.g. instance-of v0, v1, Ljava/lang/String;
|
: //e.g. instance-of v0, v1, Ljava/lang/String;
|
||||||
INSTRUCTION_FORMAT22c_TYPE REGISTER COMMA REGISTER COMMA nonvoid_type_descriptor;
|
INSTRUCTION_FORMAT22c_TYPE register COMMA register COMMA nonvoid_type_descriptor;
|
||||||
|
|
||||||
insn_format22cs_field
|
insn_format22cs_field
|
||||||
: //e.g. iget-quick v0, v1, field@0xc
|
: //e.g. iget-quick v0, v1, field@0xc
|
||||||
INSTRUCTION_FORMAT22cs_FIELD REGISTER COMMA REGISTER COMMA FIELD_OFFSET;
|
INSTRUCTION_FORMAT22cs_FIELD register COMMA register COMMA FIELD_OFFSET;
|
||||||
|
|
||||||
insn_format22s
|
insn_format22s
|
||||||
: //e.g. add-int/lit16 v0, v1, 12345
|
: //e.g. add-int/lit16 v0, v1, 12345
|
||||||
instruction_format22s REGISTER COMMA REGISTER COMMA integral_literal;
|
instruction_format22s register COMMA register COMMA integral_literal;
|
||||||
|
|
||||||
insn_format22t
|
insn_format22t
|
||||||
: //e.g. if-eq v0, v1, endloop:
|
: //e.g. if-eq v0, v1, endloop:
|
||||||
INSTRUCTION_FORMAT22t REGISTER COMMA REGISTER COMMA label_ref;
|
INSTRUCTION_FORMAT22t register COMMA register COMMA label_ref;
|
||||||
|
|
||||||
insn_format22x
|
insn_format22x
|
||||||
: //e.g. move/from16 v1, v1234
|
: //e.g. move/from16 v1, v1234
|
||||||
INSTRUCTION_FORMAT22x REGISTER COMMA REGISTER;
|
INSTRUCTION_FORMAT22x register COMMA register;
|
||||||
|
|
||||||
insn_format23x
|
insn_format23x
|
||||||
: //e.g. add-int v1, v2, v3
|
: //e.g. add-int v1, v2, v3
|
||||||
INSTRUCTION_FORMAT23x REGISTER COMMA REGISTER COMMA REGISTER;
|
INSTRUCTION_FORMAT23x register COMMA register COMMA register;
|
||||||
|
|
||||||
insn_format30t
|
insn_format30t
|
||||||
: //e.g. goto/32 endloop:
|
: //e.g. goto/32 endloop:
|
||||||
@ -778,19 +783,19 @@ insn_format30t
|
|||||||
|
|
||||||
insn_format31c
|
insn_format31c
|
||||||
: //e.g. const-string/jumbo v1 "Hello World!"
|
: //e.g. const-string/jumbo v1 "Hello World!"
|
||||||
INSTRUCTION_FORMAT31c REGISTER COMMA string_literal;
|
INSTRUCTION_FORMAT31c register COMMA string_literal;
|
||||||
|
|
||||||
insn_format31i
|
insn_format31i
|
||||||
: //e.g. const v0, 123456
|
: //e.g. const v0, 123456
|
||||||
instruction_format31i REGISTER COMMA fixed_32bit_literal;
|
instruction_format31i register COMMA fixed_32bit_literal;
|
||||||
|
|
||||||
insn_format31t
|
insn_format31t
|
||||||
: //e.g. fill-array-data v0, ArrayData:
|
: //e.g. fill-array-data v0, ArrayData:
|
||||||
INSTRUCTION_FORMAT31t REGISTER COMMA label_ref;
|
INSTRUCTION_FORMAT31t register COMMA label_ref;
|
||||||
|
|
||||||
insn_format32x
|
insn_format32x
|
||||||
: //e.g. move/16 v4567, v1234
|
: //e.g. move/16 v4567, v1234
|
||||||
INSTRUCTION_FORMAT32x REGISTER COMMA REGISTER;
|
INSTRUCTION_FORMAT32x register COMMA register;
|
||||||
|
|
||||||
insn_format35c_method
|
insn_format35c_method
|
||||||
: //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
|
: //e.g. invoke-virtual {v0,v1} java/io/PrintStream/print(Ljava/lang/Stream;)V
|
||||||
@ -834,7 +839,7 @@ insn_format3rms_method
|
|||||||
|
|
||||||
insn_format51l
|
insn_format51l
|
||||||
: //e.g. const-wide v0, 5000000000L
|
: //e.g. const-wide v0, 5000000000L
|
||||||
INSTRUCTION_FORMAT51l REGISTER COMMA fixed_literal;
|
INSTRUCTION_FORMAT51l register COMMA fixed_literal;
|
||||||
|
|
||||||
insn_array_data_directive
|
insn_array_data_directive
|
||||||
: ARRAY_DATA_DIRECTIVE
|
: ARRAY_DATA_DIRECTIVE
|
||||||
|
@ -56,6 +56,8 @@ public class SmaliElementTypes {
|
|||||||
new SmaliCompositeElementType("SOURCE_STATEMENT", SmaliSourceStatement.FACTORY);
|
new SmaliCompositeElementType("SOURCE_STATEMENT", SmaliSourceStatement.FACTORY);
|
||||||
public static final SmaliCompositeElementType REGISTERS_STATEMENT =
|
public static final SmaliCompositeElementType REGISTERS_STATEMENT =
|
||||||
new SmaliCompositeElementType("REGISTERS_STATEMENT", SmaliRegistersStatement.FACTORY);
|
new SmaliCompositeElementType("REGISTERS_STATEMENT", SmaliRegistersStatement.FACTORY);
|
||||||
|
public static final SmaliCompositeElementType REGISTER_REFERENCE =
|
||||||
|
new SmaliCompositeElementType("REGISTER_REFERENCE", SmaliRegisterReference.FACTORY);
|
||||||
public static final SmaliCompositeElementType ACCESS_LIST =
|
public static final SmaliCompositeElementType ACCESS_LIST =
|
||||||
new SmaliCompositeElementType("ACCESS_LIST", SmaliAccessList.FACTORY);
|
new SmaliCompositeElementType("ACCESS_LIST", SmaliAccessList.FACTORY);
|
||||||
public static final SmaliCompositeElementType MEMBER_NAME =
|
public static final SmaliCompositeElementType MEMBER_NAME =
|
||||||
|
@ -84,4 +84,16 @@ public abstract class SmaliCompositeElement extends CompositePsiElement {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected <T> T findAncestorByClass(Class<T> aClass) {
|
||||||
|
PsiElement parent = getParent();
|
||||||
|
while (parent != null) {
|
||||||
|
if (ReflectionCache.isInstance(parent, aClass)) {
|
||||||
|
return (T)parent;
|
||||||
|
}
|
||||||
|
parent = parent.getParent();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,11 @@
|
|||||||
|
|
||||||
package org.jf.smalidea.psi.impl;
|
package org.jf.smalidea.psi.impl;
|
||||||
|
|
||||||
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiAnnotationMemberValue;
|
import com.intellij.psi.PsiAnnotationMemberValue;
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import org.jf.smali.LiteralTools;
|
||||||
|
import org.jf.smalidea.SmaliTokens;
|
||||||
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||||
|
|
||||||
@ -45,4 +49,27 @@ public class SmaliLiteral extends SmaliCompositeElement implements PsiAnnotation
|
|||||||
public SmaliLiteral() {
|
public SmaliLiteral() {
|
||||||
super(SmaliElementTypes.LITERAL);
|
super(SmaliElementTypes.LITERAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getIntegralValue() {
|
||||||
|
ASTNode literalNode = getNode().getFirstChildNode();
|
||||||
|
IElementType literalType = literalNode.getElementType();
|
||||||
|
|
||||||
|
if (literalType == SmaliTokens.LONG_LITERAL) {
|
||||||
|
return LiteralTools.parseLong(literalNode.getText());
|
||||||
|
} else if (literalType == SmaliTokens.NEGATIVE_INTEGER_LITERAL ||
|
||||||
|
literalType == SmaliTokens.POSITIVE_INTEGER_LITERAL) {
|
||||||
|
return LiteralTools.parseInt(literalNode.getText());
|
||||||
|
} else if (literalType == SmaliTokens.SHORT_LITERAL) {
|
||||||
|
return LiteralTools.parseShort(literalNode.getText());
|
||||||
|
} else if (literalType == SmaliTokens.CHAR_LITERAL) {
|
||||||
|
// TODO: implement this
|
||||||
|
return -1;
|
||||||
|
} else if (literalType == SmaliTokens.BYTE_LITERAL) {
|
||||||
|
return LiteralTools.parseByte(literalNode.getText());
|
||||||
|
} else if (literalType == SmaliTokens.BOOL_LITERAL) {
|
||||||
|
return Boolean.parseBoolean(literalNode.getText())?1:0;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Not an integral literal");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,4 +44,17 @@ public class SmaliMethod extends SmaliStubBasedPsiElement<SmaliMethodStub> {
|
|||||||
public SmaliMethod(@NotNull ASTNode node) {
|
public SmaliMethod(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRegisterCount() {
|
||||||
|
SmaliRegistersStatement registersStatement = findChildByClass(SmaliRegistersStatement.class);
|
||||||
|
if (registersStatement == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return registersStatement.getRegisterCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getParameterRegisterCount() {
|
||||||
|
// TODO: implement this
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, 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.smalidea.psi.impl;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||||
|
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||||
|
|
||||||
|
public class SmaliRegisterReference extends SmaliCompositeElement {
|
||||||
|
public static final SmaliCompositeElementFactory FACTORY = new SmaliCompositeElementFactory() {
|
||||||
|
@Override public SmaliCompositeElement createElement() {
|
||||||
|
return new SmaliRegisterReference();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public SmaliRegisterReference() {
|
||||||
|
super(SmaliElementTypes.REGISTER_REFERENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public SmaliMethod getParentMethod() {
|
||||||
|
SmaliMethod parentMethod = findAncestorByClass(SmaliMethod.class);
|
||||||
|
assert parentMethod != null;
|
||||||
|
return parentMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRegisterNumber() {
|
||||||
|
int registerNumber = Integer.parseInt(getText().substring(1));
|
||||||
|
|
||||||
|
if (isParameterRegister()) {
|
||||||
|
SmaliMethod method = getParentMethod();
|
||||||
|
registerNumber += method.getRegisterCount() - method.getParameterRegisterCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
return registerNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isParameterRegister() {
|
||||||
|
return getText().charAt(0) == 'p';
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
package org.jf.smalidea.psi.impl;
|
package org.jf.smalidea.psi.impl;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jf.smalidea.SmaliTokens;
|
||||||
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
import org.jf.smalidea.psi.SmaliCompositeElementFactory;
|
||||||
import org.jf.smalidea.psi.SmaliElementTypes;
|
import org.jf.smalidea.psi.SmaliElementTypes;
|
||||||
|
|
||||||
@ -44,4 +46,30 @@ public class SmaliRegistersStatement extends SmaliCompositeElement {
|
|||||||
public SmaliRegistersStatement() {
|
public SmaliRegistersStatement() {
|
||||||
super(SmaliElementTypes.REGISTERS_STATEMENT);
|
super(SmaliElementTypes.REGISTERS_STATEMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private SmaliMethod getParentMethod() {
|
||||||
|
return findAncestorByClass(SmaliMethod.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the total number of registers for the method
|
||||||
|
*/
|
||||||
|
public int getRegisterCount() {
|
||||||
|
SmaliLiteral literal = findChildByClass(SmaliLiteral.class);
|
||||||
|
assert literal != null;
|
||||||
|
|
||||||
|
long registerCount = literal.getIntegralValue();
|
||||||
|
// TODO: check for register count that's too large
|
||||||
|
if (isLocals()) {
|
||||||
|
SmaliMethod parentMethod = getParentMethod();
|
||||||
|
return (int)registerCount + parentMethod.getParameterRegisterCount();
|
||||||
|
}
|
||||||
|
return (int)registerCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLocals() {
|
||||||
|
return findChildByType(SmaliTokens.LOCALS_DIRECTIVE) != null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
78
smalidea/src/test/java/org/jf/smalidea/SmaliLiteralTest.java
Normal file
78
smalidea/src/test/java/org/jf/smalidea/SmaliLiteralTest.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, 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.smalidea;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.jf.smalidea.psi.impl.SmaliFile;
|
||||||
|
import org.jf.smalidea.psi.impl.SmaliLiteral;
|
||||||
|
|
||||||
|
public class SmaliLiteralTest extends LightCodeInsightFixtureTestCase {
|
||||||
|
private void doTest(long expectedValue, String literalValue) {
|
||||||
|
String text =
|
||||||
|
".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" +
|
||||||
|
".method blah()V\n" +
|
||||||
|
" .registers <ref>" + literalValue + "\n" +
|
||||||
|
" return-void\n" +
|
||||||
|
".end method";
|
||||||
|
|
||||||
|
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
|
||||||
|
text.replace("<ref>", ""));
|
||||||
|
|
||||||
|
PsiElement leafElement = file.findElementAt(text.indexOf("<ref>"));
|
||||||
|
Assert.assertNotNull(leafElement);
|
||||||
|
SmaliLiteral literalElement = (SmaliLiteral)leafElement.getParent();
|
||||||
|
Assert.assertNotNull(literalElement);
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedValue, literalElement.getIntegralValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIntegerValue() {
|
||||||
|
doTest(123, "123");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLongValue() {
|
||||||
|
doTest(100, "100L");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testShortValue() {
|
||||||
|
doTest(99, "99s");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testByteValue() {
|
||||||
|
doTest(127, "127t");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: test char
|
||||||
|
// TODO: test bool
|
||||||
|
}
|
61
smalidea/src/test/java/org/jf/smalidea/SmaliMethodTest.java
Normal file
61
smalidea/src/test/java/org/jf/smalidea/SmaliMethodTest.java
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, 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.smalidea;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.jf.smalidea.psi.impl.SmaliFile;
|
||||||
|
import org.jf.smalidea.psi.impl.SmaliMethod;
|
||||||
|
|
||||||
|
public class SmaliMethodTest extends LightCodeInsightFixtureTestCase {
|
||||||
|
public void testMethodRegisters() {
|
||||||
|
String text =
|
||||||
|
".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" +
|
||||||
|
".me<ref>thod blah()V\n" +
|
||||||
|
" .registers 123\n" +
|
||||||
|
" return-void\n" +
|
||||||
|
".end method";
|
||||||
|
|
||||||
|
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
|
||||||
|
text.replace("<ref>", ""));
|
||||||
|
|
||||||
|
PsiElement leafElement = file.findElementAt(text.indexOf("<ref>"));
|
||||||
|
Assert.assertNotNull(leafElement);
|
||||||
|
SmaliMethod methodElement = (SmaliMethod)leafElement.getParent();
|
||||||
|
Assert.assertNotNull(methodElement);
|
||||||
|
|
||||||
|
Assert.assertEquals(123, methodElement.getRegisterCount());
|
||||||
|
// TODO: test getParameterRegisterCount()
|
||||||
|
// TODO: test .locals directive
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014, 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.smalidea;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.jf.smalidea.psi.impl.SmaliFile;
|
||||||
|
import org.jf.smalidea.psi.impl.SmaliRegisterReference;
|
||||||
|
|
||||||
|
public class SmaliRegisterTest extends LightCodeInsightFixtureTestCase {
|
||||||
|
public void testRegisterReference() {
|
||||||
|
String text =
|
||||||
|
".class public Lmy/pkg/blah; .super Ljava/lang/Object;\n" +
|
||||||
|
".method blah()V\n" +
|
||||||
|
" .registers 123\n" +
|
||||||
|
" const <ref>v10, 123\n" +
|
||||||
|
" return-void\n" +
|
||||||
|
".end method";
|
||||||
|
|
||||||
|
SmaliFile file = (SmaliFile)myFixture.addFileToProject("my/pkg/blah.smali",
|
||||||
|
text.replace("<ref>", ""));
|
||||||
|
|
||||||
|
PsiElement leafElement = file.findElementAt(text.indexOf("<ref>"));
|
||||||
|
Assert.assertNotNull(leafElement);
|
||||||
|
SmaliRegisterReference registerReference = (SmaliRegisterReference)leafElement.getParent();
|
||||||
|
Assert.assertNotNull(registerReference);
|
||||||
|
|
||||||
|
Assert.assertEquals(10, registerReference.getRegisterNumber());
|
||||||
|
// TODO: test parameter register
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user