- Added support for specifying a char literal for various types of instruction

- Fixed a bug preventing the usage of negative float/double literals
- Fixed escape sequences in character literals
- Added source file name to parser error messages
- Fixed an issue where the parser would exit without an error message, when it encountered a bad "top level" token (in the smali_file rule)
- Fixed an issue that prevented the usage of non long/double literals with the the const-wide instruction
- Fixed an issue with the invoke-static/range, where it wouldn't calculate the number of parameter registers correctly, and would erroneously generate an error message

git-svn-id: https://smali.googlecode.com/svn/trunk@90 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-06-05 05:14:26 +00:00
parent 5dc3a8d75a
commit 0900e0040e
4 changed files with 27 additions and 13 deletions

View File

@ -811,6 +811,7 @@ fragment INTEGRAL_LITERAL_EMITCHILD
: LONG_LITERAL_EMIT
| INTEGER_LITERAL_EMIT
| SHORT_LITERAL_EMIT
| CHAR_LITERAL_EMIT
| BYTE_LITERAL_EMIT;
fragment FIXED_LITERAL_EMITCHILD
@ -1020,23 +1021,28 @@ fragment BINARY_EXPONENT
fragment FLOAT_LITERAL_EMIT
: FLOAT_LITERAL {emit($FLOAT_LITERAL, FLOAT_LITERAL);};
fragment FLOAT_LITERAL
: (FLOATING_POINT_NUMBER | ('0' .. '9')+) ('f' | 'F');
: '-'? (FLOATING_POINT_NUMBER | ('0' .. '9')+) ('f' | 'F');
fragment DOUBLE_LITERAL_EMIT
: DOUBLE_LITERAL {emit($DOUBLE_LITERAL, DOUBLE_LITERAL);};
fragment DOUBLE_LITERAL
: FLOATING_POINT_NUMBER ('d' | 'D')?
| ('0' .. '9')+ ('d' | 'D');
: '-'? FLOATING_POINT_NUMBER ('d' | 'D')?
| '-'? ('0' .. '9')+ ('d' | 'D');
fragment CHAR_LITERAL_EMIT
: CHAR_LITERAL {emit($CHAR_LITERAL, CHAR_LITERAL);};
fragment CHAR_LITERAL
: '\'' {StringBuilder sb = new StringBuilder("'");}
( ESCAPE_SEQUENCE[sb] {sb.append("'"); setText(sb.toString());}
| ~( '\'' | '\\' | '\r' | '\n' )
@init {StringBuilder sb = new StringBuilder();}
: CHAR_LITERAL[sb]
{
$CHAR_LITERAL.setText(sb.toString());
emit($CHAR_LITERAL, CHAR_LITERAL);
};
fragment CHAR_LITERAL[StringBuilder sb]
: '\'' {sb.append("'");}
( ESCAPE_SEQUENCE[sb] {sb.append("'");}
| ~( '\'' | '\\' | '\r' | '\n' ) {sb.append((char)input.LA(-1));}
)
'\''
'\'' {sb.append("'");}
;
fragment BOOL_LITERAL_EMIT

View File

@ -147,6 +147,10 @@ import org.JesusFreke.dexlib.code.Format.*;
public String getTokenErrorDisplay(Token t) {
return t.toString();
}
public String getErrorHeader(RecognitionException e) {
return getSourceName()+"["+ e.line+","+e.charPositionInLine+"]";
}
}
@ -165,7 +169,9 @@ smali_file
| {!$smali_file::hasSourceSpec}?=> source_spec {$smali_file::hasSourceSpec = true;}
| method
| field
| annotation)*
| annotation
)+
EOF
{
if (!$smali_file::hasClassSpec) {
//TODO: throw correct exception type
@ -394,8 +400,8 @@ instruction returns [int size]
INSTRUCTION_FORMAT3rc_METHOD OPEN_BRACKET register_range CLOSE_BRACKET fully_qualified_method {$size = Format3rc.Format.getByteCount();}
-> ^(I_STATEMENT_FORMAT3rc_METHOD[$start, "I_STATEMENT_FORMAT3rc_METHOD"] INSTRUCTION_FORMAT3rc_METHOD register_range fully_qualified_method)
| //e.g. const-wide v0, 5000000000L
INSTRUCTION_FORMAT51l REGISTER (LONG_LITERAL | DOUBLE_LITERAL) {$size = Format51l.Format.getByteCount();}
-> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER LONG_LITERAL? DOUBLE_LITERAL?)
INSTRUCTION_FORMAT51l REGISTER fixed_literal {$size = Format51l.Format.getByteCount();}
-> ^(I_STATEMENT_FORMAT51l[$start, "I_STATEMENT_FORMAT51l"] INSTRUCTION_FORMAT51l REGISTER fixed_literal)
|
ARRAY_DATA_DIRECTIVE
{
@ -513,6 +519,7 @@ integral_literal
: LONG_LITERAL
| INTEGER_LITERAL
| SHORT_LITERAL
| CHAR_LITERAL
| BYTE_LITERAL;
fixed_32bit_literal

View File

@ -1076,6 +1076,7 @@ short_integral_literal returns[short value]
$value = (short)$integer_literal.value;
}
| short_literal {$value = $short_literal.value;}
| char_literal {$value = (short)$char_literal.value;}
| byte_literal {$value = $byte_literal.value;};
integral_literal returns[int value]

View File

@ -82,7 +82,7 @@ public class Format3rc extends Format
} else if (opcode >= INVOKE_VIRTUAL_RANGE.value && opcode <= INVOKE_INTERFACE_RANGE.value) {
//check data for invoke-*/range opcodes
MethodIdItem methodIdItem = (MethodIdItem)item;
if (methodIdItem.getParameterRegisterCount(opcode == INVOKE_STATIC.value) != regCount) {
if (methodIdItem.getParameterRegisterCount(opcode == INVOKE_STATIC_RANGE.value) != regCount) {
throw new RuntimeException("regCount does not match the number of arguments of the method");
}
} else {