mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 20:20:12 +02:00
- made the .registers directive optional. it defaults to .registers 0 if not present
- added logic to avoid creating an empty code_item (i.e. for abstract methods) - changed the field and parameter syntax so that there is a colon instead of a whitespace between the field/local name and the following type - changed the member name syntax, so that the initial class is specified with the preceeding 'L' and folling ';', and changed the seperator between the class name and the member name to '->' instead of just another '/' - added the ability to specify members and fields as constants for static fields or annotations (note: dalvik doesn't seem to like embedded field references) - fixed the short and byte literals in the parser (they were mistakenly using the _EMIT token) - fixed an issue with char literals where the value was always a single quote - renamed the CLASS_OR_ARRAY_TYPE_DESCRIPTOR token and related rules to REFERENCE_TYPE_DESCRIPTOR - renamed the FIELD_TYPE_DESCRIPTOR token and related rules to NONVOID_TYPE_DESCRIPTOR git-svn-id: https://smali.googlecode.com/svn/trunk@64 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
parent
5cf0028e73
commit
4250768620
@ -122,31 +122,31 @@ import java.util.ArrayDeque;
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Token nextToken() {
|
public Token nextToken() {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (tokens.size() > 0) {
|
if (tokens.size() > 0) {
|
||||||
Token token = tokens.poll();
|
Token token = tokens.poll();
|
||||||
if (token == Token.SKIP_TOKEN) {
|
if (token == Token.SKIP_TOKEN) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(token.toString());
|
System.out.println(token.toString());
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.channel = Token.DEFAULT_CHANNEL;
|
state.channel = Token.DEFAULT_CHANNEL;
|
||||||
state.tokenStartCharIndex = input.index();
|
state.tokenStartCharIndex = input.index();
|
||||||
state.tokenStartCharPositionInLine = input.getCharPositionInLine();
|
state.tokenStartCharPositionInLine = input.getCharPositionInLine();
|
||||||
state.tokenStartLine = input.getLine();
|
state.tokenStartLine = input.getLine();
|
||||||
state.text = null;
|
state.text = null;
|
||||||
if ( input.LA(1)==CharStream.EOF ) {
|
if ( input.LA(1)==CharStream.EOF ) {
|
||||||
return Token.EOF_TOKEN;
|
return Token.EOF_TOKEN;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mTokens();
|
mTokens();
|
||||||
|
|
||||||
if (tokens.size() == 0) {
|
if (tokens.size() == 0) {
|
||||||
emit();
|
emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (NoViableAltException nva) {
|
catch (NoViableAltException nva) {
|
||||||
reportError(nva);
|
reportError(nva);
|
||||||
@ -177,11 +177,6 @@ import java.util.ArrayDeque;
|
|||||||
token.setChannel(channel);
|
token.setChannel(channel);
|
||||||
tokens.add(token);
|
tokens.add(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reportError(RecognitionException e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -212,8 +207,8 @@ FIELD_PHRASE
|
|||||||
WS
|
WS
|
||||||
(FIELD_ACCESS_SPEC_EMIT WS)+
|
(FIELD_ACCESS_SPEC_EMIT WS)+
|
||||||
MEMBER_NAME_EMIT
|
MEMBER_NAME_EMIT
|
||||||
WS
|
COLON_EMIT
|
||||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD
|
NONVOID_TYPE_DESCRIPTOR_EMITCHILD
|
||||||
WS?
|
WS?
|
||||||
(EQUAL_EMIT WS? LITERAL_EMITCHILD)?;
|
(EQUAL_EMIT WS? LITERAL_EMITCHILD)?;
|
||||||
|
|
||||||
@ -267,9 +262,7 @@ INSTRUCTION_FORMAT21c_FIELD_PHRASE
|
|||||||
WS
|
WS
|
||||||
REGISTER_EMIT
|
REGISTER_EMIT
|
||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
FULLY_QUALIFIED_FIELD_EMITCHILDREN;
|
||||||
WS
|
|
||||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD;
|
|
||||||
|
|
||||||
INSTRUCTION_FORMAT21c_STRING_PHRASE
|
INSTRUCTION_FORMAT21c_STRING_PHRASE
|
||||||
: INSTRUCTION_FORMAT21c_STRING_EMIT
|
: INSTRUCTION_FORMAT21c_STRING_EMIT
|
||||||
@ -283,7 +276,7 @@ INSTRUCTION_FORMAT21c_TYPE_PHRASE
|
|||||||
WS
|
WS
|
||||||
REGISTER_EMIT
|
REGISTER_EMIT
|
||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
CLASS_OR_ARRAY_TYPE_DESCRIPTOR_EMITCHILD;
|
REFERENCE_TYPE_DESCRIPTOR_EMITCHILD;
|
||||||
|
|
||||||
INSTRUCTION_FORMAT21h_PHRASE
|
INSTRUCTION_FORMAT21h_PHRASE
|
||||||
: INSTRUCTION_FORMAT21h_EMIT
|
: INSTRUCTION_FORMAT21h_EMIT
|
||||||
@ -322,9 +315,7 @@ INSTRUCTION_FORMAT22c_FIELD_PHRASE
|
|||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
REGISTER_EMIT
|
REGISTER_EMIT
|
||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
FULLY_QUALIFIED_FIELD_EMITCHILDREN;
|
||||||
WS
|
|
||||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD;
|
|
||||||
|
|
||||||
INSTRUCTION_FORMAT22c_TYPE_PHRASE
|
INSTRUCTION_FORMAT22c_TYPE_PHRASE
|
||||||
: INSTRUCTION_FORMAT22c_TYPE_EMIT
|
: INSTRUCTION_FORMAT22c_TYPE_EMIT
|
||||||
@ -333,7 +324,7 @@ INSTRUCTION_FORMAT22c_TYPE_PHRASE
|
|||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
REGISTER_EMIT
|
REGISTER_EMIT
|
||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD;
|
NONVOID_TYPE_DESCRIPTOR_EMITCHILD;
|
||||||
|
|
||||||
INSTRUCTION_FORMAT22s_PHRASE
|
INSTRUCTION_FORMAT22s_PHRASE
|
||||||
: INSTRUCTION_FORMAT22s_EMIT
|
: INSTRUCTION_FORMAT22s_EMIT
|
||||||
@ -407,16 +398,14 @@ INSTRUCTION_FORMAT35c_METHOD_PHRASE
|
|||||||
WS
|
WS
|
||||||
REGISTER_LIST_EMITCHILDREN
|
REGISTER_LIST_EMITCHILDREN
|
||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
FULLY_QUALIFIED_METHOD_EMITCHILDREN;
|
||||||
METHOD_PROTOTYPE_EMITCHILDREN;
|
|
||||||
|
|
||||||
INSTRUCTION_FORMAT3rc_METHOD_PHRASE
|
INSTRUCTION_FORMAT3rc_METHOD_PHRASE
|
||||||
: INSTRUCTION_FORMAT3rc_METHOD_EMIT
|
: INSTRUCTION_FORMAT3rc_METHOD_EMIT
|
||||||
WS
|
WS
|
||||||
REGISTER_RANGE_EMITCHILDREN
|
REGISTER_RANGE_EMITCHILDREN
|
||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
FULLY_QUALIFIED_METHOD_EMITCHILDREN;
|
||||||
METHOD_PROTOTYPE_EMITCHILDREN;
|
|
||||||
|
|
||||||
INSTRUCTION_FORMAT51l_PHRASE
|
INSTRUCTION_FORMAT51l_PHRASE
|
||||||
: INSTRUCTION_FORMAT51l_EMIT
|
: INSTRUCTION_FORMAT51l_EMIT
|
||||||
@ -459,7 +448,7 @@ REGISTERS_PHRASE
|
|||||||
CATCH_PHRASE
|
CATCH_PHRASE
|
||||||
: CATCH_DIRECTIVE_EMIT
|
: CATCH_DIRECTIVE_EMIT
|
||||||
WS
|
WS
|
||||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD
|
NONVOID_TYPE_DESCRIPTOR_EMITCHILD
|
||||||
WS? '{' WS?
|
WS? '{' WS?
|
||||||
(LABEL_EMIT | OFFSET_EMIT)
|
(LABEL_EMIT | OFFSET_EMIT)
|
||||||
WS '..' WS
|
WS '..' WS
|
||||||
@ -485,8 +474,8 @@ LOCAL_PHRASE
|
|||||||
REGISTER_EMIT
|
REGISTER_EMIT
|
||||||
WS? COMMA_EMIT WS?
|
WS? COMMA_EMIT WS?
|
||||||
SIMPLE_NAME_EMIT
|
SIMPLE_NAME_EMIT
|
||||||
WS
|
COLON_EMIT
|
||||||
FIELD_TYPE_DESCRIPTOR_EMITCHILD
|
NONVOID_TYPE_DESCRIPTOR_EMITCHILD
|
||||||
WS?
|
WS?
|
||||||
( COMMA_EMIT WS? STRING_LITERAL_EMIT)?;
|
( COMMA_EMIT WS? STRING_LITERAL_EMIT)?;
|
||||||
|
|
||||||
@ -673,29 +662,35 @@ fragment REGISTER_RANGE_EMITCHILDREN
|
|||||||
|
|
||||||
fragment METHOD_PROTOTYPE_EMITCHILDREN
|
fragment METHOD_PROTOTYPE_EMITCHILDREN
|
||||||
: OPEN_PAREN_EMIT
|
: OPEN_PAREN_EMIT
|
||||||
(FIELD_TYPE_DESCRIPTOR_EMITCHILD+)?
|
(NONVOID_TYPE_DESCRIPTOR_EMITCHILD+)?
|
||||||
CLOSE_PAREN_EMIT
|
CLOSE_PAREN_EMIT
|
||||||
TYPE_DESCRIPTOR_EMITCHILD;
|
TYPE_DESCRIPTOR_EMITCHILD;
|
||||||
|
|
||||||
fragment FULLY_QUALIFIED_MEMBER_NAME_EMITCHILDREN
|
fragment FULLY_QUALIFIED_FIELD_EMITCHILDREN
|
||||||
@init {int startPos;}
|
: REFERENCE_TYPE_DESCRIPTOR_EMITCHILD
|
||||||
: {startPos = getCharIndex();} (SIMPLE_NAME '/')* token=SIMPLE_NAME {((CommonToken)$token).setStartIndex(startPos); emit($token, CLASS_NAME);}
|
ARROW_EMIT
|
||||||
'/'
|
MEMBER_NAME_EMIT
|
||||||
MEMBER_NAME_EMIT;
|
COLON_EMIT
|
||||||
|
NONVOID_TYPE_DESCRIPTOR_EMITCHILD;
|
||||||
|
|
||||||
|
fragment FULLY_QUALIFIED_METHOD_EMITCHILDREN
|
||||||
|
: REFERENCE_TYPE_DESCRIPTOR_EMITCHILD
|
||||||
|
ARROW_EMIT
|
||||||
|
MEMBER_NAME_EMIT
|
||||||
|
METHOD_PROTOTYPE_EMITCHILDREN;
|
||||||
|
|
||||||
fragment TYPE_DESCRIPTOR_EMITCHILD
|
fragment TYPE_DESCRIPTOR_EMITCHILD
|
||||||
: PRIMITIVE_TYPE_EMIT
|
: PRIMITIVE_TYPE_EMIT
|
||||||
| VOID_TYPE_EMIT
|
| VOID_TYPE_EMIT
|
||||||
| CLASS_DESCRIPTOR_EMIT
|
| CLASS_DESCRIPTOR_EMIT
|
||||||
| ARRAY_DESCRIPTOR_EMIT;
|
| ARRAY_DESCRIPTOR_EMIT;
|
||||||
|
|
||||||
|
fragment NONVOID_TYPE_DESCRIPTOR_EMITCHILD
|
||||||
fragment FIELD_TYPE_DESCRIPTOR_EMITCHILD
|
|
||||||
: PRIMITIVE_TYPE_EMIT
|
: PRIMITIVE_TYPE_EMIT
|
||||||
| CLASS_DESCRIPTOR_EMIT
|
| CLASS_DESCRIPTOR_EMIT
|
||||||
| ARRAY_DESCRIPTOR_EMIT;
|
| ARRAY_DESCRIPTOR_EMIT;
|
||||||
|
|
||||||
fragment CLASS_OR_ARRAY_TYPE_DESCRIPTOR_EMITCHILD
|
fragment REFERENCE_TYPE_DESCRIPTOR_EMITCHILD
|
||||||
: CLASS_DESCRIPTOR_EMIT
|
: CLASS_DESCRIPTOR_EMIT
|
||||||
| ARRAY_DESCRIPTOR_EMIT;
|
| ARRAY_DESCRIPTOR_EMIT;
|
||||||
|
|
||||||
@ -724,10 +719,7 @@ fragment CLASS_DESCRIPTOR_EMIT
|
|||||||
: CLASS_DESCRIPTOR {emit($CLASS_DESCRIPTOR, CLASS_DESCRIPTOR);};
|
: CLASS_DESCRIPTOR {emit($CLASS_DESCRIPTOR, CLASS_DESCRIPTOR);};
|
||||||
|
|
||||||
fragment CLASS_DESCRIPTOR
|
fragment CLASS_DESCRIPTOR
|
||||||
: 'L' CLASS_NAME ';';
|
: 'L' (SIMPLE_NAME '/')* SIMPLE_NAME ';';
|
||||||
|
|
||||||
fragment CLASS_NAME
|
|
||||||
: (SIMPLE_NAME '/')* SIMPLE_NAME;
|
|
||||||
|
|
||||||
|
|
||||||
fragment ARRAY_DESCRIPTOR_EMIT
|
fragment ARRAY_DESCRIPTOR_EMIT
|
||||||
@ -848,9 +840,9 @@ fragment LITERAL_EMITCHILD
|
|||||||
| DOUBLE_LITERAL_EMIT
|
| DOUBLE_LITERAL_EMIT
|
||||||
| CHAR_LITERAL_EMIT
|
| CHAR_LITERAL_EMIT
|
||||||
| BOOL_LITERAL_EMIT
|
| BOOL_LITERAL_EMIT
|
||||||
| TYPE_DESCRIPTOR_EMITCHILD
|
|
||||||
| ARRAY_LITERAL_EMITCHILDREN
|
| ARRAY_LITERAL_EMITCHILDREN
|
||||||
| SUBANNOTATION_EMITCHILDREN;
|
| SUBANNOTATION_EMITCHILDREN
|
||||||
|
| TYPE_FIELD_METHOD_LITERAL_EMITCHILDREN;
|
||||||
|
|
||||||
fragment SUBANNOTATION_EMITCHILDREN
|
fragment SUBANNOTATION_EMITCHILDREN
|
||||||
: SUBANNOTATION_START_EMIT
|
: SUBANNOTATION_START_EMIT
|
||||||
@ -894,7 +886,17 @@ fragment ANNOTATION_ELEMENT_EMITCHILDREN
|
|||||||
EQUAL_EMIT
|
EQUAL_EMIT
|
||||||
WS?
|
WS?
|
||||||
LITERAL_EMITCHILD;
|
LITERAL_EMITCHILD;
|
||||||
|
|
||||||
|
fragment TYPE_FIELD_METHOD_LITERAL_EMITCHILDREN
|
||||||
|
: REFERENCE_TYPE_DESCRIPTOR_EMITCHILD
|
||||||
|
( ARROW_EMIT
|
||||||
|
MEMBER_NAME_EMIT
|
||||||
|
( METHOD_PROTOTYPE_EMITCHILDREN
|
||||||
|
| COLON_EMIT NONVOID_TYPE_DESCRIPTOR_EMITCHILD))?
|
||||||
|
//TODO: allow void and primitive type here?
|
||||||
|
| PRIMITIVE_TYPE_EMIT
|
||||||
|
| VOID_TYPE_EMIT;
|
||||||
|
|
||||||
fragment ARRAY_LITERAL_EMITCHILDREN
|
fragment ARRAY_LITERAL_EMITCHILDREN
|
||||||
: ARRAY_START_EMIT
|
: ARRAY_START_EMIT
|
||||||
WS?
|
WS?
|
||||||
@ -1414,3 +1416,13 @@ fragment COMMA_EMIT
|
|||||||
: COMMA {emit($COMMA, COMMA, Token.HIDDEN_CHANNEL);};
|
: COMMA {emit($COMMA, COMMA, Token.HIDDEN_CHANNEL);};
|
||||||
fragment COMMA
|
fragment COMMA
|
||||||
: ',';
|
: ',';
|
||||||
|
|
||||||
|
fragment COLON_EMIT
|
||||||
|
: COLON {emit($COLON, COLON, Token.HIDDEN_CHANNEL);};
|
||||||
|
fragment COLON
|
||||||
|
: ':';
|
||||||
|
|
||||||
|
fragment ARROW_EMIT
|
||||||
|
: ARROW {emit($ARROW, ARROW);};
|
||||||
|
fragment ARROW
|
||||||
|
: '->';
|
||||||
|
@ -56,6 +56,8 @@ tokens {
|
|||||||
I_ANNOTATION;
|
I_ANNOTATION;
|
||||||
I_ANNOTATION_ELEMENT;
|
I_ANNOTATION_ELEMENT;
|
||||||
I_SUBANNOTATION;
|
I_SUBANNOTATION;
|
||||||
|
I_ENCODED_FIELD;
|
||||||
|
I_ENCODED_METHOD;
|
||||||
I_ENCODED_ARRAY;
|
I_ENCODED_ARRAY;
|
||||||
I_ARRAY_ELEMENT_SIZE;
|
I_ARRAY_ELEMENT_SIZE;
|
||||||
I_ARRAY_ELEMENTS;
|
I_ARRAY_ELEMENTS;
|
||||||
@ -113,9 +115,6 @@ tokens {
|
|||||||
I_STATEMENT_SPARSE_SWITCH;
|
I_STATEMENT_SPARSE_SWITCH;
|
||||||
I_REGISTER_RANGE;
|
I_REGISTER_RANGE;
|
||||||
I_REGISTER_LIST;
|
I_REGISTER_LIST;
|
||||||
|
|
||||||
CLASS_NAME;
|
|
||||||
MEMBER_NAME;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@header {
|
@header {
|
||||||
@ -200,11 +199,11 @@ access_list
|
|||||||
: ACCESS_SPEC+ -> ^(I_ACCESS_LIST[$start,"I_ACCESS_LIST"] ACCESS_SPEC+);
|
: ACCESS_SPEC+ -> ^(I_ACCESS_LIST[$start,"I_ACCESS_LIST"] ACCESS_SPEC+);
|
||||||
|
|
||||||
|
|
||||||
field : FIELD_DIRECTIVE access_list MEMBER_NAME field_type_descriptor literal?
|
field : FIELD_DIRECTIVE access_list MEMBER_NAME nonvoid_type_descriptor literal?
|
||||||
( (annotation+ END_FIELD_DIRECTIVE)=> annotation+ END_FIELD_DIRECTIVE
|
( (annotation+ END_FIELD_DIRECTIVE)=> annotation+ END_FIELD_DIRECTIVE
|
||||||
| END_FIELD_DIRECTIVE?
|
| END_FIELD_DIRECTIVE?
|
||||||
)
|
)
|
||||||
-> ^(I_FIELD[$start, "I_FIELD"] MEMBER_NAME access_list ^(I_FIELD_TYPE field_type_descriptor) ^(I_FIELD_INITIAL_VALUE literal)? ^(I_ANNOTATIONS annotation*));
|
-> ^(I_FIELD[$start, "I_FIELD"] MEMBER_NAME access_list ^(I_FIELD_TYPE nonvoid_type_descriptor) ^(I_FIELD_INITIAL_VALUE literal)? ^(I_ANNOTATIONS annotation*));
|
||||||
|
|
||||||
method
|
method
|
||||||
scope {int currentAddress;}
|
scope {int currentAddress;}
|
||||||
@ -215,15 +214,17 @@ method
|
|||||||
-> ^(I_METHOD[$start, "I_METHOD"] MEMBER_NAME method_prototype access_list statements_and_directives);
|
-> ^(I_METHOD[$start, "I_METHOD"] MEMBER_NAME method_prototype access_list statements_and_directives);
|
||||||
|
|
||||||
method_prototype
|
method_prototype
|
||||||
: OPEN_PAREN field_type_descriptor* CLOSE_PAREN type_descriptor
|
: OPEN_PAREN nonvoid_type_descriptor* CLOSE_PAREN type_descriptor
|
||||||
-> ^(I_METHOD_PROTOTYPE[$start, "I_METHOD_PROTOTYPE"] ^(I_METHOD_RETURN_TYPE type_descriptor) field_type_descriptor*);
|
-> ^(I_METHOD_PROTOTYPE[$start, "I_METHOD_PROTOTYPE"] ^(I_METHOD_RETURN_TYPE type_descriptor) nonvoid_type_descriptor*);
|
||||||
|
|
||||||
|
|
||||||
fully_qualified_method
|
fully_qualified_method
|
||||||
: CLASS_NAME MEMBER_NAME method_prototype;
|
: reference_type_descriptor ARROW MEMBER_NAME method_prototype
|
||||||
|
-> reference_type_descriptor MEMBER_NAME method_prototype;
|
||||||
|
|
||||||
fully_qualified_field
|
fully_qualified_field
|
||||||
: CLASS_NAME MEMBER_NAME field_type_descriptor;
|
: reference_type_descriptor ARROW MEMBER_NAME nonvoid_type_descriptor
|
||||||
|
-> reference_type_descriptor MEMBER_NAME nonvoid_type_descriptor;
|
||||||
|
|
||||||
statements_and_directives
|
statements_and_directives
|
||||||
scope {boolean hasRegistersDirective;}
|
scope {boolean hasRegistersDirective;}
|
||||||
@ -239,13 +240,7 @@ statements_and_directives
|
|||||||
| ordered_debug_directive
|
| ordered_debug_directive
|
||||||
| annotation
|
| annotation
|
||||||
)*
|
)*
|
||||||
{
|
-> ^(I_REGISTERS registers_directive?)
|
||||||
if (!$statements_and_directives::hasRegistersDirective) {
|
|
||||||
//TODO: throw correct exception type here
|
|
||||||
throw new RuntimeException("This method has no register directive");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-> registers_directive
|
|
||||||
^(I_LABELS label*)
|
^(I_LABELS label*)
|
||||||
^(I_STATEMENTS instruction*)
|
^(I_STATEMENTS instruction*)
|
||||||
^(I_CATCHES catch_directive*)
|
^(I_CATCHES catch_directive*)
|
||||||
@ -255,11 +250,11 @@ statements_and_directives
|
|||||||
|
|
||||||
registers_directive
|
registers_directive
|
||||||
: REGISTERS_DIRECTIVE integral_literal
|
: REGISTERS_DIRECTIVE integral_literal
|
||||||
-> ^(I_REGISTERS[$start, "I_REGISTERS"] integral_literal);
|
-> integral_literal;
|
||||||
|
|
||||||
catch_directive
|
catch_directive
|
||||||
: CATCH_DIRECTIVE field_type_descriptor from=offset_or_label to=offset_or_label using=offset_or_label
|
: CATCH_DIRECTIVE nonvoid_type_descriptor from=offset_or_label to=offset_or_label using=offset_or_label
|
||||||
-> ^(I_CATCH[$start, "I_CATCH"] I_ADDRESS[$start, Integer.toString($method::currentAddress)] field_type_descriptor $from $to $using)
|
-> ^(I_CATCH[$start, "I_CATCH"] I_ADDRESS[$start, Integer.toString($method::currentAddress)] nonvoid_type_descriptor $from $to $using)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
@ -290,8 +285,8 @@ line_directive
|
|||||||
-> ^(I_LINE integral_literal I_ADDRESS[$start, Integer.toString($method::currentAddress)]);
|
-> ^(I_LINE integral_literal I_ADDRESS[$start, Integer.toString($method::currentAddress)]);
|
||||||
|
|
||||||
local_directive
|
local_directive
|
||||||
: LOCAL_DIRECTIVE REGISTER SIMPLE_NAME field_type_descriptor STRING_LITERAL?
|
: LOCAL_DIRECTIVE REGISTER SIMPLE_NAME nonvoid_type_descriptor STRING_LITERAL?
|
||||||
-> ^(I_LOCAL[$start, "I_LOCAL"] REGISTER SIMPLE_NAME field_type_descriptor STRING_LITERAL? I_ADDRESS[$start, Integer.toString($method::currentAddress)]);
|
-> ^(I_LOCAL[$start, "I_LOCAL"] REGISTER SIMPLE_NAME nonvoid_type_descriptor STRING_LITERAL? I_ADDRESS[$start, Integer.toString($method::currentAddress)]);
|
||||||
|
|
||||||
end_local_directive
|
end_local_directive
|
||||||
: END_LOCAL_DIRECTIVE REGISTER
|
: END_LOCAL_DIRECTIVE REGISTER
|
||||||
@ -344,8 +339,8 @@ instruction returns [int size]
|
|||||||
INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL {$size = Format21c.Format.getByteCount();}
|
INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL {$size = Format21c.Format.getByteCount();}
|
||||||
-> ^(I_STATEMENT_FORMAT21c_STRING[$start, "I_STATEMENT_FORMAT21c_STRING"] INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL)
|
-> ^(I_STATEMENT_FORMAT21c_STRING[$start, "I_STATEMENT_FORMAT21c_STRING"] INSTRUCTION_FORMAT21c_STRING REGISTER STRING_LITERAL)
|
||||||
| //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2
|
| //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2
|
||||||
INSTRUCTION_FORMAT21c_TYPE REGISTER class_or_array_type_descriptor {$size = Format21c.Format.getByteCount();}
|
INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor {$size = Format21c.Format.getByteCount();}
|
||||||
-> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_FORMAT21c_TYPE REGISTER class_or_array_type_descriptor)
|
-> ^(I_STATEMENT_FORMAT21c_TYPE[$start, "I_STATEMENT_FORMAT21c"] INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor)
|
||||||
| //e.g. const/high16 v1, 1234
|
| //e.g. const/high16 v1, 1234
|
||||||
INSTRUCTION_FORMAT21h REGISTER integral_literal {$size = Format21h.Format.getByteCount();}
|
INSTRUCTION_FORMAT21h REGISTER integral_literal {$size = Format21h.Format.getByteCount();}
|
||||||
-> ^(I_STATEMENT_FORMAT21h[$start, "I_STATEMENT_FORMAT21h"] INSTRUCTION_FORMAT21h REGISTER integral_literal)
|
-> ^(I_STATEMENT_FORMAT21h[$start, "I_STATEMENT_FORMAT21h"] INSTRUCTION_FORMAT21h REGISTER integral_literal)
|
||||||
@ -362,8 +357,8 @@ instruction returns [int size]
|
|||||||
INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field {$size = Format22c.Format.getByteCount();}
|
INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field {$size = Format22c.Format.getByteCount();}
|
||||||
-> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_STATEMENT_FORMAT22c_FIELD"] INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field)
|
-> ^(I_STATEMENT_FORMAT22c_FIELD[$start, "I_STATEMENT_FORMAT22c_FIELD"] INSTRUCTION_FORMAT22c_FIELD REGISTER REGISTER fully_qualified_field)
|
||||||
| //e.g. instance-of v0, v1, Ljava/lang/String;
|
| //e.g. instance-of v0, v1, Ljava/lang/String;
|
||||||
INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER field_type_descriptor {$size = Format22c.Format.getByteCount();}
|
INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor {$size = Format22c.Format.getByteCount();}
|
||||||
-> ^(I_STATEMENT_FORMAT22c_TYPE[$start, "I_STATEMENT_FORMAT22c_TYPE"] INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER field_type_descriptor)
|
-> ^(I_STATEMENT_FORMAT22c_TYPE[$start, "I_STATEMENT_FORMAT22c_TYPE"] INSTRUCTION_FORMAT22c_TYPE REGISTER REGISTER nonvoid_type_descriptor)
|
||||||
| //e.g. add-int/lit16 v0, v1, 12345
|
| //e.g. add-int/lit16 v0, v1, 12345
|
||||||
INSTRUCTION_FORMAT22s REGISTER REGISTER integral_literal {$size = Format22s.Format.getByteCount();}
|
INSTRUCTION_FORMAT22s REGISTER REGISTER integral_literal {$size = Format22s.Format.getByteCount();}
|
||||||
-> ^(I_STATEMENT_FORMAT22s[$start, "I_STATEMENT_FORMAT22s"] INSTRUCTION_FORMAT22s REGISTER REGISTER integral_literal)
|
-> ^(I_STATEMENT_FORMAT22s[$start, "I_STATEMENT_FORMAT22s"] INSTRUCTION_FORMAT22s REGISTER REGISTER integral_literal)
|
||||||
@ -496,13 +491,13 @@ register_range
|
|||||||
: REGISTER REGISTER? -> ^(I_REGISTER_RANGE[$start, "I_REGISTER_RANGE"] REGISTER REGISTER?);
|
: REGISTER REGISTER? -> ^(I_REGISTER_RANGE[$start, "I_REGISTER_RANGE"] REGISTER REGISTER?);
|
||||||
|
|
||||||
|
|
||||||
field_type_descriptor
|
nonvoid_type_descriptor
|
||||||
: PRIMITIVE_TYPE
|
: PRIMITIVE_TYPE
|
||||||
| CLASS_DESCRIPTOR
|
| CLASS_DESCRIPTOR
|
||||||
| ARRAY_DESCRIPTOR
|
| ARRAY_DESCRIPTOR
|
||||||
;
|
;
|
||||||
|
|
||||||
class_or_array_type_descriptor
|
reference_type_descriptor
|
||||||
: CLASS_DESCRIPTOR
|
: CLASS_DESCRIPTOR
|
||||||
| ARRAY_DESCRIPTOR;
|
| ARRAY_DESCRIPTOR;
|
||||||
|
|
||||||
@ -541,16 +536,16 @@ fixed_literal returns[int size]
|
|||||||
literal
|
literal
|
||||||
: INTEGER_LITERAL
|
: INTEGER_LITERAL
|
||||||
| LONG_LITERAL
|
| LONG_LITERAL
|
||||||
| SHORT_LITERAL_EMIT
|
| SHORT_LITERAL
|
||||||
| BYTE_LITERAL_EMIT
|
| BYTE_LITERAL
|
||||||
| FLOAT_LITERAL
|
| FLOAT_LITERAL
|
||||||
| DOUBLE_LITERAL
|
| DOUBLE_LITERAL
|
||||||
| CHAR_LITERAL
|
| CHAR_LITERAL
|
||||||
| STRING_LITERAL
|
| STRING_LITERAL
|
||||||
| BOOL_LITERAL
|
| BOOL_LITERAL
|
||||||
| type_descriptor
|
|
||||||
| array_literal
|
| array_literal
|
||||||
| subannotation;
|
| subannotation
|
||||||
|
| type_field_method;
|
||||||
|
|
||||||
array_literal
|
array_literal
|
||||||
: ARRAY_START literal* ARRAY_END
|
: ARRAY_START literal* ARRAY_END
|
||||||
@ -568,3 +563,14 @@ annotation_element
|
|||||||
subannotation
|
subannotation
|
||||||
: SUBANNOTATION_START CLASS_DESCRIPTOR annotation_element* SUBANNOTATION_END
|
: SUBANNOTATION_START CLASS_DESCRIPTOR annotation_element* SUBANNOTATION_END
|
||||||
-> ^(I_SUBANNOTATION[$start, "I_SUBANNOTATION"] CLASS_DESCRIPTOR annotation_element*);
|
-> ^(I_SUBANNOTATION[$start, "I_SUBANNOTATION"] CLASS_DESCRIPTOR annotation_element*);
|
||||||
|
|
||||||
|
type_field_method
|
||||||
|
: reference_type_descriptor
|
||||||
|
( ARROW MEMBER_NAME
|
||||||
|
( nonvoid_type_descriptor -> ^(I_ENCODED_FIELD reference_type_descriptor MEMBER_NAME nonvoid_type_descriptor)
|
||||||
|
| method_prototype -> ^(I_ENCODED_METHOD reference_type_descriptor MEMBER_NAME method_prototype)
|
||||||
|
)
|
||||||
|
| -> reference_type_descriptor
|
||||||
|
)
|
||||||
|
| PRIMITIVE_TYPE
|
||||||
|
| VOID_TYPE;
|
||||||
|
@ -197,11 +197,11 @@ methods returns[List<AnnotationDirectoryItem.MethodAnnotation> methodAnnotationS
|
|||||||
})*);
|
})*);
|
||||||
|
|
||||||
field returns[ClassDataItem.EncodedField encodedField, EncodedValue encodedValue, AnnotationDirectoryItem.FieldAnnotation fieldAnnotationSet]
|
field returns[ClassDataItem.EncodedField encodedField, EncodedValue encodedValue, AnnotationDirectoryItem.FieldAnnotation fieldAnnotationSet]
|
||||||
:^(I_FIELD MEMBER_NAME access_list ^(I_FIELD_TYPE field_type_descriptor) field_initial_value annotations?)
|
:^(I_FIELD MEMBER_NAME access_list ^(I_FIELD_TYPE nonvoid_type_descriptor) field_initial_value annotations?)
|
||||||
{
|
{
|
||||||
TypeIdItem classType = classDefItem.getClassType();
|
TypeIdItem classType = classDefItem.getClassType();
|
||||||
StringIdItem memberName = new StringIdItem(dexFile, $MEMBER_NAME.text);
|
StringIdItem memberName = new StringIdItem(dexFile, $MEMBER_NAME.text);
|
||||||
TypeIdItem fieldType = $field_type_descriptor.type;
|
TypeIdItem fieldType = $nonvoid_type_descriptor.type;
|
||||||
|
|
||||||
FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, memberName, fieldType);
|
FieldIdItem fieldIdItem = new FieldIdItem(dexFile, classType, memberName, fieldType);
|
||||||
$encodedField = new ClassDataItem.EncodedField(dexFile, fieldIdItem, $access_list.value);
|
$encodedField = new ClassDataItem.EncodedField(dexFile, fieldIdItem, $access_list.value);
|
||||||
@ -239,7 +239,9 @@ literal returns[EncodedValue encodedValue]
|
|||||||
| bool_literal { $encodedValue = new EncodedValue(dexFile, new BoolEncodedValueSubField($bool_literal.value)); }
|
| bool_literal { $encodedValue = new EncodedValue(dexFile, new BoolEncodedValueSubField($bool_literal.value)); }
|
||||||
| type_descriptor { $encodedValue = new EncodedValue(dexFile, new EncodedIndexedItemReference(dexFile, $type_descriptor.type)); }
|
| type_descriptor { $encodedValue = new EncodedValue(dexFile, new EncodedIndexedItemReference(dexFile, $type_descriptor.type)); }
|
||||||
| array_literal { $encodedValue = new EncodedValue(dexFile, new ArrayEncodedValueSubField(dexFile, $array_literal.values)); }
|
| array_literal { $encodedValue = new EncodedValue(dexFile, new ArrayEncodedValueSubField(dexFile, $array_literal.values)); }
|
||||||
| subannotation { $encodedValue = new EncodedValue(dexFile, $subannotation.value); };
|
| subannotation { $encodedValue = new EncodedValue(dexFile, $subannotation.value); }
|
||||||
|
| field_literal { $encodedValue = new EncodedValue(dexFile, $field_literal.value); }
|
||||||
|
| method_literal { $encodedValue = new EncodedValue(dexFile, $method_literal.value); };
|
||||||
|
|
||||||
|
|
||||||
//everything but string
|
//everything but string
|
||||||
@ -355,46 +357,59 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod,
|
|||||||
parameters
|
parameters
|
||||||
ordered_debug_directives
|
ordered_debug_directives
|
||||||
annotations
|
annotations
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MethodIdItem methodIdItem = $method_name_and_prototype.methodIdItem;
|
MethodIdItem methodIdItem = $method_name_and_prototype.methodIdItem;
|
||||||
int registers = $registers_directive.registers;
|
|
||||||
int access = $access_list.value;
|
int access = $access_list.value;
|
||||||
boolean isStatic = (access & AccessFlags.STATIC) != 0;
|
boolean isStatic = (access & AccessFlags.STATIC) != 0;
|
||||||
|
|
||||||
|
int registers = $registers_directive.registers;
|
||||||
ArrayList<Instruction> instructions = $statements.instructions;
|
ArrayList<Instruction> instructions = $statements.instructions;
|
||||||
|
|
||||||
|
|
||||||
int minRegisters = methodIdItem.getParameterRegisterCount((access & AccessFlags.STATIC) != 0);
|
|
||||||
|
|
||||||
if (registers < minRegisters) {
|
|
||||||
//TODO: throw the correct exception type
|
|
||||||
throw new RuntimeException( "This method requires at least " +
|
|
||||||
Integer.toString(minRegisters) +
|
|
||||||
" registers, for the method parameters");
|
|
||||||
}
|
|
||||||
|
|
||||||
Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> temp = $method::tryList.encodeTries(dexFile);
|
Pair<List<CodeItem.TryItem>, List<CodeItem.EncodedCatchHandler>> temp = $method::tryList.encodeTries(dexFile);
|
||||||
List<CodeItem.TryItem> tries = temp.first;
|
List<CodeItem.TryItem> tries = temp.first;
|
||||||
List<CodeItem.EncodedCatchHandler> handlers = temp.second;
|
List<CodeItem.EncodedCatchHandler> handlers = temp.second;
|
||||||
|
|
||||||
|
|
||||||
|
DebugInfoItem debugInfoItem = $method::debugInfo.encodeDebugInfo(dexFile);
|
||||||
|
|
||||||
int methodParameterCount = methodIdItem.getParameterCount();
|
CodeItem codeItem;
|
||||||
if ($method::debugInfo.getParameterNameCount() > methodParameterCount) {
|
|
||||||
//TODO: throw the correct exception type
|
|
||||||
throw new RuntimeException( "Too many parameter names specified. This method only has " +
|
|
||||||
Integer.toString(methodParameterCount) +
|
|
||||||
" parameters.");
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugInfoItem debugInfoItem = $method::debugInfo.encodeDebugInfo(dexFile);
|
if (registers == 0 &&
|
||||||
|
instructions.size() == 0 &&
|
||||||
|
$method::labels.size()== 0 &&
|
||||||
|
(tries == null || tries.size() == 0) &&
|
||||||
|
(handlers == null || handlers.size() == 0) &&
|
||||||
|
debugInfoItem == null) {
|
||||||
|
|
||||||
|
codeItem = null;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
int minRegisters = methodIdItem.getParameterRegisterCount((access & AccessFlags.STATIC) != 0);
|
||||||
|
|
||||||
CodeItem codeItem = new CodeItem(dexFile,
|
if (registers < minRegisters) {
|
||||||
|
//TODO: throw the correct exception type
|
||||||
|
throw new RuntimeException( "This method requires at least " +
|
||||||
|
Integer.toString(minRegisters) +
|
||||||
|
" registers, for the method parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
int methodParameterCount = methodIdItem.getParameterCount();
|
||||||
|
if ($method::debugInfo.getParameterNameCount() > methodParameterCount) {
|
||||||
|
//TODO: throw the correct exception type
|
||||||
|
throw new RuntimeException( "Too many parameter names specified. This method only has " +
|
||||||
|
Integer.toString(methodParameterCount) +
|
||||||
|
" parameters.");
|
||||||
|
}
|
||||||
|
|
||||||
|
codeItem = new CodeItem(dexFile,
|
||||||
registers,
|
registers,
|
||||||
methodIdItem.getParameterRegisterCount(isStatic),
|
methodIdItem.getParameterRegisterCount(isStatic),
|
||||||
instructions,
|
instructions,
|
||||||
debugInfoItem,
|
debugInfoItem,
|
||||||
tries,
|
tries,
|
||||||
handlers);
|
handlers);
|
||||||
|
}
|
||||||
|
|
||||||
$encodedMethod = new ClassDataItem.EncodedMethod(dexFile, methodIdItem, access, codeItem);
|
$encodedMethod = new ClassDataItem.EncodedMethod(dexFile, methodIdItem, access, codeItem);
|
||||||
|
|
||||||
@ -433,33 +448,34 @@ field_type_list returns[ArrayList<TypeIdItem> types]
|
|||||||
$types = new ArrayList<TypeIdItem>();
|
$types = new ArrayList<TypeIdItem>();
|
||||||
}
|
}
|
||||||
: (
|
: (
|
||||||
field_type_descriptor
|
nonvoid_type_descriptor
|
||||||
{
|
{
|
||||||
$types.add($field_type_descriptor.type);
|
$types.add($nonvoid_type_descriptor.type);
|
||||||
}
|
}
|
||||||
)*;
|
)*;
|
||||||
|
|
||||||
|
|
||||||
fully_qualified_method returns[MethodIdItem methodIdItem]
|
fully_qualified_method returns[MethodIdItem methodIdItem]
|
||||||
: CLASS_NAME MEMBER_NAME method_prototype
|
: reference_type_descriptor MEMBER_NAME method_prototype
|
||||||
{
|
{
|
||||||
TypeIdItem classType = new TypeIdItem(dexFile, "L" + $CLASS_NAME.text + ";");
|
TypeIdItem classType = $reference_type_descriptor.type;
|
||||||
StringIdItem methodName = new StringIdItem(dexFile, $MEMBER_NAME.text);
|
StringIdItem methodName = new StringIdItem(dexFile, $MEMBER_NAME.text);
|
||||||
ProtoIdItem prototype = $method_prototype.protoIdItem;
|
ProtoIdItem prototype = $method_prototype.protoIdItem;
|
||||||
$methodIdItem = new MethodIdItem(dexFile, classType, methodName, prototype);
|
$methodIdItem = new MethodIdItem(dexFile, classType, methodName, prototype);
|
||||||
};
|
};
|
||||||
|
|
||||||
fully_qualified_field returns[FieldIdItem fieldIdItem]
|
fully_qualified_field returns[FieldIdItem fieldIdItem]
|
||||||
: CLASS_NAME MEMBER_NAME field_type_descriptor
|
: reference_type_descriptor MEMBER_NAME nonvoid_type_descriptor
|
||||||
{
|
{
|
||||||
TypeIdItem classType = new TypeIdItem(dexFile, "L" + $CLASS_NAME.text + ";");
|
TypeIdItem classType = $reference_type_descriptor.type;
|
||||||
StringIdItem fieldName = new StringIdItem(dexFile, $MEMBER_NAME.text);
|
StringIdItem fieldName = new StringIdItem(dexFile, $MEMBER_NAME.text);
|
||||||
TypeIdItem fieldType = $field_type_descriptor.type;
|
TypeIdItem fieldType = $nonvoid_type_descriptor.type;
|
||||||
$fieldIdItem = new FieldIdItem(dexFile, classType, fieldName, fieldType);
|
$fieldIdItem = new FieldIdItem(dexFile, classType, fieldName, fieldType);
|
||||||
};
|
};
|
||||||
|
|
||||||
registers_directive returns[int registers]
|
registers_directive returns[int registers]
|
||||||
: ^(I_REGISTERS short_integral_literal) {$registers = $short_integral_literal.value;};
|
: {$registers = 0;}
|
||||||
|
^(I_REGISTERS (short_integral_literal {$registers = $short_integral_literal.value;} )? );
|
||||||
|
|
||||||
labels
|
labels
|
||||||
: ^(I_LABELS label_def*);
|
: ^(I_LABELS label_def*);
|
||||||
@ -480,9 +496,9 @@ label_def
|
|||||||
catches : ^(I_CATCHES catch_directive*);
|
catches : ^(I_CATCHES catch_directive*);
|
||||||
|
|
||||||
catch_directive
|
catch_directive
|
||||||
: ^(I_CATCH address field_type_descriptor from=offset_or_label_absolute[$address.address] to=offset_or_label_absolute[$address.address] using=offset_or_label_absolute[$address.address])
|
: ^(I_CATCH address nonvoid_type_descriptor from=offset_or_label_absolute[$address.address] to=offset_or_label_absolute[$address.address] using=offset_or_label_absolute[$address.address])
|
||||||
{
|
{
|
||||||
TypeIdItem type = $field_type_descriptor.type;
|
TypeIdItem type = $nonvoid_type_descriptor.type;
|
||||||
int startAddress = $from.address;
|
int startAddress = $from.address;
|
||||||
int endAddress = $to.address;
|
int endAddress = $to.address;
|
||||||
int handlerAddress = $using.address;
|
int handlerAddress = $using.address;
|
||||||
@ -547,14 +563,14 @@ line
|
|||||||
};
|
};
|
||||||
|
|
||||||
local
|
local
|
||||||
: ^(I_LOCAL REGISTER SIMPLE_NAME field_type_descriptor string_literal? address)
|
: ^(I_LOCAL REGISTER SIMPLE_NAME nonvoid_type_descriptor string_literal? address)
|
||||||
{
|
{
|
||||||
int registerNumber = parseRegister_short($REGISTER.text);
|
int registerNumber = parseRegister_short($REGISTER.text);
|
||||||
|
|
||||||
if ($string_literal.value != null) {
|
if ($string_literal.value != null) {
|
||||||
$method::debugInfo.addLocalExtended($address.address, registerNumber, $SIMPLE_NAME.text, $field_type_descriptor.type.getTypeDescriptor(), $string_literal.value);
|
$method::debugInfo.addLocalExtended($address.address, registerNumber, $SIMPLE_NAME.text, $nonvoid_type_descriptor.type.getTypeDescriptor(), $string_literal.value);
|
||||||
} else {
|
} else {
|
||||||
$method::debugInfo.addLocal($address.address, registerNumber, $SIMPLE_NAME.text, $field_type_descriptor.type.getTypeDescriptor());
|
$method::debugInfo.addLocal($address.address, registerNumber, $SIMPLE_NAME.text, $nonvoid_type_descriptor.type.getTypeDescriptor());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -725,12 +741,12 @@ instruction returns[Instruction instruction]
|
|||||||
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, stringIdItem);
|
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, stringIdItem);
|
||||||
}
|
}
|
||||||
| //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2
|
| //e.g. const-class v2 org/JesusFreke/HelloWorld2/HelloWorld2
|
||||||
^(I_STATEMENT_FORMAT21c_TYPE INSTRUCTION_FORMAT21c_TYPE REGISTER class_or_array_type_descriptor)
|
^(I_STATEMENT_FORMAT21c_TYPE INSTRUCTION_FORMAT21c_TYPE REGISTER reference_type_descriptor)
|
||||||
{
|
{
|
||||||
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21c_TYPE.text);
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT21c_TYPE.text);
|
||||||
short regA = parseRegister_byte($REGISTER.text);
|
short regA = parseRegister_byte($REGISTER.text);
|
||||||
|
|
||||||
TypeIdItem typeIdItem = $class_or_array_type_descriptor.type;
|
TypeIdItem typeIdItem = $reference_type_descriptor.type;
|
||||||
|
|
||||||
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem);
|
$instruction = Format21c.Format.make(dexFile, opcode.value, regA, typeIdItem);
|
||||||
}
|
}
|
||||||
@ -793,13 +809,13 @@ instruction returns[Instruction instruction]
|
|||||||
$instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, fieldIdItem);
|
$instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, fieldIdItem);
|
||||||
}
|
}
|
||||||
| //e.g. instance-of v0, v1, Ljava/lang/String;
|
| //e.g. instance-of v0, v1, Ljava/lang/String;
|
||||||
^(I_STATEMENT_FORMAT22c_TYPE INSTRUCTION_FORMAT22c_TYPE registerA=REGISTER registerB=REGISTER field_type_descriptor)
|
^(I_STATEMENT_FORMAT22c_TYPE INSTRUCTION_FORMAT22c_TYPE registerA=REGISTER registerB=REGISTER nonvoid_type_descriptor)
|
||||||
{
|
{
|
||||||
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22c_TYPE.text);
|
Opcode opcode = Opcode.getOpcodeByName($INSTRUCTION_FORMAT22c_TYPE.text);
|
||||||
byte regA = parseRegister_nibble($registerA.text);
|
byte regA = parseRegister_nibble($registerA.text);
|
||||||
byte regB = parseRegister_nibble($registerB.text);
|
byte regB = parseRegister_nibble($registerB.text);
|
||||||
|
|
||||||
TypeIdItem typeIdItem = $field_type_descriptor.type;
|
TypeIdItem typeIdItem = $nonvoid_type_descriptor.type;
|
||||||
|
|
||||||
$instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, typeIdItem);
|
$instruction = Format22c.Format.make(dexFile, opcode.value, regA, regB, typeIdItem);
|
||||||
}
|
}
|
||||||
@ -1002,7 +1018,7 @@ register_range returns[int startRegister, int endRegister]
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
field_type_descriptor returns [TypeIdItem type]
|
nonvoid_type_descriptor returns [TypeIdItem type]
|
||||||
: (PRIMITIVE_TYPE
|
: (PRIMITIVE_TYPE
|
||||||
| CLASS_DESCRIPTOR
|
| CLASS_DESCRIPTOR
|
||||||
| ARRAY_DESCRIPTOR)
|
| ARRAY_DESCRIPTOR)
|
||||||
@ -1010,7 +1026,7 @@ field_type_descriptor returns [TypeIdItem type]
|
|||||||
$type = new TypeIdItem(dexFile, $start.getText());
|
$type = new TypeIdItem(dexFile, $start.getText());
|
||||||
};
|
};
|
||||||
|
|
||||||
class_or_array_type_descriptor returns [TypeIdItem type]
|
reference_type_descriptor returns [TypeIdItem type]
|
||||||
: (CLASS_DESCRIPTOR
|
: (CLASS_DESCRIPTOR
|
||||||
| ARRAY_DESCRIPTOR)
|
| ARRAY_DESCRIPTOR)
|
||||||
{
|
{
|
||||||
@ -1025,7 +1041,7 @@ class_type_descriptor returns [TypeIdItem type]
|
|||||||
|
|
||||||
type_descriptor returns [TypeIdItem type]
|
type_descriptor returns [TypeIdItem type]
|
||||||
: VOID_TYPE {$type = new TypeIdItem(dexFile, "V");}
|
: VOID_TYPE {$type = new TypeIdItem(dexFile, "V");}
|
||||||
| field_type_descriptor {$type = $field_type_descriptor.type;}
|
| nonvoid_type_descriptor {$type = $nonvoid_type_descriptor.type;}
|
||||||
;
|
;
|
||||||
|
|
||||||
short_integral_literal returns[short value]
|
short_integral_literal returns[short value]
|
||||||
@ -1072,7 +1088,7 @@ double_literal returns[double value]
|
|||||||
: DOUBLE_LITERAL { $value = Double.parseDouble($DOUBLE_LITERAL.text); };
|
: DOUBLE_LITERAL { $value = Double.parseDouble($DOUBLE_LITERAL.text); };
|
||||||
|
|
||||||
char_literal returns[char value]
|
char_literal returns[char value]
|
||||||
: CHAR_LITERAL { $value = $CHAR_LITERAL.text.charAt(0); };
|
: CHAR_LITERAL { $value = $CHAR_LITERAL.text.charAt(1); };
|
||||||
|
|
||||||
string_literal returns[String value]
|
string_literal returns[String value]
|
||||||
: STRING_LITERAL
|
: STRING_LITERAL
|
||||||
@ -1120,4 +1136,15 @@ subannotation returns[AnnotationEncodedValueSubField value]
|
|||||||
{
|
{
|
||||||
$value = new AnnotationEncodedValueSubField(dexFile, $class_type_descriptor.type, elements);
|
$value = new AnnotationEncodedValueSubField(dexFile, $class_type_descriptor.type, elements);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
field_literal returns[EncodedIndexedItemReference<FieldIdItem> value]
|
||||||
|
: ^(I_ENCODED_FIELD fully_qualified_field)
|
||||||
|
{
|
||||||
|
$value = new EncodedIndexedItemReference<FieldIdItem>(dexFile, $fully_qualified_field.fieldIdItem);
|
||||||
|
};
|
||||||
|
|
||||||
|
method_literal returns[EncodedIndexedItemReference<MethodIdItem> value]
|
||||||
|
: ^(I_ENCODED_METHOD fully_qualified_method)
|
||||||
|
{
|
||||||
|
$value = new EncodedIndexedItemReference<MethodIdItem>(dexFile, $fully_qualified_method.methodIdItem);
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user