Refactor the registers directive related rules

git-svn-id: https://smali.googlecode.com/svn/trunk@717 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2010-04-18 05:03:38 +00:00
parent 4fb7679be9
commit fd997c84b6
2 changed files with 25 additions and 18 deletions

View File

@ -50,6 +50,7 @@ tokens {
I_METHOD_PROTOTYPE; I_METHOD_PROTOTYPE;
I_METHOD_RETURN_TYPE; I_METHOD_RETURN_TYPE;
I_REGISTERS; I_REGISTERS;
I_LOCALS;
I_LABELS; I_LABELS;
I_LABEL; I_LABEL;
I_ANNOTATIONS; I_ANNOTATIONS;
@ -316,7 +317,7 @@ statements_and_directives
$statements_and_directives::methodAnnotations = new ArrayList<CommonTree>(); $statements_and_directives::methodAnnotations = new ArrayList<CommonTree>();
} }
( instruction {$method::currentAddress += $instruction.size/2;} ( instruction {$method::currentAddress += $instruction.size/2;}
| {!$statements_and_directives::hasRegistersDirective}?=> registers_directive {$statements_and_directives::hasRegistersDirective = true;} | registers_directive
| label | label
| catch_directive | catch_directive
| catchall_directive | catchall_directive
@ -324,7 +325,7 @@ statements_and_directives
| ordered_debug_directive | ordered_debug_directive
| annotation {$statements_and_directives::methodAnnotations.add($annotation.tree);} | annotation {$statements_and_directives::methodAnnotations.add($annotation.tree);}
)* )*
-> ^(I_REGISTERS registers_directive?) -> registers_directive?
^(I_LABELS label*) ^(I_LABELS label*)
{buildTree(I_PACKED_SWITCH_DECLARATIONS, "I_PACKED_SWITCH_DECLARATIONS", $statements_and_directives::packedSwitchDeclarations)} {buildTree(I_PACKED_SWITCH_DECLARATIONS, "I_PACKED_SWITCH_DECLARATIONS", $statements_and_directives::packedSwitchDeclarations)}
{buildTree(I_SPARSE_SWITCH_DECLARATIONS, "I_SPARSE_SWITCH_DECLARATIONS", $statements_and_directives::sparseSwitchDeclarations)} {buildTree(I_SPARSE_SWITCH_DECLARATIONS, "I_SPARSE_SWITCH_DECLARATIONS", $statements_and_directives::sparseSwitchDeclarations)}
@ -335,8 +336,16 @@ statements_and_directives
{buildTree(I_ANNOTATIONS, "I_ANNOTATIONS", $statements_and_directives::methodAnnotations)}; {buildTree(I_ANNOTATIONS, "I_ANNOTATIONS", $statements_and_directives::methodAnnotations)};
registers_directive registers_directive
: (REGISTERS_DIRECTIVE | LOCALS_DIRECTIVE) integral_literal : (
-> REGISTERS_DIRECTIVE? LOCALS_DIRECTIVE? integral_literal; REGISTERS_DIRECTIVE regCount=integral_literal -> ^(I_REGISTERS[$REGISTERS_DIRECTIVE, "I_REGISTERS"] $regCount)
| LOCALS_DIRECTIVE regCount2=integral_literal -> ^(I_LOCALS[$LOCALS_DIRECTIVE, "I_LOCALS"] $regCount2)
)
{
if ($statements_and_directives::hasRegistersDirective) {
throw new SemanticException(input, $registers_directive.tree, "There can only be a single .registers or .locals directive in a method");
}
$statements_and_directives::hasRegistersDirective=true;
};
/*identifiers are much more general than most languages. Any of the below can either be /*identifiers are much more general than most languages. Any of the below can either be
the indicated type OR an identifier, depending on the context*/ the indicated type OR an identifier, depending on the context*/

View File

@ -487,14 +487,7 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod,
methodParameterRegisters++; methodParameterRegisters++;
} }
} }
registers_directive registers_directive?
{
if ($registers_directive.isLocalsDirective) {
totalMethodRegisters = $registers_directive.registers + methodParameterRegisters;
} else {
totalMethodRegisters = $registers_directive.registers;
}
}
labels labels
packed_switch_declarations packed_switch_declarations
sparse_switch_declarations sparse_switch_declarations
@ -524,6 +517,12 @@ method returns[ ClassDataItem.EncodedMethod encodedMethod,
codeItem = null; codeItem = null;
} else { } else {
if ($registers_directive.isLocalsDirective) {
totalMethodRegisters = $registers_directive.registers + methodParameterRegisters;
} else {
totalMethodRegisters = $registers_directive.registers;
}
if (totalMethodRegisters < methodParameterRegisters) { if (totalMethodRegisters < methodParameterRegisters) {
throw new SemanticException(input, "This method requires at least " + throw new SemanticException(input, "This method requires at least " +
Integer.toString(methodParameterRegisters) + Integer.toString(methodParameterRegisters) +
@ -614,12 +613,11 @@ fully_qualified_field returns[FieldIdItem fieldIdItem]
registers_directive returns[boolean isLocalsDirective, int registers] registers_directive returns[boolean isLocalsDirective, int registers]
: {$registers = 0;} : {$registers = 0;}
^(I_REGISTERS ^( ( I_REGISTERS {$isLocalsDirective = false;}
( ( REGISTERS_DIRECTIVE {$isLocalsDirective = false;} | I_LOCALS {$isLocalsDirective = true;}
| LOCALS_DIRECTIVE {$isLocalsDirective = true;} )
) short_integral_literal {$registers = $short_integral_literal.value;}
short_integral_literal {$registers = $short_integral_literal.value;} );
)?);
labels labels
: ^(I_LABELS label_def*); : ^(I_LABELS label_def*);