build: config spotless plugin and reformat code

This commit is contained in:
Frank.R.Wu 2023-06-15 11:08:09 +08:00
parent 281030a94c
commit 2f42539293
238 changed files with 31053 additions and 30607 deletions

View File

@ -1,9 +1,3 @@
buildscript {
dependencies {
classpath "com.diffplug.spotless:spotless-plugin-gradle:4.5.1"
}
}
plugins { plugins {
id 'java' id 'java'
id 'java-library' id 'java-library'
@ -12,18 +6,7 @@ plugins {
id 'com.github.johnrengelman.shadow' version '4.0.2' id 'com.github.johnrengelman.shadow' version '4.0.2'
} }
apply plugin: "com.diffplug.gradle.spotless" apply from: '../spotless.gradle'
spotless {
java {
removeUnusedImports()
eclipse().configFile('shardingsphere_eclipse_formatter.xml')
target fileTree('.') {
include '**/*.java'
}
}
}
//tasks.compileJava.dependsOn(spotlessJavaApply)
shadowJar { shadowJar {
classifier = "jar" classifier = "jar"

View File

@ -1,431 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles version="13">
<profile kind="CodeFormatterProfile" name="GoogleStyle" version="13">
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments.count_dependent" value="16|-1|16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_prefer_two_fragments" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_comment_inline_tags" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_local_variable_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="1040"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type.count_dependent" value="1585|-1|1585"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields.count_dependent" value="16|-1|16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression.count_dependent" value="16|4|80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration.count_dependent" value="16|4|48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration.count_dependent" value="16|4|49"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments" value="16"/>
<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration.count_dependent" value="16|4|48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_local_variable_annotation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants.count_dependent" value="16|5|48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="100"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation.count_dependent" value="16|4|48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="1585"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="16"/>
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_type_annotation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_field_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration"
value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments"
value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment_new_line_at_start_of_html_paragraph" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comment_prefix" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_parameter_annotation" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="1585"/>
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation.count_dependent"
value="16|5|80"/>
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter.count_dependent"
value="1040|-1|1040"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package.count_dependent"
value="1585|-1|1585"/>
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.force_if_else_statement_brace" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="3"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_package_annotation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression"
value="16"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation.count_dependent"
value="16|-1|16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="1585"/>
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_new_anonymous_class" value="20"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable.count_dependent"
value="1585|-1|1585"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field.count_dependent"
value="1585|-1|1585"/>
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration.count_dependent"
value="16|5|80"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant.count_dependent"
value="16|-1|16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="2"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="1585"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer.count_dependent"
value="16|5|80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration.count_dependent"
value="16|4|48"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method.count_dependent"
value="1585|-1|1585"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression.count_dependent" value="16|-1|16"/>
<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_member_annotation" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="1585"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
<setting
id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call.count_dependent"
value="16|5|80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
<setting
id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments.count_dependent"
value="16|-1|16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression.count_dependent"
value="16|5|80"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration.count_dependent"
value="16|5|80"/>
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations"
value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header"
value="true"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.alignment_for_for_statement" value="16"/>
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments"
value="do not insert"/>
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
</profile>
</profiles>

View File

@ -3,16 +3,15 @@ package org.bdware.analysis;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
public abstract class AnalysisResult { public abstract class AnalysisResult {
public AnalysisResult() { public AnalysisResult() {}
}
public abstract AnalysisResult merge(AbstractInsnNode insn); public abstract AnalysisResult merge(AbstractInsnNode insn);
public abstract void printResult(); public abstract void printResult();
public abstract boolean covers(AnalysisResult result); public abstract boolean covers(AnalysisResult result);
public abstract void mergeResult(AnalysisResult r); public abstract void mergeResult(AnalysisResult r);
public abstract AnalysisResult clone(); public abstract AnalysisResult clone();
} }

View File

@ -1,7 +1,7 @@
package org.bdware.analysis; package org.bdware.analysis;
public interface AnalysisTarget { public interface AnalysisTarget {
public boolean inList(); public boolean inList();
public void setInList(boolean b); public void setInList(boolean b);
} }

View File

@ -6,44 +6,44 @@ import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
public class BasicBlock { public class BasicBlock {
public List<AbstractInsnNode> list; public List<AbstractInsnNode> list;
public int blockID; public int blockID;
public int lineNum = -1; public int lineNum = -1;
public int insnCount; public int insnCount;
public BasicBlock(int id) { public BasicBlock(int id) {
list = new ArrayList<>(); list = new ArrayList<>();
blockID = id; blockID = id;
} }
public void add(AbstractInsnNode insn) { public void add(AbstractInsnNode insn) {
list.add(insn); list.add(insn);
} }
public int size() { public int size() {
return list.size(); return list.size();
} }
public List<AbstractInsnNode> getInsn() { public List<AbstractInsnNode> getInsn() {
return list; return list;
} }
boolean inList = false; boolean inList = false;
public AbstractInsnNode lastInsn() { public AbstractInsnNode lastInsn() {
return list.get(list.size() - 1); return list.get(list.size() - 1);
} }
public void setLineNum(int line) { public void setLineNum(int line) {
lineNum = line; lineNum = line;
} }
public boolean inList() { public boolean inList() {
return inList; return inList;
} }
public void setInList(boolean b) { public void setInList(boolean b) {
inList = b; inList = b;
} }
} }

View File

@ -6,53 +6,53 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public abstract class BreadthFirstSearch<R extends AnalysisResult, T extends AnalysisTarget> { public abstract class BreadthFirstSearch<R extends AnalysisResult, T extends AnalysisTarget> {
public Map<T, AnalysisResult> results; public Map<T, AnalysisResult> results;
protected List<T> toAnalysis; protected List<T> toAnalysis;
public abstract R execute(T t); public abstract R execute(T t);
public abstract Collection<T> getSuc(T t); public abstract Collection<T> getSuc(T t);
public BreadthFirstSearch() { public BreadthFirstSearch() {
results = new HashMap<T, AnalysisResult>(); results = new HashMap<T, AnalysisResult>();
} }
public Map<T, AnalysisResult> analysis() { public Map<T, AnalysisResult> analysis() {
results.clear(); results.clear();
T current = null; T current = null;
for (int i = 0; i < toAnalysis.size(); i++) { for (int i = 0; i < toAnalysis.size(); i++) {
current = toAnalysis.get(i); current = toAnalysis.get(i);
current.setInList(false); current.setInList(false);
AnalysisResult preResult = results.get(current); AnalysisResult preResult = results.get(current);
AnalysisResult sucResult = execute(current); AnalysisResult sucResult = execute(current);
if (preResult == null || !preResult.covers(sucResult)) { if (preResult == null || !preResult.covers(sucResult)) {
AnalysisResult cloneResult = sucResult.clone(); AnalysisResult cloneResult = sucResult.clone();
if (cloneResult != null) { if (cloneResult != null) {
results.put(current, cloneResult); results.put(current, cloneResult);
} }
Collection<T> sucs = getSuc(current); Collection<T> sucs = getSuc(current);
for (T next : sucs) { for (T next : sucs) {
if (toAnalysis.contains(next)) { if (toAnalysis.contains(next)) {
//results.remove(next); // results.remove(next);
//toAnalysis.remove(next); // toAnalysis.remove(next);
} }
if (!next.inList()) { if (!next.inList()) {
toAnalysis.add(next); toAnalysis.add(next);
next.setInList(true); next.setInList(true);
} }
} }
} }
} }
return results; return results;
} }
public int getListLength() { public int getListLength() {
return toAnalysis.size(); return toAnalysis.size();
} }
public void setToAnalysis(List<T> l) { public void setToAnalysis(List<T> l) {
toAnalysis = l; toAnalysis = l;
} }
} }

View File

@ -19,7 +19,7 @@ public abstract class CFGraph {
// type2(canThrow) and catchLabels // type2(canThrow) and catchLabels
// type3 and target labels // type3 and target labels
// type4 and catchLabels // type4 and catchLabels
// private List<TryCatchBlockNode> tryCacheList; // private List<TryCatchBlockNode> tryCacheList;
// Pass1: build basic blocks // Pass1: build basic blocks
// create a new block when: // create a new block when:
// 1.starts with Label(can jump) // 1.starts with Label(can jump)
@ -110,8 +110,8 @@ public abstract class CFGraph {
public void printSelf() { public void printSelf() {
InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out); InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out);
printer.setLabelOrder(getLabelOrder()); printer.setLabelOrder(getLabelOrder());
LOGGER.info("isStatic: " + ((methodNode.access & Opcodes.ACC_STATIC) > 0) LOGGER.info("isStatic: " + ((methodNode.access & Opcodes.ACC_STATIC) > 0) + "\tMethod:"
+ "\tMethod:" + methodNode.name + " " + methodNode.desc); + methodNode.name + " " + methodNode.desc);
LOGGER.info(methodNode.maxLocals + " " + methodNode.maxStack); LOGGER.info(methodNode.maxLocals + " " + methodNode.maxStack);
StringBuilder log = new StringBuilder(); StringBuilder log = new StringBuilder();
for (BasicBlock bb : basicBlocks) { for (BasicBlock bb : basicBlocks) {
@ -171,21 +171,17 @@ public abstract class CFGraph {
/** /**
* Visits a zero operand instruction. * Visits a zero operand instruction.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is * @param opcode the opcode of the instruction to be visited. This opcode is either NOP,
* either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4,
* ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, * ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1,
* FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE,
* LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, * FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1,
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, * DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB,
* SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, * DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, * INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR,
* IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, * LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B,
* FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, * I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, DRETURN,
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, * ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT.
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or
* MONITOREXIT.
*/ */
public void visitInsn(int opcode) { public void visitInsn(int opcode) {
currBlock.add(currInsn); currBlock.add(currInsn);
@ -199,77 +195,75 @@ public abstract class CFGraph {
/** /**
* Visits an instruction with a single int operand. * Visits an instruction with a single int operand.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH,
* either BIPUSH, SIPUSH or NEWARRAY. * SIPUSH or NEWARRAY.
* @param operand the operand of the instruction to be visited.<br> * @param operand the operand of the instruction to be visited.<br>
* When opcode is BIPUSH, operand value should be between * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and
* Byte.MIN_VALUE and Byte.MAX_VALUE.<br> * Byte.MAX_VALUE.<br>
* When opcode is SIPUSH, operand value should be between * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and
* Short.MIN_VALUE and Short.MAX_VALUE.<br> * Short.MAX_VALUE.<br>
* When opcode is NEWARRAY, operand value should be one of * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN},
* {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR}, * {@link Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
* {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, * {@link Opcodes#T_LONG}.
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/ */
public void visitIntInsn(int opcode, int operand) { public void visitIntInsn(int opcode, int operand) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a local variable instruction. A local variable instruction is an * Visits a local variable instruction. A local variable instruction is an instruction that
* instruction that loads or stores the value of a local variable. * loads or stores the value of a local variable.
* *
* @param opcode the opcode of the local variable instruction to be visited. * @param opcode the opcode of the local variable instruction to be visited. This opcode is
* This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, * either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE
* ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. * or RET.
* @param var the operand of the instruction to be visited. This operand is * @param var the operand of the instruction to be visited. This operand is the index of a
* the index of a local variable. * local variable.
*/ */
public void visitVarInsn(int opcode, int var) { public void visitVarInsn(int opcode, int var) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a type instruction. A type instruction is an instruction that takes * Visits a type instruction. A type instruction is an instruction that takes the internal
* the internal name of a class as parameter. * name of a class as parameter.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either
* is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. * NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
* @param type the operand of the instruction to be visited. This operand must * @param type the operand of the instruction to be visited. This operand must be the
* be the internal name of an object or array class (see * internal name of an object or array class (see {@link Type#getInternalName()
* {@link Type#getInternalName() getInternalName}). * getInternalName}).
*/ */
public void visitTypeInsn(int opcode, String type) { public void visitTypeInsn(int opcode, String type) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a field instruction. A field instruction is an instruction that loads * Visits a field instruction. A field instruction is an instruction that loads or stores
* or stores the value of a field of an object. * the value of a field of an object.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either
* is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* @param owner the internal name of the field's owner class (see * @param owner the internal name of the field's owner class (see
* {@link Type#getInternalName() getInternalName}). * {@link Type#getInternalName() getInternalName}).
* @param name the field's name. * @param name the field's name.
* @param desc the field's descriptor (see {@link Type Type}). * @param desc the field's descriptor (see {@link Type Type}).
*/ */
public void visitFieldInsn(int opcode, String owner, String name, String desc) { public void visitFieldInsn(int opcode, String owner, String name, String desc) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a method instruction. A method instruction is an instruction that * Visits a method instruction. A method instruction is an instruction that invokes a
* invokes a method. * method.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either
* is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
* INVOKEINTERFACE. * @param owner the internal name of the method's owner class (see
* @param owner the internal name of the method's owner class (see * {@link Type#getInternalName() getInternalName}).
* {@link Type#getInternalName() getInternalName}). * @param name the method's name.
* @param name the method's name. * @param desc the method's descriptor (see {@link Type Type}).
* @param desc the method's descriptor (see {@link Type Type}).
*/ */
public void visitMethodInsn(int opcode, String owner, String name, String desc) { public void visitMethodInsn(int opcode, String owner, String name, String desc) {
currBlock.add(currInsn); currBlock.add(currInsn);
@ -288,16 +282,16 @@ public abstract class CFGraph {
/** /**
* Visits an invokedynamic instruction. * Visits an invokedynamic instruction.
* *
* @param name the method's name. * @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}). * @param desc the method's descriptor (see {@link Type Type}).
* @param bsm the bootstrap method. * @param bsm the bootstrap method.
* @param bsmArgs the bootstrap method constant arguments. Each argument must be * @param bsmArgs the bootstrap method constant arguments. Each argument must be an
* an {@link Integer}, {@link Float}, {@link Long}, * {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String},
* {@link Double}, {@link String}, {@link Type} or {@link Handle} * {@link Type} or {@link Handle} value. This method is allowed to modify the content
* value. This method is allowed to modify the content of the * of the array so a caller should expect that this array may change.
* array so a caller should expect that this array may change.
*/ */
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
// TODO add edges to try catch blocks! // TODO add edges to try catch blocks!
currBlock.add(currInsn); currBlock.add(currInsn);
@ -309,16 +303,14 @@ public abstract class CFGraph {
} }
/** /**
* Visits a jump instruction. A jump instruction is an instruction that may jump * Visits a jump instruction. A jump instruction is an instruction that may jump to another
* to another instruction. * instruction.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either
* is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, * IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE,
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, * IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * @param label the operand of the instruction to be visited. This operand is a label that
* @param label the operand of the instruction to be visited. This operand is a * designates the instruction to which the jump instruction may jump.
* label that designates the instruction to which the jump
* instruction may jump.
*/ */
public void visitJumpInsn(int opcode, Label label) { public void visitJumpInsn(int opcode, Label label) {
currBlock.add(currInsn); currBlock.add(currInsn);
@ -331,8 +323,7 @@ public abstract class CFGraph {
} }
/** /**
* Visits a label. A label designates the instruction that will be visited just * Visits a label. A label designates the instruction that will be visited just after it.
* after it.
* *
* @param label a {@link Label Label} object. * @param label a {@link Label Label} object.
*/ */
@ -349,47 +340,45 @@ public abstract class CFGraph {
} }
/** /**
* Visits a LDC instruction. Note that new constant types may be added in future * Visits a LDC instruction. Note that new constant types may be added in future versions of
* versions of the Java Virtual Machine. To easily detect new constant types, * the Java Virtual Machine. To easily detect new constant types, implementations of this
* implementations of this method should check for unexpected constant types, * method should check for unexpected constant types, like this:
* like this:
* *
* <pre> * <pre>
* if (cst instanceof Integer) { * if (cst instanceof Integer) {
* // ... * // ...
* } else if (cst instanceof Float) { * } else if (cst instanceof Float) {
* // ... * // ...
* } else if (cst instanceof Long) { * } else if (cst instanceof Long) {
* // ... * // ...
* } else if (cst instanceof Double) { * } else if (cst instanceof Double) {
* // ... * // ...
* } else if (cst instanceof String) { * } else if (cst instanceof String) {
* // ... * // ...
* } else if (cst instanceof Type) { * } else if (cst instanceof Type) {
* int sort = ((Type) cst).getSort(); * int sort = ((Type) cst).getSort();
* if (sort == Type.OBJECT) { * if (sort == Type.OBJECT) {
* // ... * // ...
* } else if (sort == Type.ARRAY) { * } else if (sort == Type.ARRAY) {
* // ... * // ...
* } else if (sort == Type.METHOD) { * } else if (sort == Type.METHOD) {
* // ... * // ...
* } else { * } else {
* // throw an exception * // throw an exception
* } * }
* } else if (cst instanceof Handle) { * } else if (cst instanceof Handle) {
* // ... * // ...
* } else { * } else {
* // throw an exception * // throw an exception
* } * }
* </pre> * </pre>
* *
* @param cst the constant to be loaded on the stack. This parameter must be a * @param cst the constant to be loaded on the stack. This parameter must be a non null
* non null {@link Integer}, a {@link Float}, a {@link Long}, a * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or * {@link String}, a {@link Type} of OBJECT or ARRAY sort for <tt>.class</tt>
* ARRAY sort for <tt>.class</tt> constants, for classes whose * constants, for classes whose version is 49.0, a {@link Type} of METHOD sort or a
* version is 49.0, a {@link Type} of METHOD sort or a {@link Handle} * {@link Handle} for MethodType and MethodHandle constants, for classes whose
* for MethodType and MethodHandle constants, for classes whose * version is 51.0.
* version is 51.0.
*/ */
public void visitLdcInsn(Object cst) { public void visitLdcInsn(Object cst) {
currBlock.add(currInsn); currBlock.add(currInsn);
@ -398,7 +387,7 @@ public abstract class CFGraph {
/** /**
* Visits an IINC instruction. * Visits an IINC instruction.
* *
* @param var index of the local variable to be incremented. * @param var index of the local variable to be incremented.
* @param increment amount to increment the local variable by. * @param increment amount to increment the local variable by.
*/ */
public void visitIincInsn(int var, int increment) { public void visitIincInsn(int var, int increment) {
@ -411,11 +400,11 @@ public abstract class CFGraph {
/** /**
* Visits a TABLESWITCH instruction. * Visits a TABLESWITCH instruction.
* *
* @param min the minimum key value. * @param min the minimum key value.
* @param max the maximum key value. * @param max the maximum key value.
* @param dflt beginning of the default handler block. * @param dflt beginning of the default handler block.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of
* beginning of the handler block for the <tt>min + i</tt> key. * the handler block for the <tt>min + i</tt> key.
*/ */
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
currBlock.add(currInsn); currBlock.add(currInsn);
@ -426,10 +415,10 @@ public abstract class CFGraph {
/** /**
* Visits a LOOKUPSWITCH instruction. * Visits a LOOKUPSWITCH instruction.
* *
* @param dflt beginning of the default handler block. * @param dflt beginning of the default handler block.
* @param keys the values of the keys. * @param keys the values of the keys.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of
* beginning of the handler block for the <tt>keys[i]</tt> key. * the handler block for the <tt>keys[i]</tt> key.
*/ */
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
currBlock.add(currInsn); currBlock.add(currInsn);
@ -450,33 +439,31 @@ public abstract class CFGraph {
/** /**
* Visits a local variable declaration. * Visits a local variable declaration.
* *
* @param name the name of a local variable. * @param name the name of a local variable.
* @param desc the type descriptor of this local variable. * @param desc the type descriptor of this local variable.
* @param signature the type signature of this local variable. May be * @param signature the type signature of this local variable. May be <tt>null</tt> if the
* <tt>null</tt> if the local variable type does not use * local variable type does not use generic types.
* generic types. * @param start the first instruction corresponding to the scope of this local variable
* @param start the first instruction corresponding to the scope of this * (inclusive).
* local variable (inclusive). * @param end the last instruction corresponding to the scope of this local variable
* @param end the last instruction corresponding to the scope of this * (exclusive).
* local variable (exclusive). * @param index the local variable's index.
* @param index the local variable's index. * @throws IllegalArgumentException if one of the labels has not already been visited by
* @throws IllegalArgumentException if one of the labels has not already been * this visitor (by the {@link #visitLabel visitLabel} method).
* visited by this visitor (by the
* {@link #visitLabel visitLabel} method).
*/ */
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { public void visitLocalVariable(String name, String desc, String signature, Label start,
Label end, int index) {
currBlock.add(currInsn); currBlock.add(currInsn);
} }
/** /**
* Visits a line number declaration. * Visits a line number declaration.
* *
* @param line a line number. This number refers to the source file from which * @param line a line number. This number refers to the source file from which the class was
* the class was compiled. * compiled.
* @param start the first instruction corresponding to this line number. * @param start the first instruction corresponding to this line number.
* @throws IllegalArgumentException if <tt>start</tt> has not already been * @throws IllegalArgumentException if <tt>start</tt> has not already been visited by this
* visited by this visitor (by the * visitor (by the {@link #visitLabel visitLabel} method).
* {@link #visitLabel visitLabel} method).
*/ */
public void visitLineNumber(int line, Label start) { public void visitLineNumber(int line, Label start) {
currBlock.add(currInsn); currBlock.add(currInsn);
@ -557,7 +544,8 @@ public abstract class CFGraph {
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { public void visitInvokeDynamicInsn(String name, String desc, Handle bsm,
Object... bsmArgs) {
addTryCatchNodes(); addTryCatchNodes();
} }

View File

@ -1,10 +1,10 @@
package org.bdware.analysis; package org.bdware.analysis;
public interface CFType { public interface CFType {
public static final int kInstrCanBranch = 1; // conditional or unconditional branch public static final int kInstrCanBranch = 1; // conditional or unconditional branch
public static final int kInstrCanContinue = 1 << 1; // flow can continue to next statement public static final int kInstrCanContinue = 1 << 1; // flow can continue to next statement
public static final int kInstrCanSwitch = 1 << 2; // switch public static final int kInstrCanSwitch = 1 << 2; // switch
public static final int kInstrCanThrow = 1 << 3; // could cause an exception to be thrown public static final int kInstrCanThrow = 1 << 3; // could cause an exception to be thrown
public static final int kInstrCanReturn = 1 << 4; // returns, no additional statements public static final int kInstrCanReturn = 1 << 4; // returns, no additional statements
public static final int kInstrInvoke = 1 << 5; // a flavor of invoke public static final int kInstrInvoke = 1 << 5; // a flavor of invoke
} }

View File

@ -8,131 +8,127 @@ import java.util.List;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.bdware.analysis.BasicBlock;
import org.bdware.analysis.CFGraph;
import org.bdware.analysis.InsnPrinter;
import org.bdware.analysis.OpInfo;
import org.bdware.analysis.taint.TaintBB; import org.bdware.analysis.taint.TaintBB;
import org.bdware.analysis.taint.TaintCFG; import org.bdware.analysis.taint.TaintCFG;
public class FrontCF { public class FrontCF {
String methodName; String methodName;
public List<FrontBB> blocks; public List<FrontBB> blocks;
public List<FrontEdge> edges; public List<FrontEdge> edges;
public String ret; public String ret;
public String finalRet; public String finalRet;
transient InsnPrinter printer; transient InsnPrinter printer;
transient ArrayPs ps; transient ArrayPs ps;
static class ArrayPs extends PrintStream { static class ArrayPs extends PrintStream {
List<String> content; List<String> content;
public ArrayPs() throws FileNotFoundException { public ArrayPs() throws FileNotFoundException {
super("/dev/null"); super("/dev/null");
} }
public void println(String str) { public void println(String str) {
if (content != null) if (content != null)
content.add(str); content.add(str);
} }
} }
public FrontCF(CFGraph graph) { public FrontCF(CFGraph graph) {
blocks = new ArrayList<>(); blocks = new ArrayList<>();
edges = new ArrayList<>(); edges = new ArrayList<>();
try { try {
ps = new ArrayPs(); ps = new ArrayPs();
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} }
printer = new InsnPrinter(Opcodes.ASM4, ps); printer = new InsnPrinter(Opcodes.ASM4, ps);
printer.setLabelOrder(graph.getLabelOrder()); printer.setLabelOrder(graph.getLabelOrder());
} }
public static class FrontBB { public static class FrontBB {
String type; String type;
String name; //BlockNumber String name; // BlockNumber
List<String> stmts; //BlockInstructions List<String> stmts; // BlockInstructions
String original; String original;
String result; //preResult String result; // preResult
String blockDep; String blockDep;
} }
public static class EdgeLabel { public static class EdgeLabel {
String label; String label;
} }
public static class FrontEdge { public static class FrontEdge {
String from, to; String from, to;
EdgeLabel label; EdgeLabel label;
} }
public void addBB(BasicBlock bb, String original, List<Integer> ids, TaintCFG cfg) { public void addBB(BasicBlock bb, String original, List<Integer> ids, TaintCFG cfg) {
FrontBB fb = new FrontBB(); FrontBB fb = new FrontBB();
blocks.add(fb); blocks.add(fb);
fb.name = "B" + bb.blockID; fb.name = "B" + bb.blockID;
List<AbstractInsnNode> insnList = bb.getInsn(); List<AbstractInsnNode> insnList = bb.getInsn();
fb.type = "Continuous"; fb.type = "Continuous";
fb.original = original; fb.original = original;
//added
TaintBB b = (TaintBB) bb;
//if(b.preResult != null)
//b.preResult.printResult();
fb.result = b.getResult();
if(ids == null)
fb.blockDep = "";
else{
StringBuilder sb = new StringBuilder();
//sb.append("Dependence: ");
for(Integer id : ids) {
//sb.append("B"+ id +" ");
TaintBB tb = (TaintBB) cfg.getBasicBlockAt(id);
sb.append(tb.preResult.frame.getStack(0).toReadableTaint());
}
fb.blockDep = sb.toString();
}
if (insnList != null && insnList.size() > 0) {
AbstractInsnNode lastStmt = insnList.get(insnList.size() - 1);
if (lastStmt.getOpcode() >= 0) {
OpInfo info = OpInfo.ops[lastStmt.getOpcode()];
if (info.canBranch() || info.canSwitch()) {
fb.type = "Branch";
}
}
fb.stmts = new ArrayList<String>();
ps.content = fb.stmts;
for (AbstractInsnNode node : insnList) {
node.accept(printer);
}
}
}
public void addEdge(BasicBlock bb, BasicBlock suc) { // added
FrontEdge edge = new FrontEdge(); TaintBB b = (TaintBB) bb;
List<AbstractInsnNode> insnList = bb.getInsn(); // if(b.preResult != null)
edge.label = new EdgeLabel(); // b.preResult.printResult();
edge.label.label = "e"; fb.result = b.getResult();
AbstractInsnNode lastStmt = insnList.get(insnList.size() - 1); if (ids == null)
boolean ignore = false; fb.blockDep = "";
if (lastStmt.getOpcode() >= 0) { else {
OpInfo info = OpInfo.ops[lastStmt.getOpcode()]; StringBuilder sb = new StringBuilder();
if (info.canBranch() && info.toString().startsWith("if")) { // sb.append("Dependence: ");
if (suc.blockID == bb.blockID + 1) for (Integer id : ids) {
edge.label.label = "false"; // sb.append("B"+ id +" ");
else TaintBB tb = (TaintBB) cfg.getBasicBlockAt(id);
edge.label.label = "true"; sb.append(tb.preResult.frame.getStack(0).toReadableTaint());
} }
if (info.canThrow() && info.toString().startsWith("invoke")) { fb.blockDep = sb.toString();
if (suc.blockID != bb.blockID + 1) { }
ignore = true; if (insnList != null && insnList.size() > 0) {
} AbstractInsnNode lastStmt = insnList.get(insnList.size() - 1);
} if (lastStmt.getOpcode() >= 0) {
} OpInfo info = OpInfo.ops[lastStmt.getOpcode()];
edge.from = "B" + bb.blockID; if (info.canBranch() || info.canSwitch()) {
edge.to = "B" + suc.blockID; fb.type = "Branch";
if (!ignore) }
edges.add(edge); }
fb.stmts = new ArrayList<String>();
ps.content = fb.stmts;
for (AbstractInsnNode node : insnList) {
node.accept(printer);
}
}
}
} public void addEdge(BasicBlock bb, BasicBlock suc) {
FrontEdge edge = new FrontEdge();
List<AbstractInsnNode> insnList = bb.getInsn();
edge.label = new EdgeLabel();
edge.label.label = "e";
AbstractInsnNode lastStmt = insnList.get(insnList.size() - 1);
boolean ignore = false;
if (lastStmt.getOpcode() >= 0) {
OpInfo info = OpInfo.ops[lastStmt.getOpcode()];
if (info.canBranch() && info.toString().startsWith("if")) {
if (suc.blockID == bb.blockID + 1)
edge.label.label = "false";
else
edge.label.label = "true";
}
if (info.canThrow() && info.toString().startsWith("invoke")) {
if (suc.blockID != bb.blockID + 1) {
ignore = true;
}
}
}
edge.from = "B" + bb.blockID;
edge.to = "B" + suc.blockID;
if (!ignore)
edges.add(edge);
}
} }

View File

@ -10,288 +10,275 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
public class InsnPrinter extends MethodVisitor { public class InsnPrinter extends MethodVisitor {
PrintStream ps; PrintStream ps;
private Map<Label, Integer> labelOrder; private Map<Label, Integer> labelOrder;
public InsnPrinter(int api, PrintStream ps) { public InsnPrinter(int api, PrintStream ps) {
super(api); super(api);
this.ps = ps; this.ps = ps;
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Normal instructions // Normal instructions
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Visits a zero operand instruction. * Visits a zero operand instruction.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is * @param opcode the opcode of the instruction to be visited. This opcode is either NOP,
* either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
* ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
* FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
* LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, * AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL,
* SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, * IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, * ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F,
* IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, * L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG,
* FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, * MONITORENTER, or MONITOREXIT.
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, */
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, public void visitInsn(int opcode) {
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or ps.println(OpInfo.ops[opcode].toString());
* MONITOREXIT. }
*/
public void visitInsn(int opcode) {
ps.println(OpInfo.ops[opcode].toString());
}
/** /**
* Visits an instruction with a single int operand. * Visits an instruction with a single int operand.
* *
* @param opcode the opcode of the instruction to be visited. This opcode is * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH,
* either BIPUSH, SIPUSH or NEWARRAY. * SIPUSH or NEWARRAY.
* @param operand the operand of the instruction to be visited.<br> * @param operand the operand of the instruction to be visited.<br>
* When opcode is BIPUSH, operand value should be between * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and
* Byte.MIN_VALUE and Byte.MAX_VALUE.<br> * Byte.MAX_VALUE.<br>
* When opcode is SIPUSH, operand value should be between * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and
* Short.MIN_VALUE and Short.MAX_VALUE.<br> * Short.MAX_VALUE.<br>
* When opcode is NEWARRAY, operand value should be one of * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN},
* {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR}, * {@link Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
* {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, * {@link Opcodes#T_LONG}.
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. */
*/ public void visitIntInsn(int opcode, int operand) {
public void visitIntInsn(int opcode, int operand) { ps.println(OpInfo.ops[opcode].toString() + " " + operand);
ps.println(OpInfo.ops[opcode].toString() + " " + operand); }
}
/** /**
* Visits a local variable instruction. A local variable instruction is an * Visits a local variable instruction. A local variable instruction is an instruction that
* instruction that loads or stores the value of a local variable. * loads or stores the value of a local variable.
* *
* @param opcode the opcode of the local variable instruction to be visited. * @param opcode the opcode of the local variable instruction to be visited. This opcode is
* This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, * either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or
* ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. * RET.
* @param var the operand of the instruction to be visited. This operand is * @param var the operand of the instruction to be visited. This operand is the index of a local
* the index of a local variable. * variable.
*/ */
public void visitVarInsn(int opcode, int var) { public void visitVarInsn(int opcode, int var) {
ps.println(OpInfo.ops[opcode].toString() + " " + var); ps.println(OpInfo.ops[opcode].toString() + " " + var);
} }
/** /**
* Visits a type instruction. A type instruction is an instruction that takes * Visits a type instruction. A type instruction is an instruction that takes the internal name
* the internal name of a class as parameter. * of a class as parameter.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW,
* is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. * ANEWARRAY, CHECKCAST or INSTANCEOF.
* @param type the operand of the instruction to be visited. This operand must * @param type the operand of the instruction to be visited. This operand must be the internal
* be the internal name of an object or array class (see * name of an object or array class (see {@link Type#getInternalName() getInternalName}).
* {@link Type#getInternalName() getInternalName}). */
*/ public void visitTypeInsn(int opcode, String type) {
public void visitTypeInsn(int opcode, String type) { ps.println(OpInfo.ops[opcode].toString() + " " + type);
ps.println(OpInfo.ops[opcode].toString() + " " + type);
} }
/** /**
* Visits a field instruction. A field instruction is an instruction that loads * Visits a field instruction. A field instruction is an instruction that loads or stores the
* or stores the value of a field of an object. * value of a field of an object.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either
* is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* @param owner the internal name of the field's owner class (see * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()
* {@link Type#getInternalName() getInternalName}). * getInternalName}).
* @param name the field's name. * @param name the field's name.
* @param desc the field's descriptor (see {@link Type Type}). * @param desc the field's descriptor (see {@link Type Type}).
*/ */
public void visitFieldInsn(int opcode, String owner, String name, String desc) { public void visitFieldInsn(int opcode, String owner, String name, String desc) {
ps.println(OpInfo.ops[opcode].toString() + " " + owner + " " + name + " " + desc); ps.println(OpInfo.ops[opcode].toString() + " " + owner + " " + name + " " + desc);
} }
/** /**
* Visits a method instruction. A method instruction is an instruction that * Visits a method instruction. A method instruction is an instruction that invokes a method.
* invokes a method. *
* * @param opcode the opcode of the type instruction to be visited. This opcode is either
* @param opcode the opcode of the type instruction to be visited. This opcode * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
* is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or * @param owner the internal name of the method's owner class (see {@link Type#getInternalName()
* INVOKEINTERFACE. * getInternalName}).
* @param owner the internal name of the method's owner class (see * @param name the method's name.
* {@link Type#getInternalName() getInternalName}). * @param desc the method's descriptor (see {@link Type Type}).
* @param name the method's name. */
* @param desc the method's descriptor (see {@link Type Type}). public void visitMethodInsn(int opcode, String owner, String name, String desc) {
*/ ps.println(OpInfo.ops[opcode].toString() + " " + owner + " " + name + " " + desc);
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
ps.println(OpInfo.ops[opcode].toString() + " " + owner + " " + name + " " + desc);
} }
/** /**
* Visits an invokedynamic instruction. * Visits an invokedynamic instruction.
* *
* @param name the method's name. * @param name the method's name.
* @param desc the method's descriptor (see {@link Type Type}). * @param desc the method's descriptor (see {@link Type Type}).
* @param bsm the bootstrap method. * @param bsm the bootstrap method.
* @param bsmArgs the bootstrap method constant arguments. Each argument must be * @param bsmArgs the bootstrap method constant arguments. Each argument must be an
* an {@link Integer}, {@link Float}, {@link Long}, * {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String},
* {@link Double}, {@link String}, {@link Type} or {@link Handle} * {@link Type} or {@link Handle} value. This method is allowed to modify the content of
* value. This method is allowed to modify the content of the * the array so a caller should expect that this array may change.
* array so a caller should expect that this array may change. */
*/ public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { ps.println(OpInfo.INVOKEDYNAMIC.toString() + " " + name + " " + desc + " HANDLE:"
ps.println(OpInfo.INVOKEDYNAMIC.toString() + " " + name + " " + desc + " HANDLE:" + bsm.toString() + " " + bsm.toString() + " " + objs2Str(bsmArgs));
+ objs2Str(bsmArgs));
} }
private String objs2Str(Object[] bsmArgs) { private String objs2Str(Object[] bsmArgs) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Object obj : bsmArgs) for (Object obj : bsmArgs)
sb.append(obj.toString()).append(" "); sb.append(obj.toString()).append(" ");
return sb.toString(); return sb.toString();
} }
/** /**
* Visits a jump instruction. A jump instruction is an instruction that may jump * Visits a jump instruction. A jump instruction is an instruction that may jump to another
* to another instruction. * instruction.
* *
* @param opcode the opcode of the type instruction to be visited. This opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ,
* is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, * IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * @param label the operand of the instruction to be visited. This operand is a label that
* @param label the operand of the instruction to be visited. This operand is a * designates the instruction to which the jump instruction may jump.
* label that designates the instruction to which the jump */
* instruction may jump. public void visitJumpInsn(int opcode, Label label) {
*/ ps.println(OpInfo.ops[opcode].toString() + getLabelStr(label));
public void visitJumpInsn(int opcode, Label label) {
ps.println(OpInfo.ops[opcode].toString() + getLabelStr(label));
} }
/** /**
* Visits a label. A label designates the instruction that will be visited just * Visits a label. A label designates the instruction that will be visited just after it.
* after it. *
* * @param label a {@link Label Label} object.
* @param label a {@link Label Label} object. */
*/ private String getLabelStr(Label label) {
private String getLabelStr(Label label) { return "L" + labelOrder.get(label);
return "L" + labelOrder.get(label); }
}
public void visitLabel(Label label) { public void visitLabel(Label label) {
ps.println("=" + getLabelStr(label) + "="); ps.println("=" + getLabelStr(label) + "=");
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Special instructions // Special instructions
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Visits a LDC instruction. Note that new constant types may be added in future * Visits a LDC instruction. Note that new constant types may be added in future versions of the
* versions of the Java Virtual Machine. To easily detect new constant types, * Java Virtual Machine. To easily detect new constant types, implementations of this method
* implementations of this method should check for unexpected constant types, * should check for unexpected constant types, like this:
* like this: *
* * <pre>
* <pre> * if (cst instanceof Integer) {
* if (cst instanceof Integer) { * // ...
* // ... * } else if (cst instanceof Float) {
* } else if (cst instanceof Float) { * // ...
* // ... * } else if (cst instanceof Long) {
* } else if (cst instanceof Long) { * // ...
* // ... * } else if (cst instanceof Double) {
* } else if (cst instanceof Double) { * // ...
* // ... * } else if (cst instanceof String) {
* } else if (cst instanceof String) { * // ...
* // ... * } else if (cst instanceof Type) {
* } else if (cst instanceof Type) { * int sort = ((Type) cst).getSort();
* int sort = ((Type) cst).getSort(); * if (sort == Type.OBJECT) {
* if (sort == Type.OBJECT) { * // ...
* // ... * } else if (sort == Type.ARRAY) {
* } else if (sort == Type.ARRAY) { * // ...
* // ... * } else if (sort == Type.METHOD) {
* } else if (sort == Type.METHOD) { * // ...
* // ... * } else {
* } else { * // throw an exception
* // throw an exception * }
* } * } else if (cst instanceof Handle) {
* } else if (cst instanceof Handle) { * // ...
* // ... * } else {
* } else { * // throw an exception
* // throw an exception * }
* } * </pre>
* </pre> *
* * @param cst the constant to be loaded on the stack. This parameter must be a non null
* @param cst the constant to be loaded on the stack. This parameter must be a * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String},
* non null {@link Integer}, a {@link Float}, a {@link Long}, a * a {@link Type} of OBJECT or ARRAY sort for <tt>.class</tt> constants, for classes
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or * whose version is 49.0, a {@link Type} of METHOD sort or a {@link Handle} for
* ARRAY sort for <tt>.class</tt> constants, for classes whose * MethodType and MethodHandle constants, for classes whose version is 51.0.
* version is 49.0, a {@link Type} of METHOD sort or a {@link Handle} */
* for MethodType and MethodHandle constants, for classes whose public void visitLdcInsn(Object cst) {
* version is 51.0. ps.println("ldc " + cst);
*/ }
public void visitLdcInsn(Object cst) {
ps.println("ldc " + cst);
}
/** /**
* Visits an IINC instruction. * Visits an IINC instruction.
* *
* @param var index of the local variable to be incremented. * @param var index of the local variable to be incremented.
* @param increment amount to increment the local variable by. * @param increment amount to increment the local variable by.
*/ */
public void visitIincInsn(int var, int increment) { public void visitIincInsn(int var, int increment) {
ps.println("iinc " + var + " " + increment); ps.println("iinc " + var + " " + increment);
} }
/** /**
* Visits a TABLESWITCH instruction. * Visits a TABLESWITCH instruction.
* *
* @param min the minimum key value. * @param min the minimum key value.
* @param max the maximum key value. * @param max the maximum key value.
* @param dflt beginning of the default handler block. * @param dflt beginning of the default handler block.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
* beginning of the handler block for the <tt>min + i</tt> key. * handler block for the <tt>min + i</tt> key.
*/ */
public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
ps.println(OpInfo.TABLESWITCH.toString() + " labels:" + getLabelStr(dflt) + " " + convertLabels(labels)); ps.println(OpInfo.TABLESWITCH.toString() + " labels:" + getLabelStr(dflt) + " "
+ convertLabels(labels));
} }
private String convertLabels(Label[] labels) { private String convertLabels(Label[] labels) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Label l : labels) for (Label l : labels)
sb.append(getLabelStr(l)).append(" "); sb.append(getLabelStr(l)).append(" ");
return sb.toString(); return sb.toString();
} }
/** /**
* Visits a LOOKUPSWITCH instruction. * Visits a LOOKUPSWITCH instruction.
* *
* @param dflt beginning of the default handler block. * @param dflt beginning of the default handler block.
* @param keys the values of the keys. * @param keys the values of the keys.
* @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
* beginning of the handler block for the <tt>keys[i]</tt> key. * handler block for the <tt>keys[i]</tt> key.
*/ */
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
ps.println(OpInfo.LOOKUPSWITCH.toString() + " labels:" + getLabelStr(dflt) + " " + convertLabels(labels)); ps.println(OpInfo.LOOKUPSWITCH.toString() + " labels:" + getLabelStr(dflt) + " "
+ convertLabels(labels));
} }
/** /**
* Visits a MULTIANEWARRAY instruction. * Visits a MULTIANEWARRAY instruction.
* *
* @param desc an array type descriptor (see {@link Type Type}). * @param desc an array type descriptor (see {@link Type Type}).
* @param dims number of dimensions of the array to allocate. * @param dims number of dimensions of the array to allocate.
*/ */
public void visitMultiANewArrayInsn(String desc, int dims) { public void visitMultiANewArrayInsn(String desc, int dims) {
ps.println(OpInfo.MULTIANEWARRAY + " " + desc + " " + dims); ps.println(OpInfo.MULTIANEWARRAY + " " + desc + " " + dims);
} }
public void setLabelOrder(Map<Label, Integer> labelOrder) { public void setLabelOrder(Map<Label, Integer> labelOrder) {
this.labelOrder = labelOrder; this.labelOrder = labelOrder;
} }
} }

View File

@ -1,256 +1,257 @@
package org.bdware.analysis; package org.bdware.analysis;
public enum OpInfo implements CFType { public enum OpInfo implements CFType {
NOP(0x00, "nop", kInstrCanContinue, 0), // -- NOP(0x00, "nop", kInstrCanContinue, 0), // --
ACONST_NULL(0x01, "aconst_null", kInstrCanContinue, 1), // -- ACONST_NULL(0x01, "aconst_null", kInstrCanContinue, 1), // --
ICONST_M1(0x02, "iconst_m1", kInstrCanContinue, 1), // -- ICONST_M1(0x02, "iconst_m1", kInstrCanContinue, 1), // --
ICONST_0(0x03, "iconst_0", kInstrCanContinue, 1), // -- ICONST_0(0x03, "iconst_0", kInstrCanContinue, 1), // --
ICONST_1(0x04, "iconst_1", kInstrCanContinue, 1), // -- ICONST_1(0x04, "iconst_1", kInstrCanContinue, 1), // --
ICONST_2(0x05, "iconst_2", kInstrCanContinue, 1), // -- ICONST_2(0x05, "iconst_2", kInstrCanContinue, 1), // --
ICONST_3(0x06, "iconst_3", kInstrCanContinue, 1), // -- ICONST_3(0x06, "iconst_3", kInstrCanContinue, 1), // --
ICONST_4(0x07, "iconst_4", kInstrCanContinue, 1), // -- ICONST_4(0x07, "iconst_4", kInstrCanContinue, 1), // --
ICONST_5(0x08, "iconst_5", kInstrCanContinue, 1), // -- ICONST_5(0x08, "iconst_5", kInstrCanContinue, 1), // --
LCONST_0(0x09, "lconst_0", kInstrCanContinue, 2), // -- LCONST_0(0x09, "lconst_0", kInstrCanContinue, 2), // --
LCONST_1(0x0a, "lconst_1", kInstrCanContinue, 2), // -- LCONST_1(0x0a, "lconst_1", kInstrCanContinue, 2), // --
FCONST_0(0x0b, "fconst_0", kInstrCanContinue, 1), // -- FCONST_0(0x0b, "fconst_0", kInstrCanContinue, 1), // --
FCONST_1(0x0c, "fconst_1", kInstrCanContinue, 1), // -- FCONST_1(0x0c, "fconst_1", kInstrCanContinue, 1), // --
FCONST_2(0x0d, "fconst_2", kInstrCanContinue, 1), // -- FCONST_2(0x0d, "fconst_2", kInstrCanContinue, 1), // --
DCONST_0(0x0e, "dconst_0", kInstrCanContinue, 2), // -- DCONST_0(0x0e, "dconst_0", kInstrCanContinue, 2), // --
DCONST_1(0x0f, "dconst_1", kInstrCanContinue, 2), // -- DCONST_1(0x0f, "dconst_1", kInstrCanContinue, 2), // --
BIPUSH(0x10, "bipush", kInstrCanContinue, 1), // -- BIPUSH(0x10, "bipush", kInstrCanContinue, 1), // --
SIPUSH(0x11, "sipush", kInstrCanContinue, 1), // -- SIPUSH(0x11, "sipush", kInstrCanContinue, 1), // --
LDC(0x12, "ldc", kInstrCanContinue, 1), // -- LDC(0x12, "ldc", kInstrCanContinue, 1), // --
LDC_W(0x13, "ldc_w", kInstrCanContinue, 1), // -- LDC_W(0x13, "ldc_w", kInstrCanContinue, 1), // --
LDC2_W(0x14, "ldc2_w", kInstrCanContinue, 2), // -- LDC2_W(0x14, "ldc2_w", kInstrCanContinue, 2), // --
ILOAD(0x15, "iload", kInstrCanContinue, 1), // -- ILOAD(0x15, "iload", kInstrCanContinue, 1), // --
LLOAD(0x16, "lload", kInstrCanContinue, 2), // -- LLOAD(0x16, "lload", kInstrCanContinue, 2), // --
FLOAD(0x17, "fload", kInstrCanContinue, 1), // -- FLOAD(0x17, "fload", kInstrCanContinue, 1), // --
DLOAD(0x18, "dload", kInstrCanContinue, 2), // -- DLOAD(0x18, "dload", kInstrCanContinue, 2), // --
ALOAD(0x19, "aload", kInstrCanContinue, 1), // -- ALOAD(0x19, "aload", kInstrCanContinue, 1), // --
ILOAD_0(0x1a, "iload_0", kInstrCanContinue, 1), // -- ILOAD_0(0x1a, "iload_0", kInstrCanContinue, 1), // --
ILOAD_1(0x1b, "iload_1", kInstrCanContinue, 1), // -- ILOAD_1(0x1b, "iload_1", kInstrCanContinue, 1), // --
ILOAD_2(0x1c, "iload_2", kInstrCanContinue, 1), // -- ILOAD_2(0x1c, "iload_2", kInstrCanContinue, 1), // --
ILOAD_3(0x1d, "iload_3", kInstrCanContinue, 1), // -- ILOAD_3(0x1d, "iload_3", kInstrCanContinue, 1), // --
LLOAD_0(0x1e, "lload_0", kInstrCanContinue, 2), // -- LLOAD_0(0x1e, "lload_0", kInstrCanContinue, 2), // --
LLOAD_1(0x1f, "lload_1", kInstrCanContinue, 2), // -- LLOAD_1(0x1f, "lload_1", kInstrCanContinue, 2), // --
LLOAD_2(0x20, "lload_2", kInstrCanContinue, 2), // -- LLOAD_2(0x20, "lload_2", kInstrCanContinue, 2), // --
LLOAD_3(0x21, "lload_3", kInstrCanContinue, 2), // -- LLOAD_3(0x21, "lload_3", kInstrCanContinue, 2), // --
FLOAD_0(0x22, "fload_0", kInstrCanContinue, 1), // -- FLOAD_0(0x22, "fload_0", kInstrCanContinue, 1), // --
FLOAD_1(0x23, "fload_1", kInstrCanContinue, 1), // -- FLOAD_1(0x23, "fload_1", kInstrCanContinue, 1), // --
FLOAD_2(0x24, "fload_2", kInstrCanContinue, 1), // -- FLOAD_2(0x24, "fload_2", kInstrCanContinue, 1), // --
FLOAD_3(0x25, "fload_3", kInstrCanContinue, 1), // -- FLOAD_3(0x25, "fload_3", kInstrCanContinue, 1), // --
DLOAD_0(0x26, "dload_0", kInstrCanContinue, 2), // -- DLOAD_0(0x26, "dload_0", kInstrCanContinue, 2), // --
DLOAD_1(0x27, "dload_1", kInstrCanContinue, 2), // -- DLOAD_1(0x27, "dload_1", kInstrCanContinue, 2), // --
DLOAD_2(0x28, "dload_2", kInstrCanContinue, 2), // -- DLOAD_2(0x28, "dload_2", kInstrCanContinue, 2), // --
DLOAD_3(0x29, "dload_3", kInstrCanContinue, 2), // -- DLOAD_3(0x29, "dload_3", kInstrCanContinue, 2), // --
ALOAD_0(0x2a, "aload_0", kInstrCanContinue, 1), // -- ALOAD_0(0x2a, "aload_0", kInstrCanContinue, 1), // --
ALOAD_1(0x2b, "aload_1", kInstrCanContinue, 1), // -- ALOAD_1(0x2b, "aload_1", kInstrCanContinue, 1), // --
ALOAD_2(0x2c, "aload_2", kInstrCanContinue, 1), // -- ALOAD_2(0x2c, "aload_2", kInstrCanContinue, 1), // --
ALOAD_3(0x2d, "aload_3", kInstrCanContinue, 1), // -- ALOAD_3(0x2d, "aload_3", kInstrCanContinue, 1), // --
IALOAD(0x2e, "iaload", kInstrCanContinue, -1), // -- IALOAD(0x2e, "iaload", kInstrCanContinue, -1), // --
LALOAD(0x2f, "laload", kInstrCanContinue, 0), // -- LALOAD(0x2f, "laload", kInstrCanContinue, 0), // --
FALOAD(0x30, "faload", kInstrCanContinue, -1), // -- FALOAD(0x30, "faload", kInstrCanContinue, -1), // --
DALOAD(0x31, "daload", kInstrCanContinue, 0), // -- DALOAD(0x31, "daload", kInstrCanContinue, 0), // --
AALOAD(0x32, "aaload", kInstrCanContinue, -1), // -- AALOAD(0x32, "aaload", kInstrCanContinue, -1), // --
BALOAD(0x33, "baload", kInstrCanContinue, -1), // -- BALOAD(0x33, "baload", kInstrCanContinue, -1), // --
CALOAD(0x34, "caload", kInstrCanContinue, -1), // -- CALOAD(0x34, "caload", kInstrCanContinue, -1), // --
SALOAD(0x35, "saload", kInstrCanContinue, -1), // -- SALOAD(0x35, "saload", kInstrCanContinue, -1), // --
ISTORE(0x36, "istore", kInstrCanContinue, -1), // -- ISTORE(0x36, "istore", kInstrCanContinue, -1), // --
LSTORE(0x37, "lstore", kInstrCanContinue, -2), // -- LSTORE(0x37, "lstore", kInstrCanContinue, -2), // --
FSTORE(0x38, "fstore", kInstrCanContinue, -1), // -- FSTORE(0x38, "fstore", kInstrCanContinue, -1), // --
DSTORE(0x39, "dstore", kInstrCanContinue, -2), // -- DSTORE(0x39, "dstore", kInstrCanContinue, -2), // --
ASTORE(0x3a, "astore", kInstrCanContinue, -1), // -- ASTORE(0x3a, "astore", kInstrCanContinue, -1), // --
ISTORE_0(0x3b, "istore_0", kInstrCanContinue, -1), // -- ISTORE_0(0x3b, "istore_0", kInstrCanContinue, -1), // --
ISTORE_1(0x3c, "istore_1", kInstrCanContinue, -1), // -- ISTORE_1(0x3c, "istore_1", kInstrCanContinue, -1), // --
ISTORE_2(0x3d, "istore_2", kInstrCanContinue, -1), // -- ISTORE_2(0x3d, "istore_2", kInstrCanContinue, -1), // --
ISTORE_3(0x3e, "istore_3", kInstrCanContinue, -1), // -- ISTORE_3(0x3e, "istore_3", kInstrCanContinue, -1), // --
LSTORE_0(0x3f, "lstore_0", kInstrCanContinue, -2), // -- LSTORE_0(0x3f, "lstore_0", kInstrCanContinue, -2), // --
LSTORE_1(0x40, "lstore_1", kInstrCanContinue, -2), // -- LSTORE_1(0x40, "lstore_1", kInstrCanContinue, -2), // --
LSTORE_2(0x41, "lstore_2", kInstrCanContinue, -2), // -- LSTORE_2(0x41, "lstore_2", kInstrCanContinue, -2), // --
LSTORE_3(0x42, "lstore_3", kInstrCanContinue, -2), // -- LSTORE_3(0x42, "lstore_3", kInstrCanContinue, -2), // --
FSTORE_0(0x43, "fstore_0", kInstrCanContinue, -1), // -- FSTORE_0(0x43, "fstore_0", kInstrCanContinue, -1), // --
FSTORE_1(0x44, "fstore_1", kInstrCanContinue, -1), // -- FSTORE_1(0x44, "fstore_1", kInstrCanContinue, -1), // --
FSTORE_2(0x45, "fstore_2", kInstrCanContinue, -1), // -- FSTORE_2(0x45, "fstore_2", kInstrCanContinue, -1), // --
FSTORE_3(0x46, "fstore_3", kInstrCanContinue, -1), // -- FSTORE_3(0x46, "fstore_3", kInstrCanContinue, -1), // --
DSTORE_0(0x47, "dstore_0", kInstrCanContinue, -2), // -- DSTORE_0(0x47, "dstore_0", kInstrCanContinue, -2), // --
DSTORE_1(0x48, "dstore_1", kInstrCanContinue, -2), // -- DSTORE_1(0x48, "dstore_1", kInstrCanContinue, -2), // --
DSTORE_2(0x49, "dstore_2", kInstrCanContinue, -2), // -- DSTORE_2(0x49, "dstore_2", kInstrCanContinue, -2), // --
DSTORE_3(0x4a, "dstore_3", kInstrCanContinue, -2), // -- DSTORE_3(0x4a, "dstore_3", kInstrCanContinue, -2), // --
ASTORE_0(0x4b, "astore_0", kInstrCanContinue, -1), // -- ASTORE_0(0x4b, "astore_0", kInstrCanContinue, -1), // --
ASTORE_1(0x4c, "astore_1", kInstrCanContinue, -1), // -- ASTORE_1(0x4c, "astore_1", kInstrCanContinue, -1), // --
ASTORE_2(0x4d, "astore_2", kInstrCanContinue, -1), // -- ASTORE_2(0x4d, "astore_2", kInstrCanContinue, -1), // --
ASTORE_3(0x4e, "astore_3", kInstrCanContinue, -1), // -- ASTORE_3(0x4e, "astore_3", kInstrCanContinue, -1), // --
IASTORE(0x4f, "iastore", kInstrCanContinue, -3), // -- IASTORE(0x4f, "iastore", kInstrCanContinue, -3), // --
LASTORE(0x50, "lastore", kInstrCanContinue, -4), // -- LASTORE(0x50, "lastore", kInstrCanContinue, -4), // --
FASTORE(0x51, "fastore", kInstrCanContinue, -3), // -- FASTORE(0x51, "fastore", kInstrCanContinue, -3), // --
DASTORE(0x52, "dastore", kInstrCanContinue, -4), // -- DASTORE(0x52, "dastore", kInstrCanContinue, -4), // --
AASTORE(0x53, "aastore", kInstrCanContinue, -3), // -- AASTORE(0x53, "aastore", kInstrCanContinue, -3), // --
BASTORE(0x54, "bastore", kInstrCanContinue, -3), // -- BASTORE(0x54, "bastore", kInstrCanContinue, -3), // --
CASTORE(0x55, "castore", kInstrCanContinue, -3), // -- CASTORE(0x55, "castore", kInstrCanContinue, -3), // --
SASTORE(0x56, "sastore", kInstrCanContinue, -3), // -- SASTORE(0x56, "sastore", kInstrCanContinue, -3), // --
POP(0x57, "pop", kInstrCanContinue, -1), // -- POP(0x57, "pop", kInstrCanContinue, -1), // --
POP2(0x58, "pop2", kInstrCanContinue, -2), // -- POP2(0x58, "pop2", kInstrCanContinue, -2), // --
DUP(0x59, "dup", kInstrCanContinue, 1), // -- DUP(0x59, "dup", kInstrCanContinue, 1), // --
DUP_X1(0x5a, "dup_x1", kInstrCanContinue, 1), // -- DUP_X1(0x5a, "dup_x1", kInstrCanContinue, 1), // --
DUP_X2(0x5b, "dup_x2", kInstrCanContinue, 1), // -- DUP_X2(0x5b, "dup_x2", kInstrCanContinue, 1), // --
DUP2(0x5c, "dup2", kInstrCanContinue, 2), // -- DUP2(0x5c, "dup2", kInstrCanContinue, 2), // --
DUP2_X1(0x5d, "dup2_x1", kInstrCanContinue, 2), // -- DUP2_X1(0x5d, "dup2_x1", kInstrCanContinue, 2), // --
DUP2_X2(0x5e, "dup2_x2", kInstrCanContinue, 2), // -- DUP2_X2(0x5e, "dup2_x2", kInstrCanContinue, 2), // --
SWAP(0x5f, "swap", kInstrCanContinue, 0), // -- SWAP(0x5f, "swap", kInstrCanContinue, 0), // --
IADD(0x60, "iadd", kInstrCanContinue, -1), // -- IADD(0x60, "iadd", kInstrCanContinue, -1), // --
LADD(0x61, "ladd", kInstrCanContinue, -2), // -- LADD(0x61, "ladd", kInstrCanContinue, -2), // --
FADD(0x62, "fadd", kInstrCanContinue, -1), // -- FADD(0x62, "fadd", kInstrCanContinue, -1), // --
DADD(0x63, "dadd", kInstrCanContinue, -2), // -- DADD(0x63, "dadd", kInstrCanContinue, -2), // --
ISUB(0x64, "isub", kInstrCanContinue, -1), // -- ISUB(0x64, "isub", kInstrCanContinue, -1), // --
LSUB(0x65, "lsub", kInstrCanContinue, -2), // -- LSUB(0x65, "lsub", kInstrCanContinue, -2), // --
FSUB(0x66, "fsub", kInstrCanContinue, -1), // -- FSUB(0x66, "fsub", kInstrCanContinue, -1), // --
DSUB(0x67, "dsub", kInstrCanContinue, -2), // -- DSUB(0x67, "dsub", kInstrCanContinue, -2), // --
IMUL(0x68, "imul", kInstrCanContinue, -1), // -- IMUL(0x68, "imul", kInstrCanContinue, -1), // --
LMUL(0x69, "lmul", kInstrCanContinue, -2), // -- LMUL(0x69, "lmul", kInstrCanContinue, -2), // --
FMUL(0x6a, "fmul", kInstrCanContinue, -1), // -- FMUL(0x6a, "fmul", kInstrCanContinue, -1), // --
DMUL(0x6b, "dmul", kInstrCanContinue, -2), // -- DMUL(0x6b, "dmul", kInstrCanContinue, -2), // --
IDIV(0x6c, "idiv", kInstrCanContinue, -1), // -- IDIV(0x6c, "idiv", kInstrCanContinue, -1), // --
LDIV(0x6d, "ldiv", kInstrCanContinue, -2), // -- LDIV(0x6d, "ldiv", kInstrCanContinue, -2), // --
FDIV(0x6e, "fdiv", kInstrCanContinue, -1), // -- FDIV(0x6e, "fdiv", kInstrCanContinue, -1), // --
DDIV(0x6f, "ddiv", kInstrCanContinue, -2), // -- DDIV(0x6f, "ddiv", kInstrCanContinue, -2), // --
IREM(0x70, "irem", kInstrCanContinue, -1), // -- IREM(0x70, "irem", kInstrCanContinue, -1), // --
LREM(0x71, "lrem", kInstrCanContinue, -2), // -- LREM(0x71, "lrem", kInstrCanContinue, -2), // --
FREM(0x72, "frem", kInstrCanContinue, -1), // -- FREM(0x72, "frem", kInstrCanContinue, -1), // --
DREM(0x73, "drem", kInstrCanContinue, -2), // -- DREM(0x73, "drem", kInstrCanContinue, -2), // --
INEG(0x74, "ineg", kInstrCanContinue, 0), // -- INEG(0x74, "ineg", kInstrCanContinue, 0), // --
LNEG(0x75, "lneg", kInstrCanContinue, 0), // -- LNEG(0x75, "lneg", kInstrCanContinue, 0), // --
FNEG(0x76, "fneg", kInstrCanContinue, 0), // -- FNEG(0x76, "fneg", kInstrCanContinue, 0), // --
DNEG(0x77, "dneg", kInstrCanContinue, 0), // -- DNEG(0x77, "dneg", kInstrCanContinue, 0), // --
ISHL(0x78, "ishl", kInstrCanContinue, -1), // -- ISHL(0x78, "ishl", kInstrCanContinue, -1), // --
LSHL(0x79, "lshl", kInstrCanContinue, -1), // -- LSHL(0x79, "lshl", kInstrCanContinue, -1), // --
ISHR(0x7a, "ishr", kInstrCanContinue, -1), // -- ISHR(0x7a, "ishr", kInstrCanContinue, -1), // --
LSHR(0x7b, "lshr", kInstrCanContinue, -1), // -- LSHR(0x7b, "lshr", kInstrCanContinue, -1), // --
IUSHR(0x7c, "iushr", kInstrCanContinue, -1), // -- IUSHR(0x7c, "iushr", kInstrCanContinue, -1), // --
LUSHR(0x7d, "lushr", kInstrCanContinue, -1), // -- LUSHR(0x7d, "lushr", kInstrCanContinue, -1), // --
IAND(0x7e, "iand", kInstrCanContinue, -1), // -- IAND(0x7e, "iand", kInstrCanContinue, -1), // --
LAND(0x7f, "land", kInstrCanContinue, -2), // -- LAND(0x7f, "land", kInstrCanContinue, -2), // --
IOR(0x80, "ior", kInstrCanContinue, -1), // -- IOR(0x80, "ior", kInstrCanContinue, -1), // --
LOR(0x81, "lor", kInstrCanContinue, -2), // -- LOR(0x81, "lor", kInstrCanContinue, -2), // --
IXOR(0x82, "ixor", kInstrCanContinue, -1), // -- IXOR(0x82, "ixor", kInstrCanContinue, -1), // --
LXOR(0x83, "lxor", kInstrCanContinue, -2), // -- LXOR(0x83, "lxor", kInstrCanContinue, -2), // --
IINC(0x84, "iinc", kInstrCanContinue, 0), // -- IINC(0x84, "iinc", kInstrCanContinue, 0), // --
I2L(0x85, "i2l", kInstrCanContinue, 1), // -- I2L(0x85, "i2l", kInstrCanContinue, 1), // --
I2F(0x86, "i2f", kInstrCanContinue, 0), // -- I2F(0x86, "i2f", kInstrCanContinue, 0), // --
I2D(0x87, "i2d", kInstrCanContinue, 1), // -- I2D(0x87, "i2d", kInstrCanContinue, 1), // --
L2I(0x88, "l2i", kInstrCanContinue, -1), // -- L2I(0x88, "l2i", kInstrCanContinue, -1), // --
L2F(0x89, "l2f", kInstrCanContinue, -1), // -- L2F(0x89, "l2f", kInstrCanContinue, -1), // --
L2D(0x8a, "l2d", kInstrCanContinue, 0), // -- L2D(0x8a, "l2d", kInstrCanContinue, 0), // --
F2I(0x8b, "f2i", kInstrCanContinue, 0), // -- F2I(0x8b, "f2i", kInstrCanContinue, 0), // --
F2L(0x8c, "f2l", kInstrCanContinue, 1), // -- F2L(0x8c, "f2l", kInstrCanContinue, 1), // --
F2D(0x8d, "f2d", kInstrCanContinue, 1), // -- F2D(0x8d, "f2d", kInstrCanContinue, 1), // --
D2I(0x8e, "d2i", kInstrCanContinue, -1), // -- D2I(0x8e, "d2i", kInstrCanContinue, -1), // --
D2L(0x8f, "d2l", kInstrCanContinue, 0), // -- D2L(0x8f, "d2l", kInstrCanContinue, 0), // --
D2F(0x90, "d2f", kInstrCanContinue, -1), // -- D2F(0x90, "d2f", kInstrCanContinue, -1), // --
I2B(0x91, "i2b", kInstrCanContinue, 0), // -- I2B(0x91, "i2b", kInstrCanContinue, 0), // --
I2C(0x92, "i2c", kInstrCanContinue, 0), // -- I2C(0x92, "i2c", kInstrCanContinue, 0), // --
I2S(0x93, "i2s", kInstrCanContinue, 0), // -- I2S(0x93, "i2s", kInstrCanContinue, 0), // --
LCMP(0x94, "lcmp", kInstrCanContinue, -2), // -- LCMP(0x94, "lcmp", kInstrCanContinue, -2), // --
FCMPL(0x95, "fcmpl", kInstrCanContinue, -1), // -- FCMPL(0x95, "fcmpl", kInstrCanContinue, -1), // --
FCMPG(0x96, "fcmpg", kInstrCanContinue, -1), // -- FCMPG(0x96, "fcmpg", kInstrCanContinue, -1), // --
DCMPL(0x97, "dcmpl", kInstrCanContinue, -3), // -- DCMPL(0x97, "dcmpl", kInstrCanContinue, -3), // --
DCMPG(0x98, "dcmpg", kInstrCanContinue, -3), // -- DCMPG(0x98, "dcmpg", kInstrCanContinue, -3), // --
IFEQ(0x99, "ifeq", kInstrCanBranch, -1), // -- IFEQ(0x99, "ifeq", kInstrCanBranch, -1), // --
IFNE(0x9a, "ifne", kInstrCanBranch, -1), // -- IFNE(0x9a, "ifne", kInstrCanBranch, -1), // --
IFLT(0x9b, "iflt", kInstrCanBranch, -1), // -- IFLT(0x9b, "iflt", kInstrCanBranch, -1), // --
IFGE(0x9c, "ifge", kInstrCanBranch, -1), // -- IFGE(0x9c, "ifge", kInstrCanBranch, -1), // --
IFGT(0x9d, "ifgt", kInstrCanBranch, -1), // -- IFGT(0x9d, "ifgt", kInstrCanBranch, -1), // --
IFLE(0x9e, "ifle", kInstrCanBranch, -1), // -- IFLE(0x9e, "ifle", kInstrCanBranch, -1), // --
IF_ICMPEQ(0x9f, "if_icmpeq", kInstrCanBranch, -2), // -- IF_ICMPEQ(0x9f, "if_icmpeq", kInstrCanBranch, -2), // --
IF_ICMPNE(0xa0, "if_icmpne", kInstrCanBranch, -2), // -- IF_ICMPNE(0xa0, "if_icmpne", kInstrCanBranch, -2), // --
IF_ICMPLT(0xa1, "if_icmplt", kInstrCanBranch, -2), // -- IF_ICMPLT(0xa1, "if_icmplt", kInstrCanBranch, -2), // --
IF_ICMPGE(0xa2, "if_icmpge", kInstrCanBranch, -2), // -- IF_ICMPGE(0xa2, "if_icmpge", kInstrCanBranch, -2), // --
IF_ICMPGT(0xa3, "if_icmpgt", kInstrCanBranch, -2), // -- IF_ICMPGT(0xa3, "if_icmpgt", kInstrCanBranch, -2), // --
IF_ICMPLE(0xa4, "if_icmple", kInstrCanBranch, -2), // -- IF_ICMPLE(0xa4, "if_icmple", kInstrCanBranch, -2), // --
IF_ACMPEQ(0xa5, "if_acmpeq", kInstrCanBranch, -2), // -- IF_ACMPEQ(0xa5, "if_acmpeq", kInstrCanBranch, -2), // --
IF_ACMPNE(0xa6, "if_acmpne", kInstrCanBranch, -2), // -- IF_ACMPNE(0xa6, "if_acmpne", kInstrCanBranch, -2), // --
GOTO(0xa7, "goto", kInstrCanBranch, 0), // -- GOTO(0xa7, "goto", kInstrCanBranch, 0), // --
JSR(0xa8, "jsr", kInstrCanContinue, 1), // ??-- JSR(0xa8, "jsr", kInstrCanContinue, 1), // ??--
RET(0xa9, "ret", kInstrCanContinue, -1), // ??-- RET(0xa9, "ret", kInstrCanContinue, -1), // ??--
TABLESWITCH(0xaa, "tableswitch", kInstrCanBranch, 1), // -- TABLESWITCH(0xaa, "tableswitch", kInstrCanBranch, 1), // --
LOOKUPSWITCH(0xab, "lookupswitch", kInstrCanBranch, 0), // -- LOOKUPSWITCH(0xab, "lookupswitch", kInstrCanBranch, 0), // --
IRETURN(0xac, "ireturn", kInstrCanReturn, -1), // -- IRETURN(0xac, "ireturn", kInstrCanReturn, -1), // --
LRETURN(0xad, "lreturn", kInstrCanReturn, -2), // -- LRETURN(0xad, "lreturn", kInstrCanReturn, -2), // --
FRETURN(0xae, "freturn", kInstrCanReturn, -1), // -- FRETURN(0xae, "freturn", kInstrCanReturn, -1), // --
DRETURN(0xaf, "dreturn", kInstrCanReturn, -2), // -- DRETURN(0xaf, "dreturn", kInstrCanReturn, -2), // --
ARETURN(0xb0, "areturn", kInstrCanReturn, -1), // -- ARETURN(0xb0, "areturn", kInstrCanReturn, -1), // --
RETURN(0xb1, "return", kInstrCanReturn, 0), // -- RETURN(0xb1, "return", kInstrCanReturn, 0), // --
GETSTATIC(0xb2, "getstatic", kInstrCanContinue, 0), // dynamic changing+ -- GETSTATIC(0xb2, "getstatic", kInstrCanContinue, 0), // dynamic changing+ --
PUTSTATIC(0xb3, "putstatic", kInstrCanContinue, 0), // dynamic changing- -- PUTSTATIC(0xb3, "putstatic", kInstrCanContinue, 0), // dynamic changing- --
GETFIELD(0xb4, "getfield", kInstrCanContinue, 0), // dynamic changing_+ -- GETFIELD(0xb4, "getfield", kInstrCanContinue, 0), // dynamic changing_+ --
PUTFIELD(0xb5, "putfield", kInstrCanContinue, 0), // dynamic changing-- -- PUTFIELD(0xb5, "putfield", kInstrCanContinue, 0), // dynamic changing-- --
INVOKEVIRTUAL(0xb6, "invokevirtual", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- INVOKEVIRTUAL(0xb6, "invokevirtual", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
INVOKESPECIAL(0xb7, "invokespecial", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- INVOKESPECIAL(0xb7, "invokespecial", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
INVOKESTATIC(0xb8, "invokestatic", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- INVOKESTATIC(0xb8, "invokestatic", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
INVOKEINTERFACE(0xb9, "invokeinterface", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- INVOKEINTERFACE(0xb9, "invokeinterface", kInstrInvoke | kInstrCanThrow, 0), // dynamic
INVOKEDYNAMIC(0xba, "invokedynamic", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- -- // changing-- --
NEW(0xbb, "new", kInstrCanContinue, 1), // -- INVOKEDYNAMIC(0xba, "invokedynamic", kInstrInvoke | kInstrCanThrow, 0), // dynamic changing-- --
NEWARRAY(0xbc, "newarray", kInstrCanContinue, 0), // -- NEW(0xbb, "new", kInstrCanContinue, 1), // --
ANEWARRAY(0xbd, "anewarray", kInstrCanContinue, 0), // -- NEWARRAY(0xbc, "newarray", kInstrCanContinue, 0), // --
ARRAYLENGTH(0xbe, "arraylength", kInstrCanContinue, 0), // -- ANEWARRAY(0xbd, "anewarray", kInstrCanContinue, 0), // --
ATHROW(0xbf, "athrow", kInstrCanReturn, 0), // -- ARRAYLENGTH(0xbe, "arraylength", kInstrCanContinue, 0), // --
CHECKCAST(0xc0, "checkcast", kInstrCanContinue, 0), // -- ATHROW(0xbf, "athrow", kInstrCanReturn, 0), // --
INSTANCEOF(0xc1, "instanceof", kInstrCanContinue, 0), // -- CHECKCAST(0xc0, "checkcast", kInstrCanContinue, 0), // --
MONITORENTER(0xc2, "monitorenter", kInstrCanContinue, -1), // -- INSTANCEOF(0xc1, "instanceof", kInstrCanContinue, 0), // --
MONITOREXIT(0xc3, "monitorexit", kInstrCanContinue, -1), // -- MONITORENTER(0xc2, "monitorenter", kInstrCanContinue, -1), // --
WIDE(0xc4, "wide", kInstrCanContinue, 0), // -- MONITOREXIT(0xc3, "monitorexit", kInstrCanContinue, -1), // --
MULTIANEWARRAY(0xc5, "multianewarray", kInstrCanContinue, 0), // dynamic changing-- WIDE(0xc4, "wide", kInstrCanContinue, 0), // --
IFNULL(0xc6, "ifnull", kInstrCanBranch, -1), // -- MULTIANEWARRAY(0xc5, "multianewarray", kInstrCanContinue, 0), // dynamic changing--
IFNONNULL(0xc7, "ifnonnull", kInstrCanBranch, -1), // -- IFNULL(0xc6, "ifnull", kInstrCanBranch, -1), // --
GOTO_W(0xc8, "goto_w", kInstrCanBranch, 0), // -- IFNONNULL(0xc7, "ifnonnull", kInstrCanBranch, -1), // --
JSR_W(0xc9, "jsr_w", kInstrCanContinue, 1);// ??-- GOTO_W(0xc8, "goto_w", kInstrCanBranch, 0), // --
public final static OpInfo ops[] = new OpInfo[256]; JSR_W(0xc9, "jsr_w", kInstrCanContinue, 1);// ??--
static { public final static OpInfo ops[] = new OpInfo[256];
OpInfo[] ops = OpInfo.ops;
for (OpInfo op : OpInfo.values()) {
if (op.opcode >= 0) {
ops[op.opcode] = op;
}
}
}
public boolean changeFrame;
int changeStack;
private int flags;
private String displayName;
private int opcode;
OpInfo() { static {
} OpInfo[] ops = OpInfo.ops;
for (OpInfo op : OpInfo.values()) {
if (op.opcode >= 0) {
ops[op.opcode] = op;
}
}
}
public boolean changeFrame;
int changeStack;
private int flags;
private String displayName;
private int opcode;
OpInfo(int opcode, String displayName, int branchType, int changStack) { OpInfo() {}
flags = branchType;
this.displayName = displayName;
this.opcode = opcode;
this.changeStack = changeStack;
}
public boolean canBranch() { OpInfo(int opcode, String displayName, int branchType, int changStack) {
return 0 != (flags & kInstrCanBranch); flags = branchType;
} this.displayName = displayName;
this.opcode = opcode;
this.changeStack = changeStack;
}
public boolean canContinue() { public boolean canBranch() {
return 0 != (flags & kInstrCanContinue); return 0 != (flags & kInstrCanBranch);
} }
public boolean canReturn() { public boolean canContinue() {
return 0 != (flags & kInstrCanReturn); return 0 != (flags & kInstrCanContinue);
} }
public boolean canSwitch() { public boolean canReturn() {
return 0 != (flags & kInstrCanSwitch); return 0 != (flags & kInstrCanReturn);
} }
public boolean canThrow() { public boolean canSwitch() {
return 0 != (flags & kInstrCanThrow); return 0 != (flags & kInstrCanSwitch);
} }
public String toString() { public boolean canThrow() {
return displayName; return 0 != (flags & kInstrCanThrow);
} }
public String toString() {
return displayName;
}
} }

View File

@ -18,7 +18,8 @@ import org.objectweb.asm.tree.MethodNode;
import java.util.*; import java.util.*;
public class FieldSensitiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, TaintBB> { public class FieldSensitiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, TaintBB> {
private static final Logger LOGGER = LogManager.getLogger(FieldSensitiveDynamicTaintAnalysis.class); private static final Logger LOGGER =
LogManager.getLogger(FieldSensitiveDynamicTaintAnalysis.class);
public static boolean isDebug = false; public static boolean isDebug = false;
TaintCFG cfg; TaintCFG cfg;
TracedFile tf; TracedFile tf;
@ -79,8 +80,8 @@ public class FieldSensitiveDynamicTaintAnalysis extends BreadthFirstSearch<Taint
// subBlock.clear(); // subBlock.clear();
subBlock.add(cfg.getBasicBlockAt(t.blockID + 1)); subBlock.add(cfg.getBasicBlockAt(t.blockID + 1));
} else if (OpInfo.ops[insn.getOpcode()].canBranch()) { } else if (OpInfo.ops[insn.getOpcode()].canBranch()) {
// subBlock.clear(); // subBlock.clear();
// LOGGER.info("can branch " + t.blockID); // LOGGER.info("can branch " + t.blockID);
int block = handleBranchCase(subBlock, insn, t); int block = handleBranchCase(subBlock, insn, t);
subBlock.add(cfg.getBasicBlockAt(block)); subBlock.add(cfg.getBasicBlockAt(block));
} else if (OpInfo.ops[insn.getOpcode()].canSwitch()) { } else if (OpInfo.ops[insn.getOpcode()].canSwitch()) {
@ -91,14 +92,14 @@ public class FieldSensitiveDynamicTaintAnalysis extends BreadthFirstSearch<Taint
} }
} }
Set<TaintBB> ret = new HashSet<>(); Set<TaintBB> ret = new HashSet<>();
// StringBuilder log = new StringBuilder("nextBB:"); // StringBuilder log = new StringBuilder("nextBB:");
for (BasicBlock bb : subBlock) { for (BasicBlock bb : subBlock) {
// log.append("\n\t").append(bb.blockID); // log.append("\n\t").append(bb.blockID);
TaintBB ntbb = (TaintBB) bb; TaintBB ntbb = (TaintBB) bb;
ntbb.preResult.mergeResult(t.sucResult); ntbb.preResult.mergeResult(t.sucResult);
ret.add(ntbb); ret.add(ntbb);
} }
// LOGGER.info(log.toString()); // LOGGER.info(log.toString());
return ret; return ret;
} }

View File

@ -27,7 +27,8 @@ public class NaiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, T
String methodDesc = mn.desc; String methodDesc = mn.desc;
methodDesc = methodDesc.replaceAll("\\).*$", ")"); methodDesc = methodDesc.replaceAll("\\).*$", ")");
int pos = 2; int pos = 2;
if (methodDesc.split(";").length == 3) pos = 1; if (methodDesc.split(";").length == 3)
pos = 1;
// TODO add inputBlock! // TODO add inputBlock!
TaintBB b = (TaintBB) cfg.getBasicBlockAt(0); TaintBB b = (TaintBB) cfg.getBasicBlockAt(0);
b.preResult = new TaintResult(); b.preResult = new TaintResult();
@ -47,11 +48,8 @@ public class NaiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, T
setToAnalysis(toAnalysis); setToAnalysis(toAnalysis);
if (isDebug) { if (isDebug) {
System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc); System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc);
System.out.println( System.out.println("===Local:" + cfg.getMethodNode().maxLocals + " "
"===Local:" + cfg.getMethodNode().maxStack);
+ cfg.getMethodNode().maxLocals
+ " "
+ cfg.getMethodNode().maxStack);
} }
} }
@ -68,7 +66,8 @@ public class NaiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, T
AbstractInsnNode insn = t.lastInsn(); AbstractInsnNode insn = t.lastInsn();
if (insn != null) { if (insn != null) {
OpInfo info = null; OpInfo info = null;
if (insn.getOpcode() >= 0) info = OpInfo.ops[insn.getOpcode()]; if (insn.getOpcode() >= 0)
info = OpInfo.ops[insn.getOpcode()];
if (info == null) { if (info == null) {
subBlock.addAll(cfg.getSucBlocks(t)); subBlock.addAll(cfg.getSucBlocks(t));
} else if (info.canThrow()) { } else if (info.canThrow()) {
@ -104,9 +103,8 @@ public class NaiveDynamicTaintAnalysis extends BreadthFirstSearch<TaintResult, T
if (functionName.contains("traceif")) { if (functionName.contains("traceif")) {
traceIfNum = (int) invoke; traceIfNum = (int) invoke;
if (branchCount.get(functionGlobel).containsKey(traceIfNum)) { if (branchCount.get(functionGlobel).containsKey(traceIfNum)) {
branchCount branchCount.get(functionGlobel).put(traceIfNum,
.get(functionGlobel) branchCount.get(functionGlobel).get(traceIfNum) + 1);
.put(traceIfNum, branchCount.get(functionGlobel).get(traceIfNum) + 1);
} else { } else {
branchCount.get(functionGlobel).put(traceIfNum, 1); branchCount.get(functionGlobel).put(traceIfNum, 1);
} }

View File

@ -33,23 +33,23 @@ public class ProgramPoint {
System.out.println("[stringsss: ]" + strings[0]); System.out.println("[stringsss: ]" + strings[0]);
funcTx.insert(strings[0], "ENTER"); funcTx.insert(strings[0], "ENTER");
} }
// if (string.contains("EXIT")) { // if (string.contains("EXIT")) {
// String[] strings = string.split("_"); // String[] strings = string.split("_");
// strings=strings[1].split("-"); // strings=strings[1].split("-");
// System.out.println("[stringsss: ]" + strings[0]); // System.out.println("[stringsss: ]" + strings[0]);
// functionMap.put(strings[1], "EXIT"); // functionMap.put(strings[1], "EXIT");
// } // }
if (string.contains("traceMark")) { if (string.contains("traceMark")) {
JsonObject jo = JsonUtil.parseStringAsJsonObject(string); JsonObject jo = JsonUtil.parseStringAsJsonObject(string);
if (jo.get("traceMark") != null) { if (jo.get("traceMark") != null) {
if (jo.get("lval") != null) { if (jo.get("lval") != null) {
transaction.insert( transaction.insert(jo.get("traceMark").getAsInt(),
jo.get("traceMark").getAsInt(), jo.get("lval").getAsInt()); jo.get("lval").getAsInt());
transaction.insert( transaction.insert(jo.get("traceMark").getAsInt(),
jo.get("traceMark").getAsInt(), jo.get("rval").getAsInt()); jo.get("rval").getAsInt());
} else { } else {
transaction.insert( transaction.insert(jo.get("traceMark").getAsInt(),
jo.get("traceMark").getAsInt(), jo.get("val").getAsInt()); jo.get("val").getAsInt());
} }
} }
} }

View File

@ -21,16 +21,14 @@ public class FieldSensitiveTaintAnalysis extends BreadthFirstSearch<TaintResult,
this.cfg = cfg; this.cfg = cfg;
List<TaintBB> toAnalysis = new ArrayList<>(); List<TaintBB> toAnalysis = new ArrayList<>();
/* /*
* NaiveTaintBB<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> boolean inList NaiveTaintResult preResult NaiveTaintResult * NaiveTaintBB<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> boolean inList NaiveTaintResult preResult NaiveTaintResult sucResult
* sucResult
*/ */
TaintBB b = (TaintBB) cfg.getBasicBlockAt(0); TaintBB b = (TaintBB) cfg.getBasicBlockAt(0);
/* /*
* NaiveTaintResult<EFBFBD>еı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Frame<TaintValue> frame TaintInterpreter interpreter * NaiveTaintResult<EFBFBD>еı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Frame<TaintValue> frame TaintInterpreter interpreter TaintValue
* TaintValue ret InsnPrinter printer int nLocals int nStack * ret InsnPrinter printer int nLocals int nStack NaiveTaintResult<EFBFBD>е<EFBFBD><EFBFBD> TaintValue int size
* NaiveTaintResult<EFBFBD>е<EFBFBD><EFBFBD> TaintValue int size boolean isTainted * boolean isTainted TaintInterpreter() NaiveTaintResult currentResult Frame<EFBFBD>еı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> V
* TaintInterpreter() NaiveTaintResult currentResult Frame<EFBFBD>еı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> V returnValue * returnValue //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊvoid<EFBFBD><EFBFBD>Ϊnull V[] values //<EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> int locals
* //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊvoid<EFBFBD><EFBFBD>Ϊnull V[] values //<EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> int locals
* //<EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD> int top //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>Ԫ<EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD> * //<EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD> int top //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD>Ԫ<EFBFBD>ظ<EFBFBD><EFBFBD><EFBFBD>
*/ */
b.preResult = new TaintResult(); b.preResult = new TaintResult();
@ -40,10 +38,9 @@ public class FieldSensitiveTaintAnalysis extends BreadthFirstSearch<TaintResult,
TaintResult.interpreter.setTaintBits(cfg.taintBits); TaintResult.interpreter.setTaintBits(cfg.taintBits);
b.preResult.frame.setLocal(arg, new TaintValue(1, cfg.taintBits.allocate("arg" + arg))); b.preResult.frame.setLocal(arg, new TaintValue(1, cfg.taintBits.allocate("arg" + arg)));
/* /*
* if (NaiveTaintResult.nLocals > 2) { b.preResult.frame.setLocal(0, new * if (NaiveTaintResult.nLocals > 2) { b.preResult.frame.setLocal(0, new TaintValue(1,
* TaintValue(1, cfg.taintBits.allocate("arg0"))); b.preResult.frame.setLocal(1, * cfg.taintBits.allocate("arg0"))); b.preResult.frame.setLocal(1, new TaintValue(1,
* new TaintValue(1, cfg.taintBits.allocate("arg1"))); * cfg.taintBits.allocate("arg1"))); b.preResult.frame.setLocal(2, new TaintValue(1,
* b.preResult.frame.setLocal(2, new TaintValue(1,
* cfg.taintBits.allocate("arg2"))); } * cfg.taintBits.allocate("arg2"))); }
*/ */
// .ret = TaintValue<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>size=1 // .ret = TaintValue<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>size=1
@ -54,8 +51,7 @@ public class FieldSensitiveTaintAnalysis extends BreadthFirstSearch<TaintResult,
b.setInList(true); b.setInList(true);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>BreadthFirstSearch<EFBFBD><EFBFBD><EFBFBD>еĺ<EFBFBD><EFBFBD><EFBFBD>setToAnalysis<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱBreadthFirstSearch<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>toAnalysisΪ<EFBFBD><EFBFBD>ǰ<EFBFBD>Ŀ<EFBFBD><EFBFBD>б<EFBFBD>ֻ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>B0 // <EFBFBD><EFBFBD><EFBFBD><EFBFBD>BreadthFirstSearch<EFBFBD><EFBFBD><EFBFBD>еĺ<EFBFBD><EFBFBD><EFBFBD>setToAnalysis<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱBreadthFirstSearch<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>toAnalysisΪ<EFBFBD><EFBFBD>ǰ<EFBFBD>Ŀ<EFBFBD><EFBFBD>б<EFBFBD>ֻ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>B0
/* /*
* BreadthFirstSearch<EFBFBD><EFBFBD><EFBFBD>еı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Map<T, AnalysisResult> results; List<T> * BreadthFirstSearch<EFBFBD><EFBFBD><EFBFBD>еı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Map<T, AnalysisResult> results; List<T> toAnalysis;
* toAnalysis;
*/ */
setToAnalysis(toAnalysis); setToAnalysis(toAnalysis);
if (isDebug) { if (isDebug) {

View File

@ -37,11 +37,8 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
setToAnalysis(toAnalysis); setToAnalysis(toAnalysis);
if (TaintConfig.isDebug) { if (TaintConfig.isDebug) {
System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc); System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc);
System.out.println( System.out.println("===Local:" + cfg.getMethodNode().maxLocals + " "
"===Local:" + cfg.getMethodNode().maxStack);
+ cfg.getMethodNode().maxLocals
+ " "
+ cfg.getMethodNode().maxStack);
} }
} }
@ -57,18 +54,12 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
for (BasicBlock bb : subBlock) { for (BasicBlock bb : subBlock) {
TaintBB ntbb = (TaintBB) bb; TaintBB ntbb = (TaintBB) bb;
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out.println( System.out.println("[MultiSoruceTaintAnalysis] B" + ntbb.blockID + " beforeMerge:"
"[MultiSoruceTaintAnalysis] B" + ntbb.preResult.frame2Str());
+ ntbb.blockID
+ " beforeMerge:"
+ ntbb.preResult.frame2Str());
ntbb.preResult.mergeResult(t.sucResult); ntbb.preResult.mergeResult(t.sucResult);
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out.println( System.out.println("[MultiSoruceTaintAnalysis] B" + ntbb.blockID + " afterMerge:"
"[MultiSoruceTaintAnalysis] B" + ntbb.preResult.frame2Str());
+ ntbb.blockID
+ " afterMerge:"
+ ntbb.preResult.frame2Str());
ret.add(ntbb); ret.add(ntbb);
} }
@ -95,9 +86,10 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
} }
} }
} }
/*Step2: Traverse all the blocks, for each block, traverse all the depBlocks, /*
* for each depBlock, traverse all the sucBlocks, * Step2: Traverse all the blocks, for each block, traverse all the depBlocks, for each
* if all the sucBlocks are arrival from each block, then the block is dependency with the depBlock. * depBlock, traverse all the sucBlocks, if all the sucBlocks are arrival from each block,
* then the block is dependency with the depBlock.
*/ */
List<BasicBlock> blocks = cfg.getBlocks(); List<BasicBlock> blocks = cfg.getBlocks();
Map<Integer, List<Integer>> map = new HashMap<>(); Map<Integer, List<Integer>> map = new HashMap<>();
@ -108,9 +100,11 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
int sucSize = sucBlocks.size(); int sucSize = sucBlocks.size();
int count = 0; int count = 0;
for (BasicBlock sucBlock : sucBlocks) { for (BasicBlock sucBlock : sucBlocks) {
if (isArrival(cfg, sucBlock, bb)) count++; if (isArrival(cfg, sucBlock, bb))
count++;
} }
if (count > 0 && count != sucSize) list.add(id); if (count > 0 && count != sucSize)
list.add(id);
} }
map.put(bb.blockID, list); map.put(bb.blockID, list);
} }
@ -129,10 +123,8 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
} }
} }
/* /*
for(int i : entry.getValue()) * for(int i : entry.getValue()) System.out.print(i+ " "); System.out.println();
System.out.print(i+ " "); */
System.out.println();
*/
} }
// add dependence to the last block // add dependence to the last block
@ -141,7 +133,8 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
for (Map.Entry<Integer, List<Integer>> entry : returnMap.entrySet()) { for (Map.Entry<Integer, List<Integer>> entry : returnMap.entrySet()) {
List<Integer> listID = entry.getValue(); List<Integer> listID = entry.getValue();
for (Integer i : listID) { for (Integer i : listID) {
if (!lastBlockDep.contains(i)) lastBlockDep.add(i); if (!lastBlockDep.contains(i))
lastBlockDep.add(i);
} }
} }
returnMap.put(cfg.getBasicBlockSize() - 1, lastBlockDep); returnMap.put(cfg.getBasicBlockSize() - 1, lastBlockDep);
@ -149,14 +142,10 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
// TODO get value from branch block // TODO get value from branch block
/* /*
List<Integer> list = returnMap.get(cfg.getBasicBlockSize()-1); * List<Integer> list = returnMap.get(cfg.getBasicBlockSize()-1); for(int i : list) {
for(int i : list) { * System.out.println(i); TaintBB tb = (TaintBB) cfg.getBasicBlockAt(i);
System.out.println(i); * System.out.println("Test:"); tb.preResult.printResult(); }
TaintBB tb = (TaintBB) cfg.getBasicBlockAt(i); */
System.out.println("Test:");
tb.preResult.printResult();
}
*/
return returnMap; return returnMap;
} }
@ -164,20 +153,14 @@ public class MultiSourceTaintAnalysis extends BreadthFirstSearch<TaintResult, Ta
public static boolean isArrival(TaintCFG cfg, BasicBlock suc, BasicBlock bb) { public static boolean isArrival(TaintCFG cfg, BasicBlock suc, BasicBlock bb) {
// Test // Test
/* /*
if(suc.blockID == bb.blockID) * if(suc.blockID == bb.blockID) return true; if(suc.blockID == 7 && bb.blockID == 11)
return true; * return true; if(suc.blockID == 9 && bb.blockID == 11) return true; if(suc.blockID == 7 &&
if(suc.blockID == 7 && bb.blockID == 11) * bb.blockID == 12) return true; if(suc.blockID == 9 && bb.blockID == 12) return true;
return true; * return false;
if(suc.blockID == 9 && bb.blockID == 11) */
return true;
if(suc.blockID == 7 && bb.blockID == 12)
return true;
if(suc.blockID == 9 && bb.blockID == 12)
return true;
return false;
*/
if (suc.blockID == bb.blockID) return true; if (suc.blockID == bb.blockID)
return true;
DirectGraphDFS dgDFS = new DirectGraphDFS(cfg, suc); DirectGraphDFS dgDFS = new DirectGraphDFS(cfg, suc);
return dgDFS.isArrival(bb); return dgDFS.isArrival(bb);
} }

View File

@ -33,11 +33,8 @@ public class NaiveTaintAnalysis extends BreadthFirstSearch<TaintResult, TaintBB>
setToAnalysis(toAnalysis); setToAnalysis(toAnalysis);
if (TaintConfig.isDebug) { if (TaintConfig.isDebug) {
System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc); System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc);
System.out.println( System.out.println("===Local:" + cfg.getMethodNode().maxLocals + " "
"===Local:" + cfg.getMethodNode().maxStack);
+ cfg.getMethodNode().maxLocals
+ " "
+ cfg.getMethodNode().maxStack);
} }
} }

View File

@ -6,26 +6,29 @@ import java.util.List;
import org.bdware.analysis.BasicBlock; import org.bdware.analysis.BasicBlock;
public abstract class BFS { public abstract class BFS {
protected List<BasicBlock> toAnalysis; protected List<BasicBlock> toAnalysis;
public abstract Collection<BasicBlock> getSuc(BasicBlock BB);
public void analysis() { public abstract Collection<BasicBlock> getSuc(BasicBlock BB);
BasicBlock current = null;
for (int i = 0; i < toAnalysis.size(); i++) { public void analysis() {
current = toAnalysis.get(i); BasicBlock current = null;
//current.setInList(false); for (int i = 0; i < toAnalysis.size(); i++) {
if(current.inList()) { current = toAnalysis.get(i);
Collection<BasicBlock> sucs = getSuc(current); // current.setInList(false);
for (BasicBlock next : sucs) { if (current.inList()) {
if (!next.inList()) { Collection<BasicBlock> sucs = getSuc(current);
toAnalysis.add(next); for (BasicBlock next : sucs) {
next.setInList(true); if (!next.inList()) {
} toAnalysis.add(next);
} next.setInList(true);
} }
} }
} }
public void setToAnalysis(List<BasicBlock> l) { }
toAnalysis = l; }
}
public void setToAnalysis(List<BasicBlock> l) {
toAnalysis = l;
}
} }

View File

@ -1 +1 @@
package org.bdware.analysis.gas; package org.bdware.analysis.gas;

View File

@ -12,215 +12,215 @@ import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.JumpInsnNode;
public class CountProgramPoint { public class CountProgramPoint {
public static HashMap<Integer, Map<String, Integer>> ppcount; public static HashMap<Integer, Map<String, Integer>> ppcount;
CFGraph actionCfg; CFGraph actionCfg;
private String bdName; private String bdName;
HashMap<String, CFGraph> cfgraphMap; HashMap<String, CFGraph> cfgraphMap;
String actionName; String actionName;
int globalPC; int globalPC;
public CountProgramPoint(HashMap<String, CFGraph> cfgMap, int startPc, int endPc, String aName, public CountProgramPoint(HashMap<String, CFGraph> cfgMap, int startPc, int endPc, String aName,
HashMap<Integer, Map<String, Integer>> ppc) { HashMap<Integer, Map<String, Integer>> ppc) {
ppcount = ppc; ppcount = ppc;
cfgraphMap = cfgMap; cfgraphMap = cfgMap;
actionName = aName; actionName = aName;
typeCount(startPc, endPc); typeCount(startPc, endPc);
} }
private HashMap<Integer, Map<String, Integer>> callCount(AbstractInsnNode insn) { private HashMap<Integer, Map<String, Integer>> callCount(AbstractInsnNode insn) {
if (insn instanceof InvokeDynamicInsnNode) { if (insn instanceof InvokeDynamicInsnNode) {
invoke = ((InvokeDynamicInsnNode) insn).bsmArgs[0]; invoke = ((InvokeDynamicInsnNode) insn).bsmArgs[0];
String functionName = ((InvokeDynamicInsnNode) insn).name; String functionName = ((InvokeDynamicInsnNode) insn).name;
dynCount(functionName); dynCount(functionName);
} else { } else {
normalCount(insn); normalCount(insn);
} }
return ppcount; return ppcount;
} }
Object invoke = 0; Object invoke = 0;
public HashMap<Integer, Map<String, Integer>> typeCount(int startPc, int endPc) { public HashMap<Integer, Map<String, Integer>> typeCount(int startPc, int endPc) {
if (startPc == 0) { if (startPc == 0) {
ppcount.put(startPc, new HashMap<>()); ppcount.put(startPc, new HashMap<>());
globalPC = startPc; globalPC = startPc;
} else { } else {
ppcount.put(endPc, new HashMap<>()); ppcount.put(endPc, new HashMap<>());
globalPC = endPc; globalPC = endPc;
} }
actionCfg = cfgraphMap.get(actionName); actionCfg = cfgraphMap.get(actionName);
int blockStart = 0, blockend = 0; int blockStart = 0, blockend = 0;
if (startPc == 0) { if (startPc == 0) {
blockStart = 0; blockStart = 0;
} else { } else {
OUT: for (int j = 0; j < actionCfg.getBasicBlockSize(); j++) { OUT: for (int j = 0; j < actionCfg.getBasicBlockSize(); j++) {
BasicBlock bb = actionCfg.getBasicBlockAt(j); BasicBlock bb = actionCfg.getBasicBlockAt(j);
AbstractInsnNode insnNode = bb.lastInsn(); AbstractInsnNode insnNode = bb.lastInsn();
if (insnNode instanceof InvokeDynamicInsnNode) { if (insnNode instanceof InvokeDynamicInsnNode) {
invoke = ((InvokeDynamicInsnNode) insnNode).bsmArgs[0]; invoke = ((InvokeDynamicInsnNode) insnNode).bsmArgs[0];
if ((int) invoke == startPc) { if ((int) invoke == startPc) {
blockStart = j; blockStart = j;
break OUT; break OUT;
} }
} }
} }
} }
OUT: for (int j = 0; j < actionCfg.getBasicBlockSize(); j++) { OUT: for (int j = 0; j < actionCfg.getBasicBlockSize(); j++) {
BasicBlock bb = actionCfg.getBasicBlockAt(j); BasicBlock bb = actionCfg.getBasicBlockAt(j);
AbstractInsnNode insnNode = bb.lastInsn(); AbstractInsnNode insnNode = bb.lastInsn();
if (insnNode instanceof InvokeDynamicInsnNode) { if (insnNode instanceof InvokeDynamicInsnNode) {
invoke = ((InvokeDynamicInsnNode) insnNode).bsmArgs[0]; invoke = ((InvokeDynamicInsnNode) insnNode).bsmArgs[0];
if ((int) invoke == endPc) { if ((int) invoke == endPc) {
blockend = j; blockend = j;
break OUT; break OUT;
} }
} }
} }
return getInsn(blockStart, blockend); return getInsn(blockStart, blockend);
} }
private HashMap<Integer, Map<String, Integer>> getInsn(int blockStart, int blockend) { private HashMap<Integer, Map<String, Integer>> getInsn(int blockStart, int blockend) {
BasicBlock t; BasicBlock t;
if (blockend == blockStart && blockStart != 0) { if (blockend == blockStart && blockStart != 0) {
System.out.println("blockend" + blockend); System.out.println("blockend" + blockend);
t = actionCfg.getBasicBlockAt(blockend); t = actionCfg.getBasicBlockAt(blockend);
if (t.list.size() > 0) { if (t.list.size() > 0) {
List<AbstractInsnNode> insnList = t.getInsn(); List<AbstractInsnNode> insnList = t.getInsn();
for (AbstractInsnNode insn : insnList) { for (AbstractInsnNode insn : insnList) {
if (insn instanceof InvokeDynamicInsnNode) { if (insn instanceof InvokeDynamicInsnNode) {
callCount(insn); callCount(insn);
} else if (insn instanceof JumpInsnNode) { } else if (insn instanceof JumpInsnNode) {
jumpCount(insn); jumpCount(insn);
} else { } else {
normalCount(insn); normalCount(insn);
} }
} }
} }
return ppcount; return ppcount;
} else if (blockend == 0) { } else if (blockend == 0) {
return ppcount; return ppcount;
} else if (blockend != blockStart && blockStart != 0) { } else if (blockend != blockStart && blockStart != 0) {
blockStart = blockStart + 1; blockStart = blockStart + 1;
blockend = blockend + 1; blockend = blockend + 1;
System.out.println(blockStart); System.out.println(blockStart);
} }
for (int i = blockStart; i < blockend; i++) { for (int i = blockStart; i < blockend; i++) {
t = actionCfg.getBasicBlockAt(i); t = actionCfg.getBasicBlockAt(i);
System.out.println("[t.blockID]" + t.blockID); System.out.println("[t.blockID]" + t.blockID);
if (t.list.size() > 0) { if (t.list.size() > 0) {
List<AbstractInsnNode> insnList = t.getInsn(); List<AbstractInsnNode> insnList = t.getInsn();
for (AbstractInsnNode insn : insnList) { for (AbstractInsnNode insn : insnList) {
if (insn != null) { if (insn != null) {
OpInfo info = null; OpInfo info = null;
if (insn.getOpcode() >= 0) { if (insn.getOpcode() >= 0) {
info = OpInfo.ops[insn.getOpcode()]; info = OpInfo.ops[insn.getOpcode()];
System.out.println("[info.toString()]" + info.toString()); System.out.println("[info.toString()]" + info.toString());
} }
if (info == null) { if (info == null) {
} else if (info.canThrow()) { } else if (info.canThrow()) {
callCount(insn); callCount(insn);
} else if (info.canBranch()) { } else if (info.canBranch()) {
jumpCount(insn); jumpCount(insn);
} else if (info.canContinue()) { } else if (info.canContinue()) {
normalCount(insn); normalCount(insn);
} else if (info.canReturn()) { } else if (info.canReturn()) {
normalCount(insn); normalCount(insn);
} else if (info.canSwitch()) { } else if (info.canSwitch()) {
normalCount(insn); normalCount(insn);
} else { } else {
System.out.println("[info:else]" + info); System.out.println("[info:else]" + info);
normalCount(insn); normalCount(insn);
} }
} }
} }
} }
} }
return ppcount; return ppcount;
} }
private void normalCount(AbstractInsnNode insn) { private void normalCount(AbstractInsnNode insn) {
bdName = FeeSchedule.BDInsn.name(); bdName = FeeSchedule.BDInsn.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} }
private void jumpCount(AbstractInsnNode insn) { private void jumpCount(AbstractInsnNode insn) {
bdName = FeeSchedule.BDjump.name(); bdName = FeeSchedule.BDjump.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} }
private void dynCount(String functionName) { private void dynCount(String functionName) {
if (functionName.contains("getProp")) { if (functionName.contains("getProp")) {
bdName = FeeSchedule.BDgetMethod.name(); bdName = FeeSchedule.BDgetMethod.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else if (functionName.contains("setProp")) { } else if (functionName.contains("setProp")) {
bdName = FeeSchedule.BDsetMethod.name(); bdName = FeeSchedule.BDsetMethod.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else if (functionName.contains("call") && functionName.contains("Util")) { } else if (functionName.contains("call") && functionName.contains("Util")) {
bdName = FeeSchedule.BDcallUtil.name(); bdName = FeeSchedule.BDcallUtil.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else if (functionName.contains("call") && isInnerfunction(functionName)) { } else if (functionName.contains("call") && isInnerfunction(functionName)) {
bdName = FeeSchedule.BDcallFuntion.name(); bdName = FeeSchedule.BDcallFuntion.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else if (functionName.contains("call")) { } else if (functionName.contains("call")) {
bdName = FeeSchedule.BDcallUtil.name(); bdName = FeeSchedule.BDcallUtil.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} else { } else {
bdName = FeeSchedule.BDInsn.name(); bdName = FeeSchedule.BDInsn.name();
if (ppcount.get(globalPC).containsKey(bdName)) { if (ppcount.get(globalPC).containsKey(bdName)) {
ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1); ppcount.get(globalPC).put(bdName, ppcount.get(globalPC).get(bdName) + 1);
} else { } else {
ppcount.get(globalPC).put(bdName, 1); ppcount.get(globalPC).put(bdName, 1);
} }
} }
} }
private boolean isInnerfunction(String functionName) { private boolean isInnerfunction(String functionName) {
String string = functionName.split(":")[2]; String string = functionName.split(":")[2];
if (cfgraphMap.containsKey(string)) { if (cfgraphMap.containsKey(string)) {
return true; return true;
} else { } else {
return false; return false;
} }
} }
} }

View File

@ -15,7 +15,8 @@ public abstract class DFS {
// System.out.println("[start.blockID]" + start.blockID); // System.out.println("[start.blockID]" + start.blockID);
Set<BasicBlock> sucBlocks = getSuc(start); Set<BasicBlock> sucBlocks = getSuc(start);
for (BasicBlock bb : sucBlocks) { for (BasicBlock bb : sucBlocks) {
if (!marked[bb.blockID]) dfs(cfg, bb); if (!marked[bb.blockID])
dfs(cfg, bb);
} }
} }

View File

@ -20,7 +20,7 @@ public class Evaluates {
long fee = getValue(cmap.getKey()); long fee = getValue(cmap.getKey());
value = fee * cmap.getValue() + value; value = fee * cmap.getValue() + value;
} }
CountResult.put(cfrKey, value); CountResult.put(cfrKey, value);
} }
return CountResult; return CountResult;
} }
@ -62,14 +62,14 @@ public class Evaluates {
Set<HashMap<String, Long>> set = new HashSet<>(); Set<HashMap<String, Long>> set = new HashSet<>();
public void getGas(HashMap<String, Set<Map<Integer, HashMap<String, Integer>>>> branchCount) { public void getGas(HashMap<String, Set<Map<Integer, HashMap<String, Integer>>>> branchCount) {
for (Entry<String, Set<Map<Integer, HashMap<String, Integer>>>> varInsn : for (Entry<String, Set<Map<Integer, HashMap<String, Integer>>>> varInsn : branchCount
branchCount.entrySet()) { .entrySet()) {
sum = 0; sum = 0;
for (Map<Integer, HashMap<String, Integer>> m : varInsn.getValue()) { for (Map<Integer, HashMap<String, Integer>> m : varInsn.getValue()) {
blockGas(m); blockGas(m);
}
map.put(varInsn.getKey(), sum);
} }
map.put(varInsn.getKey(), sum);
}
} }
private void blockGas(Map<Integer, HashMap<String, Integer>> m) { private void blockGas(Map<Integer, HashMap<String, Integer>> m) {
@ -84,13 +84,13 @@ public class Evaluates {
public static HashMap<String, Long> map = new HashMap<>(); public static HashMap<String, Long> map = new HashMap<>();
public void getInsnGas(Map<Integer, Set<Map<Integer, HashMap<String, Integer>>>> ppMap) { public void getInsnGas(Map<Integer, Set<Map<Integer, HashMap<String, Integer>>>> ppMap) {
for (Entry<Integer, Set<Map<Integer, HashMap<String, Integer>>>> varInsn : for (Entry<Integer, Set<Map<Integer, HashMap<String, Integer>>>> varInsn : ppMap
ppMap.entrySet()) { .entrySet()) {
sum = 0; sum = 0;
for (Map<Integer, HashMap<String, Integer>> m : varInsn.getValue()) { for (Map<Integer, HashMap<String, Integer>> m : varInsn.getValue()) {
blockGas(m); blockGas(m);
} }
map.put(varInsn.getKey().toString(), sum); map.put(varInsn.getKey().toString(), sum);
} }
} }
} }

View File

@ -1,51 +1,52 @@
package org.bdware.analysis.gas; package org.bdware.analysis.gas;
public enum FeeSchedule { public enum FeeSchedule {
// BDaload(20L),BDstore(200L), // BDaload(20L),BDstore(200L),
BDgetMethod(10L), BDsetMethod(20L), BDnew(20L),BDcallUtil(30L), BDcallFuntion(40L), BDcall(10L), BDjump(15L), BDInsn(1L); BDgetMethod(10L), BDsetMethod(20L), BDnew(20L), BDcallUtil(30L), BDcallFuntion(40L), BDcall(
10L), BDjump(15L), BDInsn(1L);
long fee; long fee;
FeeSchedule(long value) { FeeSchedule(long value) {
fee = value; fee = value;
} }
public long getFee() { public long getFee() {
return fee; return fee;
} }
public long getValue(String name) { public long getValue(String name) {
long value=0; long value = 0;
switch (name) { switch (name) {
case "BDgetMethod": case "BDgetMethod":
value=BDgetMethod.getFee(); value = BDgetMethod.getFee();
break; break;
case "BDsetMethod": case "BDsetMethod":
value= BDsetMethod.getFee(); value = BDsetMethod.getFee();
break; break;
case "BDcallUtil": case "BDcallUtil":
value= BDcallUtil.getFee(); value = BDcallUtil.getFee();
break; break;
case "BDcallFuntion": case "BDcallFuntion":
value= BDcallFuntion.getFee(); value = BDcallFuntion.getFee();
break; break;
case "BDcall": case "BDcall":
value= BDcall.getFee(); value = BDcall.getFee();
break; break;
case "BDjump": case "BDjump":
value= BDjump.getFee(); value = BDjump.getFee();
break; break;
case "BDInsn": case "BDInsn":
value= BDInsn.getFee(); value = BDInsn.getFee();
break; break;
default: default:
break; break;
} }
return value; return value;
} }
public String getString(FeeSchedule feeName) { public String getString(FeeSchedule feeName) {
return feeName.toString(); return feeName.toString();
} }
} }

View File

@ -11,12 +11,8 @@ import java.util.Set;
import org.bdware.analysis.BasicBlock; import org.bdware.analysis.BasicBlock;
import org.bdware.analysis.CFGraph; import org.bdware.analysis.CFGraph;
import org.bdware.analysis.OpInfo; import org.bdware.analysis.OpInfo;
import org.bdware.analysis.gas.DFS;
import org.bdware.analysis.gas.FeeSchedule;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode; import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode; import org.objectweb.asm.tree.LabelNode;
@ -49,7 +45,7 @@ public class PPCount extends DFS {
BasicBlock b = cfg.getBasicBlockAt(0); BasicBlock b = cfg.getBasicBlockAt(0);
toAnalysis.add(b); toAnalysis.add(b);
b.setInList(true); b.setInList(true);
// System.out.println("=========:"+cfg.getMethodNode().name); // System.out.println("=========:"+cfg.getMethodNode().name);
functionList.add(cfg.getMethodNode().name); functionList.add(cfg.getMethodNode().name);
isBranchBlock = new boolean[cfg.getBasicBlockSize()]; isBranchBlock = new boolean[cfg.getBasicBlockSize()];
// setToAnalysis(toAnalysis); // setToAnalysis(toAnalysis);
@ -302,44 +298,42 @@ public class PPCount extends DFS {
if (function.contains("getProp")) { if (function.contains("getProp")) {
bdName = FeeSchedule.BDgetMethod.name(); bdName = FeeSchedule.BDgetMethod.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID) BlockInsn.get(globalBlockID).put(bdName,
.put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1); BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (function.contains("setProp")) { } else if (function.contains("setProp")) {
bdName = FeeSchedule.BDsetMethod.name(); bdName = FeeSchedule.BDsetMethod.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID) BlockInsn.get(globalBlockID).put(bdName,
.put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1); BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (function.contains("new")) { } else if (function.contains("new")) {
bdName = FeeSchedule.BDnew.name(); bdName = FeeSchedule.BDnew.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID) BlockInsn.get(globalBlockID).put(bdName,
.put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1); BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (function.contains("call") && functionName.split(":")[2].contains("Util")) { } else if (function.contains("call") && functionName.split(":")[2].contains("Util")) {
bdName = FeeSchedule.BDcallUtil.name(); bdName = FeeSchedule.BDcallUtil.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID) BlockInsn.get(globalBlockID).put(bdName,
.put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1); BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (function.contains("call") && isInnerfunction(functionName)) { } else if (function.contains("call") && isInnerfunction(functionName)) {
// System.out.println("[call ]" + functionName); // System.out.println("[call ]" + functionName);
String methName = functionName.split(":")[2]; String methName = functionName.split(":")[2];
bdName = FeeSchedule.BDcallFuntion.name(); bdName = FeeSchedule.BDcallFuntion.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID) BlockInsn.get(globalBlockID).put(bdName + "," + methName,
.put( BlockInsn.get(globalBlockID).get(bdName + "," + methName) + 1);
bdName + "," + methName,
BlockInsn.get(globalBlockID).get(bdName + "," + methName) + 1);
System.out.println(" function " + functionName); System.out.println(" function " + functionName);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName + "," + methName, 1); BlockInsn.get(globalBlockID).put(bdName + "," + methName, 1);
@ -348,16 +342,16 @@ public class PPCount extends DFS {
} else if (function.contains("call")) { } else if (function.contains("call")) {
bdName = FeeSchedule.BDcall.name(); bdName = FeeSchedule.BDcall.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID) BlockInsn.get(globalBlockID).put(bdName,
.put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1); BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
} else if (functionName.contains("traceif")) { } else if (functionName.contains("traceif")) {
bdName = FeeSchedule.BDjump.name(); bdName = FeeSchedule.BDjump.name();
if (BlockInsn.get(globalBlockID).containsKey(bdName)) { if (BlockInsn.get(globalBlockID).containsKey(bdName)) {
BlockInsn.get(globalBlockID) BlockInsn.get(globalBlockID).put(bdName,
.put(bdName, BlockInsn.get(globalBlockID).get(bdName) + 1); BlockInsn.get(globalBlockID).get(bdName) + 1);
} else { } else {
BlockInsn.get(globalBlockID).put(bdName, 1); BlockInsn.get(globalBlockID).put(bdName, 1);
} }
@ -366,8 +360,8 @@ public class PPCount extends DFS {
private boolean isInnerfunction(String functionName) { private boolean isInnerfunction(String functionName) {
String string = functionName.split(":")[2]; String string = functionName.split(":")[2];
// System.out.println("++++++++++++++" + functionName); // System.out.println("++++++++++++++" + functionName);
// System.out.println("【function】" + functionList); // System.out.println("【function】" + functionList);
if (functionList.contains(string)) { if (functionList.contains(string)) {
return true; return true;
} else { } else {
@ -375,57 +369,57 @@ public class PPCount extends DFS {
} }
} }
// public static void main(String[] args) throws Exception { // public static void main(String[] args) throws Exception {
// String path = "/Users/hulingxuan/git/SmartContract/output/main.yjs"; // String path = "/Users/hulingxuan/git/SmartContract/output/main.yjs";
// ContractNode contractNode = null; // ContractNode contractNode = null;
// YJSCompiler compiler = new YJSCompiler(); // YJSCompiler compiler = new YJSCompiler();
// contractNode = compiler.compile(new FileInputStream(path), null); // contractNode = compiler.compile(new FileInputStream(path), null);
// engine = new DesktopEngine(); // engine = new DesktopEngine();
// engine.loadContract(contractNode, false); // engine.loadContract(contractNode, false);
// //
// Map<String, byte[]> clzs = engine.dumpClass(); // Map<String, byte[]> clzs = engine.dumpClass();
// Map<String, MethodNode> methods = new HashMap<>(); // Map<String, MethodNode> methods = new HashMap<>();
// for (byte[] clz : clzs.values()) { // for (byte[] clz : clzs.values()) {
// ClassNode classNode = new ClassNode(); // ClassNode classNode = new ClassNode();
// ClassReader cr = new ClassReader(clz); // ClassReader cr = new ClassReader(clz);
// cr.accept(classNode, ClassReader.EXPAND_FRAMES); // cr.accept(classNode, ClassReader.EXPAND_FRAMES);
// for (MethodNode mn : classNode.methods) { // for (MethodNode mn : classNode.methods) {
// methods.put(mn.name, mn); // methods.put(mn.name, mn);
// } // }
// } // }
// int flag = 0; // int flag = 0;
// for (FunctionNode fn : contractNode.getFunctions()) { // for (FunctionNode fn : contractNode.getFunctions()) {
// functionList.add(fn.functionName); // functionList.add(fn.functionName);
// MethodNode mn = methods.get(fn.functionName); // MethodNode mn = methods.get(fn.functionName);
// if (mn != null) { // if (mn != null) {
// CFGraph cfg = new CFGraph(mn) { // CFGraph cfg = new CFGraph(mn) {
// @Override // @Override
// public BasicBlock getBasicBlock(int id) { // public BasicBlock getBasicBlock(int id) {
// return new BasicBlock(id); // return new BasicBlock(id);
// } // }
// }; // };
// // cfg.getLabelOrder(); // // cfg.getLabelOrder();
// PPCount countFee = new PPCount(cfg, flag); // PPCount countFee = new PPCount(cfg, flag);
// //
// BasicBlock bb = cfg.getBasicBlockAt(0); // BasicBlock bb = cfg.getBasicBlockAt(0);
// countFee.dfs(cfg, bb); // countFee.dfs(cfg, bb);
// // cfg.printSelf(); // // cfg.printSelf();
// //
// Evaluates feEvaluates = new Evaluates(); // Evaluates feEvaluates = new Evaluates();
// feEvaluates.getGas(branchCount); // feEvaluates.getGas(branchCount);
// feEvaluates.getInsnGas(ppMap); // feEvaluates.getInsnGas(ppMap);
// countFunction(fn.functionName, Evaluates.map); // countFunction(fn.functionName, Evaluates.map);
// System.out.println("+++++++" + functionSumGas); // System.out.println("+++++++" + functionSumGas);
// System.out.println("========" + Evaluates.map); // System.out.println("========" + Evaluates.map);
// flag++; // flag++;
// } // }
// } // }
// System.out.println(branchCount); // System.out.println(branchCount);
// System.out.println(BlockInsn); // System.out.println(BlockInsn);
// System.out.println(ppMap); // System.out.println(ppMap);
// //
// // System.out.println(feEvaluates.getCallFee()); // // System.out.println(feEvaluates.getCallFee());
// } // }
public static HashMap<String, Long> functionSumGas = new HashMap<>(); public static HashMap<String, Long> functionSumGas = new HashMap<>();

View File

@ -5,24 +5,24 @@ import java.util.Set;
import org.bdware.analysis.BasicBlock; import org.bdware.analysis.BasicBlock;
public class DirectGraphDFS { public class DirectGraphDFS {
private boolean[] marked; private boolean[] marked;
public DirectGraphDFS(TaintCFG cfg, BasicBlock start) { public DirectGraphDFS(TaintCFG cfg, BasicBlock start) {
marked = new boolean[cfg.getBlocks().size()]; marked = new boolean[cfg.getBlocks().size()];
dfs(cfg, start); dfs(cfg, start);
} }
private void dfs(TaintCFG cfg, BasicBlock start) { private void dfs(TaintCFG cfg, BasicBlock start) {
marked[start.blockID] = true; marked[start.blockID] = true;
Set<BasicBlock> sucBlocks = cfg.getSucBlocks(start); Set<BasicBlock> sucBlocks = cfg.getSucBlocks(start);
for(BasicBlock bb : sucBlocks) { for (BasicBlock bb : sucBlocks) {
if(!marked[bb.blockID]) if (!marked[bb.blockID])
dfs(cfg, bb); dfs(cfg, bb);
} }
} }
public boolean isArrival(BasicBlock end) { public boolean isArrival(BasicBlock end) {
return marked[end.blockID]; return marked[end.blockID];
} }
} }

View File

@ -11,237 +11,240 @@ import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode; import org.objectweb.asm.tree.InvokeDynamicInsnNode;
public class HeapObject extends TaintValue { public class HeapObject extends TaintValue {
private Map<String, TaintValue> fields = new HashMap<String, TaintValue>(); private Map<String, TaintValue> fields = new HashMap<String, TaintValue>();
static int allocatID = 0; static int allocatID = 0;
int id; int id;
public HeapObject() { public HeapObject() {
super(1); super(1);
id = allocatID++; id = allocatID++;
} }
public HeapObject(TaintValue t) { public HeapObject(TaintValue t) {
this(); this();
if (t != null) { if (t != null) {
merge(t); merge(t);
size = t.size; size = t.size;
} else { } else {
isTainted = 0; isTainted = 0;
size = 1; size = 1;
} }
} }
public static HeapObject getRootObject() { public static HeapObject getRootObject() {
HeapObject ret = new HeapObject(); HeapObject ret = new HeapObject();
ret.setProp("Global", new HeapObject()); ret.setProp("Global", new HeapObject());
ret.setProp("getScope", new HeapObject()); ret.setProp("getScope", new HeapObject());
return ret; return ret;
} }
@Override @Override
public String toString() { public String toString() {
return countSize() + "|" + super.toString(); return countSize() + "|" + super.toString();
} }
private String countSize() { private String countSize() {
objSet = new HashSet<>(); objSet = new HashSet<>();
return countSizeInternal(); return countSizeInternal();
} }
private String countSizeInternal() { private String countSizeInternal() {
if (objSet.contains(this)) if (objSet.contains(this))
return "{H" + id + "}"; return "{H" + id + "}";
objSet.add(this); objSet.add(this);
String ret = "{H" + id + ","; String ret = "{H" + id + ",";
for (String field : fields.keySet()) { for (String field : fields.keySet()) {
TaintValue tv = fields.get(field); TaintValue tv = fields.get(field);
if (tv instanceof HeapObject) if (tv instanceof HeapObject)
ret += field + ":" + ((HeapObject) tv).countSizeInternal() + ","; ret += field + ":" + ((HeapObject) tv).countSizeInternal() + ",";
else else
ret += field + ":" + tv.isTainted; ret += field + ":" + tv.isTainted;
} }
ret += isTainted + "}"; ret += isTainted + "}";
return ret; return ret;
} }
private static HashSet<HeapObject> objSet; private static HashSet<HeapObject> objSet;
public static TaintValue operate(AbstractInsnNode insn, List<? extends TaintValue> values, public static TaintValue operate(AbstractInsnNode insn, List<? extends TaintValue> values,
TaintValue calculatedVal) { TaintValue calculatedVal) {
TaintValue retVal = null; TaintValue retVal = null;
String desc; String desc;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case Opcodes.INVOKEVIRTUAL: case Opcodes.INVOKEVIRTUAL:
desc = ((MethodInsnNode) insn).owner; desc = ((MethodInsnNode) insn).owner;
if (isGetScopeObject((MethodInsnNode) insn) && values.size() != 0) { if (isGetScopeObject((MethodInsnNode) insn) && values.size() != 0) {
TaintValue tv = values.get(0); TaintValue tv = values.get(0);
if (tv instanceof HeapObject) { if (tv instanceof HeapObject) {
HeapObject heapObject = (HeapObject) tv; HeapObject heapObject = (HeapObject) tv;
retVal = heapObject.getProp("getScope"); retVal = heapObject.getProp("getScope");
if (retVal == null) { if (retVal == null) {
return calculatedVal; return calculatedVal;
} else } else
return retVal; return retVal;
} }
} }
break; break;
case Opcodes.INVOKESPECIAL: case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKESTATIC: case Opcodes.INVOKESTATIC:
case Opcodes.INVOKEINTERFACE: case Opcodes.INVOKEINTERFACE:
break; break;
case Opcodes.INVOKEDYNAMIC: case Opcodes.INVOKEDYNAMIC:
desc = ((InvokeDynamicInsnNode) insn).name; desc = ((InvokeDynamicInsnNode) insn).name;
desc = desc.replaceAll(".*:", ""); desc = desc.replaceAll(".*:", "");
if (isDynGet((InvokeDynamicInsnNode) insn)) { if (isDynGet((InvokeDynamicInsnNode) insn)) {
TaintValue tval = values.get(0); TaintValue tval = values.get(0);
if (tval instanceof HeapObject) { if (tval instanceof HeapObject) {
HeapObject heapObject = (HeapObject) tval; HeapObject heapObject = (HeapObject) tval;
retVal = heapObject.getProp(desc); retVal = heapObject.getProp(desc);
if (retVal != null) { if (retVal != null) {
if (TaintConfig.isDebug) if (TaintConfig.isDebug)
System.out.println("[HeapObject] get:" + desc + " taintVal:" + retVal); System.out.println(
return retVal; "[HeapObject] get:" + desc + " taintVal:" + retVal);
} else { return retVal;
if (TaintConfig.isDebug) } else {
System.out.println("[HeapObject] get:" + desc + " taintVal: empty"); if (TaintConfig.isDebug)
heapObject.setProp(desc, new HeapObject()); System.out.println("[HeapObject] get:" + desc + " taintVal: empty");
return heapObject.getProp(desc); heapObject.setProp(desc, new HeapObject());
} return heapObject.getProp(desc);
} else { }
// TODO } else {
} // TODO
} else if (isDynSet((InvokeDynamicInsnNode) insn)) { }
// TaintValue tv = values.get(0); } else if (isDynSet((InvokeDynamicInsnNode) insn)) {
if (TaintConfig.isDebug) // TaintValue tv = values.get(0);
System.out.println("[HeapObject] set:" + desc + " taintVal:" + values.get(1)); if (TaintConfig.isDebug)
TaintValue tval = values.get(0); System.out
if (tval instanceof HeapObject) { .println("[HeapObject] set:" + desc + " taintVal:" + values.get(1));
HeapObject heapObject = (HeapObject) tval; TaintValue tval = values.get(0);
// heapObject.merge(values.get(1)); if (tval instanceof HeapObject) {
heapObject.setProp(desc, HeapObject heapObject = (HeapObject) tval;
values.get(1) instanceof HeapObject ? values.get(1) : new HeapObject(values.get(1))); // heapObject.merge(values.get(1));
} else { heapObject.setProp(desc, values.get(1) instanceof HeapObject ? values.get(1)
HeapObject heapObject = new HeapObject(tval); : new HeapObject(values.get(1)));
heapObject.merge(tval); } else {
// heapObject.merge(values.get(1)); HeapObject heapObject = new HeapObject(tval);
heapObject.setProp(desc, values.get(1)); heapObject.merge(tval);
} // heapObject.merge(values.get(1));
} else { heapObject.setProp(desc, values.get(1));
for (TaintValue tv : values) { }
if (tv instanceof HeapObject) { } else {
calculatedVal.isTainted |= ((HeapObject) tv).wholeTaint(); for (TaintValue tv : values) {
} if (tv instanceof HeapObject) {
} calculatedVal.isTainted |= ((HeapObject) tv).wholeTaint();
} }
break; }
default: }
} break;
return calculatedVal; default:
}
return calculatedVal;
} }
private static boolean isDynGet(InvokeDynamicInsnNode insn) { private static boolean isDynGet(InvokeDynamicInsnNode insn) {
String desc = insn.name; String desc = insn.name;
if (desc.contains("getProp") && desc.contains("getMethod") && desc.contains("getElem")) { if (desc.contains("getProp") && desc.contains("getMethod") && desc.contains("getElem")) {
return true; return true;
} }
return false; return false;
} }
private static boolean isDynSet(InvokeDynamicInsnNode insn) { private static boolean isDynSet(InvokeDynamicInsnNode insn) {
String desc = insn.name; String desc = insn.name;
if (desc.contains("setProp") && desc.contains("setElem")) { if (desc.contains("setProp") && desc.contains("setElem")) {
// System.out.println(desc); // System.out.println(desc);
return true; return true;
} }
return false; return false;
} }
private static boolean isGetScopeObject(MethodInsnNode insn) { private static boolean isGetScopeObject(MethodInsnNode insn) {
if (insn.owner.contains("wrp/jdk/nashorn/internal/runtime/ScriptFunction") && insn.name.equals("getScope")) if (insn.owner.contains("wrp/jdk/nashorn/internal/runtime/ScriptFunction")
return true; && insn.name.equals("getScope"))
return false; return true;
} return false;
}
public TaintValue getProp(String str) { public TaintValue getProp(String str) {
return fields.get(str); return fields.get(str);
} }
public TaintValue setProp(String str, TaintValue val) { public TaintValue setProp(String str, TaintValue val) {
return fields.put(str, val); return fields.put(str, val);
} }
@Override @Override
public HeapObject clone() { public HeapObject clone() {
return this; return this;
} }
public HeapObject actualClone() { public HeapObject actualClone() {
ccObj = new HashMap<>(); ccObj = new HashMap<>();
return cloneInternal(); return cloneInternal();
} }
static Map<HeapObject, HeapObject> ccObj; static Map<HeapObject, HeapObject> ccObj;
private HeapObject cloneInternal() { private HeapObject cloneInternal() {
if (ccObj.containsKey(this)) if (ccObj.containsKey(this))
return ccObj.get(this); return ccObj.get(this);
HeapObject ho = new HeapObject(); HeapObject ho = new HeapObject();
ccObj.put(this, ho); ccObj.put(this, ho);
ho.isTainted = isTainted; ho.isTainted = isTainted;
for (String field : fields.keySet()) { for (String field : fields.keySet()) {
TaintValue target = fields.get(field); TaintValue target = fields.get(field);
if (target instanceof HeapObject) if (target instanceof HeapObject)
ho.fields.put(field, ((HeapObject) target).cloneInternal()); ho.fields.put(field, ((HeapObject) target).cloneInternal());
else else
ho.fields.put(field, target.clone()); ho.fields.put(field, target.clone());
} }
return ho; return ho;
} }
// TODO consider the "Cite circle" // TODO consider the "Cite circle"
public void heapMerge(TaintValue target) { public void heapMerge(TaintValue target) {
merge(target); merge(target);
if (target instanceof HeapObject) { if (target instanceof HeapObject) {
HeapObject targetObject = (HeapObject) target; HeapObject targetObject = (HeapObject) target;
for (String field : targetObject.fields.keySet()) { for (String field : targetObject.fields.keySet()) {
if (fields.containsKey(field)) { if (fields.containsKey(field)) {
TaintValue t2 = fields.get(field); TaintValue t2 = fields.get(field);
TaintValue target2 = targetObject.fields.get(field); TaintValue target2 = targetObject.fields.get(field);
// System.out.println("[HeapObject heapMerge]:" + field); // System.out.println("[HeapObject heapMerge]:" + field);
if (t2 instanceof HeapObject) { if (t2 instanceof HeapObject) {
((HeapObject) t2).heapMerge(target2); ((HeapObject) t2).heapMerge(target2);
} else if (target2 instanceof HeapObject) { } else if (target2 instanceof HeapObject) {
HeapObject next = ((HeapObject) target2).clone(); HeapObject next = ((HeapObject) target2).clone();
next.merge(t2); next.merge(t2);
fields.put(field, next); fields.put(field, next);
} else } else
t2.merge(target2); t2.merge(target2);
} else } else
fields.put(field, targetObject.fields.get(field).clone()); fields.put(field, targetObject.fields.get(field).clone());
} }
} }
} }
public synchronized long wholeTaint() { public synchronized long wholeTaint() {
objSet = new HashSet<>(); objSet = new HashSet<>();
return wholeTaintInternal(); return wholeTaintInternal();
} }
private long wholeTaintInternal() { private long wholeTaintInternal() {
if (objSet.contains(this)) if (objSet.contains(this))
return 0L; return 0L;
objSet.add(this); objSet.add(this);
long ret = isTainted; long ret = isTainted;
for (TaintValue tv : fields.values()) { for (TaintValue tv : fields.values()) {
if (tv instanceof HeapObject) if (tv instanceof HeapObject)
ret |= ((HeapObject) tv).wholeTaintInternal(); ret |= ((HeapObject) tv).wholeTaintInternal();
else else
ret |= tv.isTainted; ret |= tv.isTainted;
} }
return ret; return ret;
} }
} }

View File

@ -7,64 +7,68 @@ import org.bdware.analysis.BasicBlock;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
public class TaintBB extends BasicBlock implements AnalysisTarget { public class TaintBB extends BasicBlock implements AnalysisTarget {
boolean inList = false; boolean inList = false;
public TaintBB(int id) { public TaintBB(int id) {
super(id); super(id);
preResult = new TaintResult(); preResult = new TaintResult();
sucResult = new TaintResult(); sucResult = new TaintResult();
} }
public TaintResult preResult; public TaintResult preResult;
public TaintResult sucResult; public TaintResult sucResult;
@Override @Override
public boolean inList() { public boolean inList() {
return inList; return inList;
} }
@Override @Override
public void setInList(boolean b) { public void setInList(boolean b) {
inList = b; inList = b;
} }
public String getResult() {
return (sucResult.frame2Str() + " Ret:" + sucResult.ret.toString());
}
public String getResultWithTaintBit() { public String getResult() {
return "Ret:" + sucResult.ret.toReadableTaint(); return (sucResult.frame2Str() + " Ret:" + sucResult.ret.toString());
} }
public TaintResult forwardAnalysis() { public String getResultWithTaintBit() {
TaintResult oldSuc = sucResult; return "Ret:" + sucResult.ret.toReadableTaint();
sucResult = (TaintResult) preResult.clone(); }
TaintResult currentResult = sucResult;
List<AbstractInsnNode> insns = getInsn();
if (TaintConfig.isDebug)
System.out.println("[TaintBB] Enter B" + blockID + ":" + getResult() + " size:" + insns.size());
for (int i = 0; i < insns.size(); i++) { public TaintResult forwardAnalysis() {
currentResult = (TaintResult) currentResult.merge(insns.get(i)); TaintResult oldSuc = sucResult;
} sucResult = (TaintResult) preResult.clone();
currentResult.mergeResult(oldSuc); TaintResult currentResult = sucResult;
List<AbstractInsnNode> insns = getInsn();
if (TaintConfig.isDebug)
System.out.println(
"[TaintBB] Enter B" + blockID + ":" + getResult() + " size:" + insns.size());
if (TaintConfig.isDebug) for (int i = 0; i < insns.size(); i++) {
System.out.println("[TaintBB] Leave B" + blockID + ":" + getResult() + " size:" + insns.size()); currentResult = (TaintResult) currentResult.merge(insns.get(i));
// already done. }
return currentResult; currentResult.mergeResult(oldSuc);
}
if (TaintConfig.isDebug)
System.out.println(
"[TaintBB] Leave B" + blockID + ":" + getResult() + " size:" + insns.size());
// already done.
return currentResult;
}
public AbstractInsnNode lastInsn() {
return list.get(list.size() - 1);
}
public AbstractInsnNode firstInsn() {
return list.get(0);
}
public List<AbstractInsnNode> AllInsn() {
return list;
}
public AbstractInsnNode lastInsn() {
return list.get(list.size() - 1);
}
public AbstractInsnNode firstInsn() {
return list.get(0);
}
public List<AbstractInsnNode> AllInsn() {
return list;
}
} }

View File

@ -4,65 +4,65 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class TaintBits { public class TaintBits {
Map<Long, String> data; Map<Long, String> data;
Map<String, Long> type2Taint; Map<String, Long> type2Taint;
long curr; long curr;
Map<String, String> reallocate; Map<String, String> reallocate;
int count = 0; int count = 0;
public TaintBits() { public TaintBits() {
curr = 1L; curr = 1L;
data = new HashMap<>(); data = new HashMap<>();
type2Taint = new HashMap<>(); type2Taint = new HashMap<>();
reallocate = new HashMap<>(); reallocate = new HashMap<>();
} }
public long allocate(String type) { public long allocate(String type) {
type = reallocateCall(type); type = reallocateCall(type);
if (type2Taint.containsKey(type)) if (type2Taint.containsKey(type))
return type2Taint.get(type); return type2Taint.get(type);
long ret = curr; long ret = curr;
data.put(curr, type); data.put(curr, type);
type2Taint.put(type, curr); type2Taint.put(type, curr);
curr <<= 1; curr <<= 1;
return ret; return ret;
} }
private String reallocateCall(String type) { private String reallocateCall(String type) {
if (reallocate.containsKey(type)) if (reallocate.containsKey(type))
return reallocate.get(type); return reallocate.get(type);
if (type.contains("dyn:call:executeContract")) { if (type.contains("dyn:call:executeContract")) {
reallocate.put(type, "executeContract" + (count++)); reallocate.put(type, "executeContract" + (count++));
return reallocate.get(type); return reallocate.get(type);
} }
return type; return type;
} }
public long getTaintValue(String type) { public long getTaintValue(String type) {
type = reallocateCall(type); type = reallocateCall(type);
if (type2Taint.containsKey(type)) if (type2Taint.containsKey(type))
return type2Taint.get(type); return type2Taint.get(type);
return -1; return -1;
} }
public String taintInfo() { public String taintInfo() {
String ret = ""; String ret = "";
long curr = this.curr >> 1; long curr = this.curr >> 1;
for (; curr >= 1L;) { for (; curr >= 1L;) {
ret += data.get(curr) + ", "; ret += data.get(curr) + ", ";
curr >>= 1; curr >>= 1;
} }
return ret; return ret;
} }
public String parse(long isTainted) { public String parse(long isTainted) {
String ret = ""; String ret = "";
long curr = this.curr >> 1; long curr = this.curr >> 1;
for (; curr >= 1L;) { for (; curr >= 1L;) {
if ((isTainted & curr) != 0) if ((isTainted & curr) != 0)
ret += data.get(curr) + " "; ret += data.get(curr) + " ";
curr >>= 1; curr >>= 1;
} }
return ret; return ret;
} }
} }

View File

@ -11,74 +11,75 @@ import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
public class TaintCFG extends CFGraph { public class TaintCFG extends CFGraph {
public TaintBits taintBits; public TaintBits taintBits;
public TaintCFG(MethodNode mn) { public TaintCFG(MethodNode mn) {
super(mn); super(mn);
taintBits = new TaintBits(); taintBits = new TaintBits();
} }
@Override @Override
public BasicBlock getBasicBlock(int id) { public BasicBlock getBasicBlock(int id) {
return new TaintBB(id); return new TaintBB(id);
} }
public int argsLocal() { public int argsLocal() {
String desc = getMethodNode().desc; String desc = getMethodNode().desc;
String[] parameters = desc.split("[)]"); String[] parameters = desc.split("[)]");
String parameter = parameters[0]; String parameter = parameters[0];
String[] args = parameter.split("[;]"); String[] args = parameter.split("[;]");
return args.length - 1; return args.length - 1;
} }
public void executeLocal() { public void executeLocal() {
for (BasicBlock bb : basicBlocks) { for (BasicBlock bb : basicBlocks) {
for (AbstractInsnNode an : bb.getInsn()) { for (AbstractInsnNode an : bb.getInsn()) {
if (an instanceof InvokeDynamicInsnNode) { if (an instanceof InvokeDynamicInsnNode) {
InvokeDynamicInsnNode inDy = (InvokeDynamicInsnNode) an; InvokeDynamicInsnNode inDy = (InvokeDynamicInsnNode) an;
if (inDy.name.contains("dyn:call:executeContract")) { if (inDy.name.contains("dyn:call:executeContract")) {
taintBits.allocate(inDy.name + inDy.hashCode()); taintBits.allocate(inDy.name + inDy.hashCode());
} }
} }
} }
} }
return; return;
} }
public void printSelf() { public void printSelf() {
InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out); InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out);
printer.setLabelOrder(getLabelOrder()); printer.setLabelOrder(getLabelOrder());
System.out.println("======Method:" + getMethodNode().name + getMethodNode().desc + "======="); System.out
System.out.println("=====TaintInfo: " + taintBits.taintInfo() + "==========="); .println("======Method:" + getMethodNode().name + getMethodNode().desc + "=======");
for (BasicBlock bb : basicBlocks) { System.out.println("=====TaintInfo: " + taintBits.taintInfo() + "===========");
System.out.print("==B" + bb.blockID); for (BasicBlock bb : basicBlocks) {
if (getSucBlocks(bb).size() > 0) System.out.print("==B" + bb.blockID);
System.out.print("-->"); if (getSucBlocks(bb).size() > 0)
for (BasicBlock suc : getSucBlocks(bb)) System.out.print("-->");
System.out.print(" B" + suc.blockID); for (BasicBlock suc : getSucBlocks(bb))
System.out.println("=="); System.out.print(" B" + suc.blockID);
TaintBB b = (TaintBB) bb; System.out.println("==");
if (b.preResult != null) { TaintBB b = (TaintBB) bb;
System.out.print("前序分析结果:"); if (b.preResult != null) {
b.preResult.printResult(); System.out.print("前序分析结果:");
//System.out.println("test:"+b.getResultWithTaintBit()); b.preResult.printResult();
} // System.out.println("test:"+b.getResultWithTaintBit());
}
for (AbstractInsnNode an : bb.getInsn()) { for (AbstractInsnNode an : bb.getInsn()) {
an.accept(printer); an.accept(printer);
} }
} }
} }
public TaintBB getLastBlock() { public TaintBB getLastBlock() {
if (basicBlocks != null && basicBlocks.size() > 0) if (basicBlocks != null && basicBlocks.size() > 0)
return (TaintBB) basicBlocks.get(basicBlocks.size() - 1); return (TaintBB) basicBlocks.get(basicBlocks.size() - 1);
return null; return null;
} }
public List<BasicBlock> getBlocks() { public List<BasicBlock> getBlocks() {
return basicBlocks; return basicBlocks;
} }
} }

View File

@ -1,5 +1,5 @@
package org.bdware.analysis.taint; package org.bdware.analysis.taint;
public class TaintConfig { public class TaintConfig {
public static boolean isDebug = false; public static boolean isDebug = false;
} }

View File

@ -12,166 +12,172 @@ import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.Interpreter; import org.objectweb.asm.tree.analysis.Interpreter;
public class TaintInterpreter extends Interpreter<TaintValue> { public class TaintInterpreter extends Interpreter<TaintValue> {
TaintResult currentResult; TaintResult currentResult;
TaintBits taintBits; TaintBits taintBits;
public TaintInterpreter(int api) { public TaintInterpreter(int api) {
super(api); super(api);
} }
@Override @Override
public TaintValue newValue(Type type) { public TaintValue newValue(Type type) {
if (type != null) if (type != null)
return new TaintValue(type.getSize()); return new TaintValue(type.getSize());
return new TaintValue(1); return new TaintValue(1);
} }
@Override @Override
public TaintValue newOperation(AbstractInsnNode insn) throws AnalyzerException { public TaintValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
TaintValue ret; TaintValue ret;
switch (insn.getOpcode()) { switch (insn.getOpcode()) {
case Opcodes.LCONST_0: case Opcodes.LCONST_0:
case Opcodes.LCONST_1: case Opcodes.LCONST_1:
case Opcodes.DCONST_0: case Opcodes.DCONST_0:
case Opcodes.DCONST_1: case Opcodes.DCONST_1:
ret = new TaintValue(2); ret = new TaintValue(2);
break; break;
case Opcodes.NEW: case Opcodes.NEW:
TypeInsnNode typeNode = (TypeInsnNode) insn; TypeInsnNode typeNode = (TypeInsnNode) insn;
if (typeNode.desc.startsWith("wrp/jdk/nashorn/internal/scripts/JO")) { if (typeNode.desc.startsWith("wrp/jdk/nashorn/internal/scripts/JO")) {
ret = new HeapObject(); ret = new HeapObject();
} else { } else {
ret = new TaintValue(1); ret = new TaintValue(1);
} }
break; break;
default: default:
ret = new TaintValue(1); ret = new TaintValue(1);
} }
return ret; return ret;
} }
@Override @Override
public TaintValue copyOperation(AbstractInsnNode insn, TaintValue value) throws AnalyzerException { public TaintValue copyOperation(AbstractInsnNode insn, TaintValue value)
return value; throws AnalyzerException {
} return value;
}
@Override @Override
public TaintValue unaryOperation(AbstractInsnNode insn, TaintValue value) throws AnalyzerException { public TaintValue unaryOperation(AbstractInsnNode insn, TaintValue value)
return value; throws AnalyzerException {
} return value;
}
@Override @Override
public TaintValue binaryOperation(AbstractInsnNode insn, TaintValue value1, TaintValue value2) public TaintValue binaryOperation(AbstractInsnNode insn, TaintValue value1, TaintValue value2)
throws AnalyzerException { throws AnalyzerException {
/* /*
* IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, LADD, * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, LADD, FADD, DADD,
* FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, * ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM,
* DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, * DREM, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP,
* LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IF_ICMPEQ, * FCMPL, FCMPG, DCMPL, DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, PUTFIELD
* PUTFIELD */
*/ TaintValue ret = new TaintValue(1);
TaintValue ret = new TaintValue(1); ret.isTainted = value1.isTainted | value2.isTainted;
ret.isTainted = value1.isTainted | value2.isTainted; switch (insn.getOpcode()) {
switch (insn.getOpcode()) { case Opcodes.DALOAD:
case Opcodes.DALOAD: case Opcodes.DADD:
case Opcodes.DADD: case Opcodes.DSUB:
case Opcodes.DSUB: case Opcodes.DMUL:
case Opcodes.DMUL: case Opcodes.DDIV:
case Opcodes.DDIV: case Opcodes.DREM:
case Opcodes.DREM: case Opcodes.LALOAD:
case Opcodes.LALOAD: case Opcodes.LADD:
case Opcodes.LADD: case Opcodes.LSUB:
case Opcodes.LSUB: case Opcodes.LMUL:
case Opcodes.LMUL: case Opcodes.LDIV:
case Opcodes.LDIV: case Opcodes.LREM:
case Opcodes.LREM: case Opcodes.LSHL:
case Opcodes.LSHL: case Opcodes.LSHR:
case Opcodes.LSHR: case Opcodes.LUSHR:
case Opcodes.LUSHR: case Opcodes.LAND:
case Opcodes.LAND: case Opcodes.LXOR:
case Opcodes.LXOR: case Opcodes.LOR:
case Opcodes.LOR: ret.size = 2;
ret.size = 2; default:
default: }
} return ret;
return ret; }
}
@Override @Override
public TaintValue ternaryOperation(AbstractInsnNode insn, TaintValue value1, TaintValue value2, TaintValue value3) public TaintValue ternaryOperation(AbstractInsnNode insn, TaintValue value1, TaintValue value2,
throws AnalyzerException { TaintValue value3) throws AnalyzerException {
// TODO // TODO
value1.isTainted |= value3.isTainted; value1.isTainted |= value3.isTainted;
return value1; return value1;
} }
@Override @Override
public TaintValue naryOperation(AbstractInsnNode insn, List<? extends TaintValue> values) throws AnalyzerException { public TaintValue naryOperation(AbstractInsnNode insn, List<? extends TaintValue> values)
int size = 1; throws AnalyzerException {
/* int size = 1;
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY /*
* and INVOKEDYNAMIC * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, MULTIANEWARRAY and
*/ * INVOKEDYNAMIC
String desc; */
switch (insn.getOpcode()) { String desc;
case Opcodes.INVOKEVIRTUAL: switch (insn.getOpcode()) {
case Opcodes.INVOKESPECIAL: case Opcodes.INVOKEVIRTUAL:
case Opcodes.INVOKESTATIC: case Opcodes.INVOKESPECIAL:
case Opcodes.INVOKEINTERFACE: case Opcodes.INVOKESTATIC:
desc = ((MethodInsnNode) insn).desc; case Opcodes.INVOKEINTERFACE:
if (desc != null && (desc.charAt(desc.length() - 1) == 'D' || desc.charAt(desc.length() - 1) == 'J')) desc = ((MethodInsnNode) insn).desc;
size = 2; if (desc != null && (desc.charAt(desc.length() - 1) == 'D'
break; || desc.charAt(desc.length() - 1) == 'J'))
case Opcodes.INVOKEDYNAMIC: size = 2;
desc = ((InvokeDynamicInsnNode) insn).desc; break;
if (desc != null && (desc.charAt(desc.length() - 1) == 'D' || desc.charAt(desc.length() - 1) == 'J')) case Opcodes.INVOKEDYNAMIC:
size = 2; desc = ((InvokeDynamicInsnNode) insn).desc;
if (desc != null && (desc.charAt(desc.length() - 1) == 'D'
|| desc.charAt(desc.length() - 1) == 'J'))
size = 2;
// Extra..Judgeffff x // Extra..Judgeffff x
if (((InvokeDynamicInsnNode) insn).name.startsWith("dyn:setElem|setProp:")) { if (((InvokeDynamicInsnNode) insn).name.startsWith("dyn:setElem|setProp:")) {
if (values.size() == 2) { if (values.size() == 2) {
values.get(0).isTainted |= values.get(1).isTainted; values.get(0).isTainted |= values.get(1).isTainted;
} }
} }
break; break;
default: default:
} }
TaintValue ret = new TaintValue(size); TaintValue ret = new TaintValue(size);
for (TaintValue v : values) for (TaintValue v : values)
if (v != null) if (v != null)
ret.isTainted |= v.isTainted; ret.isTainted |= v.isTainted;
if (insn instanceof InvokeDynamicInsnNode) { if (insn instanceof InvokeDynamicInsnNode) {
long taint = (taintBits.getTaintValue(((InvokeDynamicInsnNode) insn).name + insn.hashCode())); long taint = (taintBits
.getTaintValue(((InvokeDynamicInsnNode) insn).name + insn.hashCode()));
if (taint > 0L) if (taint > 0L)
ret.isTainted |= taint; ret.isTainted |= taint;
} }
return HeapObject.operate(insn, values, ret); return HeapObject.operate(insn, values, ret);
} }
@Override @Override
public void returnOperation(AbstractInsnNode insn, TaintValue value, TaintValue expected) throws AnalyzerException { public void returnOperation(AbstractInsnNode insn, TaintValue value, TaintValue expected)
if (value instanceof HeapObject) { throws AnalyzerException {
currentResult.ret.isTainted |= ((HeapObject) value).wholeTaint(); if (value instanceof HeapObject) {
} else if (value!=null) currentResult.ret.isTainted |= ((HeapObject) value).wholeTaint();
currentResult.ret.isTainted |= value.isTainted; } else if (value != null)
} currentResult.ret.isTainted |= value.isTainted;
}
@Override @Override
public TaintValue merge(TaintValue v, TaintValue w) { public TaintValue merge(TaintValue v, TaintValue w) {
TaintValue ret = new TaintValue(v.getSize()); TaintValue ret = new TaintValue(v.getSize());
ret.isTainted |= v.isTainted; ret.isTainted |= v.isTainted;
ret.isTainted |= w.isTainted; ret.isTainted |= w.isTainted;
return ret; return ret;
} }
public void setCurrentResult(TaintResult naiveTaintResult) { public void setCurrentResult(TaintResult naiveTaintResult) {
currentResult = naiveTaintResult; currentResult = naiveTaintResult;
} }
public void setTaintBits(TaintBits tb) { public void setTaintBits(TaintBits tb) {
taintBits = tb; taintBits = tb;
} }
} }

View File

@ -8,183 +8,183 @@ import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.Frame; import org.objectweb.asm.tree.analysis.Frame;
public class TaintResult extends AnalysisResult { public class TaintResult extends AnalysisResult {
// public HeapObject heapObejct; // public HeapObject heapObejct;
public Frame<TaintValue> frame; public Frame<TaintValue> frame;
public TaintValue ret; public TaintValue ret;
public static int nLocals = 0; public static int nLocals = 0;
public static int nStack = 0; public static int nStack = 0;
public static InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out); public static InsnPrinter printer = new InsnPrinter(Opcodes.ASM4, System.out);
public static TaintInterpreter interpreter = new TaintInterpreter(Opcodes.ASM4); public static TaintInterpreter interpreter = new TaintInterpreter(Opcodes.ASM4);
public TaintResult() { public TaintResult() {
frame = new Frame<>(nLocals, nStack); frame = new Frame<>(nLocals, nStack);
ret = new TaintValue(1); ret = new TaintValue(1);
ret.isTainted = 0L; ret.isTainted = 0L;
} }
@Override @Override
public AnalysisResult merge(AbstractInsnNode insn) { public AnalysisResult merge(AbstractInsnNode insn) {
interpreter.setCurrentResult(this); interpreter.setCurrentResult(this);
try { try {
if (TaintConfig.isDebug && insn.getOpcode() >= 0) { if (TaintConfig.isDebug && insn.getOpcode() >= 0) {
System.out.println("[TaintResult] frameStatus:" + frame2Str()); System.out.println("[TaintResult] frameStatus:" + frame2Str());
insn.accept(printer); insn.accept(printer);
} }
if (insn.getOpcode() < 0) { if (insn.getOpcode() < 0) {
// System.out.println("[TaintResult] MetLabel:" + // System.out.println("[TaintResult] MetLabel:" +
// insn.getClass().getCanonicalName()); // insn.getClass().getCanonicalName());
} else } else
frame.execute(insn, interpreter); frame.execute(insn, interpreter);
if (TaintConfig.isDebug && insn.getOpcode() >= 0) { if (TaintConfig.isDebug && insn.getOpcode() >= 0) {
System.out.println("[TaintResult] frameStatus:" + frame2Str()); System.out.println("[TaintResult] frameStatus:" + frame2Str());
} }
} catch (AnalyzerException e) { } catch (AnalyzerException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
// we use suc instead,so we don't create new object here. // we use suc instead,so we don't create new object here.
return this; return this;
} }
@Override
public void printResult() {
System.out.println("====" + frame2Str() + " Ret:" + ret.toString() + "====");
}
public String frame2Str() { @Override
StringBuilder sb = new StringBuilder(); public void printResult() {
sb.append("Local:"); System.out.println("====" + frame2Str() + " Ret:" + ret.toString() + "====");
for (int i = 0; i < frame.getLocals(); i++) { // getLocals<EFBFBD><EFBFBD><EFBFBD><EFBFBD>local<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>size }
TaintValue t = frame.getLocal(i);
if (t != null)
sb.append(t.toString());
else
sb.append("0--");
}
sb.append(" Stack:");
for (int i = 0; i < frame.getStackSize(); i++) { // getStackSize<EFBFBD><EFBFBD><EFBFBD><EFBFBD>stack<EFBFBD>ĵ<EFBFBD>ǰsize
TaintValue t = frame.getStack(i);
if (t != null)
sb.append(t.toString());
else
sb.append("0--");
}
return sb.toString();
}
private static boolean cover(TaintValue t1, TaintValue t2) { public String frame2Str() {
// if (t2 == null || t2.isTainted == 0) StringBuilder sb = new StringBuilder();
// return true; sb.append("Local:");
// TODO whether is cover? for (int i = 0; i < frame.getLocals(); i++) { // getLocals<EFBFBD><EFBFBD><EFBFBD><EFBFBD>local<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>size
if (t1 != null && t1.isTainted != 0) { TaintValue t = frame.getLocal(i);
if (t2 == null || t1.isTainted != t2.isTainted) if (t != null)
return true; sb.append(t.toString());
} else
return false; sb.append("0--");
} }
sb.append(" Stack:");
for (int i = 0; i < frame.getStackSize(); i++) { // getStackSize<EFBFBD><EFBFBD><EFBFBD><EFBFBD>stack<EFBFBD>ĵ<EFBFBD>ǰsize
TaintValue t = frame.getStack(i);
if (t != null)
sb.append(t.toString());
else
sb.append("0--");
}
return sb.toString();
}
/* private static boolean cover(TaintValue t1, TaintValue t2) {
* private static boolean isTainted(TaintValue t1) { if (t1 != null && // if (t2 == null || t2.isTainted == 0)
* t1.isTainted) { return true; } return false; } // return true;
*/ // TODO whether is cover?
private static boolean isTainted(TaintValue t1) { if (t1 != null && t1.isTainted != 0) {
if (t1 != null && t1.isTainted != 0) { if (t2 == null || t1.isTainted != t2.isTainted)
return true; return true;
} }
return false; return false;
} }
@Override /*
public boolean covers(AnalysisResult result) { * private static boolean isTainted(TaintValue t1) { if (t1 != null && t1.isTainted) { return
TaintResult tr = (TaintResult) result; * true; } return false; }
boolean ret = coversInternal(tr); */
return ret; private static boolean isTainted(TaintValue t1) {
// System.out.println("[NaiveTaintResult] Cover:" + ret); if (t1 != null && t1.isTainted != 0) {
// System.out.println("[NaiveTaintResult] " + frame.toString()); return true;
// System.out.println("[NaiveTaintResult] " + tr.frame.toString()); }
} return false;
}
// preResult cover sucResult means @Override
// preResult's taint is large or equals sucResult. public boolean covers(AnalysisResult result) {
public boolean coversInternal(TaintResult tr) { TaintResult tr = (TaintResult) result;
for (int i = 0; i < frame.getLocals() && i < tr.frame.getLocals(); i++) boolean ret = coversInternal(tr);
if (cover(tr.frame.getLocal(i), frame.getLocal(i))) return ret;
return false; // System.out.println("[NaiveTaintResult] Cover:" + ret);
// TODO why locals is not equal?? // System.out.println("[NaiveTaintResult] " + frame.toString());
for (int i = frame.getLocals(); i < tr.frame.getLocals(); i++) // System.out.println("[NaiveTaintResult] " + tr.frame.toString());
if (isTainted(tr.frame.getLocal(i))) }
return false;
for (int i = 0; i < frame.getStackSize() && i < tr.frame.getStackSize(); i++)
if (cover(tr.frame.getStack(i), frame.getStack(i)))
return false;
for (int i = frame.getStackSize(); i < tr.frame.getStackSize(); i++)
if (isTainted(tr.frame.getStack(i)))
return false;
return true;
}
@Override // preResult cover sucResult means
public void mergeResult(AnalysisResult r) { // preResult's taint is large or equals sucResult.
TaintResult from = (TaintResult) r; public boolean coversInternal(TaintResult tr) {
for (int i = 0; i < from.frame.getLocals(); i++) { for (int i = 0; i < frame.getLocals() && i < tr.frame.getLocals(); i++)
TaintValue target = from.frame.getLocal(i); if (cover(tr.frame.getLocal(i), frame.getLocal(i)))
if (frame.getLocals() > i) { return false;
TaintValue t1 = frame.getLocal(i); // TODO why locals is not equal??
if (target != null) { for (int i = frame.getLocals(); i < tr.frame.getLocals(); i++)
if (t1 == null) { if (isTainted(tr.frame.getLocal(i)))
t1 = target.clone(); return false;
frame.setLocal(i, t1); for (int i = 0; i < frame.getStackSize() && i < tr.frame.getStackSize(); i++)
} else { if (cover(tr.frame.getStack(i), frame.getStack(i)))
t1.merge(target); return false;
} for (int i = frame.getStackSize(); i < tr.frame.getStackSize(); i++)
} if (isTainted(tr.frame.getStack(i)))
} else { return false;
frame.setLocal(i, target.clone()); return true;
} }
}
for (int i = 0; i < from.frame.getStackSize(); i++) { @Override
TaintValue target = from.frame.getStack(i); public void mergeResult(AnalysisResult r) {
if (frame.getStackSize() > i) { TaintResult from = (TaintResult) r;
TaintValue t1 = frame.getStack(i); for (int i = 0; i < from.frame.getLocals(); i++) {
if (target != null) { TaintValue target = from.frame.getLocal(i);
if (t1 == null) { if (frame.getLocals() > i) {
t1 = target.clone(); TaintValue t1 = frame.getLocal(i);
frame.setStack(i, t1); if (target != null) {
} else { if (t1 == null) {
t1.merge(target); t1 = target.clone();
} frame.setLocal(i, t1);
} } else {
t1.merge(target);
}
}
} else {
frame.setLocal(i, target.clone());
}
}
t1.merge(from.frame.getStack(i)); for (int i = 0; i < from.frame.getStackSize(); i++) {
} else { TaintValue target = from.frame.getStack(i);
if (target != null) if (frame.getStackSize() > i) {
frame.push(target.clone()); TaintValue t1 = frame.getStack(i);
else if (target != null) {
frame.push(new TaintValue(1,0)); if (t1 == null) {
} t1 = target.clone();
} frame.setStack(i, t1);
ret.merge(from.ret); } else {
} t1.merge(target);
}
}
@Override t1.merge(from.frame.getStack(i));
public AnalysisResult clone() { } else {
TaintResult ret = new TaintResult(); if (target != null)
ret.frame = new Frame<>(frame); frame.push(target.clone());
for (int i = 0; i < ret.frame.getLocals(); i++) { else
TaintValue t = ret.frame.getLocal(i); frame.push(new TaintValue(1, 0));
if (t != null) }
ret.frame.setLocal(i, t.clone()); }
} ret.merge(from.ret);
for (int i = 0; i < ret.frame.getStackSize(); i++) { }
TaintValue t = ret.frame.getStack(i);
if (t != null) @Override
ret.frame.setStack(i, t.clone()); public AnalysisResult clone() {
} TaintResult ret = new TaintResult();
ret.ret = this.ret.clone(); ret.frame = new Frame<>(frame);
return ret; for (int i = 0; i < ret.frame.getLocals(); i++) {
} TaintValue t = ret.frame.getLocal(i);
if (t != null)
ret.frame.setLocal(i, t.clone());
}
for (int i = 0; i < ret.frame.getStackSize(); i++) {
TaintValue t = ret.frame.getStack(i);
if (t != null)
ret.frame.setStack(i, t.clone());
}
ret.ret = this.ret.clone();
return ret;
}
} }

View File

@ -3,52 +3,52 @@ package org.bdware.analysis.taint;
import org.objectweb.asm.tree.analysis.Value; import org.objectweb.asm.tree.analysis.Value;
public class TaintValue implements Value { public class TaintValue implements Value {
public int size; public int size;
// public boolean isTainted; // public boolean isTainted;
public long isTainted; public long isTainted;
public TaintValue(int size) { public TaintValue(int size) {
this.size = size; this.size = size;
isTainted = 0L; isTainted = 0L;
} }
public TaintValue(int size, long isTainted) { public TaintValue(int size, long isTainted) {
this.size = size; this.size = size;
this.isTainted = isTainted; this.isTainted = isTainted;
} }
@Override @Override
public int getSize() { public int getSize() {
return size; return size;
} }
@Override @Override
public String toString() { public String toString() {
String s = Long.toBinaryString(isTainted); String s = Long.toBinaryString(isTainted);
char[] c = s.toCharArray(); char[] c = s.toCharArray();
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
for (int i = 0; i < c.length; i++) { for (int i = 0; i < c.length; i++) {
if (c[i] == '1') if (c[i] == '1')
buf.append("1/"); buf.append("1/");
else else
buf.append("0/"); buf.append("0/");
} }
buf.append("--"); buf.append("--");
return buf.toString(); return buf.toString();
} }
public TaintValue clone() { public TaintValue clone() {
TaintValue ret = new TaintValue(size); TaintValue ret = new TaintValue(size);
ret.isTainted = isTainted; ret.isTainted = isTainted;
return ret; return ret;
} }
public String toReadableTaint() { public String toReadableTaint() {
return TaintResult.interpreter.taintBits.parse(isTainted); return TaintResult.interpreter.taintBits.parse(isTainted);
} }
public void merge(TaintValue target) { public void merge(TaintValue target) {
if (target != null) if (target != null)
isTainted |= target.isTainted; isTainted |= target.isTainted;
} }
} }

View File

@ -1,38 +1,30 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
/** /**
* A visitor to visit a Java annotation. The methods of this class must be * A visitor to visit a Java annotation. The methods of this class must be called in the following
* called in the following order: ( <tt>visit</tt> | <tt>visitEnum</tt> | * order: ( <tt>visit</tt> | <tt>visitEnum</tt> | <tt>visitAnnotation</tt> | <tt>visitArray</tt> )*
* <tt>visitAnnotation</tt> | <tt>visitArray</tt> )* <tt>visitEnd</tt>. * <tt>visitEnd</tt>.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Eugene Kuleshov * @author Eugene Kuleshov
@ -40,23 +32,21 @@ package org.objectweb.asm;
public abstract class AnnotationVisitor { public abstract class AnnotationVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of
* must be one of {@link Opcodes#ASM4}. * {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* The annotation visitor to which this visitor must delegate method calls. * The annotation visitor to which this visitor must delegate method calls. May be null.
* May be null.
*/ */
protected AnnotationVisitor av; protected AnnotationVisitor av;
/** /**
* Constructs a new {@link AnnotationVisitor}. * Constructs a new {@link AnnotationVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}.
*/ */
public AnnotationVisitor(final int api) { public AnnotationVisitor(final int api) {
this(api, null); this(api, null);
@ -65,12 +55,10 @@ public abstract class AnnotationVisitor {
/** /**
* Constructs a new {@link AnnotationVisitor}. * Constructs a new {@link AnnotationVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param av the annotation visitor to which this visitor must delegate method calls. May be
* @param av * null.
* the annotation visitor to which this visitor must delegate
* method calls. May be null.
*/ */
public AnnotationVisitor(final int api, final AnnotationVisitor av) { public AnnotationVisitor(final int api, final AnnotationVisitor av) {
if (api != Opcodes.ASM4) { if (api != Opcodes.ASM4) {
@ -83,17 +71,13 @@ public abstract class AnnotationVisitor {
/** /**
* Visits a primitive value of the annotation. * Visits a primitive value of the annotation.
* *
* @param name * @param name the value name.
* the value name. * @param value the actual value, whose type must be {@link Byte}, {@link Boolean},
* @param value * {@link Character}, {@link Short}, {@link Integer} , {@link Long}, {@link Float},
* the actual value, whose type must be {@link Byte}, * {@link Double}, {@link String} or {@link Type} or OBJECT or ARRAY sort. This value can
* {@link Boolean}, {@link Character}, {@link Short}, * also be an array of byte, boolean, short, char, int, long, float or double values
* {@link Integer} , {@link Long}, {@link Float}, {@link Double}, * (this is equivalent to using {@link #visitArray visitArray} and visiting each array
* {@link String} or {@link Type} or OBJECT or ARRAY sort. This * element in turn, but is more convenient).
* value can also be an array of byte, boolean, short, char, int,
* long, float or double values (this is equivalent to using
* {@link #visitArray visitArray} and visiting each array element
* in turn, but is more convenient).
*/ */
public void visit(String name, Object value) { public void visit(String name, Object value) {
if (av != null) { if (av != null) {
@ -104,12 +88,9 @@ public abstract class AnnotationVisitor {
/** /**
* Visits an enumeration value of the annotation. * Visits an enumeration value of the annotation.
* *
* @param name * @param name the value name.
* the value name. * @param desc the class descriptor of the enumeration class.
* @param desc * @param value the actual enumeration value.
* the class descriptor of the enumeration class.
* @param value
* the actual enumeration value.
*/ */
public void visitEnum(String name, String desc, String value) { public void visitEnum(String name, String desc, String value) {
if (av != null) { if (av != null) {
@ -120,15 +101,12 @@ public abstract class AnnotationVisitor {
/** /**
* Visits a nested annotation value of the annotation. * Visits a nested annotation value of the annotation.
* *
* @param name * @param name the value name.
* the value name. * @param desc the class descriptor of the nested annotation class.
* @param desc * @return a visitor to visit the actual nested annotation value, or <tt>null</tt> if this
* the class descriptor of the nested annotation class. * visitor is not interested in visiting this nested annotation. <i>The nested
* @return a visitor to visit the actual nested annotation value, or * annotation value must be fully visited before calling other methods on this
* <tt>null</tt> if this visitor is not interested in visiting this * annotation visitor</i>.
* nested annotation. <i>The nested annotation value must be fully
* visited before calling other methods on this annotation
* visitor</i>.
*/ */
public AnnotationVisitor visitAnnotation(String name, String desc) { public AnnotationVisitor visitAnnotation(String name, String desc) {
if (av != null) { if (av != null) {
@ -138,18 +116,15 @@ public abstract class AnnotationVisitor {
} }
/** /**
* Visits an array value of the annotation. Note that arrays of primitive * Visits an array value of the annotation. Note that arrays of primitive types (such as byte,
* types (such as byte, boolean, short, char, int, long, float or double) * boolean, short, char, int, long, float or double) can be passed as value to {@link #visit
* can be passed as value to {@link #visit visit}. This is what * visit}. This is what {@link ClassReader} does.
* {@link ClassReader} does.
* *
* @param name * @param name the value name.
* the value name. * @return a visitor to visit the actual array value elements, or <tt>null</tt> if this visitor
* @return a visitor to visit the actual array value elements, or * is not interested in visiting these values. The 'name' parameters passed to the
* <tt>null</tt> if this visitor is not interested in visiting these * methods of this visitor are ignored. <i>All the array values must be visited before
* values. The 'name' parameters passed to the methods of this * calling other methods on this annotation visitor</i>.
* visitor are ignored. <i>All the array values must be visited
* before calling other methods on this annotation visitor</i>.
*/ */
public AnnotationVisitor visitArray(String name) { public AnnotationVisitor visitArray(String name) {
if (av != null) { if (av != null) {

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
@ -35,344 +27,267 @@ package org.objectweb.asm;
* @author Eric Bruneton * @author Eric Bruneton
* @author Eugene Kuleshov * @author Eugene Kuleshov
*/ */
final class AnnotationWriter extends AnnotationVisitor final class AnnotationWriter extends AnnotationVisitor {
{
/** /**
* The class writer to which this annotation must be added. * The class writer to which this annotation must be added.
*/ */
private final ClassWriter cw; private final ClassWriter cw;
/** /**
* The number of values in this annotation. * The number of values in this annotation.
*/ */
private int size; private int size;
/** /**
* <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation * <tt>true<tt> if values are named, <tt>false</tt> otherwise. Annotation writers used for
* writers used for annotation default and annotation arrays use unnamed * annotation default and annotation arrays use unnamed values.
* values. */
*/ private final boolean named;
private final boolean named;
/** /**
* The annotation values in bytecode form. This byte vector only contains * The annotation values in bytecode form. This byte vector only contains the values themselves,
* the values themselves, i.e. the number of values must be stored as a * i.e. the number of values must be stored as a unsigned short just before these bytes.
* unsigned short just before these bytes. */
*/ private final ByteVector bv;
private final ByteVector bv;
/** /**
* The byte vector to be used to store the number of values of this * The byte vector to be used to store the number of values of this annotation. See {@link #bv}.
* annotation. See {@link #bv}. */
*/ private final ByteVector parent;
private final ByteVector parent;
/** /**
* Where the number of values of this annotation must be stored in * Where the number of values of this annotation must be stored in {@link #parent}.
* {@link #parent}. */
*/ private final int offset;
private final int offset;
/** /**
* Next annotation writer. This field is used to store annotation lists. * Next annotation writer. This field is used to store annotation lists.
*/ */
AnnotationWriter next; AnnotationWriter next;
/** /**
* Previous annotation writer. This field is used to store annotation lists. * Previous annotation writer. This field is used to store annotation lists.
*/ */
AnnotationWriter prev; AnnotationWriter prev;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Constructor // Constructor
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Constructs a new {@link AnnotationWriter}. * Constructs a new {@link AnnotationWriter}.
* *
* @param cw * @param cw the class writer to which this annotation must be added.
* the class writer to which this annotation must be added. * @param named <tt>true<tt> if values are named, <tt>false</tt> otherwise.
* @param named * @param bv where the annotation values must be stored.
* <tt>true<tt> if values are named, <tt>false</tt> otherwise. * @param parent where the number of annotation values must be stored.
* @param bv * @param offset where in <tt>parent</tt> the number of annotation values must be stored.
* where the annotation values must be stored. */
* @param parent AnnotationWriter(final ClassWriter cw, final boolean named, final ByteVector bv,
* where the number of annotation values must be stored. final ByteVector parent, final int offset) {
* @param offset super(Opcodes.ASM4);
* where in <tt>parent</tt> the number of annotation values must this.cw = cw;
* be stored. this.named = named;
*/ this.bv = bv;
AnnotationWriter(final ClassWriter cw, final boolean named, this.parent = parent;
final ByteVector bv, final ByteVector parent, final int offset) this.offset = offset;
{ }
super(Opcodes.ASM4);
this.cw = cw;
this.named = named;
this.bv = bv;
this.parent = parent;
this.offset = offset;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Implementation of the AnnotationVisitor abstract class // Implementation of the AnnotationVisitor abstract class
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public void visit(final String name, final Object value) public void visit(final String name, final Object value) {
{ ++size;
++size; if (named) {
if (named) bv.putShort(cw.newUTF8(name));
{ }
bv.putShort(cw.newUTF8(name)); if (value instanceof String) {
} bv.put12('s', cw.newUTF8((String) value));
if (value instanceof String) } else if (value instanceof Byte) {
{ bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index);
bv.put12('s', cw.newUTF8((String) value)); } else if (value instanceof Boolean) {
} int v = ((Boolean) value).booleanValue() ? 1 : 0;
else if (value instanceof Byte) bv.put12('Z', cw.newInteger(v).index);
{ } else if (value instanceof Character) {
bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index); bv.put12('C', cw.newInteger(((Character) value).charValue()).index);
} } else if (value instanceof Short) {
else if (value instanceof Boolean) bv.put12('S', cw.newInteger(((Short) value).shortValue()).index);
{ } else if (value instanceof Type) {
int v = ((Boolean) value).booleanValue() ? 1 : 0; bv.put12('c', cw.newUTF8(((Type) value).getDescriptor()));
bv.put12('Z', cw.newInteger(v).index); } else if (value instanceof byte[]) {
} byte[] v = (byte[]) value;
else if (value instanceof Character) bv.put12('[', v.length);
{ for (int i = 0; i < v.length; i++) {
bv.put12('C', cw.newInteger(((Character) value).charValue()).index); bv.put12('B', cw.newInteger(v[i]).index);
} }
else if (value instanceof Short) } else if (value instanceof boolean[]) {
{ boolean[] v = (boolean[]) value;
bv.put12('S', cw.newInteger(((Short) value).shortValue()).index); bv.put12('[', v.length);
} for (int i = 0; i < v.length; i++) {
else if (value instanceof Type) bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index);
{ }
bv.put12('c', cw.newUTF8(((Type) value).getDescriptor())); } else if (value instanceof short[]) {
} short[] v = (short[]) value;
else if (value instanceof byte[]) bv.put12('[', v.length);
{ for (int i = 0; i < v.length; i++) {
byte[] v = (byte[]) value; bv.put12('S', cw.newInteger(v[i]).index);
bv.put12('[', v.length); }
for (int i = 0; i < v.length; i++) } else if (value instanceof char[]) {
{ char[] v = (char[]) value;
bv.put12('B', cw.newInteger(v[i]).index); bv.put12('[', v.length);
} for (int i = 0; i < v.length; i++) {
} bv.put12('C', cw.newInteger(v[i]).index);
else if (value instanceof boolean[]) }
{ } else if (value instanceof int[]) {
boolean[] v = (boolean[]) value; int[] v = (int[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) for (int i = 0; i < v.length; i++) {
{ bv.put12('I', cw.newInteger(v[i]).index);
bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index); }
} } else if (value instanceof long[]) {
} long[] v = (long[]) value;
else if (value instanceof short[]) bv.put12('[', v.length);
{ for (int i = 0; i < v.length; i++) {
short[] v = (short[]) value; bv.put12('J', cw.newLong(v[i]).index);
bv.put12('[', v.length); }
for (int i = 0; i < v.length; i++) } else if (value instanceof float[]) {
{ float[] v = (float[]) value;
bv.put12('S', cw.newInteger(v[i]).index); bv.put12('[', v.length);
} for (int i = 0; i < v.length; i++) {
} bv.put12('F', cw.newFloat(v[i]).index);
else if (value instanceof char[]) }
{ } else if (value instanceof double[]) {
char[] v = (char[]) value; double[] v = (double[]) value;
bv.put12('[', v.length); bv.put12('[', v.length);
for (int i = 0; i < v.length; i++) for (int i = 0; i < v.length; i++) {
{ bv.put12('D', cw.newDouble(v[i]).index);
bv.put12('C', cw.newInteger(v[i]).index); }
} } else {
} Item i = cw.newConstItem(value);
else if (value instanceof int[]) bv.put12(".s.IFJDCS".charAt(i.type), i.index);
{ }
int[] v = (int[]) value; }
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++)
{
bv.put12('I', cw.newInteger(v[i]).index);
}
}
else if (value instanceof long[])
{
long[] v = (long[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++)
{
bv.put12('J', cw.newLong(v[i]).index);
}
}
else if (value instanceof float[])
{
float[] v = (float[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++)
{
bv.put12('F', cw.newFloat(v[i]).index);
}
}
else if (value instanceof double[])
{
double[] v = (double[]) value;
bv.put12('[', v.length);
for (int i = 0; i < v.length; i++)
{
bv.put12('D', cw.newDouble(v[i]).index);
}
}
else
{
Item i = cw.newConstItem(value);
bv.put12(".s.IFJDCS".charAt(i.type), i.index);
}
}
@Override @Override
public void visitEnum(final String name, final String desc, public void visitEnum(final String name, final String desc, final String value) {
final String value) ++size;
{ // TODO add by chq! &&name!=null;
++size; if (named && name != null) {
// TODO add by chq! &&name!=null; bv.putShort(cw.newUTF8(name));
if (named && name != null) }
{ bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
bv.putShort(cw.newUTF8(name)); }
}
bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value));
}
@Override @Override
public AnnotationVisitor visitAnnotation(final String name, public AnnotationVisitor visitAnnotation(final String name, final String desc) {
final String desc) ++size;
{ if (named) {
++size; bv.putShort(cw.newUTF8(name));
if (named) }
{ // write tag and type, and reserve space for values count
bv.putShort(cw.newUTF8(name)); bv.put12('@', cw.newUTF8(desc)).putShort(0);
} return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
// write tag and type, and reserve space for values count }
bv.put12('@', cw.newUTF8(desc)).putShort(0);
return new AnnotationWriter(cw, true, bv, bv, bv.length - 2);
}
@Override @Override
public AnnotationVisitor visitArray(final String name) public AnnotationVisitor visitArray(final String name) {
{ ++size;
++size; if (named) {
if (named) bv.putShort(cw.newUTF8(name));
{ }
bv.putShort(cw.newUTF8(name)); // write tag, and reserve space for array size
} bv.put12('[', 0);
// write tag, and reserve space for array size return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
bv.put12('[', 0); }
return new AnnotationWriter(cw, false, bv, bv, bv.length - 2);
}
@Override @Override
public void visitEnd() public void visitEnd() {
{ if (parent != null) {
if (parent != null) byte[] data = parent.data;
{ data[offset] = (byte) (size >>> 8);
byte[] data = parent.data; data[offset + 1] = (byte) size;
data[offset] = (byte) (size >>> 8); }
data[offset + 1] = (byte) size; }
}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Utility methods // Utility methods
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the size of this annotation writer list. * Returns the size of this annotation writer list.
* *
* @return the size of this annotation writer list. * @return the size of this annotation writer list.
*/ */
int getSize() int getSize() {
{ int size = 0;
int size = 0; AnnotationWriter aw = this;
AnnotationWriter aw = this; while (aw != null) {
while (aw != null) size += aw.bv.length;
{ aw = aw.next;
size += aw.bv.length; }
aw = aw.next; return size;
} }
return size;
}
/** /**
* Puts the annotations of this annotation writer list into the given byte * Puts the annotations of this annotation writer list into the given byte vector.
* vector. *
* * @param out where the annotations must be put.
* @param out */
* where the annotations must be put. void put(final ByteVector out) {
*/ int n = 0;
void put(final ByteVector out) int size = 2;
{ AnnotationWriter aw = this;
int n = 0; AnnotationWriter last = null;
int size = 2; while (aw != null) {
AnnotationWriter aw = this; ++n;
AnnotationWriter last = null; size += aw.bv.length;
while (aw != null) aw.visitEnd(); // in case user forgot to call visitEnd
{ aw.prev = last;
++n; last = aw;
size += aw.bv.length; aw = aw.next;
aw.visitEnd(); // in case user forgot to call visitEnd }
aw.prev = last; out.putInt(size);
last = aw; out.putShort(n);
aw = aw.next; aw = last;
} while (aw != null) {
out.putInt(size); out.putByteArray(aw.bv.data, 0, aw.bv.length);
out.putShort(n); aw = aw.prev;
aw = last; }
while (aw != null) }
{
out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev;
}
}
/** /**
* Puts the given annotation lists into the given byte vector. * Puts the given annotation lists into the given byte vector.
* *
* @param panns * @param panns an array of annotation writer lists.
* an array of annotation writer lists. * @param off index of the first annotation to be written.
* @param off * @param out where the annotations must be put.
* index of the first annotation to be written. */
* @param out static void put(final AnnotationWriter[] panns, final int off, final ByteVector out) {
* where the annotations must be put. int size = 1 + 2 * (panns.length - off);
*/ for (int i = off; i < panns.length; ++i) {
static void put(final AnnotationWriter[] panns, final int off, size += panns[i] == null ? 0 : panns[i].getSize();
final ByteVector out) }
{ out.putInt(size).putByte(panns.length - off);
int size = 1 + 2 * (panns.length - off); for (int i = off; i < panns.length; ++i) {
for (int i = off; i < panns.length; ++i) AnnotationWriter aw = panns[i];
{ AnnotationWriter last = null;
size += panns[i] == null ? 0 : panns[i].getSize(); int n = 0;
} while (aw != null) {
out.putInt(size).putByte(panns.length - off); ++n;
for (int i = off; i < panns.length; ++i) aw.visitEnd(); // in case user forgot to call visitEnd
{ aw.prev = last;
AnnotationWriter aw = panns[i]; last = aw;
AnnotationWriter last = null; aw = aw.next;
int n = 0; }
while (aw != null) out.putShort(n);
{ aw = last;
++n; while (aw != null) {
aw.visitEnd(); // in case user forgot to call visitEnd out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw.prev = last; aw = aw.prev;
last = aw; }
aw = aw.next; }
} }
out.putShort(n);
aw = last;
while (aw != null)
{
out.putByteArray(aw.bv.data, 0, aw.bv.length);
aw = aw.prev;
}
}
}
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
@ -55,16 +47,15 @@ public class Attribute {
/** /**
* Constructs a new empty attribute. * Constructs a new empty attribute.
* *
* @param type * @param type the type of the attribute.
* the type of the attribute.
*/ */
protected Attribute(final String type) { protected Attribute(final String type) {
this.type = type; this.type = type;
} }
/** /**
* Returns <tt>true</tt> if this type of attribute is unknown. The default * Returns <tt>true</tt> if this type of attribute is unknown. The default implementation of
* implementation of this method always returns <tt>true</tt>. * this method always returns <tt>true</tt>.
* *
* @return <tt>true</tt> if this type of attribute is unknown. * @return <tt>true</tt> if this type of attribute is unknown.
*/ */
@ -84,47 +75,36 @@ public class Attribute {
/** /**
* Returns the labels corresponding to this attribute. * Returns the labels corresponding to this attribute.
* *
* @return the labels corresponding to this attribute, or <tt>null</tt> if * @return the labels corresponding to this attribute, or <tt>null</tt> if this attribute is not
* this attribute is not a code attribute that contains labels. * a code attribute that contains labels.
*/ */
protected Label[] getLabels() { protected Label[] getLabels() {
return null; return null;
} }
/** /**
* Reads a {@link #type type} attribute. This method must return a * Reads a {@link #type type} attribute. This method must return a <i>new</i> {@link Attribute}
* <i>new</i> {@link Attribute} object, of type {@link #type type}, * object, of type {@link #type type}, corresponding to the <tt>len</tt> bytes starting at the
* corresponding to the <tt>len</tt> bytes starting at the given offset, in * given offset, in the given class reader.
* the given class reader.
* *
* @param cr * @param cr the class that contains the attribute to be read.
* the class that contains the attribute to be read. * @param off index of the first byte of the attribute's content in {@link ClassReader#b cr.b}.
* @param off * The 6 attribute header bytes, containing the type and the length of the attribute, are
* index of the first byte of the attribute's content in * not taken into account here.
* {@link ClassReader#b cr.b}. The 6 attribute header bytes, * @param len the length of the attribute's content.
* containing the type and the length of the attribute, are not * @param buf buffer to be used to call {@link ClassReader#readUTF8 readUTF8},
* taken into account here. * {@link ClassReader#readClass(int,char[]) readClass} or {@link ClassReader#readConst
* @param len * readConst}.
* the length of the attribute's content. * @param codeOff index of the first byte of code's attribute content in {@link ClassReader#b
* @param buf * cr.b}, or -1 if the attribute to be read is not a code attribute. The 6 attribute
* buffer to be used to call {@link ClassReader#readUTF8 * header bytes, containing the type and the length of the attribute, are not taken into
* readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} * account here.
* or {@link ClassReader#readConst readConst}. * @param labels the labels of the method's code, or <tt>null</tt> if the attribute to be read
* @param codeOff * is not a code attribute.
* index of the first byte of code's attribute content in * @return a <i>new</i> {@link Attribute} object corresponding to the given bytes.
* {@link ClassReader#b cr.b}, or -1 if the attribute to be read
* is not a code attribute. The 6 attribute header bytes,
* containing the type and the length of the attribute, are not
* taken into account here.
* @param labels
* the labels of the method's code, or <tt>null</tt> if the
* attribute to be read is not a code attribute.
* @return a <i>new</i> {@link Attribute} object corresponding to the given
* bytes.
*/ */
protected Attribute read(final ClassReader cr, final int off, protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf,
final int len, final char[] buf, final int codeOff, final int codeOff, final Label[] labels) {
final Label[] labels) {
Attribute attr = new Attribute(type); Attribute attr = new Attribute(type);
attr.value = new byte[len]; attr.value = new byte[len];
System.arraycopy(cr.b, off, attr.value, 0, len); System.arraycopy(cr.b, off, attr.value, 0, len);
@ -134,30 +114,20 @@ public class Attribute {
/** /**
* Returns the byte array form of this attribute. * Returns the byte array form of this attribute.
* *
* @param cw * @param cw the class to which this attribute must be added. This parameter can be used to add
* the class to which this attribute must be added. This * to the constant pool of this class the items that corresponds to this attribute.
* parameter can be used to add to the constant pool of this * @param code the bytecode of the method corresponding to this code attribute, or <tt>null</tt>
* class the items that corresponds to this attribute. * if this attribute is not a code attributes.
* @param code * @param len the length of the bytecode of the method corresponding to this code attribute, or
* the bytecode of the method corresponding to this code * <tt>null</tt> if this attribute is not a code attribute.
* attribute, or <tt>null</tt> if this attribute is not a code * @param maxStack the maximum stack size of the method corresponding to this code attribute, or
* attributes. * -1 if this attribute is not a code attribute.
* @param len * @param maxLocals the maximum number of local variables of the method corresponding to this
* the length of the bytecode of the method corresponding to this * code attribute, or -1 if this attribute is not a code attribute.
* code attribute, or <tt>null</tt> if this attribute is not a
* code attribute.
* @param maxStack
* the maximum stack size of the method corresponding to this
* code attribute, or -1 if this attribute is not a code
* attribute.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to this code attribute, or -1 if this attribute
* is not a code attribute.
* @return the byte array form of this attribute. * @return the byte array form of this attribute.
*/ */
protected ByteVector write(final ClassWriter cw, final byte[] code, protected ByteVector write(final ClassWriter cw, final byte[] code, final int len,
final int len, final int maxStack, final int maxLocals) { final int maxStack, final int maxLocals) {
ByteVector v = new ByteVector(); ByteVector v = new ByteVector();
v.data = value; v.data = value;
v.length = value.length; v.length = value.length;
@ -182,30 +152,21 @@ public class Attribute {
/** /**
* Returns the size of all the attributes in this attribute list. * Returns the size of all the attributes in this attribute list.
* *
* @param cw * @param cw the class writer to be used to convert the attributes into byte arrays, with the
* the class writer to be used to convert the attributes into * {@link #write write} method.
* byte arrays, with the {@link #write write} method. * @param code the bytecode of the method corresponding to these code attributes, or
* @param code * <tt>null</tt> if these attributes are not code attributes.
* the bytecode of the method corresponding to these code * @param len the length of the bytecode of the method corresponding to these code attributes,
* attributes, or <tt>null</tt> if these attributes are not code * or <tt>null</tt> if these attributes are not code attributes.
* attributes. * @param maxStack the maximum stack size of the method corresponding to these code attributes,
* @param len * or -1 if these attributes are not code attributes.
* the length of the bytecode of the method corresponding to * @param maxLocals the maximum number of local variables of the method corresponding to these
* these code attributes, or <tt>null</tt> if these attributes * code attributes, or -1 if these attributes are not code attributes.
* are not code attributes. * @return the size of all the attributes in this attribute list. This size includes the size of
* @param maxStack * the attribute headers.
* the maximum stack size of the method corresponding to these
* code attributes, or -1 if these attributes are not code
* attributes.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @return the size of all the attributes in this attribute list. This size
* includes the size of the attribute headers.
*/ */
final int getSize(final ClassWriter cw, final byte[] code, final int len, final int getSize(final ClassWriter cw, final byte[] code, final int len, final int maxStack,
final int maxStack, final int maxLocals) { final int maxLocals) {
Attribute attr = this; Attribute attr = this;
int size = 0; int size = 0;
while (attr != null) { while (attr != null) {
@ -217,33 +178,22 @@ public class Attribute {
} }
/** /**
* Writes all the attributes of this attribute list in the given byte * Writes all the attributes of this attribute list in the given byte vector.
* vector.
* *
* @param cw * @param cw the class writer to be used to convert the attributes into byte arrays, with the
* the class writer to be used to convert the attributes into * {@link #write write} method.
* byte arrays, with the {@link #write write} method. * @param code the bytecode of the method corresponding to these code attributes, or
* @param code * <tt>null</tt> if these attributes are not code attributes.
* the bytecode of the method corresponding to these code * @param len the length of the bytecode of the method corresponding to these code attributes,
* attributes, or <tt>null</tt> if these attributes are not code * or <tt>null</tt> if these attributes are not code attributes.
* attributes. * @param maxStack the maximum stack size of the method corresponding to these code attributes,
* @param len * or -1 if these attributes are not code attributes.
* the length of the bytecode of the method corresponding to * @param maxLocals the maximum number of local variables of the method corresponding to these
* these code attributes, or <tt>null</tt> if these attributes * code attributes, or -1 if these attributes are not code attributes.
* are not code attributes. * @param out where the attributes must be written.
* @param maxStack
* the maximum stack size of the method corresponding to these
* code attributes, or -1 if these attributes are not code
* attributes.
* @param maxLocals
* the maximum number of local variables of the method
* corresponding to these code attributes, or -1 if these
* attributes are not code attributes.
* @param out
* where the attributes must be written.
*/ */
final void put(final ClassWriter cw, final byte[] code, final int len, final void put(final ClassWriter cw, final byte[] code, final int len, final int maxStack,
final int maxStack, final int maxLocals, final ByteVector out) { final int maxLocals, final ByteVector out) {
Attribute attr = this; Attribute attr = this;
while (attr != null) { while (attr != null) {
ByteVector b = attr.write(cw, code, len, maxStack, maxLocals); ByteVector b = attr.write(cw, code, len, maxStack, maxLocals);

View File

@ -1,37 +1,29 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
/** /**
* A dynamically extensible vector of bytes. This class is roughly equivalent to * A dynamically extensible vector of bytes. This class is roughly equivalent to a DataOutputStream
* a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. * on top of a ByteArrayOutputStream, but is more efficient.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@ -48,30 +40,25 @@ public class ByteVector {
int length; int length;
/** /**
* Constructs a new {@link ByteVector ByteVector} with a default initial * Constructs a new {@link ByteVector ByteVector} with a default initial size.
* size.
*/ */
public ByteVector() { public ByteVector() {
data = new byte[64]; data = new byte[64];
} }
/** /**
* Constructs a new {@link ByteVector ByteVector} with the given initial * Constructs a new {@link ByteVector ByteVector} with the given initial size.
* size.
* *
* @param initialSize * @param initialSize the initial size of the byte vector to be constructed.
* the initial size of the byte vector to be constructed.
*/ */
public ByteVector(final int initialSize) { public ByteVector(final int initialSize) {
data = new byte[initialSize]; data = new byte[initialSize];
} }
/** /**
* Puts a byte into this byte vector. The byte vector is automatically * Puts a byte into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param b * @param b a byte.
* a byte.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putByte(final int b) { public ByteVector putByte(final int b) {
@ -85,13 +72,10 @@ public class ByteVector {
} }
/** /**
* Puts two bytes into this byte vector. The byte vector is automatically * Puts two bytes into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param b1 * @param b1 a byte.
* a byte. * @param b2 another byte.
* @param b2
* another byte.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector put11(final int b1, final int b2) { ByteVector put11(final int b1, final int b2) {
@ -107,11 +91,9 @@ public class ByteVector {
} }
/** /**
* Puts a short into this byte vector. The byte vector is automatically * Puts a short into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param s * @param s a short.
* a short.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putShort(final int s) { public ByteVector putShort(final int s) {
@ -127,13 +109,11 @@ public class ByteVector {
} }
/** /**
* Puts a byte and a short into this byte vector. The byte vector is * Puts a byte and a short into this byte vector. The byte vector is automatically enlarged if
* automatically enlarged if necessary. * necessary.
* *
* @param b * @param b a byte.
* a byte. * @param s a short.
* @param s
* a short.
* @return this byte vector. * @return this byte vector.
*/ */
ByteVector put12(final int b, final int s) { ByteVector put12(final int b, final int s) {
@ -150,11 +130,9 @@ public class ByteVector {
} }
/** /**
* Puts an int into this byte vector. The byte vector is automatically * Puts an int into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param i * @param i an int.
* an int.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putInt(final int i) { public ByteVector putInt(final int i) {
@ -172,11 +150,9 @@ public class ByteVector {
} }
/** /**
* Puts a long into this byte vector. The byte vector is automatically * Puts a long into this byte vector. The byte vector is automatically enlarged if necessary.
* enlarged if necessary.
* *
* @param l * @param l a long.
* a long.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putLong(final long l) { public ByteVector putLong(final long l) {
@ -200,11 +176,10 @@ public class ByteVector {
} }
/** /**
* Puts an UTF8 string into this byte vector. The byte vector is * Puts an UTF8 string into this byte vector. The byte vector is automatically enlarged if
* automatically enlarged if necessary. * necessary.
* *
* @param s * @param s a String whose UTF8 encoded length must be less than 65536.
* a String whose UTF8 encoded length must be less than 65536.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putUTF8(final String s) { public ByteVector putUTF8(final String s) {
@ -272,16 +247,13 @@ public class ByteVector {
} }
/** /**
* Puts an array of bytes into this byte vector. The byte vector is * Puts an array of bytes into this byte vector. The byte vector is automatically enlarged if
* automatically enlarged if necessary. * necessary.
* *
* @param b * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt> null bytes into this
* an array of bytes. May be <tt>null</tt> to put <tt>len</tt> * byte vector.
* null bytes into this byte vector. * @param off index of the fist byte of b that must be copied.
* @param off * @param len number of bytes of b that must be copied.
* index of the fist byte of b that must be copied.
* @param len
* number of bytes of b that must be copied.
* @return this byte vector. * @return this byte vector.
*/ */
public ByteVector putByteArray(final byte[] b, final int off, final int len) { public ByteVector putByteArray(final byte[] b, final int off, final int len) {
@ -298,9 +270,7 @@ public class ByteVector {
/** /**
* Enlarge this byte vector so that it can receive n more bytes. * Enlarge this byte vector so that it can receive n more bytes.
* *
* @param size * @param size number of additional bytes that this byte vector should be able to receive.
* number of additional bytes that this byte vector should be
* able to receive.
*/ */
private void enlarge(final int size) { private void enlarge(final int size) {
int length1 = 2 * data.length; int length1 = 2 * data.length;

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,29 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
/** /**
* A visitor to visit a Java class. The methods of this class must be called in * A visitor to visit a Java class. The methods of this class must be called in the following order:
* the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [ * <tt>visit</tt> [ <tt>visitSource</tt> ] [ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> | <tt>visitField</tt> | * <tt>visitAttribute</tt> )* ( <tt>visitInnerClass</tt> | <tt>visitField</tt> |
* <tt>visitMethod</tt> )* <tt>visitEnd</tt>. * <tt>visitMethod</tt> )* <tt>visitEnd</tt>.
* *
@ -41,23 +32,21 @@ package org.objectweb.asm;
public abstract class ClassVisitor { public abstract class ClassVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of
* must be one of {@link Opcodes#ASM4}. * {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* The class visitor to which this visitor must delegate method calls. May * The class visitor to which this visitor must delegate method calls. May be null.
* be null.
*/ */
protected ClassVisitor cv; protected ClassVisitor cv;
/** /**
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}.
*/ */
public ClassVisitor(final int api) { public ClassVisitor(final int api) {
this(api, null); this(api, null);
@ -66,12 +55,9 @@ public abstract class ClassVisitor {
/** /**
* Constructs a new {@link ClassVisitor}. * Constructs a new {@link ClassVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param cv the class visitor to which this visitor must delegate method calls. May be null.
* @param cv
* the class visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public ClassVisitor(final int api, final ClassVisitor cv) { public ClassVisitor(final int api, final ClassVisitor cv) {
if (api != Opcodes.ASM4) { if (api != Opcodes.ASM4) {
@ -84,30 +70,21 @@ public abstract class ClassVisitor {
/** /**
* Visits the header of the class. * Visits the header of the class.
* *
* @param version * @param version the class version.
* the class version. * @param access the class's access flags (see {@link Opcodes}). This parameter also indicates
* @param access * if the class is deprecated.
* the class's access flags (see {@link Opcodes}). This parameter * @param name the internal name of the class (see {@link Type#getInternalName()
* also indicates if the class is deprecated. * getInternalName}).
* @param name * @param signature the signature of this class. May be <tt>null</tt> if the class is not a
* the internal name of the class (see * generic one, and does not extend or implement generic classes or interfaces.
* {@link Type#getInternalName() getInternalName}). * @param superName the internal of name of the super class (see {@link Type#getInternalName()
* @param signature * getInternalName}). For interfaces, the super class is {@link Object}. May be
* the signature of this class. May be <tt>null</tt> if the class * <tt>null</tt>, but only for the {@link Object} class.
* is not a generic one, and does not extend or implement generic * @param interfaces the internal names of the class's interfaces (see
* classes or interfaces. * {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>.
* @param superName
* the internal of name of the super class (see
* {@link Type#getInternalName() getInternalName}). For
* interfaces, the super class is {@link Object}. May be
* <tt>null</tt>, but only for the {@link Object} class.
* @param interfaces
* the internal names of the class's interfaces (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public void visit(int version, int access, String name, String signature, public void visit(int version, int access, String name, String signature, String superName,
String superName, String[] interfaces) { String[] interfaces) {
if (cv != null) { if (cv != null) {
cv.visit(version, access, name, signature, superName, interfaces); cv.visit(version, access, name, signature, superName, interfaces);
} }
@ -116,13 +93,10 @@ public abstract class ClassVisitor {
/** /**
* Visits the source of the class. * Visits the source of the class.
* *
* @param source * @param source the name of the source file from which the class was compiled. May be
* the name of the source file from which the class was compiled. * <tt>null</tt>.
* May be <tt>null</tt>. * @param debug additional debug information to compute the correspondance between source and
* @param debug * compiled elements of the class. May be <tt>null</tt>.
* additional debug information to compute the correspondance
* between source and compiled elements of the class. May be
* <tt>null</tt>.
*/ */
public void visitSource(String source, String debug) { public void visitSource(String source, String debug) {
if (cv != null) { if (cv != null) {
@ -131,19 +105,14 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits the enclosing class of the class. This method must be called only * Visits the enclosing class of the class. This method must be called only if the class has an
* if the class has an enclosing class. * enclosing class.
* *
* @param owner * @param owner internal name of the enclosing class of the class.
* internal name of the enclosing class of the class. * @param name the name of the method that contains the class, or <tt>null</tt> if the class is
* @param name * not enclosed in a method of its enclosing class.
* the name of the method that contains the class, or * @param desc the descriptor of the method that contains the class, or <tt>null</tt> if the
* <tt>null</tt> if the class is not enclosed in a method of its * class is not enclosed in a method of its enclosing class.
* enclosing class.
* @param desc
* the descriptor of the method that contains the class, or
* <tt>null</tt> if the class is not enclosed in a method of its
* enclosing class.
*/ */
public void visitOuterClass(String owner, String name, String desc) { public void visitOuterClass(String owner, String name, String desc) {
if (cv != null) { if (cv != null) {
@ -154,12 +123,10 @@ public abstract class ClassVisitor {
/** /**
* Visits an annotation of the class. * Visits an annotation of the class.
* *
* @param desc * @param desc the class descriptor of the annotation class.
* the class descriptor of the annotation class. * @param visible <tt>true</tt> if the annotation is visible at runtime.
* @param visible * @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
* <tt>true</tt> if the annotation is visible at runtime. * interested in visiting this annotation.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (cv != null) { if (cv != null) {
@ -171,8 +138,7 @@ public abstract class ClassVisitor {
/** /**
* Visits a non standard attribute of the class. * Visits a non standard attribute of the class.
* *
* @param attr * @param attr an attribute.
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (cv != null) { if (cv != null) {
@ -181,25 +147,20 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits information about an inner class. This inner class is not * Visits information about an inner class. This inner class is not necessarily a member of the
* necessarily a member of the class being visited. * class being visited.
* *
* @param name * @param name the internal name of an inner class (see {@link Type#getInternalName()
* the internal name of an inner class (see * getInternalName}).
* {@link Type#getInternalName() getInternalName}). * @param outerName the internal name of the class to which the inner class belongs (see
* @param outerName * {@link Type#getInternalName() getInternalName}). May be <tt>null</tt> for not member
* the internal name of the class to which the inner class * classes.
* belongs (see {@link Type#getInternalName() getInternalName}). * @param innerName the (simple) name of the inner class inside its enclosing class. May be
* May be <tt>null</tt> for not member classes. * <tt>null</tt> for anonymous inner classes.
* @param innerName * @param access the access flags of the inner class as originally declared in the enclosing
* the (simple) name of the inner class inside its enclosing * class.
* class. May be <tt>null</tt> for anonymous inner classes.
* @param access
* the access flags of the inner class as originally declared in
* the enclosing class.
*/ */
public void visitInnerClass(String name, String outerName, public void visitInnerClass(String name, String outerName, String innerName, int access) {
String innerName, int access) {
if (cv != null) { if (cv != null) {
cv.visitInnerClass(name, outerName, innerName, access); cv.visitInnerClass(name, outerName, innerName, access);
} }
@ -208,32 +169,23 @@ public abstract class ClassVisitor {
/** /**
* Visits a field of the class. * Visits a field of the class.
* *
* @param access * @param access the field's access flags (see {@link Opcodes}). This parameter also indicates
* the field's access flags (see {@link Opcodes}). This parameter * if the field is synthetic and/or deprecated.
* also indicates if the field is synthetic and/or deprecated. * @param name the field's name.
* @param name * @param desc the field's descriptor (see {@link Type Type}).
* the field's name. * @param signature the field's signature. May be <tt>null</tt> if the field's type does not use
* @param desc * generic types.
* the field's descriptor (see {@link Type Type}). * @param value the field's initial value. This parameter, which may be <tt>null</tt> if the
* @param signature * field does not have an initial value, must be an {@link Integer}, a {@link Float}, a
* the field's signature. May be <tt>null</tt> if the field's * {@link Long}, a {@link Double} or a {@link String} (for <tt>int</tt>, <tt>float</tt>,
* type does not use generic types. * <tt>long</tt> or <tt>String</tt> fields respectively). <i>This parameter is only used
* @param value * for static fields</i>. Its value is ignored for non static fields, which must be
* the field's initial value. This parameter, which may be * initialized through bytecode instructions in constructors or methods.
* <tt>null</tt> if the field does not have an initial value, * @return a visitor to visit field annotations and attributes, or <tt>null</tt> if this class
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a * visitor is not interested in visiting these annotations and attributes.
* {@link Double} or a {@link String} (for <tt>int</tt>,
* <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
* respectively). <i>This parameter is only used for static
* fields</i>. Its value is ignored for non static fields, which
* must be initialized through bytecode instructions in
* constructors or methods.
* @return a visitor to visit field annotations and attributes, or
* <tt>null</tt> if this class visitor is not interested in visiting
* these annotations and attributes.
*/ */
public FieldVisitor visitField(int access, String name, String desc, public FieldVisitor visitField(int access, String name, String desc, String signature,
String signature, Object value) { Object value) {
if (cv != null) { if (cv != null) {
return cv.visitField(access, name, desc, signature, value); return cv.visitField(access, name, desc, signature, value);
} }
@ -241,32 +193,23 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits a method of the class. This method <i>must</i> return a new * Visits a method of the class. This method <i>must</i> return a new {@link MethodVisitor}
* {@link MethodVisitor} instance (or <tt>null</tt>) each time it is called, * instance (or <tt>null</tt>) each time it is called, i.e., it should not return a previously
* i.e., it should not return a previously returned visitor. * returned visitor.
* *
* @param access * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates
* the method's access flags (see {@link Opcodes}). This * if the method is synthetic and/or deprecated.
* parameter also indicates if the method is synthetic and/or * @param name the method's name.
* deprecated. * @param desc the method's descriptor (see {@link Type Type}).
* @param name * @param signature the method's signature. May be <tt>null</tt> if the method parameters,
* the method's name. * return type and exceptions do not use generic types.
* @param desc * @param exceptions the internal names of the method's exception classes (see
* the method's descriptor (see {@link Type Type}). * {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>.
* @param signature * @return an object to visit the byte code of the method, or <tt>null</tt> if this class
* the method's signature. May be <tt>null</tt> if the method * visitor is not interested in visiting the code of this method.
* parameters, return type and exceptions do not use generic
* types.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
* @return an object to visit the byte code of the method, or <tt>null</tt>
* if this class visitor is not interested in visiting the code of
* this method.
*/ */
public MethodVisitor visitMethod(int access, String name, String desc, public MethodVisitor visitMethod(int access, String name, String desc, String signature,
String signature, String[] exceptions) { String[] exceptions) {
if (cv != null) { if (cv != null) {
return cv.visitMethod(access, name, desc, signature, exceptions); return cv.visitMethod(access, name, desc, signature, exceptions);
} }
@ -274,9 +217,8 @@ public abstract class ClassVisitor {
} }
/** /**
* Visits the end of the class. This method, which is the last one to be * Visits the end of the class. This method, which is the last one to be called, is used to
* called, is used to inform the visitor that all the fields and methods of * inform the visitor that all the fields and methods of the class have been visited.
* the class have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (cv != null) { if (cv != null) {

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
@ -88,8 +80,8 @@ class Context {
int localCount; int localCount;
/** /**
* The number locals in the latest stack map frame that has been parsed, * The number locals in the latest stack map frame that has been parsed, minus the number of
* minus the number of locals in the previous frame. * locals in the previous frame.
*/ */
int localDiff; int localDiff;
@ -107,4 +99,4 @@ class Context {
* The stack values of the latest stack map frame that has been parsed. * The stack values of the latest stack map frame that has been parsed.
*/ */
Object[] stack; Object[] stack;
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
@ -42,23 +34,20 @@ class Edge {
static final int NORMAL = 0; static final int NORMAL = 0;
/** /**
* Denotes a control flow graph edge corresponding to an exception handler. * Denotes a control flow graph edge corresponding to an exception handler. More precisely any
* More precisely any {@link Edge} whose {@link #info} is strictly positive * {@link Edge} whose {@link #info} is strictly positive corresponds to an exception handler.
* corresponds to an exception handler. The actual value of {@link #info} is * The actual value of {@link #info} is the index, in the {@link ClassWriter} type table, of the
* the index, in the {@link ClassWriter} type table, of the exception that * exception that is catched.
* is catched.
*/ */
static final int EXCEPTION = 0x7FFFFFFF; static final int EXCEPTION = 0x7FFFFFFF;
/** /**
* Information about this control flow graph edge. If * Information about this control flow graph edge. If {@link ClassWriter#COMPUTE_MAXS} is used
* {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative) * this field is the (relative) stack size in the basic block from which this edge originates.
* stack size in the basic block from which this edge originates. This size * This size is equal to the stack size at the "jump" instruction to which this edge
* is equal to the stack size at the "jump" instruction to which this edge * corresponds, relatively to the stack size at the beginning of the originating basic block. If
* corresponds, relatively to the stack size at the beginning of the * {@link ClassWriter#COMPUTE_FRAMES} is used, this field is the kind of this control flow graph
* originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used, * edge (i.e. NORMAL or EXCEPTION).
* this field is the kind of this control flow graph edge (i.e. NORMAL or
* EXCEPTION).
*/ */
int info; int info;
@ -68,8 +57,8 @@ class Edge {
Label successor; Label successor;
/** /**
* The next edge in the list of successors of the originating basic block. * The next edge in the list of successors of the originating basic block. See
* See {@link Label#successors successors}. * {@link Label#successors successors}.
*/ */
Edge next; Edge next;
} }

View File

@ -1,61 +1,50 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
/** /**
* A visitor to visit a Java field. The methods of this class must be called in * A visitor to visit a Java field. The methods of this class must be called in the following order:
* the following order: ( <tt>visitAnnotation</tt> | <tt>visitAttribute</tt> )* * ( <tt>visitAnnotation</tt> | <tt>visitAttribute</tt> )* <tt>visitEnd</tt>.
* <tt>visitEnd</tt>.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public abstract class FieldVisitor { public abstract class FieldVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of
* must be one of {@link Opcodes#ASM4}. * {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* The field visitor to which this visitor must delegate method calls. May * The field visitor to which this visitor must delegate method calls. May be null.
* be null.
*/ */
protected FieldVisitor fv; protected FieldVisitor fv;
/** /**
* Constructs a new {@link FieldVisitor}. * Constructs a new {@link FieldVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}.
*/ */
public FieldVisitor(final int api) { public FieldVisitor(final int api) {
this(api, null); this(api, null);
@ -64,12 +53,9 @@ public abstract class FieldVisitor {
/** /**
* Constructs a new {@link FieldVisitor}. * Constructs a new {@link FieldVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param fv the field visitor to which this visitor must delegate method calls. May be null.
* @param fv
* the field visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public FieldVisitor(final int api, final FieldVisitor fv) { public FieldVisitor(final int api, final FieldVisitor fv) {
if (api != Opcodes.ASM4) { if (api != Opcodes.ASM4) {
@ -82,12 +68,10 @@ public abstract class FieldVisitor {
/** /**
* Visits an annotation of the field. * Visits an annotation of the field.
* *
* @param desc * @param desc the class descriptor of the annotation class.
* the class descriptor of the annotation class. * @param visible <tt>true</tt> if the annotation is visible at runtime.
* @param visible * @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
* <tt>true</tt> if the annotation is visible at runtime. * interested in visiting this annotation.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (fv != null) { if (fv != null) {
@ -99,8 +83,7 @@ public abstract class FieldVisitor {
/** /**
* Visits a non standard attribute of the field. * Visits a non standard attribute of the field.
* *
* @param attr * @param attr an attribute.
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (fv != null) { if (fv != null) {
@ -109,9 +92,8 @@ public abstract class FieldVisitor {
} }
/** /**
* Visits the end of the field. This method, which is the last one to be * Visits the end of the field. This method, which is the last one to be called, is used to
* called, is used to inform the visitor that all the annotations and * inform the visitor that all the annotations and attributes of the field have been visited.
* attributes of the field have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (fv != null) { if (fv != null) {

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
@ -47,26 +39,22 @@ final class FieldWriter extends FieldVisitor {
private final int access; private final int access;
/** /**
* The index of the constant pool item that contains the name of this * The index of the constant pool item that contains the name of this method.
* method.
*/ */
private final int name; private final int name;
/** /**
* The index of the constant pool item that contains the descriptor of this * The index of the constant pool item that contains the descriptor of this field.
* field.
*/ */
private final int desc; private final int desc;
/** /**
* The index of the constant pool item that contains the signature of this * The index of the constant pool item that contains the signature of this field.
* field.
*/ */
private int signature; private int signature;
/** /**
* The index of the constant pool item that contains the constant value of * The index of the constant pool item that contains the constant value of this field.
* this field.
*/ */
private int value; private int value;
@ -92,21 +80,15 @@ final class FieldWriter extends FieldVisitor {
/** /**
* Constructs a new {@link FieldWriter}. * Constructs a new {@link FieldWriter}.
* *
* @param cw * @param cw the class writer to which this field must be added.
* the class writer to which this field must be added. * @param access the field's access flags (see {@link Opcodes}).
* @param access * @param name the field's name.
* the field's access flags (see {@link Opcodes}). * @param desc the field's descriptor (see {@link Type}).
* @param name * @param signature the field's signature. May be <tt>null</tt>.
* the field's name. * @param value the field's constant value. May be <tt>null</tt>.
* @param desc
* the field's descriptor (see {@link Type}).
* @param signature
* the field's signature. May be <tt>null</tt>.
* @param value
* the field's constant value. May be <tt>null</tt>.
*/ */
FieldWriter(final ClassWriter cw, final int access, final String name, FieldWriter(final ClassWriter cw, final int access, final String name, final String desc,
final String desc, final String signature, final Object value) { final String signature, final Object value) {
super(Opcodes.ASM4); super(Opcodes.ASM4);
if (cw.firstField == null) { if (cw.firstField == null) {
cw.firstField = this; cw.firstField = this;
@ -131,8 +113,7 @@ final class FieldWriter extends FieldVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
final boolean visible) {
if (!ClassReader.ANNOTATIONS) { if (!ClassReader.ANNOTATIONS) {
return null; return null;
} }
@ -157,8 +138,7 @@ final class FieldWriter extends FieldVisitor {
} }
@Override @Override
public void visitEnd() { public void visitEnd() {}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Utility methods // Utility methods
@ -207,8 +187,7 @@ final class FieldWriter extends FieldVisitor {
/** /**
* Puts the content of this field into the given byte vector. * Puts the content of this field into the given byte vector.
* *
* @param out * @param out where the content of this field must be put.
* where the content of this field must be put.
*/ */
void put(final ByteVector out) { void put(final ByteVector out) {
final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC;

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
@ -39,9 +31,8 @@ package org.objectweb.asm;
public final class Handle { public final class Handle {
/** /**
* The kind of field or method designated by this Handle. Should be * The kind of field or method designated by this Handle. Should be {@link Opcodes#H_GETFIELD},
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC},
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC},
* {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}. * {@link Opcodes#H_INVOKEINTERFACE}.
@ -49,8 +40,7 @@ public final class Handle {
final int tag; final int tag;
/** /**
* The internal name of the class that owns the field or method designated * The internal name of the class that owns the field or method designated by this handle.
* by this handle.
*/ */
final String owner; final String owner;
@ -67,23 +57,15 @@ public final class Handle {
/** /**
* Constructs a new field or method handle. * Constructs a new field or method handle.
* *
* @param tag * @param tag the kind of field or method designated by this Handle. Must be
* the kind of field or method designated by this Handle. Must be * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
* {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, * {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_INVOKEVIRTUAL}, * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
* {@link Opcodes#H_INVOKESTATIC}, * @param owner the internal name of the class that owns the field or method designated by this
* {@link Opcodes#H_INVOKESPECIAL}, * handle.
* {@link Opcodes#H_NEWINVOKESPECIAL} or * @param name the name of the field or method designated by this handle.
* {@link Opcodes#H_INVOKEINTERFACE}. * @param desc the descriptor of the field or method designated by this handle.
* @param owner
* the internal name of the class that owns the field or method
* designated by this handle.
* @param name
* the name of the field or method designated by this handle.
* @param desc
* the descriptor of the field or method designated by this
* handle.
*/ */
public Handle(int tag, String owner, String name, String desc) { public Handle(int tag, String owner, String name, String desc) {
this.tag = tag; this.tag = tag;
@ -95,23 +77,21 @@ public final class Handle {
/** /**
* Returns the kind of field or method designated by this handle. * Returns the kind of field or method designated by this handle.
* *
* @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD},
* {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL},
* {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, * {@link Opcodes#H_INVOKESTATIC}, {@link Opcodes#H_INVOKESPECIAL},
* {@link Opcodes#H_INVOKESPECIAL}, * {@link Opcodes#H_NEWINVOKESPECIAL} or {@link Opcodes#H_INVOKEINTERFACE}.
* {@link Opcodes#H_NEWINVOKESPECIAL} or
* {@link Opcodes#H_INVOKEINTERFACE}.
*/ */
public int getTag() { public int getTag() {
return tag; return tag;
} }
/** /**
* Returns the internal name of the class that owns the field or method * Returns the internal name of the class that owns the field or method designated by this
* designated by this handle. * handle.
* *
* @return the internal name of the class that owns the field or method * @return the internal name of the class that owns the field or method designated by this
* designated by this handle. * handle.
*/ */
public String getOwner() { public String getOwner() {
return owner; return owner;
@ -144,8 +124,7 @@ public final class Handle {
return false; return false;
} }
Handle h = (Handle) obj; Handle h = (Handle) obj;
return tag == h.tag && owner.equals(h.owner) && name.equals(h.name) return tag == h.tag && owner.equals(h.owner) && name.equals(h.name) && desc.equals(h.desc);
&& desc.equals(h.desc);
} }
@Override @Override
@ -154,8 +133,7 @@ public final class Handle {
} }
/** /**
* Returns the textual representation of this handle. The textual * Returns the textual representation of this handle. The textual representation is:
* representation is:
* *
* <pre> * <pre>
* owner '.' name desc ' ' '(' tag ')' * owner '.' name desc ' ' '(' tag ')'

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
@ -52,14 +44,14 @@ class Handler {
Label handler; Label handler;
/** /**
* Internal name of the type of exceptions handled by this handler, or * Internal name of the type of exceptions handled by this handler, or <tt>null</tt> to catch
* <tt>null</tt> to catch any exceptions. * any exceptions.
*/ */
String desc; String desc;
/** /**
* Constant pool index of the internal name of the type of exceptions * Constant pool index of the internal name of the type of exceptions handled by this handler,
* handled by this handler, or 0 to catch any exceptions. * or 0 to catch any exceptions.
*/ */
int type; int type;
@ -69,15 +61,11 @@ class Handler {
Handler next; Handler next;
/** /**
* Removes the range between start and end from the given exception * Removes the range between start and end from the given exception handlers.
* handlers.
* *
* @param h * @param h an exception handler list.
* an exception handler list. * @param start the start of the range to be removed.
* @param start * @param end the end of the range to be removed. Maybe null.
* the start of the range to be removed.
* @param end
* the end of the range to be removed. Maybe null.
* @return the exception handler list with the start-end range removed. * @return the exception handler list with the start-end range removed.
*/ */
static Handler remove(Handler h, Label start, Label end) { static Handler remove(Handler h, Label start, Label end) {

View File

@ -1,37 +1,29 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
/** /**
* A constant pool item. Constant pool items can be created with the 'newXXX' * A constant pool item. Constant pool items can be created with the 'newXXX' methods in the
* methods in the {@link ClassWriter} class. * {@link ClassWriter} class.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@ -43,25 +35,21 @@ final class Item {
int index; int index;
/** /**
* Type of this constant pool item. A single class is used to represent all * Type of this constant pool item. A single class is used to represent all constant pool item
* constant pool item types, in order to minimize the bytecode size of this * types, in order to minimize the bytecode size of this package. The value of this field is one
* package. The value of this field is one of {@link ClassWriter#INT}, * of {@link ClassWriter#INT}, {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT},
* {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, {@link ClassWriter#STR},
* {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, * {@link ClassWriter#CLASS}, {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
* {@link ClassWriter#STR}, {@link ClassWriter#CLASS}, * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}, {@link ClassWriter#MTYPE},
* {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD}, * {@link ClassWriter#INDY}.
* {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
* {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
* *
* MethodHandle constant 9 variations are stored using a range of 9 values * MethodHandle constant 9 variations are stored using a range of 9 values from
* from {@link ClassWriter#HANDLE_BASE} + 1 to * {@link ClassWriter#HANDLE_BASE} + 1 to {@link ClassWriter#HANDLE_BASE} + 9.
* {@link ClassWriter#HANDLE_BASE} + 9.
* *
* Special Item types are used for Items that are stored in the ClassWriter * Special Item types are used for Items that are stored in the ClassWriter
* {@link ClassWriter#typeTable}, instead of the constant pool, in order to * {@link ClassWriter#typeTable}, instead of the constant pool, in order to avoid clashes with
* avoid clashes with normal constant pool items in the ClassWriter constant * normal constant pool items in the ClassWriter constant pool's hash table. These special item
* pool's hash table. These special item types are * types are {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
* {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and
* {@link ClassWriter#TYPE_MERGED}. * {@link ClassWriter#TYPE_MERGED}.
*/ */
int type; int type;
@ -77,20 +65,17 @@ final class Item {
long longVal; long longVal;
/** /**
* First part of the value of this item, for items that do not hold a * First part of the value of this item, for items that do not hold a primitive value.
* primitive value.
*/ */
String strVal1; String strVal1;
/** /**
* Second part of the value of this item, for items that do not hold a * Second part of the value of this item, for items that do not hold a primitive value.
* primitive value.
*/ */
String strVal2; String strVal2;
/** /**
* Third part of the value of this item, for items that do not hold a * Third part of the value of this item, for items that do not hold a primitive value.
* primitive value.
*/ */
String strVal3; String strVal3;
@ -100,23 +85,20 @@ final class Item {
int hashCode; int hashCode;
/** /**
* Link to another constant pool item, used for collision lists in the * Link to another constant pool item, used for collision lists in the constant pool's hash
* constant pool's hash table. * table.
*/ */
Item next; Item next;
/** /**
* Constructs an uninitialized {@link Item}. * Constructs an uninitialized {@link Item}.
*/ */
Item() { Item() {}
}
/** /**
* Constructs an uninitialized {@link Item} for constant pool element at * Constructs an uninitialized {@link Item} for constant pool element at given position.
* given position.
* *
* @param index * @param index index of the item to be constructed.
* index of the item to be constructed.
*/ */
Item(final int index) { Item(final int index) {
this.index = index; this.index = index;
@ -125,10 +107,8 @@ final class Item {
/** /**
* Constructs a copy of the given item. * Constructs a copy of the given item.
* *
* @param index * @param index index of the item to be constructed.
* index of the item to be constructed. * @param i the item that must be copied into the item to be constructed.
* @param i
* the item that must be copied into the item to be constructed.
*/ */
Item(final int index, final Item i) { Item(final int index, final Item i) {
this.index = index; this.index = index;
@ -144,8 +124,7 @@ final class Item {
/** /**
* Sets this item to an integer item. * Sets this item to an integer item.
* *
* @param intVal * @param intVal the value of this item.
* the value of this item.
*/ */
void set(final int intVal) { void set(final int intVal) {
this.type = ClassWriter.INT; this.type = ClassWriter.INT;
@ -156,8 +135,7 @@ final class Item {
/** /**
* Sets this item to a long item. * Sets this item to a long item.
* *
* @param longVal * @param longVal the value of this item.
* the value of this item.
*/ */
void set(final long longVal) { void set(final long longVal) {
this.type = ClassWriter.LONG; this.type = ClassWriter.LONG;
@ -168,8 +146,7 @@ final class Item {
/** /**
* Sets this item to a float item. * Sets this item to a float item.
* *
* @param floatVal * @param floatVal the value of this item.
* the value of this item.
*/ */
void set(final float floatVal) { void set(final float floatVal) {
this.type = ClassWriter.FLOAT; this.type = ClassWriter.FLOAT;
@ -180,8 +157,7 @@ final class Item {
/** /**
* Sets this item to a double item. * Sets this item to a double item.
* *
* @param doubleVal * @param doubleVal the value of this item.
* the value of this item.
*/ */
void set(final double doubleVal) { void set(final double doubleVal) {
this.type = ClassWriter.DOUBLE; this.type = ClassWriter.DOUBLE;
@ -192,72 +168,60 @@ final class Item {
/** /**
* Sets this item to an item that do not hold a primitive value. * Sets this item to an item that do not hold a primitive value.
* *
* @param type * @param type the type of this item.
* the type of this item. * @param strVal1 first part of the value of this item.
* @param strVal1 * @param strVal2 second part of the value of this item.
* first part of the value of this item. * @param strVal3 third part of the value of this item.
* @param strVal2
* second part of the value of this item.
* @param strVal3
* third part of the value of this item.
*/ */
void set(final int type, final String strVal1, final String strVal2, void set(final int type, final String strVal1, final String strVal2, final String strVal3) {
final String strVal3) {
this.type = type; this.type = type;
this.strVal1 = strVal1; this.strVal1 = strVal1;
this.strVal2 = strVal2; this.strVal2 = strVal2;
this.strVal3 = strVal3; this.strVal3 = strVal3;
switch (type) { switch (type) {
case ClassWriter.UTF8: case ClassWriter.UTF8:
case ClassWriter.STR: case ClassWriter.STR:
case ClassWriter.CLASS: case ClassWriter.CLASS:
case ClassWriter.MTYPE: case ClassWriter.MTYPE:
case ClassWriter.TYPE_NORMAL: case ClassWriter.TYPE_NORMAL:
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
return; return;
case ClassWriter.NAME_TYPE: { case ClassWriter.NAME_TYPE: {
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() * strVal2.hashCode());
* strVal2.hashCode()); return;
return; }
} // ClassWriter.FIELD:
// ClassWriter.FIELD: // ClassWriter.METH:
// ClassWriter.METH: // ClassWriter.IMETH:
// ClassWriter.IMETH: // ClassWriter.HANDLE_BASE + 1..9
// ClassWriter.HANDLE_BASE + 1..9 default:
default: hashCode = 0x7FFFFFFF
hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() & (type + strVal1.hashCode() * strVal2.hashCode() * strVal3.hashCode());
* strVal2.hashCode() * strVal3.hashCode());
} }
} }
/** /**
* Sets the item to an InvokeDynamic item. * Sets the item to an InvokeDynamic item.
* *
* @param name * @param name invokedynamic's name.
* invokedynamic's name. * @param desc invokedynamic's desc.
* @param desc * @param bsmIndex zero based index into the class attribute BootrapMethods.
* invokedynamic's desc.
* @param bsmIndex
* zero based index into the class attribute BootrapMethods.
*/ */
void set(String name, String desc, int bsmIndex) { void set(String name, String desc, int bsmIndex) {
this.type = ClassWriter.INDY; this.type = ClassWriter.INDY;
this.longVal = bsmIndex; this.longVal = bsmIndex;
this.strVal1 = name; this.strVal1 = name;
this.strVal2 = desc; this.strVal2 = desc;
this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex this.hashCode = 0x7FFFFFFF
* strVal1.hashCode() * strVal2.hashCode()); & (ClassWriter.INDY + bsmIndex * strVal1.hashCode() * strVal2.hashCode());
} }
/** /**
* Sets the item to a BootstrapMethod item. * Sets the item to a BootstrapMethod item.
* *
* @param position * @param position position in byte in the class attribute BootrapMethods.
* position in byte in the class attribute BootrapMethods. * @param hashCode hashcode of the item. This hashcode is processed from the hashcode of the
* @param hashCode * bootstrap method and the hashcode of all bootstrap arguments.
* hashcode of the item. This hashcode is processed from the
* hashcode of the bootstrap method and the hashcode of all
* bootstrap arguments.
*/ */
void set(int position, int hashCode) { void set(int position, int hashCode) {
this.type = ClassWriter.BSM; this.type = ClassWriter.BSM;
@ -266,45 +230,42 @@ final class Item {
} }
/** /**
* Indicates if the given item is equal to this one. <i>This method assumes * Indicates if the given item is equal to this one. <i>This method assumes that the two items
* that the two items have the same {@link #type}</i>. * have the same {@link #type}</i>.
* *
* @param i * @param i the item to be compared to this one. Both items must have the same {@link #type}.
* the item to be compared to this one. Both items must have the * @return <tt>true</tt> if the given item if equal to this one, <tt>false</tt> otherwise.
* same {@link #type}.
* @return <tt>true</tt> if the given item if equal to this one,
* <tt>false</tt> otherwise.
*/ */
boolean isEqualTo(final Item i) { boolean isEqualTo(final Item i) {
switch (type) { switch (type) {
case ClassWriter.UTF8: case ClassWriter.UTF8:
case ClassWriter.STR: case ClassWriter.STR:
case ClassWriter.CLASS: case ClassWriter.CLASS:
case ClassWriter.MTYPE: case ClassWriter.MTYPE:
case ClassWriter.TYPE_NORMAL: case ClassWriter.TYPE_NORMAL:
return i.strVal1.equals(strVal1); return i.strVal1.equals(strVal1);
case ClassWriter.TYPE_MERGED: case ClassWriter.TYPE_MERGED:
case ClassWriter.LONG: case ClassWriter.LONG:
case ClassWriter.DOUBLE: case ClassWriter.DOUBLE:
return i.longVal == longVal; return i.longVal == longVal;
case ClassWriter.INT: case ClassWriter.INT:
case ClassWriter.FLOAT: case ClassWriter.FLOAT:
return i.intVal == intVal; return i.intVal == intVal;
case ClassWriter.TYPE_UNINIT: case ClassWriter.TYPE_UNINIT:
return i.intVal == intVal && i.strVal1.equals(strVal1); return i.intVal == intVal && i.strVal1.equals(strVal1);
case ClassWriter.NAME_TYPE: case ClassWriter.NAME_TYPE:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2);
case ClassWriter.INDY: { case ClassWriter.INDY: {
return i.longVal == longVal && i.strVal1.equals(strVal1) return i.longVal == longVal && i.strVal1.equals(strVal1)
&& i.strVal2.equals(strVal2); && i.strVal2.equals(strVal2);
} }
// case ClassWriter.FIELD: // case ClassWriter.FIELD:
// case ClassWriter.METH: // case ClassWriter.METH:
// case ClassWriter.IMETH: // case ClassWriter.IMETH:
// case ClassWriter.HANDLE_BASE + 1..9 // case ClassWriter.HANDLE_BASE + 1..9
default: default:
return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2)
&& i.strVal3.equals(strVal3); && i.strVal3.equals(strVal3);
} }
} }

View File

@ -1,50 +1,40 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
/** /**
* A label represents a position in the bytecode of a method. Labels are used * A label represents a position in the bytecode of a method. Labels are used for jump, goto, and
* for jump, goto, and switch instructions, and for try catch blocks. A label * switch instructions, and for try catch blocks. A label designates the <i>instruction</i> that is
* designates the <i>instruction</i> that is just after. Note however that there * just after. Note however that there can be other elements between a label and the instruction it
* can be other elements between a label and the instruction it designates (such * designates (such as other labels, stack map frames, line numbers, etc.).
* as other labels, stack map frames, line numbers, etc.).
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class Label { public class Label {
/** /**
* Indicates if this label is only used for debug attributes. Such a label * Indicates if this label is only used for debug attributes. Such a label is not the start of a
* is not the start of a basic block, the target of a jump instruction, or * basic block, the target of a jump instruction, or an exception handler. It can be safely
* an exception handler. It can be safely ignored in control flow graph * ignored in control flow graph analysis algorithms (for optimization purposes).
* analysis algorithms (for optimization purposes).
*/ */
static final int DEBUG = 1; static final int DEBUG = 1;
@ -59,14 +49,14 @@ public class Label {
static final int RESIZED = 4; static final int RESIZED = 4;
/** /**
* Indicates if this basic block has been pushed in the basic block stack. * Indicates if this basic block has been pushed in the basic block stack. See
* See {@link MethodWriter#visitMaxs visitMaxs}. * {@link MethodWriter#visitMaxs visitMaxs}.
*/ */
static final int PUSHED = 8; static final int PUSHED = 8;
/** /**
* Indicates if this label is the target of a jump instruction, or the start * Indicates if this label is the target of a jump instruction, or the start of an exception
* of an exception handler. * handler.
*/ */
static final int TARGET = 16; static final int TARGET = 16;
@ -96,21 +86,20 @@ public class Label {
static final int SUBROUTINE = 512; static final int SUBROUTINE = 512;
/** /**
* Indicates if this subroutine basic block has been visited by a * Indicates if this subroutine basic block has been visited by a visitSubroutine(null, ...)
* visitSubroutine(null, ...) call. * call.
*/ */
static final int VISITED = 1024; static final int VISITED = 1024;
/** /**
* Indicates if this subroutine basic block has been visited by a * Indicates if this subroutine basic block has been visited by a visitSubroutine(!null, ...)
* visitSubroutine(!null, ...) call. * call.
*/ */
static final int VISITED2 = 2048; static final int VISITED2 = 2048;
/** /**
* Field used to associate user information to a label. Warning: this field * Field used to associate user information to a label. Warning: this field is used by the ASM
* is used by the ASM tree package. In order to use it with the ASM tree * tree package. In order to use it with the ASM tree package you must override the
* package you must override the
* {@link org.objectweb.asm.tree.MethodNode#getLabelNode} method. * {@link org.objectweb.asm.tree.MethodNode#getLabelNode} method.
*/ */
public Object info; public Object info;
@ -146,100 +135,89 @@ public class Label {
private int referenceCount; private int referenceCount;
/** /**
* Informations about forward references. Each forward reference is * Informations about forward references. Each forward reference is described by two consecutive
* described by two consecutive integers in this array: the first one is the * integers in this array: the first one is the position of the first byte of the bytecode
* position of the first byte of the bytecode instruction that contains the * instruction that contains the forward reference, while the second is the position of the
* forward reference, while the second is the position of the first byte of * first byte of the forward reference itself. In fact the sign of the first integer indicates
* the forward reference itself. In fact the sign of the first integer * if this reference uses 2 or 4 bytes, and its absolute value gives the position of the
* indicates if this reference uses 2 or 4 bytes, and its absolute value * bytecode instruction. This array is also used as a bitset to store the subroutines to which a
* gives the position of the bytecode instruction. This array is also used * basic block belongs. This information is needed in {@linked MethodWriter#visitMaxs}, after
* as a bitset to store the subroutines to which a basic block belongs. This * all forward references have been resolved. Hence the same array can be used for both purposes
* information is needed in {@linked MethodWriter#visitMaxs}, after all * without problems.
* forward references have been resolved. Hence the same array can be used
* for both purposes without problems.
*/ */
private int[] srcAndRefPositions; private int[] srcAndRefPositions;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/* /*
* Fields for the control flow and data flow graph analysis algorithms (used * Fields for the control flow and data flow graph analysis algorithms (used to compute the
* to compute the maximum stack size or the stack map frames). A control * maximum stack size or the stack map frames). A control flow graph contains one node per
* flow graph contains one node per "basic block", and one edge per "jump" * "basic block", and one edge per "jump" from one basic block to another. Each node (i.e., each
* from one basic block to another. Each node (i.e., each basic block) is * basic block) is represented by the Label object that corresponds to the first instruction of
* represented by the Label object that corresponds to the first instruction * this basic block. Each node also stores the list of its successors in the graph, as a linked
* of this basic block. Each node also stores the list of its successors in * list of Edge objects.
* the graph, as a linked list of Edge objects.
* *
* The control flow analysis algorithms used to compute the maximum stack * The control flow analysis algorithms used to compute the maximum stack size or the stack map
* size or the stack map frames are similar and use two steps. The first * frames are similar and use two steps. The first step, during the visit of each instruction,
* step, during the visit of each instruction, builds information about the * builds information about the state of the local variables and the operand stack at the end of
* state of the local variables and the operand stack at the end of each * each basic block, called the "output frame", <i>relatively</i> to the frame state at the
* basic block, called the "output frame", <i>relatively</i> to the frame * beginning of the basic block, which is called the "input frame", and which is <i>unknown</i>
* state at the beginning of the basic block, which is called the "input * during this step. The second step, in {@link MethodWriter#visitMaxs}, is a fix point
* frame", and which is <i>unknown</i> during this step. The second step, in * algorithm that computes information about the input frame of each basic block, from the input
* {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes * state of the first basic block (known from the method signature), and by the using the
* information about the input frame of each basic block, from the input * previously computed relative output frames.
* state of the first basic block (known from the method signature), and by
* the using the previously computed relative output frames.
* *
* The algorithm used to compute the maximum stack size only computes the * The algorithm used to compute the maximum stack size only computes the relative output and
* relative output and absolute input stack heights, while the algorithm * absolute input stack heights, while the algorithm used to compute stack map frames computes
* used to compute stack map frames computes relative output frames and * relative output frames and absolute input frames.
* absolute input frames.
*/ */
/** /**
* Start of the output stack relatively to the input stack. The exact * Start of the output stack relatively to the input stack. The exact semantics of this field
* semantics of this field depends on the algorithm that is used. * depends on the algorithm that is used.
* *
* When only the maximum stack size is computed, this field is the number of * When only the maximum stack size is computed, this field is the number of elements in the
* elements in the input stack. * input stack.
* *
* When the stack map frames are completely computed, this field is the * When the stack map frames are completely computed, this field is the offset of the first
* offset of the first output stack element relatively to the top of the * output stack element relatively to the top of the input stack. This offset is always negative
* input stack. This offset is always negative or null. A null offset means * or null. A null offset means that the output stack must be appended to the input stack. A -n
* that the output stack must be appended to the input stack. A -n offset * offset means that the first n output stack elements must replace the top n input stack
* means that the first n output stack elements must replace the top n input * elements, and that the other elements must be appended to the input stack.
* stack elements, and that the other elements must be appended to the input
* stack.
*/ */
int inputStackTop; int inputStackTop;
/** /**
* Maximum height reached by the output stack, relatively to the top of the * Maximum height reached by the output stack, relatively to the top of the input stack. This
* input stack. This maximum is always positive or null. * maximum is always positive or null.
*/ */
int outputStackMax; int outputStackMax;
/** /**
* Information about the input and output stack map frames of this basic * Information about the input and output stack map frames of this basic block. This field is
* block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES} * only used when {@link ClassWriter#COMPUTE_FRAMES} option is used.
* option is used.
*/ */
Frame frame; Frame frame;
/** /**
* The successor of this label, in the order they are visited. This linked * The successor of this label, in the order they are visited. This linked list does not include
* list does not include labels used for debug info only. If * labels used for debug info only. If {@link ClassWriter#COMPUTE_FRAMES} option is used then,
* {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it * in addition, it does not contain successive labels that denote the same bytecode position (in
* does not contain successive labels that denote the same bytecode position * this case only the first label appears in this list).
* (in this case only the first label appears in this list).
*/ */
Label successor; Label successor;
/** /**
* The successors of this node in the control flow graph. These successors * The successors of this node in the control flow graph. These successors are stored in a
* are stored in a linked list of {@link Edge Edge} objects, linked to each * linked list of {@link Edge Edge} objects, linked to each other by their {@link Edge#next}
* other by their {@link Edge#next} field. * field.
*/ */
Edge successors; Edge successors;
/** /**
* The next basic block in the basic block stack. This stack is used in the * The next basic block in the basic block stack. This stack is used in the main loop of the fix
* main loop of the fix point algorithm used in the second step of the * point algorithm used in the second step of the control flow analysis algorithms. It is also
* control flow analysis algorithms. It is also used in * used in {@link #visitSubroutine} to avoid using a recursive method.
* {@link #visitSubroutine} to avoid using a recursive method.
* *
* @see MethodWriter#visitMaxs * @see MethodWriter#visitMaxs
*/ */
@ -252,49 +230,39 @@ public class Label {
/** /**
* Constructs a new label. * Constructs a new label.
*/ */
public Label() { public Label() {}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Methods to compute offsets and to manage forward references // Methods to compute offsets and to manage forward references
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the offset corresponding to this label. This offset is computed * Returns the offset corresponding to this label. This offset is computed from the start of the
* from the start of the method's bytecode. <i>This method is intended for * method's bytecode. <i>This method is intended for {@link Attribute} sub classes, and is
* {@link Attribute} sub classes, and is normally not needed by class * normally not needed by class generators or adapters.</i>
* generators or adapters.</i>
* *
* @return the offset corresponding to this label. * @return the offset corresponding to this label.
* @throws IllegalStateException * @throws IllegalStateException if this label is not resolved yet.
* if this label is not resolved yet.
*/ */
public int getOffset() { public int getOffset() {
if ((status & RESOLVED) == 0) { if ((status & RESOLVED) == 0) {
throw new IllegalStateException( throw new IllegalStateException("Label offset position has not been resolved yet");
"Label offset position has not been resolved yet");
} }
return position; return position;
} }
/** /**
* Puts a reference to this label in the bytecode of a method. If the * Puts a reference to this label in the bytecode of a method. If the position of the label is
* position of the label is known, the offset is computed and written * known, the offset is computed and written directly. Otherwise, a null offset is written and a
* directly. Otherwise, a null offset is written and a new forward reference * new forward reference is declared for this label.
* is declared for this label.
* *
* @param owner * @param owner the code writer that calls this method.
* the code writer that calls this method. * @param out the bytecode of the method.
* @param out * @param source the position of first byte of the bytecode instruction that contains this
* the bytecode of the method. * label.
* @param source * @param wideOffset <tt>true</tt> if the reference must be stored in 4 bytes, or <tt>false</tt>
* the position of first byte of the bytecode instruction that * if it must be stored with 2 bytes.
* contains this label. * @throws IllegalArgumentException if this label has not been created by the given code writer.
* @param wideOffset
* <tt>true</tt> if the reference must be stored in 4 bytes, or
* <tt>false</tt> if it must be stored with 2 bytes.
* @throws IllegalArgumentException
* if this label has not been created by the given code writer.
*/ */
void put(final MethodWriter owner, final ByteVector out, final int source, void put(final MethodWriter owner, final ByteVector out, final int source,
final boolean wideOffset) { final boolean wideOffset) {
@ -316,27 +284,22 @@ public class Label {
} }
/** /**
* Adds a forward reference to this label. This method must be called only * Adds a forward reference to this label. This method must be called only for a true forward
* for a true forward reference, i.e. only if this label is not resolved * reference, i.e. only if this label is not resolved yet. For backward references, the offset
* yet. For backward references, the offset of the reference can be, and * of the reference can be, and must be, computed and stored directly.
* must be, computed and stored directly.
* *
* @param sourcePosition * @param sourcePosition the position of the referencing instruction. This position will be used
* the position of the referencing instruction. This position * to compute the offset of this forward reference.
* will be used to compute the offset of this forward reference. * @param referencePosition the position where the offset for this forward reference must be
* @param referencePosition * stored.
* the position where the offset for this forward reference must
* be stored.
*/ */
private void addReference(final int sourcePosition, private void addReference(final int sourcePosition, final int referencePosition) {
final int referencePosition) {
if (srcAndRefPositions == null) { if (srcAndRefPositions == null) {
srcAndRefPositions = new int[6]; srcAndRefPositions = new int[6];
} }
if (referenceCount >= srcAndRefPositions.length) { if (referenceCount >= srcAndRefPositions.length) {
int[] a = new int[srcAndRefPositions.length + 6]; int[] a = new int[srcAndRefPositions.length + 6];
System.arraycopy(srcAndRefPositions, 0, a, 0, System.arraycopy(srcAndRefPositions, 0, a, 0, srcAndRefPositions.length);
srcAndRefPositions.length);
srcAndRefPositions = a; srcAndRefPositions = a;
} }
srcAndRefPositions[referenceCount++] = sourcePosition; srcAndRefPositions[referenceCount++] = sourcePosition;
@ -344,30 +307,23 @@ public class Label {
} }
/** /**
* Resolves all forward references to this label. This method must be called * Resolves all forward references to this label. This method must be called when this label is
* when this label is added to the bytecode of the method, i.e. when its * added to the bytecode of the method, i.e. when its position becomes known. This method fills
* position becomes known. This method fills in the blanks that where left * in the blanks that where left in the bytecode by each forward reference previously added to
* in the bytecode by each forward reference previously added to this label. * this label.
* *
* @param owner * @param owner the code writer that calls this method.
* the code writer that calls this method. * @param position the position of this label in the bytecode.
* @param position * @param data the bytecode of the method.
* the position of this label in the bytecode. * @return <tt>true</tt> if a blank that was left for this label was to small to store the
* @param data * offset. In such a case the corresponding jump instruction is replaced with a pseudo
* the bytecode of the method. * instruction (using unused opcodes) using an unsigned two bytes offset. These pseudo
* @return <tt>true</tt> if a blank that was left for this label was to * instructions will need to be replaced with true instructions with wider offsets (4
* small to store the offset. In such a case the corresponding jump * bytes instead of 2). This is done in {@link MethodWriter#resizeInstructions}.
* instruction is replaced with a pseudo instruction (using unused * @throws IllegalArgumentException if this label has already been resolved, or if it has not
* opcodes) using an unsigned two bytes offset. These pseudo * been created by the given code writer.
* instructions will need to be replaced with true instructions with
* wider offsets (4 bytes instead of 2). This is done in
* {@link MethodWriter#resizeInstructions}.
* @throws IllegalArgumentException
* if this label has already been resolved, or if it has not
* been created by the given code writer.
*/ */
boolean resolve(final MethodWriter owner, final int position, boolean resolve(final MethodWriter owner, final int position, final byte[] data) {
final byte[] data) {
boolean needUpdate = false; boolean needUpdate = false;
this.status |= RESOLVED; this.status |= RESOLVED;
this.position = position; this.position = position;
@ -380,13 +336,11 @@ public class Label {
offset = position - source; offset = position - source;
if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) { if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) {
/* /*
* changes the opcode of the jump instruction, in order to * changes the opcode of the jump instruction, in order to be able to find it
* be able to find it later (see resizeInstructions in * later (see resizeInstructions in MethodWriter). These temporary opcodes are
* MethodWriter). These temporary opcodes are similar to * similar to jump instruction opcodes, except that the 2 bytes offset is
* jump instruction opcodes, except that the 2 bytes offset * unsigned (and can therefore represent values from 0 to 65535, which is
* is unsigned (and can therefore represent values from 0 to * sufficient since the size of a method is limited to 65535 bytes).
* 65535, which is sufficient since the size of a method is
* limited to 65535 bytes).
*/ */
int opcode = data[reference - 1] & 0xFF; int opcode = data[reference - 1] & 0xFF;
if (opcode <= Opcodes.JSR) { if (opcode <= Opcodes.JSR) {
@ -412,10 +366,9 @@ public class Label {
} }
/** /**
* Returns the first label of the series to which this label belongs. For an * Returns the first label of the series to which this label belongs. For an isolated label or
* isolated label or for the first label in a series of successive labels, * for the first label in a series of successive labels, this method returns the label itself.
* this method returns the label itself. For other labels it returns the * For other labels it returns the first label of the series.
* first label of the series.
* *
* @return the first label of the series to which this label belongs. * @return the first label of the series to which this label belongs.
*/ */
@ -430,8 +383,7 @@ public class Label {
/** /**
* Returns true is this basic block belongs to the given subroutine. * Returns true is this basic block belongs to the given subroutine.
* *
* @param id * @param id a subroutine id.
* a subroutine id.
* @return true is this basic block belongs to the given subroutine. * @return true is this basic block belongs to the given subroutine.
*/ */
boolean inSubroutine(final long id) { boolean inSubroutine(final long id) {
@ -442,13 +394,10 @@ public class Label {
} }
/** /**
* Returns true if this basic block and the given one belong to a common * Returns true if this basic block and the given one belong to a common subroutine.
* subroutine.
* *
* @param block * @param block another basic block.
* another basic block. * @return true if this basic block and the given one belong to a common subroutine.
* @return true if this basic block and the given one belong to a common
* subroutine.
*/ */
boolean inSameSubroutine(final Label block) { boolean inSameSubroutine(final Label block) {
if ((status & VISITED) == 0 || (block.status & VISITED) == 0) { if ((status & VISITED) == 0 || (block.status & VISITED) == 0) {
@ -465,10 +414,8 @@ public class Label {
/** /**
* Marks this basic block as belonging to the given subroutine. * Marks this basic block as belonging to the given subroutine.
* *
* @param id * @param id a subroutine id.
* a subroutine id. * @param nbSubroutines the total number of subroutines in the method.
* @param nbSubroutines
* the total number of subroutines in the method.
*/ */
void addToSubroutine(final long id, final int nbSubroutines) { void addToSubroutine(final long id, final int nbSubroutines) {
if ((status & VISITED) == 0) { if ((status & VISITED) == 0) {
@ -479,19 +426,14 @@ public class Label {
} }
/** /**
* Finds the basic blocks that belong to a given subroutine, and marks these * Finds the basic blocks that belong to a given subroutine, and marks these blocks as belonging
* blocks as belonging to this subroutine. This method follows the control * to this subroutine. This method follows the control flow graph to find all the blocks that
* flow graph to find all the blocks that are reachable from the current * are reachable from the current block WITHOUT following any JSR target.
* block WITHOUT following any JSR target.
* *
* @param JSR * @param JSR a JSR block that jumps to this subroutine. If this JSR is not null it is added to
* a JSR block that jumps to this subroutine. If this JSR is not * the successor of the RET blocks found in the subroutine.
* null it is added to the successor of the RET blocks found in * @param id the id of this subroutine.
* the subroutine. * @param nbSubroutines the total number of subroutines in the method.
* @param id
* the id of this subroutine.
* @param nbSubroutines
* the total number of subroutines in the method.
*/ */
void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) { void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) {
// user managed stack of labels, to avoid using a recursive method // user managed stack of labels, to avoid using a recursive method

View File

@ -1,71 +1,58 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
/** /**
* A visitor to visit a Java method. The methods of this class must be called in * A visitor to visit a Java method. The methods of this class must be called in the following
* the following order: [ <tt>visitAnnotationDefault</tt> ] ( * order: [ <tt>visitAnnotationDefault</tt> ] ( <tt>visitAnnotation</tt> |
* <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> | * <tt>visitParameterAnnotation</tt> | <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> (
* <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> | * <tt>visitFrame</tt> | <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> |
* <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> | * <tt>visitTryCatchBlock</tt> | <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt> )*
* <tt>visitTryCatchBlock</tt> | <tt>visitLocalVariable</tt> | * <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In addition, the <tt>visit</tt><i>X</i>Insn</tt> and
* <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ] <tt>visitEnd</tt>. In * <tt>visitLabel</tt> methods must be called in the sequential order of the bytecode instructions
* addition, the <tt>visit</tt><i>X</i>Insn</tt> and <tt>visitLabel</tt> methods * of the visited code, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the labels passed
* must be called in the sequential order of the bytecode instructions of the * as arguments have been visited, and the <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt>
* visited code, <tt>visitTryCatchBlock</tt> must be called <i>before</i> the * methods must be called <i>after</i> the labels passed as arguments have been visited.
* labels passed as arguments have been visited, and the
* <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt> methods must be
* called <i>after</i> the labels passed as arguments have been visited.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public abstract class MethodVisitor { public abstract class MethodVisitor {
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of
* must be one of {@link Opcodes#ASM4}. * {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* The method visitor to which this visitor must delegate method calls. May * The method visitor to which this visitor must delegate method calls. May be null.
* be null.
*/ */
protected MethodVisitor mv; protected MethodVisitor mv;
/** /**
* Constructs a new {@link MethodVisitor}. * Constructs a new {@link MethodVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}.
*/ */
public MethodVisitor(final int api) { public MethodVisitor(final int api) {
this(api, null); this(api, null);
@ -74,12 +61,9 @@ public abstract class MethodVisitor {
/** /**
* Constructs a new {@link MethodVisitor}. * Constructs a new {@link MethodVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param mv the method visitor to which this visitor must delegate method calls. May be null.
* @param mv
* the method visitor to which this visitor must delegate method
* calls. May be null.
*/ */
public MethodVisitor(final int api, final MethodVisitor mv) { public MethodVisitor(final int api, final MethodVisitor mv) {
if (api != Opcodes.ASM4) { if (api != Opcodes.ASM4) {
@ -96,12 +80,11 @@ public abstract class MethodVisitor {
/** /**
* Visits the default value of this annotation interface method. * Visits the default value of this annotation interface method.
* *
* @return a visitor to the visit the actual default value of this * @return a visitor to the visit the actual default value of this annotation interface method,
* annotation interface method, or <tt>null</tt> if this visitor is * or <tt>null</tt> if this visitor is not interested in visiting this default value.
* not interested in visiting this default value. The 'name' * The 'name' parameters passed to the methods of this annotation visitor are ignored.
* parameters passed to the methods of this annotation visitor are * Moreover, exacly one visit method must be called on this annotation visitor, followed
* ignored. Moreover, exacly one visit method must be called on this * by visitEnd.
* annotation visitor, followed by visitEnd.
*/ */
public AnnotationVisitor visitAnnotationDefault() { public AnnotationVisitor visitAnnotationDefault() {
if (mv != null) { if (mv != null) {
@ -113,12 +96,10 @@ public abstract class MethodVisitor {
/** /**
* Visits an annotation of this method. * Visits an annotation of this method.
* *
* @param desc * @param desc the class descriptor of the annotation class.
* the class descriptor of the annotation class. * @param visible <tt>true</tt> if the annotation is visible at runtime.
* @param visible * @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
* <tt>true</tt> if the annotation is visible at runtime. * interested in visiting this annotation.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (mv != null) { if (mv != null) {
@ -130,17 +111,13 @@ public abstract class MethodVisitor {
/** /**
* Visits an annotation of a parameter this method. * Visits an annotation of a parameter this method.
* *
* @param parameter * @param parameter the parameter index.
* the parameter index. * @param desc the class descriptor of the annotation class.
* @param desc * @param visible <tt>true</tt> if the annotation is visible at runtime.
* the class descriptor of the annotation class. * @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not
* @param visible * interested in visiting this annotation.
* <tt>true</tt> if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or <tt>null</tt> if
* this visitor is not interested in visiting this annotation.
*/ */
public AnnotationVisitor visitParameterAnnotation(int parameter, public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
String desc, boolean visible) {
if (mv != null) { if (mv != null) {
return mv.visitParameterAnnotation(parameter, desc, visible); return mv.visitParameterAnnotation(parameter, desc, visible);
} }
@ -150,8 +127,7 @@ public abstract class MethodVisitor {
/** /**
* Visits a non standard attribute of this method. * Visits a non standard attribute of this method.
* *
* @param attr * @param attr an attribute.
* an attribute.
*/ */
public void visitAttribute(Attribute attr) { public void visitAttribute(Attribute attr) {
if (mv != null) { if (mv != null) {
@ -169,80 +145,63 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the current state of the local variables and operand stack * Visits the current state of the local variables and operand stack elements. This method
* elements. This method must(*) be called <i>just before</i> any * must(*) be called <i>just before</i> any instruction <b>i</b> that follows an unconditional
* instruction <b>i</b> that follows an unconditional branch instruction * branch instruction such as GOTO or THROW, that is the target of a jump instruction, or that
* such as GOTO or THROW, that is the target of a jump instruction, or that * starts an exception handler block. The visited types must describe the values of the local
* starts an exception handler block. The visited types must describe the * variables and of the operand stack elements <i>just before</i> <b>i</b> is executed.<br>
* values of the local variables and of the operand stack elements <i>just
* before</i> <b>i</b> is executed.<br>
* <br> * <br>
* (*) this is mandatory only for classes whose version is greater than or * (*) this is mandatory only for classes whose version is greater than or equal to
* equal to {@link Opcodes#V1_6 V1_6}. <br> * {@link Opcodes#V1_6 V1_6}. <br>
* <br> * <br>
* The frames of a method must be given either in expanded form, or in * The frames of a method must be given either in expanded form, or in compressed form (all
* compressed form (all frames must use the same format, i.e. you must not * frames must use the same format, i.e. you must not mix expanded and compressed frames within
* mix expanded and compressed frames within a single method): * a single method):
* <ul> * <ul>
* <li>In expanded form, all frames must have the F_NEW type.</li> * <li>In expanded form, all frames must have the F_NEW type.</li>
* <li>In compressed form, frames are basically "deltas" from the state of * <li>In compressed form, frames are basically "deltas" from the state of the previous frame:
* the previous frame:
* <ul> * <ul>
* <li>{@link Opcodes#F_SAME} representing frame with exactly the same * <li>{@link Opcodes#F_SAME} representing frame with exactly the same locals as the previous
* locals as the previous frame and with the empty stack.</li> * frame and with the empty stack.</li>
* <li>{@link Opcodes#F_SAME1} representing frame with exactly the same * <li>{@link Opcodes#F_SAME1} representing frame with exactly the same locals as the previous
* locals as the previous frame and with single value on the stack ( * frame and with single value on the stack ( <code>nStack</code> is 1 and <code>stack[0]</code>
* <code>nStack</code> is 1 and <code>stack[0]</code> contains value for the * contains value for the type of the stack item).</li>
* type of the stack item).</li> * <li>{@link Opcodes#F_APPEND} representing frame with current locals are the same as the
* <li>{@link Opcodes#F_APPEND} representing frame with current locals are * locals in the previous frame, except that additional locals are defined (<code>nLocal</code>
* the same as the locals in the previous frame, except that additional * is 1, 2 or 3 and <code>local</code> elements contains values representing added types).</li>
* locals are defined (<code>nLocal</code> is 1, 2 or 3 and * <li>{@link Opcodes#F_CHOP} representing frame with current locals are the same as the locals
* <code>local</code> elements contains values representing added types).</li> * in the previous frame, except that the last 1-3 locals are absent and with the empty stack
* <li>{@link Opcodes#F_CHOP} representing frame with current locals are the * (<code>nLocals</code> is 1, 2 or 3).</li>
* same as the locals in the previous frame, except that the last 1-3 locals
* are absent and with the empty stack (<code>nLocals</code> is 1, 2 or 3).</li>
* <li>{@link Opcodes#F_FULL} representing complete frame data.</li></li> * <li>{@link Opcodes#F_FULL} representing complete frame data.</li></li>
* </ul> * </ul>
* </ul> <br> * </ul>
* In both cases the first frame, corresponding to the method's parameters * <br>
* and access flags, is implicit and must not be visited. Also, it is * In both cases the first frame, corresponding to the method's parameters and access flags, is
* illegal to visit two or more frames for the same code location (i.e., at * implicit and must not be visited. Also, it is illegal to visit two or more frames for the
* least one instruction must be visited between two calls to visitFrame). * same code location (i.e., at least one instruction must be visited between two calls to
* visitFrame).
* *
* @param type * @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded
* the type of this stack map frame. Must be * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
* {@link Opcodes#F_NEW} for expanded frames, or * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
* {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, * compressed frames.
* {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or * @param nLocal the number of local variables in the visited frame.
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for * @param local the local variable types in this frame. This array must not be modified.
* compressed frames. * Primitive types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
* @param nLocal * {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
* the number of local variables in the visited frame. * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or {@link Opcodes#UNINITIALIZED_THIS}
* @param local * (long and double are represented by a single element). Reference types are represented
* the local variable types in this frame. This array must not be * by String objects (representing internal names), and uninitialized types by Label
* modified. Primitive types are represented by * objects (this label designates the NEW instruction that created this uninitialized
* {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, * value).
* {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, * @param nStack the number of operand stack elements in the visited frame.
* {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or * @param stack the operand stack types in this frame. This array must not be modified. Its
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are * content has the same format as the "local" array.
* represented by a single element). Reference types are * @throws IllegalStateException if a frame is visited just after another one, without any
* represented by String objects (representing internal names), * instruction between the two (unless this frame is a Opcodes#F_SAME frame, in which
* and uninitialized types by Label objects (this label * case it is silently ignored).
* designates the NEW instruction that created this uninitialized
* value).
* @param nStack
* the number of operand stack elements in the visited frame.
* @param stack
* the operand stack types in this frame. This array must not be
* modified. Its content has the same format as the "local"
* array.
* @throws IllegalStateException
* if a frame is visited just after another one, without any
* instruction between the two (unless this frame is a
* Opcodes#F_SAME frame, in which case it is silently ignored).
*/ */
public void visitFrame(int type, int nLocal, Object[] local, int nStack, public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
Object[] stack) {
if (mv != null) { if (mv != null) {
mv.visitFrame(type, nLocal, local, nStack, stack); mv.visitFrame(type, nLocal, local, nStack, stack);
} }
@ -255,22 +214,17 @@ public abstract class MethodVisitor {
/** /**
* Visits a zero operand instruction. * Visits a zero operand instruction.
* *
* @param opcode * @param opcode the opcode of the instruction to be visited. This opcode is either NOP,
* the opcode of the instruction to be visited. This opcode is * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
* either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
* ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
* FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, * AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL,
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, * IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL,
* SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, * ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, * L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG,
* IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
* FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, * MONITORENTER, or MONITOREXIT.
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
* or MONITOREXIT.
*/ */
public void visitInsn(int opcode) { public void visitInsn(int opcode) {
if (mv != null) { if (mv != null) {
@ -281,20 +235,17 @@ public abstract class MethodVisitor {
/** /**
* Visits an instruction with a single int operand. * Visits an instruction with a single int operand.
* *
* @param opcode * @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH,
* the opcode of the instruction to be visited. This opcode is * SIPUSH or NEWARRAY.
* either BIPUSH, SIPUSH or NEWARRAY. * @param operand the operand of the instruction to be visited.<br>
* @param operand * When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and
* the operand of the instruction to be visited.<br> * Byte.MAX_VALUE.<br>
* When opcode is BIPUSH, operand value should be between * When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and
* Byte.MIN_VALUE and Byte.MAX_VALUE.<br> * Short.MAX_VALUE.<br>
* When opcode is SIPUSH, operand value should be between * When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN},
* Short.MIN_VALUE and Short.MAX_VALUE.<br> * {@link Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
* When opcode is NEWARRAY, operand value should be one of * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or
* {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR}, * {@link Opcodes#T_LONG}.
* {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
* {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
* {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
*/ */
public void visitIntInsn(int opcode, int operand) { public void visitIntInsn(int opcode, int operand) {
if (mv != null) { if (mv != null) {
@ -303,16 +254,14 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a local variable instruction. A local variable instruction is an * Visits a local variable instruction. A local variable instruction is an instruction that
* instruction that loads or stores the value of a local variable. * loads or stores the value of a local variable.
* *
* @param opcode * @param opcode the opcode of the local variable instruction to be visited. This opcode is
* the opcode of the local variable instruction to be visited. * either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or
* This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, * RET.
* ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. * @param var the operand of the instruction to be visited. This operand is the index of a local
* @param var * variable.
* the operand of the instruction to be visited. This operand is
* the index of a local variable.
*/ */
public void visitVarInsn(int opcode, int var) { public void visitVarInsn(int opcode, int var) {
if (mv != null) { if (mv != null) {
@ -321,16 +270,13 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a type instruction. A type instruction is an instruction that * Visits a type instruction. A type instruction is an instruction that takes the internal name
* takes the internal name of a class as parameter. * of a class as parameter.
* *
* @param opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either NEW,
* the opcode of the type instruction to be visited. This opcode * ANEWARRAY, CHECKCAST or INSTANCEOF.
* is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. * @param type the operand of the instruction to be visited. This operand must be the internal
* @param type * name of an object or array class (see {@link Type#getInternalName() getInternalName}).
* the operand of the instruction to be visited. This operand
* must be the internal name of an object or array class (see
* {@link Type#getInternalName() getInternalName}).
*/ */
public void visitTypeInsn(int opcode, String type) { public void visitTypeInsn(int opcode, String type) {
if (mv != null) { if (mv != null) {
@ -339,45 +285,33 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a field instruction. A field instruction is an instruction that * Visits a field instruction. A field instruction is an instruction that loads or stores the
* loads or stores the value of a field of an object. * value of a field of an object.
* *
* @param opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either
* the opcode of the type instruction to be visited. This opcode * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * @param owner the internal name of the field's owner class (see {@link Type#getInternalName()
* @param owner * getInternalName}).
* the internal name of the field's owner class (see * @param name the field's name.
* {@link Type#getInternalName() getInternalName}). * @param desc the field's descriptor (see {@link Type Type}).
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link Type Type}).
*/ */
public void visitFieldInsn(int opcode, String owner, String name, public void visitFieldInsn(int opcode, String owner, String name, String desc) {
String desc) {
if (mv != null) { if (mv != null) {
mv.visitFieldInsn(opcode, owner, name, desc); mv.visitFieldInsn(opcode, owner, name, desc);
} }
} }
/** /**
* Visits a method instruction. A method instruction is an instruction that * Visits a method instruction. A method instruction is an instruction that invokes a method.
* invokes a method.
* *
* @param opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either
* the opcode of the type instruction to be visited. This opcode * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
* is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or * @param owner the internal name of the method's owner class (see {@link Type#getInternalName()
* INVOKEINTERFACE. * getInternalName}).
* @param owner * @param name the method's name.
* the internal name of the method's owner class (see * @param desc the method's descriptor (see {@link Type Type}).
* {@link Type#getInternalName() getInternalName}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
*/ */
public void visitMethodInsn(int opcode, String owner, String name, public void visitMethodInsn(int opcode, String owner, String name, String desc) {
String desc) {
if (mv != null) { if (mv != null) {
mv.visitMethodInsn(opcode, owner, name, desc); mv.visitMethodInsn(opcode, owner, name, desc);
} }
@ -386,39 +320,29 @@ public abstract class MethodVisitor {
/** /**
* Visits an invokedynamic instruction. * Visits an invokedynamic instruction.
* *
* @param name * @param name the method's name.
* the method's name. * @param desc the method's descriptor (see {@link Type Type}).
* @param desc * @param bsm the bootstrap method.
* the method's descriptor (see {@link Type Type}). * @param bsmArgs the bootstrap method constant arguments. Each argument must be an
* @param bsm * {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String},
* the bootstrap method. * {@link Type} or {@link Handle} value. This method is allowed to modify the content of
* @param bsmArgs * the array so a caller should expect that this array may change.
* the bootstrap method constant arguments. Each argument must be
* an {@link Integer}, {@link Float}, {@link Long},
* {@link Double}, {@link String}, {@link Type} or {@link Handle}
* value. This method is allowed to modify the content of the
* array so a caller should expect that this array may change.
*/ */
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
Object... bsmArgs) {
if (mv != null) { if (mv != null) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
} }
} }
/** /**
* Visits a jump instruction. A jump instruction is an instruction that may * Visits a jump instruction. A jump instruction is an instruction that may jump to another
* jump to another instruction. * instruction.
* *
* @param opcode * @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ,
* the opcode of the type instruction to be visited. This opcode * IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
* is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, * @param label the operand of the instruction to be visited. This operand is a label that
* IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * designates the instruction to which the jump instruction may jump.
* @param label
* the operand of the instruction to be visited. This operand is
* a label that designates the instruction to which the jump
* instruction may jump.
*/ */
public void visitJumpInsn(int opcode, Label label) { public void visitJumpInsn(int opcode, Label label) {
if (mv != null) { if (mv != null) {
@ -427,11 +351,9 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits a label. A label designates the instruction that will be visited * Visits a label. A label designates the instruction that will be visited just after it.
* just after it.
* *
* @param label * @param label a {@link Label Label} object.
* a {@link Label Label} object.
*/ */
public void visitLabel(Label label) { public void visitLabel(Label label) {
if (mv != null) { if (mv != null) {
@ -444,10 +366,9 @@ public abstract class MethodVisitor {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* Visits a LDC instruction. Note that new constant types may be added in * Visits a LDC instruction. Note that new constant types may be added in future versions of the
* future versions of the Java Virtual Machine. To easily detect new * Java Virtual Machine. To easily detect new constant types, implementations of this method
* constant types, implementations of this method should check for * should check for unexpected constant types, like this:
* unexpected constant types, like this:
* *
* <pre> * <pre>
* if (cst instanceof Integer) { * if (cst instanceof Integer) {
@ -478,14 +399,11 @@ public abstract class MethodVisitor {
* } * }
* </pre> * </pre>
* *
* @param cst * @param cst the constant to be loaded on the stack. This parameter must be a non null
* the constant to be loaded on the stack. This parameter must be * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String},
* a non null {@link Integer}, a {@link Float}, a {@link Long}, a * a {@link Type} of OBJECT or ARRAY sort for <tt>.class</tt> constants, for classes
* {@link Double}, a {@link String}, a {@link Type} of OBJECT or * whose version is 49.0, a {@link Type} of METHOD sort or a {@link Handle} for
* ARRAY sort for <tt>.class</tt> constants, for classes whose * MethodType and MethodHandle constants, for classes whose version is 51.0.
* version is 49.0, a {@link Type} of METHOD sort or a
* {@link Handle} for MethodType and MethodHandle constants, for
* classes whose version is 51.0.
*/ */
public void visitLdcInsn(Object cst) { public void visitLdcInsn(Object cst) {
if (mv != null) { if (mv != null) {
@ -496,10 +414,8 @@ public abstract class MethodVisitor {
/** /**
* Visits an IINC instruction. * Visits an IINC instruction.
* *
* @param var * @param var index of the local variable to be incremented.
* index of the local variable to be incremented. * @param increment amount to increment the local variable by.
* @param increment
* amount to increment the local variable by.
*/ */
public void visitIincInsn(int var, int increment) { public void visitIincInsn(int var, int increment) {
if (mv != null) { if (mv != null) {
@ -510,18 +426,13 @@ public abstract class MethodVisitor {
/** /**
* Visits a TABLESWITCH instruction. * Visits a TABLESWITCH instruction.
* *
* @param min * @param min the minimum key value.
* the minimum key value. * @param max the maximum key value.
* @param max * @param dflt beginning of the default handler block.
* the maximum key value. * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
* @param dflt * handler block for the <tt>min + i</tt> key.
* beginning of the default handler block.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>min + i</tt> key.
*/ */
public void visitTableSwitchInsn(int min, int max, Label dflt, public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
Label... labels) {
if (mv != null) { if (mv != null) {
mv.visitTableSwitchInsn(min, max, dflt, labels); mv.visitTableSwitchInsn(min, max, dflt, labels);
} }
@ -530,13 +441,10 @@ public abstract class MethodVisitor {
/** /**
* Visits a LOOKUPSWITCH instruction. * Visits a LOOKUPSWITCH instruction.
* *
* @param dflt * @param dflt beginning of the default handler block.
* beginning of the default handler block. * @param keys the values of the keys.
* @param keys * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
* the values of the keys. * handler block for the <tt>keys[i]</tt> key.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>keys[i]</tt> key.
*/ */
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
if (mv != null) { if (mv != null) {
@ -547,10 +455,8 @@ public abstract class MethodVisitor {
/** /**
* Visits a MULTIANEWARRAY instruction. * Visits a MULTIANEWARRAY instruction.
* *
* @param desc * @param desc an array type descriptor (see {@link Type Type}).
* an array type descriptor (see {@link Type Type}). * @param dims number of dimensions of the array to allocate.
* @param dims
* number of dimensions of the array to allocate.
*/ */
public void visitMultiANewArrayInsn(String desc, int dims) { public void visitMultiANewArrayInsn(String desc, int dims) {
if (mv != null) { if (mv != null) {
@ -565,22 +471,15 @@ public abstract class MethodVisitor {
/** /**
* Visits a try catch block. * Visits a try catch block.
* *
* @param start * @param start beginning of the exception handler's scope (inclusive).
* beginning of the exception handler's scope (inclusive). * @param end end of the exception handler's scope (exclusive).
* @param end * @param handler beginning of the exception handler's code.
* end of the exception handler's scope (exclusive). * @param type internal name of the type of exceptions handled by the handler, or <tt>null</tt>
* @param handler * to catch any exceptions (for "finally" blocks).
* beginning of the exception handler's code. * @throws IllegalArgumentException if one of the labels has already been visited by this
* @param type * visitor (by the {@link #visitLabel visitLabel} method).
* internal name of the type of exceptions handled by the
* handler, or <tt>null</tt> to catch any exceptions (for
* "finally" blocks).
* @throws IllegalArgumentException
* if one of the labels has already been visited by this visitor
* (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitTryCatchBlock(Label start, Label end, Label handler, public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
String type) {
if (mv != null) { if (mv != null) {
mv.visitTryCatchBlock(start, end, handler, type); mv.visitTryCatchBlock(start, end, handler, type);
} }
@ -589,28 +488,20 @@ public abstract class MethodVisitor {
/** /**
* Visits a local variable declaration. * Visits a local variable declaration.
* *
* @param name * @param name the name of a local variable.
* the name of a local variable. * @param desc the type descriptor of this local variable.
* @param desc * @param signature the type signature of this local variable. May be <tt>null</tt> if the local
* the type descriptor of this local variable. * variable type does not use generic types.
* @param signature * @param start the first instruction corresponding to the scope of this local variable
* the type signature of this local variable. May be * (inclusive).
* <tt>null</tt> if the local variable type does not use generic * @param end the last instruction corresponding to the scope of this local variable
* types. * (exclusive).
* @param start * @param index the local variable's index.
* the first instruction corresponding to the scope of this local * @throws IllegalArgumentException if one of the labels has not already been visited by this
* variable (inclusive). * visitor (by the {@link #visitLabel visitLabel} method).
* @param end
* the last instruction corresponding to the scope of this local
* variable (exclusive).
* @param index
* the local variable's index.
* @throws IllegalArgumentException
* if one of the labels has not already been visited by this
* visitor (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitLocalVariable(String name, String desc, String signature, public void visitLocalVariable(String name, String desc, String signature, Label start,
Label start, Label end, int index) { Label end, int index) {
if (mv != null) { if (mv != null) {
mv.visitLocalVariable(name, desc, signature, start, end, index); mv.visitLocalVariable(name, desc, signature, start, end, index);
} }
@ -619,14 +510,11 @@ public abstract class MethodVisitor {
/** /**
* Visits a line number declaration. * Visits a line number declaration.
* *
* @param line * @param line a line number. This number refers to the source file from which the class was
* a line number. This number refers to the source file from * compiled.
* which the class was compiled. * @param start the first instruction corresponding to this line number.
* @param start * @throws IllegalArgumentException if <tt>start</tt> has not already been visited by this
* the first instruction corresponding to this line number. * visitor (by the {@link #visitLabel visitLabel} method).
* @throws IllegalArgumentException
* if <tt>start</tt> has not already been visited by this
* visitor (by the {@link #visitLabel visitLabel} method).
*/ */
public void visitLineNumber(int line, Label start) { public void visitLineNumber(int line, Label start) {
if (mv != null) { if (mv != null) {
@ -635,13 +523,10 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the maximum stack size and the maximum number of local variables * Visits the maximum stack size and the maximum number of local variables of the method.
* of the method.
* *
* @param maxStack * @param maxStack maximum stack size of the method.
* maximum stack size of the method. * @param maxLocals maximum number of local variables for the method.
* @param maxLocals
* maximum number of local variables for the method.
*/ */
public void visitMaxs(int maxStack, int maxLocals) { public void visitMaxs(int maxStack, int maxLocals) {
if (mv != null) { if (mv != null) {
@ -650,9 +535,8 @@ public abstract class MethodVisitor {
} }
/** /**
* Visits the end of the method. This method, which is the last one to be * Visits the end of the method. This method, which is the last one to be called, is used to
* called, is used to inform the visitor that all the annotations and * inform the visitor that all the annotations and attributes of the method have been visited.
* attributes of the method have been visited.
*/ */
public void visitEnd() { public void visitEnd() {
if (mv != null) { if (mv != null) {

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +1,32 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
/** /**
* Defines the JVM opcodes, access flags and array type codes. This interface * Defines the JVM opcodes, access flags and array type codes. This interface does not define all
* does not define all the JVM opcodes because some opcodes are automatically * the JVM opcodes because some opcodes are automatically handled. For example, the xLOAD and xSTORE
* handled. For example, the xLOAD and xSTORE opcodes are automatically replaced * opcodes are automatically replaced by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and
* by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n * xSTORE_n opcodes are therefore not defined in this interface. Likewise for LDC, automatically
* opcodes are therefore not defined in this interface. Likewise for LDC, * replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and JSR_W.
* automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and
* JSR_W.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Eugene Kuleshov * @author Eugene Kuleshov
@ -120,28 +110,26 @@ public interface Opcodes {
int F_FULL = 0; int F_FULL = 0;
/** /**
* Represents a compressed frame where locals are the same as the locals in * Represents a compressed frame where locals are the same as the locals in the previous frame,
* the previous frame, except that additional 1-3 locals are defined, and * except that additional 1-3 locals are defined, and with an empty stack.
* with an empty stack.
*/ */
int F_APPEND = 1; int F_APPEND = 1;
/** /**
* Represents a compressed frame where locals are the same as the locals in * Represents a compressed frame where locals are the same as the locals in the previous frame,
* the previous frame, except that the last 1-3 locals are absent and with * except that the last 1-3 locals are absent and with an empty stack.
* an empty stack.
*/ */
int F_CHOP = 2; int F_CHOP = 2;
/** /**
* Represents a compressed frame with exactly the same locals as the * Represents a compressed frame with exactly the same locals as the previous frame and with an
* previous frame and with an empty stack. * empty stack.
*/ */
int F_SAME = 3; int F_SAME = 3;
/** /**
* Represents a compressed frame with exactly the same locals as the * Represents a compressed frame with exactly the same locals as the previous frame and with a
* previous frame and with a single value on the stack. * single value on the stack.
*/ */
int F_SAME1 = 4; int F_SAME1 = 4;

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm; package org.objectweb.asm;
@ -33,8 +25,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
/** /**
* A Java field or method type. This class can be used to make it easier to * A Java field or method type. This class can be used to make it easier to manipulate type and
* manipulate type and method descriptors. * method descriptors.
* *
* @author Eric Bruneton * @author Eric Bruneton
* @author Chris Nokleberg * @author Chris Nokleberg
@ -104,56 +96,56 @@ public class Type {
/** /**
* The <tt>void</tt> type. * The <tt>void</tt> type.
*/ */
public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) public static final Type VOID_TYPE =
| (5 << 16) | (0 << 8) | 0, 1); new Type(VOID, null, ('V' << 24) | (5 << 16) | (0 << 8) | 0, 1);
/** /**
* The <tt>boolean</tt> type. * The <tt>boolean</tt> type.
*/ */
public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) public static final Type BOOLEAN_TYPE =
| (0 << 16) | (5 << 8) | 1, 1); new Type(BOOLEAN, null, ('Z' << 24) | (0 << 16) | (5 << 8) | 1, 1);
/** /**
* The <tt>char</tt> type. * The <tt>char</tt> type.
*/ */
public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) public static final Type CHAR_TYPE =
| (0 << 16) | (6 << 8) | 1, 1); new Type(CHAR, null, ('C' << 24) | (0 << 16) | (6 << 8) | 1, 1);
/** /**
* The <tt>byte</tt> type. * The <tt>byte</tt> type.
*/ */
public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) public static final Type BYTE_TYPE =
| (0 << 16) | (5 << 8) | 1, 1); new Type(BYTE, null, ('B' << 24) | (0 << 16) | (5 << 8) | 1, 1);
/** /**
* The <tt>short</tt> type. * The <tt>short</tt> type.
*/ */
public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) public static final Type SHORT_TYPE =
| (0 << 16) | (7 << 8) | 1, 1); new Type(SHORT, null, ('S' << 24) | (0 << 16) | (7 << 8) | 1, 1);
/** /**
* The <tt>int</tt> type. * The <tt>int</tt> type.
*/ */
public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) public static final Type INT_TYPE =
| (0 << 16) | (0 << 8) | 1, 1); new Type(INT, null, ('I' << 24) | (0 << 16) | (0 << 8) | 1, 1);
/** /**
* The <tt>float</tt> type. * The <tt>float</tt> type.
*/ */
public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) public static final Type FLOAT_TYPE =
| (2 << 16) | (2 << 8) | 1, 1); new Type(FLOAT, null, ('F' << 24) | (2 << 16) | (2 << 8) | 1, 1);
/** /**
* The <tt>long</tt> type. * The <tt>long</tt> type.
*/ */
public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) public static final Type LONG_TYPE =
| (1 << 16) | (1 << 8) | 2, 1); new Type(LONG, null, ('J' << 24) | (1 << 16) | (1 << 8) | 2, 1);
/** /**
* The <tt>double</tt> type. * The <tt>double</tt> type.
*/ */
public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24) public static final Type DOUBLE_TYPE =
| (3 << 16) | (3 << 8) | 2, 1); new Type(DOUBLE, null, ('D' << 24) | (3 << 16) | (3 << 8) | 2, 1);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Fields // Fields
@ -165,16 +157,16 @@ public class Type {
private final int sort; private final int sort;
/** /**
* A buffer containing the internal name of this Java type. This field is * A buffer containing the internal name of this Java type. This field is only used for
* only used for reference types. * reference types.
*/ */
private final char[] buf; private final char[] buf;
/** /**
* The offset of the internal name of this Java type in {@link #buf buf} or, * The offset of the internal name of this Java type in {@link #buf buf} or, for primitive
* for primitive types, the size, descriptor and getOpcode offsets for this * types, the size, descriptor and getOpcode offsets for this type (byte 0 contains the size,
* type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset * byte 1 the descriptor, byte 2 the offset for IALOAD or IASTORE, byte 3 the offset for all
* for IALOAD or IASTORE, byte 3 the offset for all other instructions). * other instructions).
*/ */
private final int off; private final int off;
@ -190,14 +182,10 @@ public class Type {
/** /**
* Constructs a reference type. * Constructs a reference type.
* *
* @param sort * @param sort the sort of the reference type to be constructed.
* the sort of the reference type to be constructed. * @param buf a buffer containing the descriptor of the previous type.
* @param buf * @param off the offset of this descriptor in the previous buffer.
* a buffer containing the descriptor of the previous type. * @param len the length of this descriptor.
* @param off
* the offset of this descriptor in the previous buffer.
* @param len
* the length of this descriptor.
*/ */
private Type(final int sort, final char[] buf, final int off, final int len) { private Type(final int sort, final char[] buf, final int off, final int len) {
this.sort = sort; this.sort = sort;
@ -209,8 +197,7 @@ public class Type {
/** /**
* Returns the Java type corresponding to the given type descriptor. * Returns the Java type corresponding to the given type descriptor.
* *
* @param typeDescriptor * @param typeDescriptor a field or method type descriptor.
* a field or method type descriptor.
* @return the Java type corresponding to the given type descriptor. * @return the Java type corresponding to the given type descriptor.
*/ */
public static Type getType(final String typeDescriptor) { public static Type getType(final String typeDescriptor) {
@ -220,8 +207,7 @@ public class Type {
/** /**
* Returns the Java type corresponding to the given internal name. * Returns the Java type corresponding to the given internal name.
* *
* @param internalName * @param internalName an internal name.
* an internal name.
* @return the Java type corresponding to the given internal name. * @return the Java type corresponding to the given internal name.
*/ */
public static Type getObjectType(final String internalName) { public static Type getObjectType(final String internalName) {
@ -230,11 +216,10 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the given method descriptor. * Returns the Java type corresponding to the given method descriptor. Equivalent to
* Equivalent to <code>Type.getType(methodDescriptor)</code>. * <code>Type.getType(methodDescriptor)</code>.
* *
* @param methodDescriptor * @param methodDescriptor a method descriptor.
* a method descriptor.
* @return the Java type corresponding to the given method descriptor. * @return the Java type corresponding to the given method descriptor.
*/ */
public static Type getMethodType(final String methodDescriptor) { public static Type getMethodType(final String methodDescriptor) {
@ -242,26 +227,20 @@ public class Type {
} }
/** /**
* Returns the Java method type corresponding to the given argument and * Returns the Java method type corresponding to the given argument and return types.
* return types.
* *
* @param returnType * @param returnType the return type of the method.
* the return type of the method. * @param argumentTypes the argument types of the method.
* @param argumentTypes * @return the Java type corresponding to the given argument and return types.
* the argument types of the method.
* @return the Java type corresponding to the given argument and return
* types.
*/ */
public static Type getMethodType(final Type returnType, public static Type getMethodType(final Type returnType, final Type... argumentTypes) {
final Type... argumentTypes) {
return getType(getMethodDescriptor(returnType, argumentTypes)); return getType(getMethodDescriptor(returnType, argumentTypes));
} }
/** /**
* Returns the Java type corresponding to the given class. * Returns the Java type corresponding to the given class.
* *
* @param c * @param c a class.
* a class.
* @return the Java type corresponding to the given class. * @return the Java type corresponding to the given class.
*/ */
public static Type getType(final Class<?> c) { public static Type getType(final Class<?> c) {
@ -282,7 +261,7 @@ public class Type {
return DOUBLE_TYPE; return DOUBLE_TYPE;
} else if (c == Float.TYPE) { } else if (c == Float.TYPE) {
return FLOAT_TYPE; return FLOAT_TYPE;
} else /* if (c == Long.TYPE) */{ } else /* if (c == Long.TYPE) */ {
return LONG_TYPE; return LONG_TYPE;
} }
} else { } else {
@ -293,8 +272,7 @@ public class Type {
/** /**
* Returns the Java method type corresponding to the given constructor. * Returns the Java method type corresponding to the given constructor.
* *
* @param c * @param c a {@link Constructor Constructor} object.
* a {@link Constructor Constructor} object.
* @return the Java method type corresponding to the given constructor. * @return the Java method type corresponding to the given constructor.
*/ */
public static Type getType(final Constructor<?> c) { public static Type getType(final Constructor<?> c) {
@ -304,8 +282,7 @@ public class Type {
/** /**
* Returns the Java method type corresponding to the given method. * Returns the Java method type corresponding to the given method.
* *
* @param m * @param m a {@link Method Method} object.
* a {@link Method Method} object.
* @return the Java method type corresponding to the given method. * @return the Java method type corresponding to the given method.
*/ */
public static Type getType(final Method m) { public static Type getType(final Method m) {
@ -313,13 +290,10 @@ public class Type {
} }
/** /**
* Returns the Java types corresponding to the argument types of the given * Returns the Java types corresponding to the argument types of the given method descriptor.
* method descriptor.
* *
* @param methodDescriptor * @param methodDescriptor a method descriptor.
* a method descriptor. * @return the Java types corresponding to the argument types of the given method descriptor.
* @return the Java types corresponding to the argument types of the given
* method descriptor.
*/ */
public static Type[] getArgumentTypes(final String methodDescriptor) { public static Type[] getArgumentTypes(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray(); char[] buf = methodDescriptor.toCharArray();
@ -349,13 +323,10 @@ public class Type {
} }
/** /**
* Returns the Java types corresponding to the argument types of the given * Returns the Java types corresponding to the argument types of the given method.
* method.
* *
* @param method * @param method a method.
* a method. * @return the Java types corresponding to the argument types of the given method.
* @return the Java types corresponding to the argument types of the given
* method.
*/ */
public static Type[] getArgumentTypes(final Method method) { public static Type[] getArgumentTypes(final Method method) {
Class<?>[] classes = method.getParameterTypes(); Class<?>[] classes = method.getParameterTypes();
@ -367,13 +338,10 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the return type of the given * Returns the Java type corresponding to the return type of the given method descriptor.
* method descriptor.
* *
* @param methodDescriptor * @param methodDescriptor a method descriptor.
* a method descriptor. * @return the Java type corresponding to the return type of the given method descriptor.
* @return the Java type corresponding to the return type of the given
* method descriptor.
*/ */
public static Type getReturnType(final String methodDescriptor) { public static Type getReturnType(final String methodDescriptor) {
char[] buf = methodDescriptor.toCharArray(); char[] buf = methodDescriptor.toCharArray();
@ -381,13 +349,10 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the return type of the given * Returns the Java type corresponding to the return type of the given method.
* method.
* *
* @param method * @param method a method.
* a method. * @return the Java type corresponding to the return type of the given method.
* @return the Java type corresponding to the return type of the given
* method.
*/ */
public static Type getReturnType(final Method method) { public static Type getReturnType(final Method method) {
return getType(method.getReturnType()); return getType(method.getReturnType());
@ -396,13 +361,11 @@ public class Type {
/** /**
* Computes the size of the arguments and of the return value of a method. * Computes the size of the arguments and of the return value of a method.
* *
* @param desc * @param desc the descriptor of a method.
* the descriptor of a method. * @return the size of the arguments of the method (plus one for the implicit this argument),
* @return the size of the arguments of the method (plus one for the * argSize, and the size of its return value, retSize, packed into a single int i =
* implicit this argument), argSize, and the size of its return * <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to <tt>i >> 2</tt>, and
* value, retSize, packed into a single int i = * retSize to <tt>i & 0x03</tt>).
* <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to
* <tt>i >> 2</tt>, and retSize to <tt>i & 0x03</tt>).
*/ */
public static int getArgumentsAndReturnSizes(final String desc) { public static int getArgumentsAndReturnSizes(final String desc) {
int n = 1; int n = 1;
@ -411,8 +374,7 @@ public class Type {
char car = desc.charAt(c++); char car = desc.charAt(c++);
if (car == ')') { if (car == ')') {
car = desc.charAt(c); car = desc.charAt(c);
return n << 2 return n << 2 | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
| (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
} else if (car == 'L') { } else if (car == 'L') {
while (desc.charAt(c++) != ';') { while (desc.charAt(c++) != ';') {
} }
@ -433,58 +395,55 @@ public class Type {
} }
/** /**
* Returns the Java type corresponding to the given type descriptor. For * Returns the Java type corresponding to the given type descriptor. For method descriptors, buf
* method descriptors, buf is supposed to contain nothing more than the * is supposed to contain nothing more than the descriptor itself.
* descriptor itself.
* *
* @param buf * @param buf a buffer containing a type descriptor.
* a buffer containing a type descriptor. * @param off the offset of this descriptor in the previous buffer.
* @param off
* the offset of this descriptor in the previous buffer.
* @return the Java type corresponding to the given type descriptor. * @return the Java type corresponding to the given type descriptor.
*/ */
private static Type getType(final char[] buf, final int off) { private static Type getType(final char[] buf, final int off) {
int len; int len;
switch (buf[off]) { switch (buf[off]) {
case 'V': case 'V':
return VOID_TYPE; return VOID_TYPE;
case 'Z': case 'Z':
return BOOLEAN_TYPE; return BOOLEAN_TYPE;
case 'C': case 'C':
return CHAR_TYPE; return CHAR_TYPE;
case 'B': case 'B':
return BYTE_TYPE; return BYTE_TYPE;
case 'S': case 'S':
return SHORT_TYPE; return SHORT_TYPE;
case 'I': case 'I':
return INT_TYPE; return INT_TYPE;
case 'F': case 'F':
return FLOAT_TYPE; return FLOAT_TYPE;
case 'J': case 'J':
return LONG_TYPE; return LONG_TYPE;
case 'D': case 'D':
return DOUBLE_TYPE; return DOUBLE_TYPE;
case '[': case '[':
len = 1; len = 1;
while (buf[off + len] == '[') { while (buf[off + len] == '[') {
++len; ++len;
} }
if (buf[off + len] == 'L') { if (buf[off + len] == 'L') {
++len; ++len;
while (buf[off + len] != ';') {
++len;
}
}
return new Type(ARRAY, buf, off, len + 1);
case 'L':
len = 1;
while (buf[off + len] != ';') { while (buf[off + len] != ';') {
++len; ++len;
} }
} return new Type(OBJECT, buf, off + 1, len - 1);
return new Type(ARRAY, buf, off, len + 1);
case 'L':
len = 1;
while (buf[off + len] != ';') {
++len;
}
return new Type(OBJECT, buf, off + 1, len - 1);
// case '(': // case '(':
default: default:
return new Type(METHOD, buf, off, buf.length - off); return new Type(METHOD, buf, off, buf.length - off);
} }
} }
@ -495,19 +454,18 @@ public class Type {
/** /**
* Returns the sort of this Java type. * Returns the sort of this Java type.
* *
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, {@link #BYTE BYTE},
* {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT}, * {@link #SHORT SHORT}, {@link #INT INT}, {@link #FLOAT FLOAT}, {@link #LONG LONG},
* {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, * {@link #DOUBLE DOUBLE}, {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or
* {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD * {@link #METHOD METHOD}.
* METHOD}.
*/ */
public int getSort() { public int getSort() {
return sort; return sort;
} }
/** /**
* Returns the number of dimensions of this array type. This method should * Returns the number of dimensions of this array type. This method should only be used for an
* only be used for an array type. * array type.
* *
* @return the number of dimensions of this array type. * @return the number of dimensions of this array type.
*/ */
@ -520,8 +478,8 @@ public class Type {
} }
/** /**
* Returns the type of the elements of this array type. This method should * Returns the type of the elements of this array type. This method should only be used for an
* only be used for an array type. * array type.
* *
* @return Returns the type of the elements of this array type. * @return Returns the type of the elements of this array type.
*/ */
@ -530,49 +488,48 @@ public class Type {
} }
/** /**
* Returns the binary name of the class corresponding to this type. This * Returns the binary name of the class corresponding to this type. This method must not be used
* method must not be used on method types. * on method types.
* *
* @return the binary name of the class corresponding to this type. * @return the binary name of the class corresponding to this type.
*/ */
public String getClassName() { public String getClassName() {
switch (sort) { switch (sort) {
case VOID: case VOID:
return "void"; return "void";
case BOOLEAN: case BOOLEAN:
return "boolean"; return "boolean";
case CHAR: case CHAR:
return "char"; return "char";
case BYTE: case BYTE:
return "byte"; return "byte";
case SHORT: case SHORT:
return "short"; return "short";
case INT: case INT:
return "int"; return "int";
case FLOAT: case FLOAT:
return "float"; return "float";
case LONG: case LONG:
return "long"; return "long";
case DOUBLE: case DOUBLE:
return "double"; return "double";
case ARRAY: case ARRAY:
StringBuffer b = new StringBuffer(getElementType().getClassName()); StringBuffer b = new StringBuffer(getElementType().getClassName());
for (int i = getDimensions(); i > 0; --i) { for (int i = getDimensions(); i > 0; --i) {
b.append("[]"); b.append("[]");
} }
return b.toString(); return b.toString();
case OBJECT: case OBJECT:
return new String(buf, off, len).replace('/', '.'); return new String(buf, off, len).replace('/', '.');
default: default:
return null; return null;
} }
} }
/** /**
* Returns the internal name of the class corresponding to this object or * Returns the internal name of the class corresponding to this object or array type. The
* array type. The internal name of a class is its fully qualified name (as * internal name of a class is its fully qualified name (as returned by Class.getName(), where
* returned by Class.getName(), where '.' are replaced by '/'. This method * '.' are replaced by '/'. This method should only be used for an object or array type.
* should only be used for an object or array type.
* *
* @return the internal name of the class corresponding to this object type. * @return the internal name of the class corresponding to this object type.
*/ */
@ -581,8 +538,8 @@ public class Type {
} }
/** /**
* Returns the argument types of methods of this type. This method should * Returns the argument types of methods of this type. This method should only be used for
* only be used for method types. * method types.
* *
* @return the argument types of methods of this type. * @return the argument types of methods of this type.
*/ */
@ -591,8 +548,8 @@ public class Type {
} }
/** /**
* Returns the return type of methods of this type. This method should only * Returns the return type of methods of this type. This method should only be used for method
* be used for method types. * types.
* *
* @return the return type of methods of this type. * @return the return type of methods of this type.
*/ */
@ -601,14 +558,13 @@ public class Type {
} }
/** /**
* Returns the size of the arguments and of the return value of methods of * Returns the size of the arguments and of the return value of methods of this type. This
* this type. This method should only be used for method types. * method should only be used for method types.
* *
* @return the size of the arguments (plus one for the implicit this * @return the size of the arguments (plus one for the implicit this argument), argSize, and the
* argument), argSize, and the size of the return value, retSize, * size of the return value, retSize, packed into a single int i =
* packed into a single int i = <tt>(argSize << 2) | retSize</tt> * <tt>(argSize << 2) | retSize</tt> (argSize is therefore equal to <tt>i >> 2</tt>, and
* (argSize is therefore equal to <tt>i >> 2</tt>, and retSize to * retSize to <tt>i & 0x03</tt>).
* <tt>i & 0x03</tt>).
*/ */
public int getArgumentsAndReturnSizes() { public int getArgumentsAndReturnSizes() {
return getArgumentsAndReturnSizes(getDescriptor()); return getArgumentsAndReturnSizes(getDescriptor());
@ -630,18 +586,13 @@ public class Type {
} }
/** /**
* Returns the descriptor corresponding to the given argument and return * Returns the descriptor corresponding to the given argument and return types.
* types.
* *
* @param returnType * @param returnType the return type of the method.
* the return type of the method. * @param argumentTypes the argument types of the method.
* @param argumentTypes * @return the descriptor corresponding to the given argument and return types.
* the argument types of the method.
* @return the descriptor corresponding to the given argument and return
* types.
*/ */
public static String getMethodDescriptor(final Type returnType, public static String getMethodDescriptor(final Type returnType, final Type... argumentTypes) {
final Type... argumentTypes) {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
buf.append('('); buf.append('(');
for (int i = 0; i < argumentTypes.length; ++i) { for (int i = 0; i < argumentTypes.length; ++i) {
@ -653,11 +604,9 @@ public class Type {
} }
/** /**
* Appends the descriptor corresponding to this Java type to the given * Appends the descriptor corresponding to this Java type to the given string buffer.
* string buffer.
* *
* @param buf * @param buf the string buffer to which the descriptor must be appended.
* the string buffer to which the descriptor must be appended.
*/ */
private void getDescriptor(final StringBuffer buf) { private void getDescriptor(final StringBuffer buf) {
if (this.buf == null) { if (this.buf == null) {
@ -679,12 +628,10 @@ public class Type {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the internal name of the given class. The internal name of a * Returns the internal name of the given class. The internal name of a class is its fully
* class is its fully qualified name, as returned by Class.getName(), where * qualified name, as returned by Class.getName(), where '.' are replaced by '/'.
* '.' are replaced by '/'.
* *
* @param c * @param c an object or array class.
* an object or array class.
* @return the internal name of the given class. * @return the internal name of the given class.
*/ */
public static String getInternalName(final Class<?> c) { public static String getInternalName(final Class<?> c) {
@ -694,8 +641,7 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given Java type. * Returns the descriptor corresponding to the given Java type.
* *
* @param c * @param c an object class, a primitive class or an array class.
* an object class, a primitive class or an array class.
* @return the descriptor corresponding to the given class. * @return the descriptor corresponding to the given class.
*/ */
public static String getDescriptor(final Class<?> c) { public static String getDescriptor(final Class<?> c) {
@ -707,8 +653,7 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given constructor. * Returns the descriptor corresponding to the given constructor.
* *
* @param c * @param c a {@link Constructor Constructor} object.
* a {@link Constructor Constructor} object.
* @return the descriptor of the given constructor. * @return the descriptor of the given constructor.
*/ */
public static String getConstructorDescriptor(final Constructor<?> c) { public static String getConstructorDescriptor(final Constructor<?> c) {
@ -724,8 +669,7 @@ public class Type {
/** /**
* Returns the descriptor corresponding to the given method. * Returns the descriptor corresponding to the given method.
* *
* @param m * @param m a {@link Method Method} object.
* a {@link Method Method} object.
* @return the descriptor of the given method. * @return the descriptor of the given method.
*/ */
public static String getMethodDescriptor(final Method m) { public static String getMethodDescriptor(final Method m) {
@ -743,10 +687,8 @@ public class Type {
/** /**
* Appends the descriptor of the given class to the given string buffer. * Appends the descriptor of the given class to the given string buffer.
* *
* @param buf * @param buf the string buffer to which the descriptor must be appended.
* the string buffer to which the descriptor must be appended. * @param c the class whose descriptor must be computed.
* @param c
* the class whose descriptor must be computed.
*/ */
private static void getDescriptor(final StringBuffer buf, final Class<?> c) { private static void getDescriptor(final StringBuffer buf, final Class<?> c) {
Class<?> d = c; Class<?> d = c;
@ -769,7 +711,7 @@ public class Type {
car = 'D'; car = 'D';
} else if (d == Float.TYPE) { } else if (d == Float.TYPE) {
car = 'F'; car = 'F';
} else /* if (d == Long.TYPE) */{ } else /* if (d == Long.TYPE) */ {
car = 'J'; car = 'J';
} }
buf.append(car); buf.append(car);
@ -796,11 +738,10 @@ public class Type {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Returns the size of values of this type. This method must not be used for * Returns the size of values of this type. This method must not be used for method types.
* method types.
* *
* @return the size of values of this type, i.e., 2 for <tt>long</tt> and * @return the size of values of this type, i.e., 2 for <tt>long</tt> and <tt>double</tt>, 0 for
* <tt>double</tt>, 0 for <tt>void</tt> and 1 otherwise. * <tt>void</tt> and 1 otherwise.
*/ */
public int getSize() { public int getSize() {
// the size is in byte 0 of 'off' for primitive types (buf == null) // the size is in byte 0 of 'off' for primitive types (buf == null)
@ -808,16 +749,15 @@ public class Type {
} }
/** /**
* Returns a JVM instruction opcode adapted to this Java type. This method * Returns a JVM instruction opcode adapted to this Java type. This method must not be used for
* must not be used for method types. * method types.
* *
* @param opcode * @param opcode a JVM instruction opcode. This opcode must be one of ILOAD, ISTORE, IALOAD,
* a JVM instruction opcode. This opcode must be one of ILOAD, * IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, ISHL, ISHR, IUSHR, IAND, IOR, IXOR and
* ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, * IRETURN.
* ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN. * @return an opcode that is similar to the given opcode, but adapted to this Java type. For
* @return an opcode that is similar to the given opcode, but adapted to * example, if this type is <tt>float</tt> and <tt>opcode</tt> is IRETURN, this method
* this Java type. For example, if this type is <tt>float</tt> and * returns FRETURN.
* <tt>opcode</tt> is IRETURN, this method returns FRETURN.
*/ */
public int getOpcode(final int opcode) { public int getOpcode(final int opcode) {
if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) { if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) {
@ -838,8 +778,7 @@ public class Type {
/** /**
* Tests if the given object is equal to this type. * Tests if the given object is equal to this type.
* *
* @param o * @param o the object to be compared to this type.
* the object to be compared to this type.
* @return <tt>true</tt> if the given object is equal to this type. * @return <tt>true</tt> if the given object is equal to this type.
*/ */
@Override @Override

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -41,17 +33,17 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
/** /**
* A {@link org.objectweb.asm.MethodVisitor} to insert before, after and around * A {@link org.objectweb.asm.MethodVisitor} to insert before, after and around advices in methods
* advices in methods and constructors. * and constructors.
* <p> * <p>
* The behavior for constructors is like this: * The behavior for constructors is like this:
* <ol> * <ol>
* *
* <li>as long as the INVOKESPECIAL for the object initialization has not been * <li>as long as the INVOKESPECIAL for the object initialization has not been reached, every
* reached, every bytecode instruction is dispatched in the ctor code visitor</li> * bytecode instruction is dispatched in the ctor code visitor</li>
* *
* <li>when this one is reached, it is only added in the ctor code visitor and a * <li>when this one is reached, it is only added in the ctor code visitor and a JP invoke is
* JP invoke is added</li> * added</li>
* *
* <li>after that, only the other code visitor receives the instructions</li> * <li>after that, only the other code visitor receives the instructions</li>
* *
@ -81,20 +73,15 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
/** /**
* Creates a new {@link AdviceAdapter}. * Creates a new {@link AdviceAdapter}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param mv the method visitor to which this adapter delegates calls.
* @param mv * @param access the method's access flags (see {@link Opcodes}).
* the method visitor to which this adapter delegates calls. * @param name the method's name.
* @param access * @param desc the method's descriptor (see {@link Type Type}).
* the method's access flags (see {@link Opcodes}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link Type Type}).
*/ */
protected AdviceAdapter(final int api, final MethodVisitor mv, protected AdviceAdapter(final int api, final MethodVisitor mv, final int access,
final int access, final String name, final String desc) { final String name, final String desc) {
super(api, mv, access, name, desc); super(api, mv, access, name, desc);
methodAccess = access; methodAccess = access;
methodDesc = desc; methodDesc = desc;
@ -130,178 +117,178 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
if (constructor) { if (constructor) {
int s; int s;
switch (opcode) { switch (opcode) {
case RETURN: // empty stack case RETURN: // empty stack
onMethodExit(opcode); onMethodExit(opcode);
break; break;
case IRETURN: // 1 before n/a after case IRETURN: // 1 before n/a after
case FRETURN: // 1 before n/a after case FRETURN: // 1 before n/a after
case ARETURN: // 1 before n/a after case ARETURN: // 1 before n/a after
case ATHROW: // 1 before n/a after case ATHROW: // 1 before n/a after
popValue(); popValue();
onMethodExit(opcode); onMethodExit(opcode);
break; break;
case LRETURN: // 2 before n/a after case LRETURN: // 2 before n/a after
case DRETURN: // 2 before n/a after case DRETURN: // 2 before n/a after
popValue(); popValue();
popValue(); popValue();
onMethodExit(opcode); onMethodExit(opcode);
break; break;
case NOP: case NOP:
case LALOAD: // remove 2 add 2 case LALOAD: // remove 2 add 2
case DALOAD: // remove 2 add 2 case DALOAD: // remove 2 add 2
case LNEG: case LNEG:
case DNEG: case DNEG:
case FNEG: case FNEG:
case INEG: case INEG:
case L2D: case L2D:
case D2L: case D2L:
case F2I: case F2I:
case I2B: case I2B:
case I2C: case I2C:
case I2S: case I2S:
case I2F: case I2F:
case ARRAYLENGTH: case ARRAYLENGTH:
break; break;
case ACONST_NULL: case ACONST_NULL:
case ICONST_M1: case ICONST_M1:
case ICONST_0: case ICONST_0:
case ICONST_1: case ICONST_1:
case ICONST_2: case ICONST_2:
case ICONST_3: case ICONST_3:
case ICONST_4: case ICONST_4:
case ICONST_5: case ICONST_5:
case FCONST_0: case FCONST_0:
case FCONST_1: case FCONST_1:
case FCONST_2: case FCONST_2:
case F2L: // 1 before 2 after case F2L: // 1 before 2 after
case F2D: case F2D:
case I2L: case I2L:
case I2D: case I2D:
pushValue(OTHER); pushValue(OTHER);
break; break;
case LCONST_0: case LCONST_0:
case LCONST_1: case LCONST_1:
case DCONST_0: case DCONST_0:
case DCONST_1: case DCONST_1:
pushValue(OTHER); pushValue(OTHER);
pushValue(OTHER); pushValue(OTHER);
break; break;
case IALOAD: // remove 2 add 1 case IALOAD: // remove 2 add 1
case FALOAD: // remove 2 add 1 case FALOAD: // remove 2 add 1
case AALOAD: // remove 2 add 1 case AALOAD: // remove 2 add 1
case BALOAD: // remove 2 add 1 case BALOAD: // remove 2 add 1
case CALOAD: // remove 2 add 1 case CALOAD: // remove 2 add 1
case SALOAD: // remove 2 add 1 case SALOAD: // remove 2 add 1
case POP: case POP:
case IADD: case IADD:
case FADD: case FADD:
case ISUB: case ISUB:
case LSHL: // 3 before 2 after case LSHL: // 3 before 2 after
case LSHR: // 3 before 2 after case LSHR: // 3 before 2 after
case LUSHR: // 3 before 2 after case LUSHR: // 3 before 2 after
case L2I: // 2 before 1 after case L2I: // 2 before 1 after
case L2F: // 2 before 1 after case L2F: // 2 before 1 after
case D2I: // 2 before 1 after case D2I: // 2 before 1 after
case D2F: // 2 before 1 after case D2F: // 2 before 1 after
case FSUB: case FSUB:
case FMUL: case FMUL:
case FDIV: case FDIV:
case FREM: case FREM:
case FCMPL: // 2 before 1 after case FCMPL: // 2 before 1 after
case FCMPG: // 2 before 1 after case FCMPG: // 2 before 1 after
case IMUL: case IMUL:
case IDIV: case IDIV:
case IREM: case IREM:
case ISHL: case ISHL:
case ISHR: case ISHR:
case IUSHR: case IUSHR:
case IAND: case IAND:
case IOR: case IOR:
case IXOR: case IXOR:
case MONITORENTER: case MONITORENTER:
case MONITOREXIT: case MONITOREXIT:
popValue(); popValue();
break; break;
case POP2: case POP2:
case LSUB: case LSUB:
case LMUL: case LMUL:
case LDIV: case LDIV:
case LREM: case LREM:
case LADD: case LADD:
case LAND: case LAND:
case LOR: case LOR:
case LXOR: case LXOR:
case DADD: case DADD:
case DMUL: case DMUL:
case DSUB: case DSUB:
case DDIV: case DDIV:
case DREM: case DREM:
popValue(); popValue();
popValue(); popValue();
break; break;
case IASTORE: case IASTORE:
case FASTORE: case FASTORE:
case AASTORE: case AASTORE:
case BASTORE: case BASTORE:
case CASTORE: case CASTORE:
case SASTORE: case SASTORE:
case LCMP: // 4 before 1 after case LCMP: // 4 before 1 after
case DCMPL: case DCMPL:
case DCMPG: case DCMPG:
popValue(); popValue();
popValue(); popValue();
popValue(); popValue();
break; break;
case LASTORE: case LASTORE:
case DASTORE: case DASTORE:
popValue(); popValue();
popValue(); popValue();
popValue(); popValue();
popValue(); popValue();
break; break;
case DUP: case DUP:
pushValue(peekValue()); pushValue(peekValue());
break; break;
case DUP_X1: case DUP_X1:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 2, stackFrame.get(s - 1)); stackFrame.add(s - 2, stackFrame.get(s - 1));
break; break;
case DUP_X2: case DUP_X2:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 3, stackFrame.get(s - 1)); stackFrame.add(s - 3, stackFrame.get(s - 1));
break; break;
case DUP2: case DUP2:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 2, stackFrame.get(s - 1)); stackFrame.add(s - 2, stackFrame.get(s - 1));
stackFrame.add(s - 2, stackFrame.get(s - 1)); stackFrame.add(s - 2, stackFrame.get(s - 1));
break; break;
case DUP2_X1: case DUP2_X1:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 3, stackFrame.get(s - 1)); stackFrame.add(s - 3, stackFrame.get(s - 1));
stackFrame.add(s - 3, stackFrame.get(s - 1)); stackFrame.add(s - 3, stackFrame.get(s - 1));
break; break;
case DUP2_X2: case DUP2_X2:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 4, stackFrame.get(s - 1)); stackFrame.add(s - 4, stackFrame.get(s - 1));
stackFrame.add(s - 4, stackFrame.get(s - 1)); stackFrame.add(s - 4, stackFrame.get(s - 1));
break; break;
case SWAP: case SWAP:
s = stackFrame.size(); s = stackFrame.size();
stackFrame.add(s - 2, stackFrame.get(s - 1)); stackFrame.add(s - 2, stackFrame.get(s - 1));
stackFrame.remove(s); stackFrame.remove(s);
break; break;
} }
} else { } else {
switch (opcode) { switch (opcode) {
case RETURN: case RETURN:
case IRETURN: case IRETURN:
case FRETURN: case FRETURN:
case ARETURN: case ARETURN:
case LRETURN: case LRETURN:
case DRETURN: case DRETURN:
case ATHROW: case ATHROW:
onMethodExit(opcode); onMethodExit(opcode);
break; break;
} }
} }
mv.visitInsn(opcode); mv.visitInsn(opcode);
@ -312,64 +299,64 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
super.visitVarInsn(opcode, var); super.visitVarInsn(opcode, var);
if (constructor) { if (constructor) {
switch (opcode) { switch (opcode) {
case ILOAD: case ILOAD:
case FLOAD: case FLOAD:
pushValue(OTHER); pushValue(OTHER);
break; break;
case LLOAD: case LLOAD:
case DLOAD: case DLOAD:
pushValue(OTHER); pushValue(OTHER);
pushValue(OTHER); pushValue(OTHER);
break; break;
case ALOAD: case ALOAD:
pushValue(var == 0 ? THIS : OTHER); pushValue(var == 0 ? THIS : OTHER);
break; break;
case ASTORE: case ASTORE:
case ISTORE: case ISTORE:
case FSTORE: case FSTORE:
popValue(); popValue();
break; break;
case LSTORE: case LSTORE:
case DSTORE: case DSTORE:
popValue(); popValue();
popValue(); popValue();
break; break;
} }
} }
} }
@Override @Override
public void visitFieldInsn(final int opcode, final String owner, public void visitFieldInsn(final int opcode, final String owner, final String name,
final String name, final String desc) { final String desc) {
mv.visitFieldInsn(opcode, owner, name, desc); mv.visitFieldInsn(opcode, owner, name, desc);
if (constructor) { if (constructor) {
char c = desc.charAt(0); char c = desc.charAt(0);
boolean longOrDouble = c == 'J' || c == 'D'; boolean longOrDouble = c == 'J' || c == 'D';
switch (opcode) { switch (opcode) {
case GETSTATIC: case GETSTATIC:
pushValue(OTHER);
if (longOrDouble) {
pushValue(OTHER); pushValue(OTHER);
} if (longOrDouble) {
break; pushValue(OTHER);
case PUTSTATIC: }
popValue(); break;
if (longOrDouble) { case PUTSTATIC:
popValue(); popValue();
} if (longOrDouble) {
break; popValue();
case PUTFIELD: }
popValue(); break;
if (longOrDouble) { case PUTFIELD:
popValue(); popValue();
popValue(); if (longOrDouble) {
} popValue();
break; popValue();
// case GETFIELD: }
default: break;
if (longOrDouble) { // case GETFIELD:
pushValue(OTHER); default:
} if (longOrDouble) {
pushValue(OTHER);
}
} }
} }
} }
@ -414,8 +401,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, public void visitMethodInsn(final int opcode, final String owner, final String name,
final String name, final String desc) { final String desc) {
mv.visitMethodInsn(opcode, owner, name, desc); mv.visitMethodInsn(opcode, owner, name, desc);
if (constructor) { if (constructor) {
Type[] types = Type.getArgumentTypes(desc); Type[] types = Type.getArgumentTypes(desc);
@ -426,22 +413,22 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
} }
switch (opcode) { switch (opcode) {
// case INVOKESTATIC: // case INVOKESTATIC:
// break; // break;
case INVOKEINTERFACE: case INVOKEINTERFACE:
case INVOKEVIRTUAL: case INVOKEVIRTUAL:
popValue(); // objectref popValue(); // objectref
break; break;
case INVOKESPECIAL: case INVOKESPECIAL:
Object type = popValue(); // objectref Object type = popValue(); // objectref
if (type == THIS && !superInitialized) { if (type == THIS && !superInitialized) {
onMethodEnter(); onMethodEnter();
superInitialized = true; superInitialized = true;
// once super has been initialized it is no longer // once super has been initialized it is no longer
// necessary to keep track of stack state // necessary to keep track of stack state
constructor = false; constructor = false;
} }
break; break;
} }
Type returnType = Type.getReturnType(desc); Type returnType = Type.getReturnType(desc);
@ -455,8 +442,7 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
Object... bsmArgs) {
mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
if (constructor) { if (constructor) {
Type[] types = Type.getArgumentTypes(desc); Type[] types = Type.getArgumentTypes(desc);
@ -482,38 +468,37 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
mv.visitJumpInsn(opcode, label); mv.visitJumpInsn(opcode, label);
if (constructor) { if (constructor) {
switch (opcode) { switch (opcode) {
case IFEQ: case IFEQ:
case IFNE: case IFNE:
case IFLT: case IFLT:
case IFGE: case IFGE:
case IFGT: case IFGT:
case IFLE: case IFLE:
case IFNULL: case IFNULL:
case IFNONNULL: case IFNONNULL:
popValue(); popValue();
break; break;
case IF_ICMPEQ: case IF_ICMPEQ:
case IF_ICMPNE: case IF_ICMPNE:
case IF_ICMPLT: case IF_ICMPLT:
case IF_ICMPGE: case IF_ICMPGE:
case IF_ICMPGT: case IF_ICMPGT:
case IF_ICMPLE: case IF_ICMPLE:
case IF_ACMPEQ: case IF_ACMPEQ:
case IF_ACMPNE: case IF_ACMPNE:
popValue(); popValue();
popValue(); popValue();
break; break;
case JSR: case JSR:
pushValue(OTHER); pushValue(OTHER);
break; break;
} }
addBranch(label); addBranch(label);
} }
} }
@Override @Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
final Label[] labels) {
mv.visitLookupSwitchInsn(dflt, keys, labels); mv.visitLookupSwitchInsn(dflt, keys, labels);
if (constructor) { if (constructor) {
popValue(); popValue();
@ -522,8 +507,8 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitTableSwitchInsn(final int min, final int max, public void visitTableSwitchInsn(final int min, final int max, final Label dflt,
final Label dflt, final Label... labels) { final Label... labels) {
mv.visitTableSwitchInsn(min, max, dflt, labels); mv.visitTableSwitchInsn(min, max, dflt, labels);
if (constructor) { if (constructor) {
popValue(); popValue();
@ -532,8 +517,7 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
@Override @Override
public void visitTryCatchBlock(Label start, Label end, Label handler, public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
String type) {
super.visitTryCatchBlock(start, end, handler, type); super.visitTryCatchBlock(start, end, handler, type);
if (constructor && !branches.containsKey(handler)) { if (constructor && !branches.containsKey(handler)) {
List<Object> stackFrame = new ArrayList<Object>(); List<Object> stackFrame = new ArrayList<Object>();
@ -569,20 +553,18 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
} }
/** /**
* Called at the beginning of the method or after super class class call in * Called at the beginning of the method or after super class class call in the constructor.
* the constructor. <br> * <br>
* <br> * <br>
* *
* <i>Custom code can use or change all the local variables, but should not * <i>Custom code can use or change all the local variables, but should not change state of the
* change state of the stack.</i> * stack.</i>
*/ */
protected void onMethodEnter() { protected void onMethodEnter() {}
}
/** /**
* Called before explicit exit from the method using either return or throw. * Called before explicit exit from the method using either return or throw. Top element on the
* Top element on the stack contains the return value or exception instance. * stack contains the return value or exception instance. For example:
* For example:
* *
* <pre> * <pre>
* public void onMethodExit(int opcode) { * public void onMethodExit(int opcode) {
@ -610,16 +592,13 @@ public abstract class AdviceAdapter extends GeneratorAdapter implements Opcodes
* <br> * <br>
* <br> * <br>
* *
* <i>Custom code can use or change all the local variables, but should not * <i>Custom code can use or change all the local variables, but should not change state of the
* change state of the stack.</i> * stack.</i>
* *
* @param opcode * @param opcode one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN, DRETURN or ATHROW
* one of the RETURN, IRETURN, FRETURN, ARETURN, LRETURN, DRETURN
* or ATHROW
* *
*/ */
protected void onMethodExit(int opcode) { protected void onMethodExit(int opcode) {}
}
// TODO onException, onMethodCall // TODO onException, onMethodCall
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -111,8 +103,8 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitFieldInsn(final int opcode, final String owner, public void visitFieldInsn(final int opcode, final String owner, final String name,
final String name, final String desc) { final String desc) {
minSize += 3; minSize += 3;
maxSize += 3; maxSize += 3;
if (mv != null) { if (mv != null) {
@ -121,8 +113,8 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, public void visitMethodInsn(final int opcode, final String owner, final String name,
final String name, final String desc) { final String desc) {
if (opcode == INVOKEINTERFACE) { if (opcode == INVOKEINTERFACE) {
minSize += 5; minSize += 5;
maxSize += 5; maxSize += 5;
@ -136,8 +128,7 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
Object... bsmArgs) {
minSize += 5; minSize += 5;
maxSize += 5; maxSize += 5;
if (mv != null) { if (mv != null) {
@ -187,8 +178,8 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitTableSwitchInsn(final int min, final int max, public void visitTableSwitchInsn(final int min, final int max, final Label dflt,
final Label dflt, final Label... labels) { final Label... labels) {
minSize += 13 + labels.length * 4; minSize += 13 + labels.length * 4;
maxSize += 16 + labels.length * 4; maxSize += 16 + labels.length * 4;
if (mv != null) { if (mv != null) {
@ -197,8 +188,7 @@ public class CodeSizeEvaluator extends MethodVisitor implements Opcodes {
} }
@Override @Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
final Label[] labels) {
minSize += 9 + keys.length * 8; minSize += 9 + keys.length * 8;
maxSize += 12 + keys.length * 8; maxSize += 12 + keys.length * 8;
if (mv != null) { if (mv != null) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -55,8 +47,8 @@ import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode; import org.objectweb.asm.tree.TryCatchBlockNode;
/** /**
* A {@link org.objectweb.asm.MethodVisitor} that removes JSR instructions and * A {@link org.objectweb.asm.MethodVisitor} that removes JSR instructions and inlines the
* inlines the referenced subroutines. * referenced subroutines.
* *
* <b>Explanation of how it works</b> TODO * <b>Explanation of how it works</b> TODO
* *
@ -72,82 +64,61 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
private final Map<LabelNode, BitSet> subroutineHeads = new HashMap<LabelNode, BitSet>(); private final Map<LabelNode, BitSet> subroutineHeads = new HashMap<LabelNode, BitSet>();
/** /**
* This subroutine instance denotes the line of execution that is not * This subroutine instance denotes the line of execution that is not contained within any
* contained within any subroutine; i.e., the "subroutine" that is executing * subroutine; i.e., the "subroutine" that is executing when a method first begins.
* when a method first begins.
*/ */
private final BitSet mainSubroutine = new BitSet(); private final BitSet mainSubroutine = new BitSet();
/** /**
* This BitSet contains the index of every instruction that belongs to more * This BitSet contains the index of every instruction that belongs to more than one subroutine.
* than one subroutine. This should not happen often. * This should not happen often.
*/ */
final BitSet dualCitizens = new BitSet(); final BitSet dualCitizens = new BitSet();
/** /**
* Creates a new JSRInliner. <i>Subclasses must not use this * Creates a new JSRInliner. <i>Subclasses must not use this constructor</i>. Instead, they must
* constructor</i>. Instead, they must use the * use the {@link #JSRInlinerAdapter(int, MethodVisitor, int, String, String, String, String[])}
* {@link #JSRInlinerAdapter(int, MethodVisitor, int, String, String, String, String[])}
* version. * version.
* *
* @param mv * @param mv the <code>MethodVisitor</code> to send the resulting inlined method code to (use
* the <code>MethodVisitor</code> to send the resulting inlined * <code>null</code> for none).
* method code to (use <code>null</code> for none). * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates
* @param access * if the method is synthetic and/or deprecated.
* the method's access flags (see {@link Opcodes}). This * @param name the method's name.
* parameter also indicates if the method is synthetic and/or * @param desc the method's descriptor (see {@link Type}).
* deprecated. * @param signature the method's signature. May be <tt>null</tt>.
* @param name * @param exceptions the internal names of the method's exception classes (see
* the method's name. * {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>.
* @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public JSRInlinerAdapter(final MethodVisitor mv, final int access, public JSRInlinerAdapter(final MethodVisitor mv, final int access, final String name,
final String name, final String desc, final String signature, final String desc, final String signature, final String[] exceptions) {
final String[] exceptions) {
this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions); this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions);
} }
/** /**
* Creates a new JSRInliner. * Creates a new JSRInliner.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param mv the <code>MethodVisitor</code> to send the resulting inlined method code to (use
* @param mv * <code>null</code> for none).
* the <code>MethodVisitor</code> to send the resulting inlined * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates
* method code to (use <code>null</code> for none). * if the method is synthetic and/or deprecated.
* @param access * @param name the method's name.
* the method's access flags (see {@link Opcodes}). This * @param desc the method's descriptor (see {@link Type}).
* parameter also indicates if the method is synthetic and/or * @param signature the method's signature. May be <tt>null</tt>.
* deprecated. * @param exceptions the internal names of the method's exception classes (see
* @param name * {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>.
* the method's name.
* @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
protected JSRInlinerAdapter(final int api, final MethodVisitor mv, protected JSRInlinerAdapter(final int api, final MethodVisitor mv, final int access,
final int access, final String name, final String desc, final String name, final String desc, final String signature,
final String signature, final String[] exceptions) { final String[] exceptions) {
super(api, access, name, desc, signature, exceptions); super(api, access, name, desc, signature, exceptions);
this.mv = mv; this.mv = mv;
} }
/** /**
* Detects a JSR instruction and sets a flag to indicate we will need to do * Detects a JSR instruction and sets a flag to indicate we will need to do inlining.
* inlining.
*/ */
@Override @Override
public void visitJumpInsn(final int opcode, final Label lbl) { public void visitJumpInsn(final int opcode, final Label lbl) {
@ -159,8 +130,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* If any JSRs were seen, triggers the inlining process. Otherwise, forwards * If any JSRs were seen, triggers the inlining process. Otherwise, forwards the byte codes
* the byte codes untouched. * untouched.
*/ */
@Override @Override
public void visitEnd() { public void visitEnd() {
@ -184,8 +155,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Walks the method and determines which internal subroutine(s), if any, * Walks the method and determines which internal subroutine(s), if any, each instruction is a
* each instruction is a method of. * method of.
*/ */
private void markSubroutines() { private void markSubroutines() {
BitSet anyvisited = new BitSet(); BitSet anyvisited = new BitSet();
@ -196,8 +167,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
// Go through the head of each subroutine and find any nodes reachable // Go through the head of each subroutine and find any nodes reachable
// to that subroutine without following any JSR links. // to that subroutine without following any JSR links.
for (Iterator<Map.Entry<LabelNode, BitSet>> it = subroutineHeads for (Iterator<Map.Entry<LabelNode, BitSet>> it = subroutineHeads.entrySet().iterator(); it
.entrySet().iterator(); it.hasNext();) { .hasNext();) {
Map.Entry<LabelNode, BitSet> entry = it.next(); Map.Entry<LabelNode, BitSet> entry = it.next();
LabelNode lab = entry.getKey(); LabelNode lab = entry.getKey();
BitSet sub = entry.getValue(); BitSet sub = entry.getValue();
@ -207,23 +178,18 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Performs a depth first search walking the normal byte code path starting * Performs a depth first search walking the normal byte code path starting at
* at <code>index</code>, and adding each instruction encountered into the * <code>index</code>, and adding each instruction encountered into the subroutine
* subroutine <code>sub</code>. After this walk is complete, iterates over * <code>sub</code>. After this walk is complete, iterates over the exception handlers to ensure
* the exception handlers to ensure that we also include those byte codes * that we also include those byte codes which are reachable through an exception that may be
* which are reachable through an exception that may be thrown during the * thrown during the execution of the subroutine. Invoked from <code>markSubroutines()</code>.
* execution of the subroutine. Invoked from <code>markSubroutines()</code>.
* *
* @param sub * @param sub the subroutine whose instructions must be computed.
* the subroutine whose instructions must be computed. * @param index an instruction of this subroutine.
* @param index * @param anyvisited indexes of the already visited instructions, i.e. marked as part of this
* an instruction of this subroutine. * subroutine or any previously computed subroutine.
* @param anyvisited
* indexes of the already visited instructions, i.e. marked as
* part of this subroutine or any previously computed subroutine.
*/ */
private void markSubroutineWalk(final BitSet sub, final int index, private void markSubroutineWalk(final BitSet sub, final int index, final BitSet anyvisited) {
final BitSet anyvisited) {
if (LOGGING) { if (LOGGING) {
log("markSubroutineWalk: sub=" + sub + " index=" + index); log("markSubroutineWalk: sub=" + sub + " index=" + index);
} }
@ -235,8 +201,7 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
boolean loop = true; boolean loop = true;
while (loop) { while (loop) {
loop = false; loop = false;
for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it.hasNext();) {
.hasNext();) {
TryCatchBlockNode trycatch = it.next(); TryCatchBlockNode trycatch = it.next();
if (LOGGING) { if (LOGGING) {
@ -255,9 +220,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
int nextbit = sub.nextSetBit(startindex); int nextbit = sub.nextSetBit(startindex);
if (nextbit != -1 && nextbit < endindex) { if (nextbit != -1 && nextbit < endindex) {
if (LOGGING) { if (LOGGING) {
log("Adding exception handler: " + startindex + '-' log("Adding exception handler: " + startindex + '-' + endindex + " due to "
+ endindex + " due to " + nextbit + " handler " + nextbit + " handler " + handlerindex);
+ handlerindex);
} }
markSubroutineWalkDFS(sub, handlerindex, anyvisited); markSubroutineWalkDFS(sub, handlerindex, anyvisited);
loop = true; loop = true;
@ -267,20 +231,15 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Performs a simple DFS of the instructions, assigning each to the * Performs a simple DFS of the instructions, assigning each to the subroutine <code>sub</code>.
* subroutine <code>sub</code>. Starts from <code>index</code>. Invoked only * Starts from <code>index</code>. Invoked only by <code>markSubroutineWalk()</code>.
* by <code>markSubroutineWalk()</code>.
* *
* @param sub * @param sub the subroutine whose instructions must be computed.
* the subroutine whose instructions must be computed. * @param index an instruction of this subroutine.
* @param index * @param anyvisited indexes of the already visited instructions, i.e. marked as part of this
* an instruction of this subroutine. * subroutine or any previously computed subroutine.
* @param anyvisited
* indexes of the already visited instructions, i.e. marked as
* part of this subroutine or any previously computed subroutine.
*/ */
private void markSubroutineWalkDFS(final BitSet sub, int index, private void markSubroutineWalkDFS(final BitSet sub, int index, final BitSet anyvisited) {
final BitSet anyvisited) {
while (true) { while (true) {
AbstractInsnNode node = instructions.get(index); AbstractInsnNode node = instructions.get(index);
@ -299,8 +258,7 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
anyvisited.set(index); anyvisited.set(index);
if (node.getType() == AbstractInsnNode.JUMP_INSN if (node.getType() == AbstractInsnNode.JUMP_INSN && node.getOpcode() != JSR) {
&& node.getOpcode() != JSR) {
// we do not follow recursively called subroutines here; but any // we do not follow recursively called subroutines here; but any
// other sort of branch we do follow // other sort of branch we do follow
JumpInsnNode jnode = (JumpInsnNode) node; JumpInsnNode jnode = (JumpInsnNode) node;
@ -331,22 +289,22 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
// check to see if this opcode falls through to the next instruction // check to see if this opcode falls through to the next instruction
// or not; if not, return. // or not; if not, return.
switch (instructions.get(index).getOpcode()) { switch (instructions.get(index).getOpcode()) {
case GOTO: case GOTO:
case RET: case RET:
case TABLESWITCH: case TABLESWITCH:
case LOOKUPSWITCH: case LOOKUPSWITCH:
case IRETURN: case IRETURN:
case LRETURN: case LRETURN:
case FRETURN: case FRETURN:
case DRETURN: case DRETURN:
case ARETURN: case ARETURN:
case RETURN: case RETURN:
case ATHROW: case ATHROW:
/* /*
* note: this either returns from this subroutine, or a parent * note: this either returns from this subroutine, or a parent subroutine which
* subroutine which invoked it * invoked it
*/ */
return; return;
} }
// Use tail recursion here in the form of an outer while loop to // Use tail recursion here in the form of an outer while loop to
@ -367,8 +325,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Creates the new instructions, inlining each instantiation of each * Creates the new instructions, inlining each instantiation of each subroutine until the code
* subroutine until the code is fully elaborated. * is fully elaborated.
*/ */
private void emitCode() { private void emitCode() {
LinkedList<Instantiation> worklist = new LinkedList<Instantiation>(); LinkedList<Instantiation> worklist = new LinkedList<Instantiation>();
@ -383,8 +341,7 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>(); List<LocalVariableNode> newLocalVariables = new ArrayList<LocalVariableNode>();
while (!worklist.isEmpty()) { while (!worklist.isEmpty()) {
Instantiation inst = worklist.removeFirst(); Instantiation inst = worklist.removeFirst();
emitSubroutine(inst, worklist, newInstructions, newTryCatchBlocks, emitSubroutine(inst, worklist, newInstructions, newTryCatchBlocks, newLocalVariables);
newLocalVariables);
} }
instructions = newInstructions; instructions = newInstructions;
tryCatchBlocks = newTryCatchBlocks; tryCatchBlocks = newTryCatchBlocks;
@ -392,25 +349,18 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Emits one instantiation of one subroutine, specified by * Emits one instantiation of one subroutine, specified by <code>instant</code>. May add new
* <code>instant</code>. May add new instantiations that are invoked by this * instantiations that are invoked by this one to the <code>worklist</code> parameter, and new
* one to the <code>worklist</code> parameter, and new try/catch blocks to * try/catch blocks to <code>newTryCatchBlocks</code>.
* <code>newTryCatchBlocks</code>.
* *
* @param instant * @param instant the instantiation that must be performed.
* the instantiation that must be performed. * @param worklist list of the instantiations that remain to be done.
* @param worklist * @param newInstructions the instruction list to which the instantiated code must be appended.
* list of the instantiations that remain to be done. * @param newTryCatchBlocks the exception handler list to which the instantiated handlers must
* @param newInstructions * be appended.
* the instruction list to which the instantiated code must be
* appended.
* @param newTryCatchBlocks
* the exception handler list to which the instantiated handlers
* must be appended.
*/ */
private void emitSubroutine(final Instantiation instant, private void emitSubroutine(final Instantiation instant, final List<Instantiation> worklist,
final List<Instantiation> worklist, final InsnList newInstructions, final InsnList newInstructions, final List<TryCatchBlockNode> newTryCatchBlocks,
final List<TryCatchBlockNode> newTryCatchBlocks,
final List<LocalVariableNode> newLocalVariables) { final List<LocalVariableNode> newLocalVariables) {
LabelNode duplbl = null; LabelNode duplbl = null;
@ -476,8 +426,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
// This is only possible if the mainSubroutine owns a RET // This is only possible if the mainSubroutine owns a RET
// instruction, which should never happen for verifiable // instruction, which should never happen for verifiable
// code. // code.
throw new RuntimeException("Instruction #" + i throw new RuntimeException(
+ " is a RET not owned by any subroutine"); "Instruction #" + i + " is a RET not owned by any subroutine");
} }
newInstructions.add(new JumpInsnNode(GOTO, retlabel)); newInstructions.add(new JumpInsnNode(GOTO, retlabel));
} else if (insn.getOpcode() == JSR) { } else if (insn.getOpcode() == JSR) {
@ -508,14 +458,13 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
// Emit try/catch blocks that are relevant to this method. // Emit try/catch blocks that are relevant to this method.
for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it for (Iterator<TryCatchBlockNode> it = tryCatchBlocks.iterator(); it.hasNext();) {
.hasNext();) {
TryCatchBlockNode trycatch = it.next(); TryCatchBlockNode trycatch = it.next();
if (LOGGING) { if (LOGGING) {
// TODO use of default toString(). // TODO use of default toString().
log("try catch block original labels=" + trycatch.start + '-' log("try catch block original labels=" + trycatch.start + '-' + trycatch.end + "->"
+ trycatch.end + "->" + trycatch.handler); + trycatch.handler);
} }
final LabelNode start = instant.rangeLabel(trycatch.start); final LabelNode start = instant.rangeLabel(trycatch.start);
@ -533,20 +482,17 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
if (LOGGING) { if (LOGGING) {
// TODO use of default toString(). // TODO use of default toString().
log(" try catch block new labels=" + start + '-' + end + "->" log(" try catch block new labels=" + start + '-' + end + "->" + handler);
+ handler);
} }
if (start == null || end == null || handler == null) { if (start == null || end == null || handler == null) {
throw new RuntimeException("Internal error!"); throw new RuntimeException("Internal error!");
} }
newTryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, newTryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, trycatch.type));
trycatch.type));
} }
for (Iterator<LocalVariableNode> it = localVariables.iterator(); it for (Iterator<LocalVariableNode> it = localVariables.iterator(); it.hasNext();) {
.hasNext();) {
LocalVariableNode lvnode = it.next(); LocalVariableNode lvnode = it.next();
if (LOGGING) { if (LOGGING) {
log("local var " + lvnode.name); log("local var " + lvnode.name);
@ -559,8 +505,8 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
continue; continue;
} }
newLocalVariables.add(new LocalVariableNode(lvnode.name, newLocalVariables.add(new LocalVariableNode(lvnode.name, lvnode.desc, lvnode.signature,
lvnode.desc, lvnode.signature, start, end, lvnode.index)); start, end, lvnode.index));
} }
} }
@ -569,18 +515,16 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* A class that represents an instantiation of a subroutine. Each * A class that represents an instantiation of a subroutine. Each instantiation has an associate
* instantiation has an associate "stack" --- which is a listing of those * "stack" --- which is a listing of those instantiations that were active when this particular
* instantiations that were active when this particular instance of this * instance of this subroutine was invoked. Each instantiation also has a map from the original
* subroutine was invoked. Each instantiation also has a map from the * labels of the program to the labels appropriate for this instantiation, and finally a label
* original labels of the program to the labels appropriate for this * to return to.
* instantiation, and finally a label to return to.
*/ */
private class Instantiation extends AbstractMap<LabelNode, LabelNode> { private class Instantiation extends AbstractMap<LabelNode, LabelNode> {
/** /**
* Previous instantiations; the stack must be statically predictable to * Previous instantiations; the stack must be statically predictable to be inlinable.
* be inlinable.
*/ */
final Instantiation previous; final Instantiation previous;
@ -590,15 +534,13 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
public final BitSet subroutine; public final BitSet subroutine;
/** /**
* This table maps Labels from the original source to Labels pointing at * This table maps Labels from the original source to Labels pointing at code specific to
* code specific to this instantiation, for use in remapping try/catch * this instantiation, for use in remapping try/catch blocks,as well as gotos.
* blocks,as well as gotos.
* *
* Note that in the presence of dual citizens instructions, that is, * Note that in the presence of dual citizens instructions, that is, instructions which
* instructions which belong to more than one subroutine due to the * belong to more than one subroutine due to the merging of control flow without a RET
* merging of control flow without a RET instruction, we will map the * instruction, we will map the target label of a GOTO to the label used by the
* target label of a GOTO to the label used by the instantiation lowest * instantiation lowest on the stack. This avoids code duplication during inlining in most
* on the stack. This avoids code duplication during inlining in most
* cases. * cases.
* *
* @see #findOwner(int) * @see #findOwner(int)
@ -660,27 +602,23 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Returns the "owner" of a particular instruction relative to this * Returns the "owner" of a particular instruction relative to this instantiation: the owner
* instantiation: the owner referes to the Instantiation which will emit * referes to the Instantiation which will emit the version of this instruction that we will
* the version of this instruction that we will execute. * execute.
* *
* Typically, the return value is either <code>this</code> or * Typically, the return value is either <code>this</code> or <code>null</code>.
* <code>null</code>. <code>this</code> indicates that this * <code>this</code> indicates that this instantiation will generate the version of this
* instantiation will generate the version of this instruction that we * instruction that we will execute, and <code>null</code> indicates that this instantiation
* will execute, and <code>null</code> indicates that this instantiation
* never executes the given instruction. * never executes the given instruction.
* *
* Sometimes, however, an instruction can belong to multiple * Sometimes, however, an instruction can belong to multiple subroutines; this is called a
* subroutines; this is called a "dual citizen" instruction (though it * "dual citizen" instruction (though it may belong to more than 2 subroutines), and occurs
* may belong to more than 2 subroutines), and occurs when multiple * when multiple subroutines branch to common points of control. In this case, the owner is
* subroutines branch to common points of control. In this case, the * the subroutine that appears lowest on the stack, and which also owns the instruction in
* owner is the subroutine that appears lowest on the stack, and which * question.
* also owns the instruction in question.
* *
* @param i * @param i the index of the instruction in the original code
* the index of the instruction in the original code * @return the "owner" of a particular instruction relative to this instantiation.
* @return the "owner" of a particular instruction relative to this
* instantiation.
*/ */
public Instantiation findOwner(final int i) { public Instantiation findOwner(final int i) {
if (!subroutine.get(i)) { if (!subroutine.get(i)) {
@ -699,13 +637,11 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Looks up the label <code>l</code> in the <code>gotoTable</code>, thus * Looks up the label <code>l</code> in the <code>gotoTable</code>, thus translating it from
* translating it from a Label in the original code, to a Label in the * a Label in the original code, to a Label in the inlined code that is appropriate for use
* inlined code that is appropriate for use by an instruction that * by an instruction that branched to the original label.
* branched to the original label.
* *
* @param l * @param l The label we will be translating
* The label we will be translating
* @return a label for use by a branch instruction in the inlined code * @return a label for use by a branch instruction in the inlined code
* @see #rangeLabel * @see #rangeLabel
*/ */
@ -717,15 +653,12 @@ public class JSRInlinerAdapter extends MethodNode implements Opcodes {
} }
/** /**
* Looks up the label <code>l</code> in the <code>rangeTable</code>, * Looks up the label <code>l</code> in the <code>rangeTable</code>, thus translating it
* thus translating it from a Label in the original code, to a Label in * from a Label in the original code, to a Label in the inlined code that is appropriate for
* the inlined code that is appropriate for use by an try/catch or * use by an try/catch or variable use annotation.
* variable use annotation.
* *
* @param l * @param l The label we will be translating
* The label we will be translating * @return a label for use by a try/catch or variable annotation in the original code
* @return a label for use by a try/catch or variable annotation in the
* original code
* @see #rangeTable * @see #rangeTable
*/ */
public LabelNode rangeLabel(final LabelNode l) { public LabelNode rangeLabel(final LabelNode l) {

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -35,12 +27,11 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
/** /**
* A {@link MethodVisitor} that renumbers local variables in their order of * A {@link MethodVisitor} that renumbers local variables in their order of appearance. This adapter
* appearance. This adapter allows one to easily add new local variables to a * allows one to easily add new local variables to a method. It may be used by inheriting from this
* method. It may be used by inheriting from this class, but the preferred way * class, but the preferred way of using it is via delegation: the next visitor in the chain can
* of using it is via delegation: the next visitor in the chain can indeed add * indeed add new locals when needed by calling {@link #newLocal} on this adapter (this requires a
* new locals when needed by calling {@link #newLocal} on this adapter (this * reference back to this {@link LocalVariablesSorter}).
* requires a reference back to this {@link LocalVariablesSorter}).
* *
* @author Chris Nokleberg * @author Chris Nokleberg
* @author Eugene Kuleshov * @author Eugene Kuleshov
@ -48,13 +39,12 @@ import org.objectweb.asm.Type;
*/ */
public class LocalVariablesSorter extends MethodVisitor { public class LocalVariablesSorter extends MethodVisitor {
private static final Type OBJECT_TYPE = Type private static final Type OBJECT_TYPE = Type.getObjectType("java/lang/Object");
.getObjectType("java/lang/Object");
/** /**
* Mapping from old to new local variable indexes. A local variable at index * Mapping from old to new local variable indexes. A local variable at index i of size 1 is
* i of size 1 is remapped to 'mapping[2*i]', while a local variable at * remapped to 'mapping[2*i]', while a local variable at index i of size 2 is remapped to
* index i of size 2 is remapped to 'mapping[2*i+1]'. * 'mapping[2*i+1]'.
*/ */
private int[] mapping = new int[40]; private int[] mapping = new int[40];
@ -79,37 +69,29 @@ public class LocalVariablesSorter extends MethodVisitor {
private boolean changed; private boolean changed;
/** /**
* Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use * Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use this constructor</i>.
* this constructor</i>. Instead, they must use the * Instead, they must use the {@link #LocalVariablesSorter(int, int, String, MethodVisitor)}
* {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version. * version.
* *
* @param access * @param access access flags of the adapted method.
* access flags of the adapted method. * @param desc the method's descriptor (see {@link Type Type}).
* @param desc * @param mv the method visitor to which this adapter delegates calls.
* the method's descriptor (see {@link Type Type}).
* @param mv
* the method visitor to which this adapter delegates calls.
*/ */
public LocalVariablesSorter(final int access, final String desc, public LocalVariablesSorter(final int access, final String desc, final MethodVisitor mv) {
final MethodVisitor mv) {
this(Opcodes.ASM4, access, desc, mv); this(Opcodes.ASM4, access, desc, mv);
} }
/** /**
* Creates a new {@link LocalVariablesSorter}. * Creates a new {@link LocalVariablesSorter}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param access access flags of the adapted method.
* @param access * @param desc the method's descriptor (see {@link Type Type}).
* access flags of the adapted method. * @param mv the method visitor to which this adapter delegates calls.
* @param desc
* the method's descriptor (see {@link Type Type}).
* @param mv
* the method visitor to which this adapter delegates calls.
*/ */
protected LocalVariablesSorter(final int api, final int access, protected LocalVariablesSorter(final int api, final int access, final String desc,
final String desc, final MethodVisitor mv) { final MethodVisitor mv) {
super(api, mv); super(api, mv);
Type[] args = Type.getArgumentTypes(desc); Type[] args = Type.getArgumentTypes(desc);
nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0; nextLocal = (Opcodes.ACC_STATIC & access) == 0 ? 1 : 0;
@ -123,32 +105,32 @@ public class LocalVariablesSorter extends MethodVisitor {
public void visitVarInsn(final int opcode, final int var) { public void visitVarInsn(final int opcode, final int var) {
Type type; Type type;
switch (opcode) { switch (opcode) {
case Opcodes.LLOAD: case Opcodes.LLOAD:
case Opcodes.LSTORE: case Opcodes.LSTORE:
type = Type.LONG_TYPE; type = Type.LONG_TYPE;
break; break;
case Opcodes.DLOAD: case Opcodes.DLOAD:
case Opcodes.DSTORE: case Opcodes.DSTORE:
type = Type.DOUBLE_TYPE; type = Type.DOUBLE_TYPE;
break; break;
case Opcodes.FLOAD: case Opcodes.FLOAD:
case Opcodes.FSTORE: case Opcodes.FSTORE:
type = Type.FLOAT_TYPE; type = Type.FLOAT_TYPE;
break; break;
case Opcodes.ILOAD: case Opcodes.ILOAD:
case Opcodes.ISTORE: case Opcodes.ISTORE:
type = Type.INT_TYPE; type = Type.INT_TYPE;
break; break;
default: default:
// case Opcodes.ALOAD: // case Opcodes.ALOAD:
// case Opcodes.ASTORE: // case Opcodes.ASTORE:
// case RET: // case RET:
type = OBJECT_TYPE; type = OBJECT_TYPE;
break; break;
} }
mv.visitVarInsn(opcode, remap(var, type)); mv.visitVarInsn(opcode, remap(var, type));
} }
@ -164,16 +146,15 @@ public class LocalVariablesSorter extends MethodVisitor {
} }
@Override @Override
public void visitLocalVariable(final String name, final String desc, public void visitLocalVariable(final String name, final String desc, final String signature,
final String signature, final Label start, final Label end, final Label start, final Label end, final int index) {
final int index) {
int newIndex = remap(index, Type.getType(desc)); int newIndex = remap(index, Type.getType(desc));
mv.visitLocalVariable(name, desc, signature, start, end, newIndex); mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
} }
@Override @Override
public void visitFrame(final int type, final int nLocal, public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack,
final Object[] local, final int nStack, final Object[] stack) { final Object[] stack) {
if (type != Opcodes.F_NEW) { // uncompressed frame if (type != Opcodes.F_NEW) { // uncompressed frame
throw new IllegalStateException( throw new IllegalStateException(
"ClassReader.accept() should be called with EXPAND_FRAMES flag"); "ClassReader.accept() should be called with EXPAND_FRAMES flag");
@ -245,36 +226,35 @@ public class LocalVariablesSorter extends MethodVisitor {
/** /**
* Creates a new local variable of the given type. * Creates a new local variable of the given type.
* *
* @param type * @param type the type of the local variable to be created.
* the type of the local variable to be created.
* @return the identifier of the newly created local variable. * @return the identifier of the newly created local variable.
*/ */
public int newLocal(final Type type) { public int newLocal(final Type type) {
Object t; Object t;
switch (type.getSort()) { switch (type.getSort()) {
case Type.BOOLEAN: case Type.BOOLEAN:
case Type.CHAR: case Type.CHAR:
case Type.BYTE: case Type.BYTE:
case Type.SHORT: case Type.SHORT:
case Type.INT: case Type.INT:
t = Opcodes.INTEGER; t = Opcodes.INTEGER;
break; break;
case Type.FLOAT: case Type.FLOAT:
t = Opcodes.FLOAT; t = Opcodes.FLOAT;
break; break;
case Type.LONG: case Type.LONG:
t = Opcodes.LONG; t = Opcodes.LONG;
break; break;
case Type.DOUBLE: case Type.DOUBLE:
t = Opcodes.DOUBLE; t = Opcodes.DOUBLE;
break; break;
case Type.ARRAY: case Type.ARRAY:
t = type.getDescriptor(); t = type.getDescriptor();
break; break;
// case Type.OBJECT: // case Type.OBJECT:
default: default:
t = type.getInternalName(); t = type.getInternalName();
break; break;
} }
int local = newLocalMapping(type); int local = newLocalMapping(type);
setLocalType(local, type); setLocalType(local, type);
@ -284,39 +264,30 @@ public class LocalVariablesSorter extends MethodVisitor {
} }
/** /**
* Notifies subclasses that a new stack map frame is being visited. The * Notifies subclasses that a new stack map frame is being visited. The array argument contains
* array argument contains the stack map frame types corresponding to the * the stack map frame types corresponding to the local variables added with {@link #newLocal}.
* local variables added with {@link #newLocal}. This method can update * This method can update these types in place for the stack map frame being visited. The
* these types in place for the stack map frame being visited. The default * default implementation of this method does nothing, i.e. a local variable added with
* implementation of this method does nothing, i.e. a local variable added * {@link #newLocal} will have the same type in all stack map frames. But this behavior is not
* with {@link #newLocal} will have the same type in all stack map frames. * always the desired one, for instance if a local variable is added in the middle of a
* But this behavior is not always the desired one, for instance if a local * try/catch block: the frame for the exception handler should have a TOP type for this new
* variable is added in the middle of a try/catch block: the frame for the * local.
* exception handler should have a TOP type for this new local.
* *
* @param newLocals * @param newLocals the stack map frame types corresponding to the local variables added with
* the stack map frame types corresponding to the local variables * {@link #newLocal} (and null for the others). The format of this array is the same as
* added with {@link #newLocal} (and null for the others). The * in {@link MethodVisitor#visitFrame}, except that long and double types use two slots.
* format of this array is the same as in * The types for the current stack map frame must be updated in place in this array.
* {@link MethodVisitor#visitFrame}, except that long and double
* types use two slots. The types for the current stack map frame
* must be updated in place in this array.
*/ */
protected void updateNewLocals(Object[] newLocals) { protected void updateNewLocals(Object[] newLocals) {}
}
/** /**
* Notifies subclasses that a local variable has been added or remapped. The * Notifies subclasses that a local variable has been added or remapped. The default
* default implementation of this method does nothing. * implementation of this method does nothing.
* *
* @param local * @param local a local variable identifier, as returned by {@link #newLocal newLocal()}.
* a local variable identifier, as returned by {@link #newLocal * @param type the type of the value being stored in the local variable.
* newLocal()}.
* @param type
* the type of the value being stored in the local variable.
*/ */
protected void setLocalType(final int local, final Type type) { protected void setLocalType(final int local, final Type type) {}
}
private void setFrameLocal(final int local, final Object type) { private void setFrameLocal(final int local, final Object type) {
int l = newLocals.length; int l = newLocals.length;

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -74,10 +66,8 @@ public class Method {
/** /**
* Creates a new {@link Method}. * Creates a new {@link Method}.
* *
* @param name * @param name the method's name.
* the method's name. * @param desc the method's descriptor.
* @param desc
* the method's descriptor.
*/ */
public Method(final String name, final String desc) { public Method(final String name, final String desc) {
this.name = name; this.name = name;
@ -87,25 +77,19 @@ public class Method {
/** /**
* Creates a new {@link Method}. * Creates a new {@link Method}.
* *
* @param name * @param name the method's name.
* the method's name. * @param returnType the method's return type.
* @param returnType * @param argumentTypes the method's argument types.
* the method's return type.
* @param argumentTypes
* the method's argument types.
*/ */
public Method(final String name, final Type returnType, public Method(final String name, final Type returnType, final Type[] argumentTypes) {
final Type[] argumentTypes) {
this(name, Type.getMethodDescriptor(returnType, argumentTypes)); this(name, Type.getMethodDescriptor(returnType, argumentTypes));
} }
/** /**
* Creates a new {@link Method}. * Creates a new {@link Method}.
* *
* @param m * @param m a java.lang.reflect method descriptor
* a java.lang.reflect method descriptor * @return a {@link Method} corresponding to the given Java method declaration.
* @return a {@link Method} corresponding to the given Java method
* declaration.
*/ */
public static Method getMethod(java.lang.reflect.Method m) { public static Method getMethod(java.lang.reflect.Method m) {
return new Method(m.getName(), Type.getMethodDescriptor(m)); return new Method(m.getName(), Type.getMethodDescriptor(m));
@ -114,60 +98,43 @@ public class Method {
/** /**
* Creates a new {@link Method}. * Creates a new {@link Method}.
* *
* @param c * @param c a java.lang.reflect constructor descriptor
* a java.lang.reflect constructor descriptor * @return a {@link Method} corresponding to the given Java constructor declaration.
* @return a {@link Method} corresponding to the given Java constructor
* declaration.
*/ */
public static Method getMethod(java.lang.reflect.Constructor<?> c) { public static Method getMethod(java.lang.reflect.Constructor<?> c) {
return new Method("<init>", Type.getConstructorDescriptor(c)); return new Method("<init>", Type.getConstructorDescriptor(c));
} }
/** /**
* Returns a {@link Method} corresponding to the given Java method * Returns a {@link Method} corresponding to the given Java method declaration.
* declaration.
* *
* @param method * @param method a Java method declaration, without argument names, of the form "returnType name
* a Java method declaration, without argument names, of the form * (argumentType1, ... argumentTypeN)", where the types are in plain Java (e.g. "int",
* "returnType name (argumentType1, ... argumentTypeN)", where * "float", "java.util.List", ...). Classes of the java.lang package can be specified by
* the types are in plain Java (e.g. "int", "float", * their unqualified name; all other classes names must be fully qualified.
* "java.util.List", ...). Classes of the java.lang package can * @return a {@link Method} corresponding to the given Java method declaration.
* be specified by their unqualified name; all other classes * @throws IllegalArgumentException if <code>method</code> could not get parsed.
* names must be fully qualified.
* @return a {@link Method} corresponding to the given Java method
* declaration.
* @throws IllegalArgumentException
* if <code>method</code> could not get parsed.
*/ */
public static Method getMethod(final String method) public static Method getMethod(final String method) throws IllegalArgumentException {
throws IllegalArgumentException {
return getMethod(method, false); return getMethod(method, false);
} }
/** /**
* Returns a {@link Method} corresponding to the given Java method * Returns a {@link Method} corresponding to the given Java method declaration.
* declaration.
* *
* @param method * @param method a Java method declaration, without argument names, of the form "returnType name
* a Java method declaration, without argument names, of the form * (argumentType1, ... argumentTypeN)", where the types are in plain Java (e.g. "int",
* "returnType name (argumentType1, ... argumentTypeN)", where * "float", "java.util.List", ...). Classes of the java.lang package may be specified by
* the types are in plain Java (e.g. "int", "float", * their unqualified name, depending on the defaultPackage argument; all other classes
* "java.util.List", ...). Classes of the java.lang package may * names must be fully qualified.
* be specified by their unqualified name, depending on the * @param defaultPackage true if unqualified class names belong to the default package, or false
* defaultPackage argument; all other classes names must be fully * if they correspond to java.lang classes. For instance "Object" means "Object" if this
* qualified. * option is true, or "java.lang.Object" otherwise.
* @param defaultPackage * @return a {@link Method} corresponding to the given Java method declaration.
* true if unqualified class names belong to the default package, * @throws IllegalArgumentException if <code>method</code> could not get parsed.
* or false if they correspond to java.lang classes. For instance
* "Object" means "Object" if this option is true, or
* "java.lang.Object" otherwise.
* @return a {@link Method} corresponding to the given Java method
* declaration.
* @throws IllegalArgumentException
* if <code>method</code> could not get parsed.
*/ */
public static Method getMethod(final String method, public static Method getMethod(final String method, final boolean defaultPackage)
final boolean defaultPackage) throws IllegalArgumentException { throws IllegalArgumentException {
int space = method.indexOf(' '); int space = method.indexOf(' ');
int start = method.indexOf('(', space) + 1; int start = method.indexOf('(', space) + 1;
int end = method.indexOf(')', start); int end = method.indexOf(')', start);
@ -279,4 +246,4 @@ public class Method {
public int hashCode() { public int hashCode() {
return name.hashCode() ^ desc.hashCode(); return name.hashCode() ^ desc.hashCode();
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -37,8 +29,7 @@ import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter; import org.objectweb.asm.signature.SignatureWriter;
/** /**
* A class responsible for remapping types and names. Subclasses can override * A class responsible for remapping types and names. Subclasses can override the following methods:
* the following methods:
* *
* <ul> * <ul>
* <li>{@link #map(String)} - map type</li> * <li>{@link #map(String)} - map type</li>
@ -53,34 +44,34 @@ public abstract class Remapper {
public String mapDesc(String desc) { public String mapDesc(String desc) {
Type t = Type.getType(desc); Type t = Type.getType(desc);
switch (t.getSort()) { switch (t.getSort()) {
case Type.ARRAY: case Type.ARRAY:
String s = mapDesc(t.getElementType().getDescriptor()); String s = mapDesc(t.getElementType().getDescriptor());
for (int i = 0; i < t.getDimensions(); ++i) { for (int i = 0; i < t.getDimensions(); ++i) {
s = '[' + s; s = '[' + s;
} }
return s; return s;
case Type.OBJECT: case Type.OBJECT:
String newType = map(t.getInternalName()); String newType = map(t.getInternalName());
if (newType != null) { if (newType != null) {
return 'L' + newType + ';'; return 'L' + newType + ';';
} }
} }
return desc; return desc;
} }
private Type mapType(Type t) { private Type mapType(Type t) {
switch (t.getSort()) { switch (t.getSort()) {
case Type.ARRAY: case Type.ARRAY:
String s = mapDesc(t.getElementType().getDescriptor()); String s = mapDesc(t.getElementType().getDescriptor());
for (int i = 0; i < t.getDimensions(); ++i) { for (int i = 0; i < t.getDimensions(); ++i) {
s = '[' + s; s = '[' + s;
} }
return Type.getType(s); return Type.getType(s);
case Type.OBJECT: case Type.OBJECT:
s = map(t.getInternalName()); s = map(t.getInternalName());
return s != null ? Type.getObjectType(s) : t; return s != null ? Type.getObjectType(s) : t;
case Type.METHOD: case Type.METHOD:
return Type.getMethodType(mapMethodDesc(t.getDescriptor())); return Type.getMethodType(mapMethodDesc(t.getDescriptor()));
} }
return t; return t;
} }
@ -137,8 +128,8 @@ public abstract class Remapper {
} }
if (value instanceof Handle) { if (value instanceof Handle) {
Handle h = (Handle) value; Handle h = (Handle) value;
return new Handle(h.getTag(), mapType(h.getOwner()), mapMethodName( return new Handle(h.getTag(), mapType(h.getOwner()),
h.getOwner(), h.getName(), h.getDesc()), mapMethodName(h.getOwner(), h.getName(), h.getDesc()),
mapMethodDesc(h.getDesc())); mapMethodDesc(h.getDesc()));
} }
return value; return value;
@ -146,10 +137,8 @@ public abstract class Remapper {
/** /**
* *
* @param typeSignature * @param typeSignature true if signature is a FieldTypeSignature, such as the signature
* true if signature is a FieldTypeSignature, such as the * parameter of the ClassVisitor.visitField or MethodVisitor.visitLocalVariable methods
* signature parameter of the ClassVisitor.visitField or
* MethodVisitor.visitLocalVariable methods
*/ */
public String mapSignature(String signature, boolean typeSignature) { public String mapSignature(String signature, boolean typeSignature) {
if (signature == null) { if (signature == null) {
@ -166,20 +155,16 @@ public abstract class Remapper {
return w.toString(); return w.toString();
} }
protected SignatureVisitor createRemappingSignatureAdapter( protected SignatureVisitor createRemappingSignatureAdapter(SignatureVisitor v) {
SignatureVisitor v) {
return new RemappingSignatureAdapter(v, this); return new RemappingSignatureAdapter(v, this);
} }
/** /**
* Map method name to the new name. Subclasses can override. * Map method name to the new name. Subclasses can override.
* *
* @param owner * @param owner owner of the method.
* owner of the method. * @param name name of the method.
* @param name * @param desc descriptor of the method.
* name of the method.
* @param desc
* descriptor of the method.
* @return new name of the method * @return new name of the method
*/ */
public String mapMethodName(String owner, String name, String desc) { public String mapMethodName(String owner, String name, String desc) {
@ -189,10 +174,8 @@ public abstract class Remapper {
/** /**
* Map invokedynamic method name to the new name. Subclasses can override. * Map invokedynamic method name to the new name. Subclasses can override.
* *
* @param name * @param name name of the invokedynamic.
* name of the invokedynamic. * @param desc descriptor of the invokedynamic.
* @param desc
* descriptor of the invokedynamic.
* @return new invokdynamic name. * @return new invokdynamic name.
*/ */
public String mapInvokeDynamicMethodName(String name, String desc) { public String mapInvokeDynamicMethodName(String name, String desc) {
@ -202,12 +185,9 @@ public abstract class Remapper {
/** /**
* Map field name to the new name. Subclasses can override. * Map field name to the new name. Subclasses can override.
* *
* @param owner * @param owner owner of the field.
* owner of the field. * @param name name of the field
* @param name * @param desc descriptor of the field
* name of the field
* @param desc
* descriptor of the field
* @return new name of the field. * @return new name of the field.
*/ */
public String mapFieldName(String owner, String name, String desc) { public String mapFieldName(String owner, String name, String desc) {

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -42,13 +34,12 @@ public class RemappingAnnotationAdapter extends AnnotationVisitor {
protected final Remapper remapper; protected final Remapper remapper;
public RemappingAnnotationAdapter(final AnnotationVisitor av, public RemappingAnnotationAdapter(final AnnotationVisitor av, final Remapper remapper) {
final Remapper remapper) {
this(Opcodes.ASM4, av, remapper); this(Opcodes.ASM4, av, remapper);
} }
protected RemappingAnnotationAdapter(final int api, protected RemappingAnnotationAdapter(final int api, final AnnotationVisitor av,
final AnnotationVisitor av, final Remapper remapper) { final Remapper remapper) {
super(api, av); super(api, av);
this.remapper = remapper; this.remapper = remapper;
} }
@ -66,14 +57,12 @@ public class RemappingAnnotationAdapter extends AnnotationVisitor {
@Override @Override
public AnnotationVisitor visitAnnotation(String name, String desc) { public AnnotationVisitor visitAnnotation(String name, String desc) {
AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc)); AnnotationVisitor v = av.visitAnnotation(name, remapper.mapDesc(desc));
return v == null ? null : (v == av ? this return v == null ? null : (v == av ? this : new RemappingAnnotationAdapter(v, remapper));
: new RemappingAnnotationAdapter(v, remapper));
} }
@Override @Override
public AnnotationVisitor visitArray(String name) { public AnnotationVisitor visitArray(String name) {
AnnotationVisitor v = av.visitArray(name); AnnotationVisitor v = av.visitArray(name);
return v == null ? null : (v == av ? this return v == null ? null : (v == av ? this : new RemappingAnnotationAdapter(v, remapper));
: new RemappingAnnotationAdapter(v, remapper));
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -51,18 +43,17 @@ public class RemappingClassAdapter extends ClassVisitor {
this(Opcodes.ASM4, cv, remapper); this(Opcodes.ASM4, cv, remapper);
} }
protected RemappingClassAdapter(final int api, final ClassVisitor cv, protected RemappingClassAdapter(final int api, final ClassVisitor cv, final Remapper remapper) {
final Remapper remapper) {
super(api, cv); super(api, cv);
this.remapper = remapper; this.remapper = remapper;
} }
@Override @Override
public void visit(int version, int access, String name, String signature, public void visit(int version, int access, String name, String signature, String superName,
String superName, String[] interfaces) { String[] interfaces) {
this.className = name; this.className = name;
super.visit(version, access, remapper.mapType(name), remapper super.visit(version, access, remapper.mapType(name),
.mapSignature(signature, false), remapper.mapType(superName), remapper.mapSignature(signature, false), remapper.mapType(superName),
interfaces == null ? null : remapper.mapTypes(interfaces)); interfaces == null ? null : remapper.mapTypes(interfaces));
} }
@ -74,39 +65,35 @@ public class RemappingClassAdapter extends ClassVisitor {
} }
@Override @Override
public FieldVisitor visitField(int access, String name, String desc, public FieldVisitor visitField(int access, String name, String desc, String signature,
String signature, Object value) { Object value) {
FieldVisitor fv = super.visitField(access, FieldVisitor fv = super.visitField(access, remapper.mapFieldName(className, name, desc),
remapper.mapFieldName(className, name, desc),
remapper.mapDesc(desc), remapper.mapSignature(signature, true), remapper.mapDesc(desc), remapper.mapSignature(signature, true),
remapper.mapValue(value)); remapper.mapValue(value));
return fv == null ? null : createRemappingFieldAdapter(fv); return fv == null ? null : createRemappingFieldAdapter(fv);
} }
@Override @Override
public MethodVisitor visitMethod(int access, String name, String desc, public MethodVisitor visitMethod(int access, String name, String desc, String signature,
String signature, String[] exceptions) { String[] exceptions) {
String newDesc = remapper.mapMethodDesc(desc); String newDesc = remapper.mapMethodDesc(desc);
MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName( MethodVisitor mv = super.visitMethod(access, remapper.mapMethodName(className, name, desc),
className, name, desc), newDesc, remapper.mapSignature( newDesc, remapper.mapSignature(signature, false),
signature, false),
exceptions == null ? null : remapper.mapTypes(exceptions)); exceptions == null ? null : remapper.mapTypes(exceptions));
return mv == null ? null : createRemappingMethodAdapter(access, return mv == null ? null : createRemappingMethodAdapter(access, newDesc, mv);
newDesc, mv);
} }
@Override @Override
public void visitInnerClass(String name, String outerName, public void visitInnerClass(String name, String outerName, String innerName, int access) {
String innerName, int access) {
// TODO should innerName be changed? // TODO should innerName be changed?
super.visitInnerClass(remapper.mapType(name), outerName == null ? null super.visitInnerClass(remapper.mapType(name),
: remapper.mapType(outerName), innerName, access); outerName == null ? null : remapper.mapType(outerName), innerName, access);
} }
@Override @Override
public void visitOuterClass(String owner, String name, String desc) { public void visitOuterClass(String owner, String name, String desc) {
super.visitOuterClass(remapper.mapType(owner), name == null ? null super.visitOuterClass(remapper.mapType(owner),
: remapper.mapMethodName(owner, name, desc), name == null ? null : remapper.mapMethodName(owner, name, desc),
desc == null ? null : remapper.mapMethodDesc(desc)); desc == null ? null : remapper.mapMethodDesc(desc));
} }
@ -114,13 +101,12 @@ public class RemappingClassAdapter extends ClassVisitor {
return new RemappingFieldAdapter(fv, remapper); return new RemappingFieldAdapter(fv, remapper);
} }
protected MethodVisitor createRemappingMethodAdapter(int access, protected MethodVisitor createRemappingMethodAdapter(int access, String newDesc,
String newDesc, MethodVisitor mv) { MethodVisitor mv) {
return new RemappingMethodAdapter(access, newDesc, mv, remapper); return new RemappingMethodAdapter(access, newDesc, mv, remapper);
} }
protected AnnotationVisitor createRemappingAnnotationAdapter( protected AnnotationVisitor createRemappingAnnotationAdapter(AnnotationVisitor av) {
AnnotationVisitor av) {
return new RemappingAnnotationAdapter(av, remapper); return new RemappingAnnotationAdapter(av, remapper);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -47,16 +39,14 @@ public class RemappingFieldAdapter extends FieldVisitor {
this(Opcodes.ASM4, fv, remapper); this(Opcodes.ASM4, fv, remapper);
} }
protected RemappingFieldAdapter(final int api, final FieldVisitor fv, protected RemappingFieldAdapter(final int api, final FieldVisitor fv, final Remapper remapper) {
final Remapper remapper) {
super(api, fv); super(api, fv);
this.remapper = remapper; this.remapper = remapper;
} }
@Override @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc), AnnotationVisitor av = fv.visitAnnotation(remapper.mapDesc(desc), visible);
visible);
return av == null ? null : new RemappingAnnotationAdapter(av, remapper); return av == null ? null : new RemappingAnnotationAdapter(av, remapper);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -45,13 +37,13 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
protected final Remapper remapper; protected final Remapper remapper;
public RemappingMethodAdapter(final int access, final String desc, public RemappingMethodAdapter(final int access, final String desc, final MethodVisitor mv,
final MethodVisitor mv, final Remapper remapper) { final Remapper remapper) {
this(Opcodes.ASM4, access, desc, mv, remapper); this(Opcodes.ASM4, access, desc, mv, remapper);
} }
protected RemappingMethodAdapter(final int api, final int access, protected RemappingMethodAdapter(final int api, final int access, final String desc,
final String desc, final MethodVisitor mv, final Remapper remapper) { final MethodVisitor mv, final Remapper remapper) {
super(api, access, desc, mv); super(api, access, desc, mv);
this.remapper = remapper; this.remapper = remapper;
} }
@ -64,22 +56,19 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
@Override @Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
AnnotationVisitor av = mv.visitAnnotation(remapper.mapDesc(desc), AnnotationVisitor av = mv.visitAnnotation(remapper.mapDesc(desc), visible);
visible);
return av == null ? av : new RemappingAnnotationAdapter(av, remapper); return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
} }
@Override @Override
public AnnotationVisitor visitParameterAnnotation(int parameter, public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
String desc, boolean visible) { AnnotationVisitor av =
AnnotationVisitor av = mv.visitParameterAnnotation(parameter, mv.visitParameterAnnotation(parameter, remapper.mapDesc(desc), visible);
remapper.mapDesc(desc), visible);
return av == null ? av : new RemappingAnnotationAdapter(av, remapper); return av == null ? av : new RemappingAnnotationAdapter(av, remapper);
} }
@Override @Override
public void visitFrame(int type, int nLocal, Object[] local, int nStack, public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
Object[] stack) {
super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack, super.visitFrame(type, nLocal, remapEntries(nLocal, local), nStack,
remapEntries(nStack, stack)); remapEntries(nStack, stack));
} }
@ -93,8 +82,7 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
} }
do { do {
Object t = entries[i]; Object t = entries[i];
newEntries[i++] = t instanceof String ? remapper newEntries[i++] = t instanceof String ? remapper.mapType((String) t) : t;
.mapType((String) t) : t;
} while (i < n); } while (i < n);
return newEntries; return newEntries;
} }
@ -103,31 +91,24 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
} }
@Override @Override
public void visitFieldInsn(int opcode, String owner, String name, public void visitFieldInsn(int opcode, String owner, String name, String desc) {
String desc) {
super.visitFieldInsn(opcode, remapper.mapType(owner), super.visitFieldInsn(opcode, remapper.mapType(owner),
remapper.mapFieldName(owner, name, desc), remapper.mapFieldName(owner, name, desc), remapper.mapDesc(desc));
remapper.mapDesc(desc));
} }
@Override @Override
public void visitMethodInsn(int opcode, String owner, String name, public void visitMethodInsn(int opcode, String owner, String name, String desc) {
String desc) {
super.visitMethodInsn(opcode, remapper.mapType(owner), super.visitMethodInsn(opcode, remapper.mapType(owner),
remapper.mapMethodName(owner, name, desc), remapper.mapMethodName(owner, name, desc), remapper.mapMethodDesc(desc));
remapper.mapMethodDesc(desc));
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
Object... bsmArgs) {
for (int i = 0; i < bsmArgs.length; i++) { for (int i = 0; i < bsmArgs.length; i++) {
bsmArgs[i] = remapper.mapValue(bsmArgs[i]); bsmArgs[i] = remapper.mapValue(bsmArgs[i]);
} }
super.visitInvokeDynamicInsn( super.visitInvokeDynamicInsn(remapper.mapInvokeDynamicMethodName(name, desc),
remapper.mapInvokeDynamicMethodName(name, desc), remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm), bsmArgs);
remapper.mapMethodDesc(desc), (Handle) remapper.mapValue(bsm),
bsmArgs);
} }
@Override @Override
@ -146,15 +127,13 @@ public class RemappingMethodAdapter extends LocalVariablesSorter {
} }
@Override @Override
public void visitTryCatchBlock(Label start, Label end, Label handler, public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
String type) { super.visitTryCatchBlock(start, end, handler, type == null ? null : remapper.mapType(type));
super.visitTryCatchBlock(start, end, handler, type == null ? null
: remapper.mapType(type));
} }
@Override @Override
public void visitLocalVariable(String name, String desc, String signature, public void visitLocalVariable(String name, String desc, String signature, Label start,
Label start, Label end, int index) { Label end, int index) {
super.visitLocalVariable(name, remapper.mapDesc(desc), super.visitLocalVariable(name, remapper.mapDesc(desc),
remapper.mapSignature(signature, true), start, end, index); remapper.mapSignature(signature, true), start, end, index);
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -46,13 +38,12 @@ public class RemappingSignatureAdapter extends SignatureVisitor {
private String className; private String className;
public RemappingSignatureAdapter(final SignatureVisitor v, public RemappingSignatureAdapter(final SignatureVisitor v, final Remapper remapper) {
final Remapper remapper) {
this(Opcodes.ASM4, v, remapper); this(Opcodes.ASM4, v, remapper);
} }
protected RemappingSignatureAdapter(final int api, protected RemappingSignatureAdapter(final int api, final SignatureVisitor v,
final SignatureVisitor v, final Remapper remapper) { final Remapper remapper) {
super(api); super(api);
this.v = v; this.v = v;
this.remapper = remapper; this.remapper = remapper;
@ -69,8 +60,8 @@ public class RemappingSignatureAdapter extends SignatureVisitor {
String remappedOuter = remapper.mapType(className) + '$'; String remappedOuter = remapper.mapType(className) + '$';
className = className + '$' + name; className = className + '$' + name;
String remappedName = remapper.mapType(className); String remappedName = remapper.mapType(className);
int index = remappedName.startsWith(remappedOuter) ? remappedOuter int index = remappedName.startsWith(remappedOuter) ? remappedOuter.length()
.length() : remappedName.lastIndexOf('$') + 1; : remappedName.lastIndexOf('$') + 1;
v.visitInnerClassType(remappedName.substring(index)); v.visitInnerClassType(remappedName.substring(index));
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -44,8 +36,8 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
/** /**
* A {@link ClassVisitor} that adds a serial version unique identifier to a * A {@link ClassVisitor} that adds a serial version unique identifier to a class if missing. Here
* class if missing. Here is typical usage of this class: * is typical usage of this class:
* *
* <pre> * <pre>
* ClassWriter cw = new ClassWriter(...); * ClassWriter cw = new ClassWriter(...);
@ -54,8 +46,8 @@ import java.util.Collection;
* new ClassReader(orginalClass).accept(ca, false); * new ClassReader(orginalClass).accept(ca, false);
* </pre> * </pre>
* <p> * <p>
* The SVUID algorithm can be found <a href= * The SVUID algorithm can be found
* "http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html" * <a href= "http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html"
* >http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html</a>: * >http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html</a>:
* *
* <pre> * <pre>
@ -113,8 +105,7 @@ import java.util.Collection;
public class SerialVersionUIDAdder extends ClassVisitor { public class SerialVersionUIDAdder extends ClassVisitor {
/** /**
* Collection of fields. (except private static and private transient * Collection of fields. (except private static and private transient fields)
* fields)
*/ */
private final Collection<Item> svuidFields; private final Collection<Item> svuidFields;
/** /**
@ -151,12 +142,10 @@ public class SerialVersionUIDAdder extends ClassVisitor {
private boolean hasStaticInitializer; private boolean hasStaticInitializer;
/** /**
* Creates a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use * Creates a new {@link SerialVersionUIDAdder}. <i>Subclasses must not use this constructor</i>.
* this constructor</i>. Instead, they must use the * Instead, they must use the {@link #SerialVersionUIDAdder(int, ClassVisitor)} version.
* {@link #SerialVersionUIDAdder(int, ClassVisitor)} version.
* *
* @param cv a {@link ClassVisitor} to which this visitor will delegate * @param cv a {@link ClassVisitor} to which this visitor will delegate calls.
* calls.
*/ */
public SerialVersionUIDAdder(final ClassVisitor cv) { public SerialVersionUIDAdder(final ClassVisitor cv) {
this(Opcodes.ASM4, cv); this(Opcodes.ASM4, cv);
@ -165,10 +154,9 @@ public class SerialVersionUIDAdder extends ClassVisitor {
/** /**
* Creates a new {@link SerialVersionUIDAdder}. * Creates a new {@link SerialVersionUIDAdder}.
* *
* @param api the ASM API version implemented by this visitor. Must be one * @param api the ASM API version implemented by this visitor. Must be one of
* of {@link Opcodes#ASM4}. * {@link Opcodes#ASM4}.
* @param cv a {@link ClassVisitor} to which this visitor will delegate * @param cv a {@link ClassVisitor} to which this visitor will delegate calls.
* calls.
*/ */
protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) { protected SerialVersionUIDAdder(final int api, final ClassVisitor cv) {
super(api, cv); super(api, cv);
@ -185,31 +173,29 @@ public class SerialVersionUIDAdder extends ClassVisitor {
* Sorts the items in the collection and writes it to the data output stream * Sorts the items in the collection and writes it to the data output stream
* *
* @param itemCollection collection of items * @param itemCollection collection of items
* @param dos a <code>DataOutputStream</code> value * @param dos a <code>DataOutputStream</code> value
* @param dotted a <code>boolean</code> value * @param dotted a <code>boolean</code> value
* @throws IOException if an error occurs * @throws IOException if an error occurs
*/ */
private static void writeItems(final Collection<Item> itemCollection, private static void writeItems(final Collection<Item> itemCollection, final DataOutput dos,
final DataOutput dos, final boolean dotted) throws IOException { final boolean dotted) throws IOException {
int size = itemCollection.size(); int size = itemCollection.size();
Item[] items = itemCollection.toArray(new Item[size]); Item[] items = itemCollection.toArray(new Item[size]);
Arrays.sort(items); Arrays.sort(items);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
dos.writeUTF(items[i].name); dos.writeUTF(items[i].name);
dos.writeInt(items[i].access); dos.writeInt(items[i].access);
dos.writeUTF(dotted ? items[i].desc.replace('/', '.') dos.writeUTF(dotted ? items[i].desc.replace('/', '.') : items[i].desc);
: items[i].desc);
} }
} }
/* /*
* Visit class header and get class name, access , and interfaces * Visit class header and get class name, access , and interfaces information (step 1,2, and 3)
* information (step 1,2, and 3) for SVUID computation. * for SVUID computation.
*/ */
@Override @Override
public void visit(final int version, final int access, final String name, public void visit(final int version, final int access, final String name,
final String signature, final String superName, final String signature, final String superName, final String[] interfaces) {
final String[] interfaces) {
computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0; computeSVUID = (access & Opcodes.ACC_INTERFACE) == 0;
if (computeSVUID) { if (computeSVUID) {
@ -222,27 +208,23 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/* /*
* Visit the methods and get constructor and method information (step 5 and * Visit the methods and get constructor and method information (step 5 and 7). Also determine
* 7). Also determine if there is a class initializer (step 6). * if there is a class initializer (step 6).
*/ */
@Override @Override
public MethodVisitor visitMethod(final int access, final String name, public MethodVisitor visitMethod(final int access, final String name, final String desc,
final String desc, final String signature, final String[] exceptions) { final String signature, final String[] exceptions) {
if (computeSVUID) { if (computeSVUID) {
if ("<clinit>".equals(name)) { if ("<clinit>".equals(name)) {
hasStaticInitializer = true; hasStaticInitializer = true;
} }
/* /*
* Remembers non private constructors and methods for SVUID * Remembers non private constructors and methods for SVUID computation For constructor
* computation For constructor and method modifiers, only the * and method modifiers, only the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC,
* ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, * ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags are used.
* ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT and ACC_STRICT flags
* are used.
*/ */
int mods = access int mods = access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED
& (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED
| Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
| Opcodes.ACC_FINAL | Opcodes.ACC_SYNCHRONIZED
| Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT); | Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_STRICT);
// all non private methods // all non private methods
@ -259,12 +241,12 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/* /*
* Gets class field information for step 4 of the algorithm. Also determines * Gets class field information for step 4 of the algorithm. Also determines if the class
* if the class already has a SVUID. * already has a SVUID.
*/ */
@Override @Override
public FieldVisitor visitField(final int access, final String name, public FieldVisitor visitField(final int access, final String name, final String desc,
final String desc, final String signature, final Object value) { final String signature, final Object value) {
if (computeSVUID) { if (computeSVUID) {
if ("serialVersionUID".equals(name)) { if ("serialVersionUID".equals(name)) {
// since the class already has SVUID, we won't be computing it. // since the class already has SVUID, we won't be computing it.
@ -272,17 +254,15 @@ public class SerialVersionUIDAdder extends ClassVisitor {
hasSVUID = true; hasSVUID = true;
} }
/* /*
* Remember field for SVUID computation For field modifiers, only * Remember field for SVUID computation For field modifiers, only the ACC_PUBLIC,
* the ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, * ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT
* ACC_FINAL, ACC_VOLATILE, and ACC_TRANSIENT flags are used when * flags are used when computing serialVersionUID values.
* computing serialVersionUID values.
*/ */
if ((access & Opcodes.ACC_PRIVATE) == 0 if ((access & Opcodes.ACC_PRIVATE) == 0
|| (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) { || (access & (Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT)) == 0) {
int mods = access int mods = access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE
& (Opcodes.ACC_PUBLIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL
| Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT);
| Opcodes.ACC_FINAL | Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT);
svuidFields.add(new Item(name, mods, desc)); svuidFields.add(new Item(name, mods, desc));
} }
} }
@ -291,15 +271,14 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/** /**
* Handle a bizarre special case. Nested classes (static classes declared * Handle a bizarre special case. Nested classes (static classes declared inside another class)
* inside another class) that are protected have their access bit set to * that are protected have their access bit set to public in their class files to deal with some
* public in their class files to deal with some odd reflection situation. * odd reflection situation. Our SVUID computation must do as the JVM does and ignore access
* Our SVUID computation must do as the JVM does and ignore access bits in * bits in the class file in favor of the access bits InnerClass attribute.
* the class file in favor of the access bits InnerClass attribute.
*/ */
@Override @Override
public void visitInnerClass(final String aname, final String outerName, public void visitInnerClass(final String aname, final String outerName, final String innerName,
final String innerName, final int attr_access) { final int attr_access) {
if ((name != null) && name.equals(aname)) { if ((name != null) && name.equals(aname)) {
this.access = attr_access; this.access = attr_access;
} }
@ -320,8 +299,7 @@ public class SerialVersionUIDAdder extends ClassVisitor {
try { try {
addSVUID(computeSVUID()); addSVUID(computeSVUID());
} catch (Throwable e) { } catch (Throwable e) {
throw new RuntimeException("Error while computing SVUID for " throw new RuntimeException("Error while computing SVUID for " + name, e);
+ name, e);
} }
} }
@ -329,8 +307,8 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/** /**
* Returns true if the class already has a SVUID field. The result of this * Returns true if the class already has a SVUID field. The result of this method is only valid
* method is only valid when visitEnd is or has been called. * when visitEnd is or has been called.
* *
* @return true if the class already has a SVUID field. * @return true if the class already has a SVUID field.
*/ */
@ -339,8 +317,8 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
protected void addSVUID(long svuid) { protected void addSVUID(long svuid) {
FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL FieldVisitor fv = super.visitField(Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
+ Opcodes.ACC_STATIC, "serialVersionUID", "J", null, svuid); "serialVersionUID", "J", null, svuid);
if (null != fv) { if (null != fv) {
fv.visitEnd(); fv.visitEnd();
} }
@ -369,13 +347,11 @@ public class SerialVersionUIDAdder extends ClassVisitor {
/* /*
* 2. The class modifiers written as a 32-bit integer. * 2. The class modifiers written as a 32-bit integer.
*/ */
dos.writeInt(access dos.writeInt(access & (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_INTERFACE
& (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_ABSTRACT));
| Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT));
/* /*
* 3. The name of each interface sorted by name written using UTF * 3. The name of each interface sorted by name written using UTF encoding.
* encoding.
*/ */
Arrays.sort(interfaces); Arrays.sort(interfaces);
for (String anInterface : interfaces) { for (String anInterface : interfaces) {
@ -383,24 +359,22 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} }
/* /*
* 4. For each field of the class sorted by field name (except * 4. For each field of the class sorted by field name (except private static and
* private static and private transient fields): * private transient fields):
* *
* 1. The name of the field in UTF encoding. 2. The modifiers of the * 1. The name of the field in UTF encoding. 2. The modifiers of the field written as a
* field written as a 32-bit integer. 3. The descriptor of the field * 32-bit integer. 3. The descriptor of the field in UTF encoding
* in UTF encoding
* *
* Note that field signatures are not dot separated. Method and * Note that field signatures are not dot separated. Method and constructor signatures
* constructor signatures are dot separated. Go figure... * are dot separated. Go figure...
*/ */
writeItems(svuidFields, dos, false); writeItems(svuidFields, dos, false);
/* /*
* 5. If a class initializer exists, write out the following: 1. The * 5. If a class initializer exists, write out the following: 1. The name of the method,
* name of the method, <clinit>, in UTF encoding. 2. The modifier of * <clinit>, in UTF encoding. 2. The modifier of the method,
* the method, java.lang.reflect.Modifier.STATIC, written as a * java.lang.reflect.Modifier.STATIC, written as a 32-bit integer. 3. The descriptor of
* 32-bit integer. 3. The descriptor of the method, ()V, in UTF * the method, ()V, in UTF encoding.
* encoding.
*/ */
if (hasStaticInitializer) { if (hasStaticInitializer) {
dos.writeUTF("<clinit>"); dos.writeUTF("<clinit>");
@ -409,42 +383,37 @@ public class SerialVersionUIDAdder extends ClassVisitor {
} // if.. } // if..
/* /*
* 6. For each non-private constructor sorted by method name and * 6. For each non-private constructor sorted by method name and signature: 1. The name
* signature: 1. The name of the method, <init>, in UTF encoding. 2. * of the method, <init>, in UTF encoding. 2. The modifiers of the method written as a
* The modifiers of the method written as a 32-bit integer. 3. The * 32-bit integer. 3. The descriptor of the method in UTF encoding.
* descriptor of the method in UTF encoding.
*/ */
writeItems(svuidConstructors, dos, true); writeItems(svuidConstructors, dos, true);
/* /*
* 7. For each non-private method sorted by method name and * 7. For each non-private method sorted by method name and signature: 1. The name of
* signature: 1. The name of the method in UTF encoding. 2. The * the method in UTF encoding. 2. The modifiers of the method written as a 32-bit
* modifiers of the method written as a 32-bit integer. 3. The * integer. 3. The descriptor of the method in UTF encoding.
* descriptor of the method in UTF encoding.
*/ */
writeItems(svuidMethods, dos, true); writeItems(svuidMethods, dos, true);
dos.flush(); dos.flush();
/* /*
* 8. The SHA-1 algorithm is executed on the stream of bytes * 8. The SHA-1 algorithm is executed on the stream of bytes produced by
* produced by DataOutputStream and produces five 32-bit values * DataOutputStream and produces five 32-bit values sha[0..4].
* sha[0..4].
*/ */
byte[] hashBytes = computeSHAdigest(bos.toByteArray()); byte[] hashBytes = computeSHAdigest(bos.toByteArray());
/* /*
* 9. The hash value is assembled from the first and second 32-bit * 9. The hash value is assembled from the first and second 32-bit values of the SHA-1
* values of the SHA-1 message digest. If the result of the message * message digest. If the result of the message digest, the five 32-bit words H0 H1 H2
* digest, the five 32-bit words H0 H1 H2 H3 H4, is in an array of * H3 H4, is in an array of five int values named sha, the hash value would be computed
* five int values named sha, the hash value would be computed as * as follows:
* follows:
* *
* long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF) * long hash = ((sha[0] >>> 24) & 0xFF) | ((sha[0] >>> 16) & 0xFF) << 8 | ((sha[0] >>>
* << 8 | ((sha[0] >>> 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) << * 8) & 0xFF) << 16 | ((sha[0] >>> 0) & 0xFF) << 24 | ((sha[1] >>> 24) & 0xFF) << 32 |
* 24 | ((sha[1] >>> 24) & 0xFF) << 32 | ((sha[1] >>> 16) & 0xFF) << * ((sha[1] >>> 16) & 0xFF) << 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) &
* 40 | ((sha[1] >>> 8) & 0xFF) << 48 | ((sha[1] >>> 0) & 0xFF) << * 0xFF) << 56;
* 56;
*/ */
for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) { for (int i = Math.min(hashBytes.length, 8) - 1; i >= 0; i--) {
svuid = (svuid << 8) | (hashBytes[i] & 0xFF); svuid = (svuid << 8) | (hashBytes[i] & 0xFF);

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -52,23 +44,21 @@ public class StaticInitMerger extends ClassVisitor {
this(Opcodes.ASM4, prefix, cv); this(Opcodes.ASM4, prefix, cv);
} }
protected StaticInitMerger(final int api, final String prefix, protected StaticInitMerger(final int api, final String prefix, final ClassVisitor cv) {
final ClassVisitor cv) {
super(api, cv); super(api, cv);
this.prefix = prefix; this.prefix = prefix;
} }
@Override @Override
public void visit(final int version, final int access, final String name, public void visit(final int version, final int access, final String name,
final String signature, final String superName, final String signature, final String superName, final String[] interfaces) {
final String[] interfaces) {
cv.visit(version, access, name, signature, superName, interfaces); cv.visit(version, access, name, signature, superName, interfaces);
this.name = name; this.name = name;
} }
@Override @Override
public MethodVisitor visitMethod(final int access, final String name, public MethodVisitor visitMethod(final int access, final String name, final String desc,
final String desc, final String signature, final String[] exceptions) { final String signature, final String[] exceptions) {
MethodVisitor mv; MethodVisitor mv;
if ("<clinit>".equals(name)) { if ("<clinit>".equals(name)) {
int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC; int a = Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC;

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -43,10 +35,8 @@ public interface TableSwitchGenerator {
/** /**
* Generates the code for a switch case. * Generates the code for a switch case.
* *
* @param key * @param key the switch case key.
* the switch case key. * @param end a label that corresponds to the end of the switch statement.
* @param end
* a label that corresponds to the end of the switch statement.
*/ */
void generateCase(int key, Label end); void generateCase(int key, Label end);

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.commons; package org.objectweb.asm.commons;
@ -39,30 +31,27 @@ import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode; import org.objectweb.asm.tree.TryCatchBlockNode;
/** /**
* A {@link MethodVisitor} adapter to sort the exception handlers. The handlers * A {@link MethodVisitor} adapter to sort the exception handlers. The handlers are sorted in a
* are sorted in a method innermost-to-outermost. This allows the programmer to * method innermost-to-outermost. This allows the programmer to add handlers without worrying about
* add handlers without worrying about ordering them correctly with respect to * ordering them correctly with respect to existing, in-code handlers.
* existing, in-code handlers.
* *
* Behavior is only defined for properly-nested handlers. If any "try" blocks * Behavior is only defined for properly-nested handlers. If any "try" blocks overlap (something
* overlap (something that isn't possible in Java code) then this may not do * that isn't possible in Java code) then this may not do what you want. In fact, this adapter just
* what you want. In fact, this adapter just sorts by the length of the "try" * sorts by the length of the "try" block, taking advantage of the fact that a given try block must
* block, taking advantage of the fact that a given try block must be larger * be larger than any block it contains).
* than any block it contains).
* *
* @author Adrian Sampson * @author Adrian Sampson
*/ */
public class TryCatchBlockSorter extends MethodNode { public class TryCatchBlockSorter extends MethodNode {
public TryCatchBlockSorter(final MethodVisitor mv, final int access, public TryCatchBlockSorter(final MethodVisitor mv, final int access, final String name,
final String name, final String desc, final String signature, final String desc, final String signature, final String[] exceptions) {
final String[] exceptions) {
this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions); this(Opcodes.ASM4, mv, access, name, desc, signature, exceptions);
} }
protected TryCatchBlockSorter(final int api, final MethodVisitor mv, protected TryCatchBlockSorter(final int api, final MethodVisitor mv, final int access,
final int access, final String name, final String desc, final String name, final String desc, final String signature,
final String signature, final String[] exceptions) { final String[] exceptions) {
super(api, access, name, desc, signature, exceptions); super(api, access, name, desc, signature, exceptions);
this.mv = mv; this.mv = mv;
} }

View File

@ -1,37 +1,28 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.signature; package org.objectweb.asm.signature;
/** /**
* A type signature parser to make a signature visitor visit an existing * A type signature parser to make a signature visitor visit an existing signature.
* signature.
* *
* @author Thomas Hallgren * @author Thomas Hallgren
* @author Eric Bruneton * @author Eric Bruneton
@ -46,28 +37,23 @@ public class SignatureReader {
/** /**
* Constructs a {@link SignatureReader} for the given signature. * Constructs a {@link SignatureReader} for the given signature.
* *
* @param signature * @param signature A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or
* A <i>ClassSignature</i>, <i>MethodTypeSignature</i>, or * <i>FieldTypeSignature</i>.
* <i>FieldTypeSignature</i>.
*/ */
public SignatureReader(final String signature) { public SignatureReader(final String signature) {
this.signature = signature; this.signature = signature;
} }
/** /**
* Makes the given visitor visit the signature of this * Makes the given visitor visit the signature of this {@link SignatureReader}. This signature
* {@link SignatureReader}. This signature is the one specified in the * is the one specified in the constructor (see {@link #SignatureReader(String)
* constructor (see {@link #SignatureReader(String) SignatureReader}). This * SignatureReader}). This method is intended to be called on a {@link SignatureReader} that was
* method is intended to be called on a {@link SignatureReader} that was * created using a <i>ClassSignature</i> (such as the <code>signature</code> parameter of the
* created using a <i>ClassSignature</i> (such as the <code>signature</code> * {@link org.objectweb.asm.ClassVisitor#visit ClassVisitor.visit} method) or a
* parameter of the {@link org.objectweb.asm.ClassVisitor#visit * <i>MethodTypeSignature</i> (such as the <code>signature</code> parameter of the
* ClassVisitor.visit} method) or a <i>MethodTypeSignature</i> (such as the * {@link org.objectweb.asm.ClassVisitor#visitMethod ClassVisitor.visitMethod} method).
* <code>signature</code> parameter of the
* {@link org.objectweb.asm.ClassVisitor#visitMethod
* ClassVisitor.visitMethod} method).
* *
* @param v * @param v the visitor that must visit this signature.
* the visitor that must visit this signature.
*/ */
public void accept(final SignatureVisitor v) { public void accept(final SignatureVisitor v) {
String signature = this.signature; String signature = this.signature;
@ -113,18 +99,15 @@ public class SignatureReader {
} }
/** /**
* Makes the given visitor visit the signature of this * Makes the given visitor visit the signature of this {@link SignatureReader}. This signature
* {@link SignatureReader}. This signature is the one specified in the * is the one specified in the constructor (see {@link #SignatureReader(String)
* constructor (see {@link #SignatureReader(String) SignatureReader}). This * SignatureReader}). This method is intended to be called on a {@link SignatureReader} that was
* method is intended to be called on a {@link SignatureReader} that was * created using a <i>FieldTypeSignature</i>, such as the <code>signature</code> parameter of
* created using a <i>FieldTypeSignature</i>, such as the * the {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField} or
* <code>signature</code> parameter of the * {@link org.objectweb.asm.MethodVisitor#visitLocalVariable MethodVisitor.visitLocalVariable}
* {@link org.objectweb.asm.ClassVisitor#visitField ClassVisitor.visitField} * methods.
* or {@link org.objectweb.asm.MethodVisitor#visitLocalVariable
* MethodVisitor.visitLocalVariable} methods.
* *
* @param v * @param v the visitor that must visit this signature.
* the visitor that must visit this signature.
*/ */
public void acceptType(final SignatureVisitor v) { public void acceptType(final SignatureVisitor v) {
parseType(this.signature, 0, v); parseType(this.signature, 0, v);
@ -133,96 +116,90 @@ public class SignatureReader {
/** /**
* Parses a field type signature and makes the given visitor visit it. * Parses a field type signature and makes the given visitor visit it.
* *
* @param signature * @param signature a string containing the signature that must be parsed.
* a string containing the signature that must be parsed. * @param pos index of the first character of the signature to parsed.
* @param pos * @param v the visitor that must visit this signature.
* index of the first character of the signature to parsed.
* @param v
* the visitor that must visit this signature.
* @return the index of the first character after the parsed signature. * @return the index of the first character after the parsed signature.
*/ */
private static int parseType(final String signature, int pos, private static int parseType(final String signature, int pos, final SignatureVisitor v) {
final SignatureVisitor v) {
char c; char c;
int start, end; int start, end;
boolean visited, inner; boolean visited, inner;
String name; String name;
switch (c = signature.charAt(pos++)) { switch (c = signature.charAt(pos++)) {
case 'Z': case 'Z':
case 'C': case 'C':
case 'B': case 'B':
case 'S': case 'S':
case 'I': case 'I':
case 'F': case 'F':
case 'J': case 'J':
case 'D': case 'D':
case 'V': case 'V':
v.visitBaseType(c); v.visitBaseType(c);
return pos; return pos;
case '[': case '[':
return parseType(signature, pos, v.visitArrayType()); return parseType(signature, pos, v.visitArrayType());
case 'T': case 'T':
end = signature.indexOf(';', pos); end = signature.indexOf(';', pos);
v.visitTypeVariable(signature.substring(pos, end)); v.visitTypeVariable(signature.substring(pos, end));
return end + 1; return end + 1;
default: // case 'L': default: // case 'L':
start = pos; start = pos;
visited = false; visited = false;
inner = false; inner = false;
for (;;) { for (;;) {
switch (c = signature.charAt(pos++)) { switch (c = signature.charAt(pos++)) {
case '.': case '.':
case ';': case ';':
if (!visited) { if (!visited) {
name = signature.substring(start, pos - 1); name = signature.substring(start, pos - 1);
if (inner) { if (inner) {
v.visitInnerClassType(name); v.visitInnerClassType(name);
} else { } else {
v.visitClassType(name); v.visitClassType(name);
} }
} }
if (c == ';') { if (c == ';') {
v.visitEnd(); v.visitEnd();
return pos; return pos;
} }
start = pos; start = pos;
visited = false; visited = false;
inner = true; inner = true;
break;
case '<':
name = signature.substring(start, pos - 1);
if (inner) {
v.visitInnerClassType(name);
} else {
v.visitClassType(name);
}
visited = true;
top: for (;;) {
switch (c = signature.charAt(pos)) {
case '>':
break top;
case '*':
++pos;
v.visitTypeArgument();
break; break;
case '+':
case '-': case '<':
pos = parseType(signature, pos + 1, name = signature.substring(start, pos - 1);
v.visitTypeArgument(c)); if (inner) {
break; v.visitInnerClassType(name);
default: } else {
pos = parseType(signature, pos, v.visitClassType(name);
v.visitTypeArgument('=')); }
break; visited = true;
} top: for (;;) {
switch (c = signature.charAt(pos)) {
case '>':
break top;
case '*':
++pos;
v.visitTypeArgument();
break;
case '+':
case '-':
pos = parseType(signature, pos + 1, v.visitTypeArgument(c));
break;
default:
pos = parseType(signature, pos, v.visitTypeArgument('='));
break;
}
}
} }
} }
}
} }
} }
} }

View File

@ -1,54 +1,41 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.signature; package org.objectweb.asm.signature;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
/** /**
* A visitor to visit a generic signature. The methods of this interface must be * A visitor to visit a generic signature. The methods of this interface must be called in one of
* called in one of the three following orders (the last one is the only valid * the three following orders (the last one is the only valid order for a {@link SignatureVisitor}
* order for a {@link SignatureVisitor} that is returned by a method of this * that is returned by a method of this interface):
* interface):
* <ul> * <ul>
* <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt> * <li><i>ClassSignature</i> = ( <tt>visitFormalTypeParameter</tt> <tt>visitClassBound</tt>?
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* ( * <tt>visitInterfaceBound</tt>* )* ( <tt>visitSuperClass</tt> <tt>visitInterface</tt>* )</li>
* <tt>visitSuperClass</tt> <tt>visitInterface</tt>* )</li> * <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt> <tt>visitClassBound</tt>?
* <li><i>MethodSignature</i> = ( <tt>visitFormalTypeParameter</tt> * <tt>visitInterfaceBound</tt>* )* ( <tt>visitParameterType</tt>* <tt>visitReturnType</tt>
* <tt>visitClassBound</tt>? <tt>visitInterfaceBound</tt>* )* (
* <tt>visitParameterType</tt>* <tt>visitReturnType</tt>
* <tt>visitExceptionType</tt>* )</li> * <tt>visitExceptionType</tt>* )</li>
* <li><i>TypeSignature</i> = <tt>visitBaseType</tt> | * <li><i>TypeSignature</i> = <tt>visitBaseType</tt> | <tt>visitTypeVariable</tt> |
* <tt>visitTypeVariable</tt> | <tt>visitArrayType</tt> | ( * <tt>visitArrayType</tt> | ( <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* (
* <tt>visitClassType</tt> <tt>visitTypeArgument</tt>* ( * <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt> ) )</li>
* <tt>visitInnerClassType</tt> <tt>visitTypeArgument</tt>* )* <tt>visitEnd</tt>
* ) )</li>
* </ul> * </ul>
* *
* @author Thomas Hallgren * @author Thomas Hallgren
@ -72,17 +59,16 @@ public abstract class SignatureVisitor {
public final static char INSTANCEOF = '='; public final static char INSTANCEOF = '=';
/** /**
* The ASM API version implemented by this visitor. The value of this field * The ASM API version implemented by this visitor. The value of this field must be one of
* must be one of {@link Opcodes#ASM4}. * {@link Opcodes#ASM4}.
*/ */
protected final int api; protected final int api;
/** /**
* Constructs a new {@link SignatureVisitor}. * Constructs a new {@link SignatureVisitor}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}.
*/ */
public SignatureVisitor(final int api) { public SignatureVisitor(final int api) {
this.api = api; this.api = api;
@ -91,11 +77,9 @@ public abstract class SignatureVisitor {
/** /**
* Visits a formal type parameter. * Visits a formal type parameter.
* *
* @param name * @param name the name of the formal parameter.
* the name of the formal parameter.
*/ */
public void visitFormalTypeParameter(String name) { public void visitFormalTypeParameter(String name) {}
}
/** /**
* Visits the class bound of the last visited formal type parameter. * Visits the class bound of the last visited formal type parameter.
@ -118,8 +102,7 @@ public abstract class SignatureVisitor {
/** /**
* Visits the type of the super class. * Visits the type of the super class.
* *
* @return a non null visitor to visit the signature of the super class * @return a non null visitor to visit the signature of the super class type.
* type.
*/ */
public SignatureVisitor visitSuperclass() { public SignatureVisitor visitSuperclass() {
return this; return this;
@ -164,63 +147,49 @@ public abstract class SignatureVisitor {
/** /**
* Visits a signature corresponding to a primitive type. * Visits a signature corresponding to a primitive type.
* *
* @param descriptor * @param descriptor the descriptor of the primitive type, or 'V' for <tt>void</tt> .
* the descriptor of the primitive type, or 'V' for <tt>void</tt>
* .
*/ */
public void visitBaseType(char descriptor) { public void visitBaseType(char descriptor) {}
}
/** /**
* Visits a signature corresponding to a type variable. * Visits a signature corresponding to a type variable.
* *
* @param name * @param name the name of the type variable.
* the name of the type variable.
*/ */
public void visitTypeVariable(String name) { public void visitTypeVariable(String name) {}
}
/** /**
* Visits a signature corresponding to an array type. * Visits a signature corresponding to an array type.
* *
* @return a non null visitor to visit the signature of the array element * @return a non null visitor to visit the signature of the array element type.
* type.
*/ */
public SignatureVisitor visitArrayType() { public SignatureVisitor visitArrayType() {
return this; return this;
} }
/** /**
* Starts the visit of a signature corresponding to a class or interface * Starts the visit of a signature corresponding to a class or interface type.
* type.
* *
* @param name * @param name the internal name of the class or interface.
* the internal name of the class or interface.
*/ */
public void visitClassType(String name) { public void visitClassType(String name) {}
}
/** /**
* Visits an inner class. * Visits an inner class.
* *
* @param name * @param name the local name of the inner class in its enclosing class.
* the local name of the inner class in its enclosing class.
*/ */
public void visitInnerClassType(String name) { public void visitInnerClassType(String name) {}
}
/** /**
* Visits an unbounded type argument of the last visited class or inner * Visits an unbounded type argument of the last visited class or inner class type.
* class type.
*/ */
public void visitTypeArgument() { public void visitTypeArgument() {}
}
/** /**
* Visits a type argument of the last visited class or inner class type. * Visits a type argument of the last visited class or inner class type.
* *
* @param wildcard * @param wildcard '+', '-' or '='.
* '+', '-' or '='.
* @return a non null visitor to visit the signature of the type argument. * @return a non null visitor to visit the signature of the type argument.
*/ */
public SignatureVisitor visitTypeArgument(char wildcard) { public SignatureVisitor visitTypeArgument(char wildcard) {
@ -230,6 +199,5 @@ public abstract class SignatureVisitor {
/** /**
* Ends the visit of a signature corresponding to a class or interface type. * Ends the visit of a signature corresponding to a class or interface type.
*/ */
public void visitEnd() { public void visitEnd() {}
}
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.signature; package org.objectweb.asm.signature;
@ -55,10 +47,9 @@ public class SignatureWriter extends SignatureVisitor {
private boolean hasParameters; private boolean hasParameters;
/** /**
* Stack used to keep track of class types that have arguments. Each element * Stack used to keep track of class types that have arguments. Each element of this stack is a
* of this stack is a boolean encoded in one bit. The top of the stack is * boolean encoded in one bit. The top of the stack is the lowest order bit. Pushing false = *2,
* the lowest order bit. Pushing false = *2, pushing true = *2+1, popping = * pushing true = *2+1, popping = /2.
* /2.
*/ */
private int argumentStack; private int argumentStack;
@ -224,4 +215,4 @@ public class SignatureWriter extends SignatureVisitor {
} }
argumentStack /= 2; argumentStack /= 2;
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -35,8 +27,8 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a bytecode instruction. <i>An instruction can appear * A node that represents a bytecode instruction. <i>An instruction can appear at most once in at
* at most once in at most one {@link InsnList} at a time</i>. * most one {@link InsnList} at a time</i>.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@ -138,18 +130,16 @@ public abstract class AbstractInsnNode {
AbstractInsnNode next; AbstractInsnNode next;
/** /**
* Index of this instruction in the list to which it belongs. The value of * Index of this instruction in the list to which it belongs. The value of this field is correct
* this field is correct only when {@link InsnList#cache} is not null. A * only when {@link InsnList#cache} is not null. A value of -1 indicates that this instruction
* value of -1 indicates that this instruction does not belong to any * does not belong to any {@link InsnList}.
* {@link InsnList}.
*/ */
int index; int index;
/** /**
* Constructs a new {@link AbstractInsnNode}. * Constructs a new {@link AbstractInsnNode}.
* *
* @param opcode * @param opcode the opcode of the instruction to be constructed.
* the opcode of the instruction to be constructed.
*/ */
protected AbstractInsnNode(final int opcode) { protected AbstractInsnNode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;
@ -168,28 +158,25 @@ public abstract class AbstractInsnNode {
/** /**
* Returns the type of this instruction. * Returns the type of this instruction.
* *
* @return the type of this instruction, i.e. one the constants defined in * @return the type of this instruction, i.e. one the constants defined in this class.
* this class.
*/ */
public abstract int getType(); public abstract int getType();
/** /**
* Returns the previous instruction in the list to which this instruction * Returns the previous instruction in the list to which this instruction belongs, if any.
* belongs, if any.
* *
* @return the previous instruction in the list to which this instruction * @return the previous instruction in the list to which this instruction belongs, if any. May
* belongs, if any. May be <tt>null</tt>. * be <tt>null</tt>.
*/ */
public AbstractInsnNode getPrevious() { public AbstractInsnNode getPrevious() {
return prev; return prev;
} }
/** /**
* Returns the next instruction in the list to which this instruction * Returns the next instruction in the list to which this instruction belongs, if any.
* belongs, if any.
* *
* @return the next instruction in the list to which this instruction * @return the next instruction in the list to which this instruction belongs, if any. May be
* belongs, if any. May be <tt>null</tt>. * <tt>null</tt>.
*/ */
public AbstractInsnNode getNext() { public AbstractInsnNode getNext() {
return next; return next;
@ -198,47 +185,38 @@ public abstract class AbstractInsnNode {
/** /**
* Makes the given code visitor visit this instruction. * Makes the given code visitor visit this instruction.
* *
* @param cv * @param cv a code visitor.
* a code visitor.
*/ */
public abstract void accept(final MethodVisitor cv); public abstract void accept(final MethodVisitor cv);
/** /**
* Returns a copy of this instruction. * Returns a copy of this instruction.
* *
* @param labels * @param labels a map from LabelNodes to cloned LabelNodes.
* a map from LabelNodes to cloned LabelNodes. * @return a copy of this instruction. The returned instruction does not belong to any
* @return a copy of this instruction. The returned instruction does not * {@link InsnList}.
* belong to any {@link InsnList}.
*/ */
public abstract AbstractInsnNode clone( public abstract AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels);
final Map<LabelNode, LabelNode> labels);
/** /**
* Returns the clone of the given label. * Returns the clone of the given label.
* *
* @param label * @param label a label.
* a label. * @param map a map from LabelNodes to cloned LabelNodes.
* @param map
* a map from LabelNodes to cloned LabelNodes.
* @return the clone of the given label. * @return the clone of the given label.
*/ */
static LabelNode clone(final LabelNode label, static LabelNode clone(final LabelNode label, final Map<LabelNode, LabelNode> map) {
final Map<LabelNode, LabelNode> map) {
return map.get(label); return map.get(label);
} }
/** /**
* Returns the clones of the given labels. * Returns the clones of the given labels.
* *
* @param labels * @param labels a list of labels.
* a list of labels. * @param map a map from LabelNodes to cloned LabelNodes.
* @param map
* a map from LabelNodes to cloned LabelNodes.
* @return the clones of the given labels. * @return the clones of the given labels.
*/ */
static LabelNode[] clone(final List<LabelNode> labels, static LabelNode[] clone(final List<LabelNode> labels, final Map<LabelNode, LabelNode> map) {
final Map<LabelNode, LabelNode> map) {
LabelNode[] clones = new LabelNode[labels.size()]; LabelNode[] clones = new LabelNode[labels.size()];
for (int i = 0; i < clones.length; ++i) { for (int i = 0; i < clones.length; ++i) {
clones[i] = map.get(labels.get(i)); clones[i] = map.get(labels.get(i));

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -35,247 +27,192 @@ import java.util.List;
import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
//import cn.edu.pku.dpartner.comm.api.context.DelayLogger; // import cn.edu.pku.dpartner.comm.api.context.DelayLogger;
/** /**
* A node that represents an annotationn. * A node that represents an annotationn.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class AnnotationNode extends AnnotationVisitor public class AnnotationNode extends AnnotationVisitor {
{
/** /**
* The class descriptor of the annotation class. * The class descriptor of the annotation class.
*/ */
public String desc; public String desc;
/** /**
* The name value pairs of this annotation. Each name value pair is stored * The name value pairs of this annotation. Each name value pair is stored as two consecutive
* as two consecutive elements in the list. The name is a {@link String}, * elements in the list. The name is a {@link String}, and the value may be a {@link Byte},
* and the value may be a {@link Byte}, {@link Boolean}, {@link Character}, * {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}, {@link Long},
* {@link Short}, {@link Integer}, {@link Long}, {@link Float}, * {@link Float}, {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an two
* {@link Double}, {@link String} or {@link org.objectweb.asm.Type}, or an * elements String array (for enumeration values), a {@link AnnotationNode}, or a {@link List}
* two elements String array (for enumeration values), a * of values of one of the preceding types. The list may be <tt>null</tt> if there is no name
* {@link AnnotationNode}, or a {@link List} of values of one of the * value pair.
* preceding types. The list may be <tt>null</tt> if there is no name value */
* pair. public List<Object> values;
*/
public List<Object> values;
/** /**
* Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this * Constructs a new {@link AnnotationNode}. <i>Subclasses must not use this constructor</i>.
* constructor</i>. Instead, they must use the * Instead, they must use the {@link #AnnotationNode(int, String)} version.
* {@link #AnnotationNode(int, String)} version. *
* * @param desc the class descriptor of the annotation class.
* @param desc */
* the class descriptor of the annotation class. public AnnotationNode(final String desc) {
*/ this(Opcodes.ASM4, desc);
public AnnotationNode(final String desc) }
{
this(Opcodes.ASM4, desc);
}
/** /**
* Constructs a new {@link AnnotationNode}. * Constructs a new {@link AnnotationNode}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param desc the class descriptor of the annotation class.
* @param desc */
* the class descriptor of the annotation class. public AnnotationNode(final int api, final String desc) {
*/ super(api);
public AnnotationNode(final int api, final String desc) this.desc = desc;
{ }
super(api);
this.desc = desc;
}
/** /**
* Constructs a new {@link AnnotationNode} to visit an array value. * Constructs a new {@link AnnotationNode} to visit an array value.
* *
* @param values * @param values where the visited values must be stored.
* where the visited values must be stored. */
*/ AnnotationNode(final List<Object> values) {
AnnotationNode(final List<Object> values) super(Opcodes.ASM4);
{ this.values = values;
super(Opcodes.ASM4); }
this.values = values;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Implementation of the AnnotationVisitor abstract class // Implementation of the AnnotationVisitor abstract class
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public void visit(final String name, final Object value) public void visit(final String name, final Object value) {
{ if (values == null) {
if (values == null) values = new ArrayList<Object>(this.desc != null ? 2 : 1);
{ }
values = new ArrayList<Object>(this.desc != null ? 2 : 1); if (this.desc != null) {
} values.add(name);
if (this.desc != null) }
{ // else
values.add(name); // {
} // System.out.println("[AnnotationNode] desc is null!");
// else // values.add("");
// { // }
// System.out.println("[AnnotationNode] desc is null!"); values.add(value);
// values.add(""); }
// }
values.add(value);
}
@Override @Override
public void visitEnum(final String name, final String desc, public void visitEnum(final String name, final String desc, final String value) {
final String value) if (values == null) {
{ values = new ArrayList<Object>(this.desc != null ? 2 : 1);
if (values == null) }
{ if (this.desc != null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1); values.add(name);
} }
if (this.desc != null) values.add(new String[] {desc, value});
{ }
values.add(name);
}
values.add(new String[]
{ desc, value });
}
@Override @Override
public AnnotationVisitor visitAnnotation(final String name, public AnnotationVisitor visitAnnotation(final String name, final String desc) {
final String desc) if (values == null) {
{ values = new ArrayList<Object>(this.desc != null ? 2 : 1);
if (values == null) }
{ if (this.desc != null) {
values = new ArrayList<Object>(this.desc != null ? 2 : 1); values.add(name);
} }
if (this.desc != null) AnnotationNode annotation = new AnnotationNode(desc);
{ values.add(annotation);
values.add(name); return annotation;
} }
AnnotationNode annotation = new AnnotationNode(desc);
values.add(annotation);
return annotation;
}
@Override @Override
public AnnotationVisitor visitArray(final String name) public AnnotationVisitor visitArray(final String name) {
{ if (values == null) {
if (values == null) values = new ArrayList<Object>(this.desc != null ? 2 : 1);
{ }
values = new ArrayList<Object>(this.desc != null ? 2 : 1); if (this.desc != null) {
} values.add(name);
if (this.desc != null) }
{ List<Object> array = new ArrayList<Object>();
values.add(name); values.add(array);
} return new AnnotationNode(array);
List<Object> array = new ArrayList<Object>(); }
values.add(array);
return new AnnotationNode(array);
}
@Override @Override
public void visitEnd() public void visitEnd() {}
{
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Accept methods // Accept methods
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Checks that this annotation node is compatible with the given ASM API * Checks that this annotation node is compatible with the given ASM API version. This methods
* version. This methods checks that this node, and all its nodes * checks that this node, and all its nodes recursively, do not contain elements that were
* recursively, do not contain elements that were introduced in more recent * introduced in more recent versions of the ASM API than the given version.
* versions of the ASM API than the given version. *
* * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
* @param api */
* an ASM API version. Must be one of {@link Opcodes#ASM4}. public void check(final int api) {
*/ // nothing to do
public void check(final int api) }
{
// nothing to do
}
/** /**
* Makes the given visitor visit this annotation. * Makes the given visitor visit this annotation.
* *
* @param av * @param av an annotation visitor. Maybe <tt>null</tt>.
* an annotation visitor. Maybe <tt>null</tt>. */
*/ public void accept(final AnnotationVisitor av) {
public void accept(final AnnotationVisitor av) if (av != null) {
{ if (values != null) {
if (av != null) for (int i = 0; i < values.size(); i += 2) {
{ if (values.get(i) == null) {
if (values != null) System.out.println("[AnnotationNode] name is null!!!!!");
{ // DelayLogger.logValue(values);
for (int i = 0; i < values.size(); i += 2) System.out.flush();
{ try {
if (values.get(i) == null) Thread.sleep(2000);
{ } catch (InterruptedException e) {
System.out // TODO Auto-generated catch block
.println("[AnnotationNode] name is null!!!!!"); e.printStackTrace();
// DelayLogger.logValue(values); }
System.out.flush(); }
try String name = (String) values.get(i);
{ Object value = values.get(i + 1);
Thread.sleep(2000); accept(av, name, value);
} }
catch (InterruptedException e) }
{ av.visitEnd();
// TODO Auto-generated catch block }
e.printStackTrace(); }
}
}
String name = (String) values.get(i);
Object value = values.get(i + 1);
accept(av, name, value);
}
}
av.visitEnd();
}
}
/** /**
* Makes the given visitor visit a given annotation value. * Makes the given visitor visit a given annotation value.
* *
* @param av * @param av an annotation visitor. Maybe <tt>null</tt>.
* an annotation visitor. Maybe <tt>null</tt>. * @param name the value name.
* @param name * @param value the actual value.
* the value name. */
* @param value static void accept(final AnnotationVisitor av, final String name, final Object value) {
* the actual value. if (av != null) {
*/ if (value instanceof String[]) {
static void accept(final AnnotationVisitor av, final String name, String[] typeconst = (String[]) value;
final Object value) av.visitEnum(name, typeconst[0], typeconst[1]);
{ } else if (value instanceof AnnotationNode) {
if (av != null) AnnotationNode an = (AnnotationNode) value;
{ an.accept(av.visitAnnotation(name, an.desc));
if (value instanceof String[]) } else if (value instanceof List) {
{ AnnotationVisitor v = av.visitArray(name);
String[] typeconst = (String[]) value; List<?> array = (List<?>) value;
av.visitEnum(name, typeconst[0], typeconst[1]); for (int j = 0; j < array.size(); ++j) {
} accept(v, null, array.get(j));
else if (value instanceof AnnotationNode) }
{ v.visitEnd();
AnnotationNode an = (AnnotationNode) value; } else {
an.accept(av.visitAnnotation(name, an.desc)); av.visit(name, value);
} }
else if (value instanceof List) }
{ }
AnnotationVisitor v = av.visitArray(name);
List<?> array = (List<?>) value;
for (int j = 0; j < array.size(); ++j)
{
accept(v, null, array.get(j));
}
v.visitEnd();
}
else
{
av.visit(name, value);
}
}
}
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -53,14 +45,14 @@ public class ClassNode extends ClassVisitor {
public int version; public int version;
/** /**
* The class's access flags (see {@link org.objectweb.asm.Opcodes}). This * The class's access flags (see {@link org.objectweb.asm.Opcodes}). This field also indicates
* field also indicates if the class is deprecated. * if the class is deprecated.
*/ */
public int access; public int access;
/** /**
* The internal name of the class (see * The internal name of the class (see {@link org.objectweb.asm.Type#getInternalName()
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). * getInternalName}).
*/ */
public String name; public String name;
@ -70,53 +62,50 @@ public class ClassNode extends ClassVisitor {
public String signature; public String signature;
/** /**
* The internal of name of the super class (see * The internal of name of the super class (see {@link org.objectweb.asm.Type#getInternalName()
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). For * getInternalName}). For interfaces, the super class is {@link Object}. May be <tt>null</tt>,
* interfaces, the super class is {@link Object}. May be <tt>null</tt>, but * but only for the {@link Object} class.
* only for the {@link Object} class.
*/ */
public String superName; public String superName;
/** /**
* The internal names of the class's interfaces (see * The internal names of the class's interfaces (see
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). This * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). This list is a list of
* list is a list of {@link String} objects. * {@link String} objects.
*/ */
public List<String> interfaces; public List<String> interfaces;
/** /**
* The name of the source file from which this class was compiled. May be * The name of the source file from which this class was compiled. May be <tt>null</tt>.
* <tt>null</tt>.
*/ */
public String sourceFile; public String sourceFile;
/** /**
* Debug information to compute the correspondence between source and * Debug information to compute the correspondence between source and compiled elements of the
* compiled elements of the class. May be <tt>null</tt>. * class. May be <tt>null</tt>.
*/ */
public String sourceDebug; public String sourceDebug;
/** /**
* The internal name of the enclosing class of the class. May be * The internal name of the enclosing class of the class. May be <tt>null</tt>.
* <tt>null</tt>.
*/ */
public String outerClass; public String outerClass;
/** /**
* The name of the method that contains the class, or <tt>null</tt> if the * The name of the method that contains the class, or <tt>null</tt> if the class is not enclosed
* class is not enclosed in a method. * in a method.
*/ */
public String outerMethod; public String outerMethod;
/** /**
* The descriptor of the method that contains the class, or <tt>null</tt> if * The descriptor of the method that contains the class, or <tt>null</tt> if the class is not
* the class is not enclosed in a method. * enclosed in a method.
*/ */
public String outerMethodDesc; public String outerMethodDesc;
/** /**
* The runtime visible annotations of this class. This list is a list of * The runtime visible annotations of this class. This list is a list of {@link AnnotationNode}
* {@link AnnotationNode} objects. May be <tt>null</tt>. * objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label visible * @label visible
@ -133,41 +122,38 @@ public class ClassNode extends ClassVisitor {
public List<AnnotationNode> invisibleAnnotations; public List<AnnotationNode> invisibleAnnotations;
/** /**
* The non standard attributes of this class. This list is a list of * The non standard attributes of this class. This list is a list of {@link Attribute} objects.
* {@link Attribute} objects. May be <tt>null</tt>. * May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.Attribute * @associates org.objectweb.asm.Attribute
*/ */
public List<Attribute> attrs; public List<Attribute> attrs;
/** /**
* Informations about the inner classes of this class. This list is a list * Informations about the inner classes of this class. This list is a list of
* of {@link InnerClassNode} objects. * {@link InnerClassNode} objects.
* *
* @associates org.objectweb.asm.tree.InnerClassNode * @associates org.objectweb.asm.tree.InnerClassNode
*/ */
public List<InnerClassNode> innerClasses; public List<InnerClassNode> innerClasses;
/** /**
* The fields of this class. This list is a list of {@link FieldNode} * The fields of this class. This list is a list of {@link FieldNode} objects.
* objects.
* *
* @associates org.objectweb.asm.tree.FieldNode * @associates org.objectweb.asm.tree.FieldNode
*/ */
public List<FieldNode> fields; public List<FieldNode> fields;
/** /**
* The methods of this class. This list is a list of {@link MethodNode} * The methods of this class. This list is a list of {@link MethodNode} objects.
* objects.
* *
* @associates org.objectweb.asm.tree.MethodNode * @associates org.objectweb.asm.tree.MethodNode
*/ */
public List<MethodNode> methods; public List<MethodNode> methods;
/** /**
* Constructs a new {@link ClassNode}. <i>Subclasses must not use this * Constructs a new {@link ClassNode}. <i>Subclasses must not use this constructor</i>. Instead,
* constructor</i>. Instead, they must use the {@link #ClassNode(int)} * they must use the {@link #ClassNode(int)} version.
* version.
*/ */
public ClassNode() { public ClassNode() {
this(Opcodes.ASM4); this(Opcodes.ASM4);
@ -176,9 +162,8 @@ public class ClassNode extends ClassVisitor {
/** /**
* Constructs a new {@link ClassNode}. * Constructs a new {@link ClassNode}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}.
*/ */
public ClassNode(final int api) { public ClassNode(final int api) {
super(api); super(api);
@ -194,8 +179,7 @@ public class ClassNode extends ClassVisitor {
@Override @Override
public void visit(final int version, final int access, final String name, public void visit(final int version, final int access, final String name,
final String signature, final String superName, final String signature, final String superName, final String[] interfaces) {
final String[] interfaces) {
this.version = version; this.version = version;
this.access = access; this.access = access;
this.name = name; this.name = name;
@ -213,16 +197,14 @@ public class ClassNode extends ClassVisitor {
} }
@Override @Override
public void visitOuterClass(final String owner, final String name, public void visitOuterClass(final String owner, final String name, final String desc) {
final String desc) {
outerClass = owner; outerClass = owner;
outerMethod = name; outerMethod = name;
outerMethodDesc = desc; outerMethodDesc = desc;
} }
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc); AnnotationNode an = new AnnotationNode(desc);
if (visible) { if (visible) {
if (visibleAnnotations == null) { if (visibleAnnotations == null) {
@ -247,46 +229,41 @@ public class ClassNode extends ClassVisitor {
} }
@Override @Override
public void visitInnerClass(final String name, final String outerName, public void visitInnerClass(final String name, final String outerName, final String innerName,
final String innerName, final int access) { final int access) {
InnerClassNode icn = new InnerClassNode(name, outerName, innerName, InnerClassNode icn = new InnerClassNode(name, outerName, innerName, access);
access);
innerClasses.add(icn); innerClasses.add(icn);
} }
@Override @Override
public FieldVisitor visitField(final int access, final String name, public FieldVisitor visitField(final int access, final String name, final String desc,
final String desc, final String signature, final Object value) { final String signature, final Object value) {
FieldNode fn = new FieldNode(access, name, desc, signature, value); FieldNode fn = new FieldNode(access, name, desc, signature, value);
fields.add(fn); fields.add(fn);
return fn; return fn;
} }
@Override @Override
public MethodVisitor visitMethod(final int access, final String name, public MethodVisitor visitMethod(final int access, final String name, final String desc,
final String desc, final String signature, final String[] exceptions) { final String signature, final String[] exceptions) {
MethodNode mn = new MethodNode(access, name, desc, signature, MethodNode mn = new MethodNode(access, name, desc, signature, exceptions);
exceptions);
methods.add(mn); methods.add(mn);
return mn; return mn;
} }
@Override @Override
public void visitEnd() { public void visitEnd() {}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Accept method // Accept method
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Checks that this class node is compatible with the given ASM API version. * Checks that this class node is compatible with the given ASM API version. This methods checks
* This methods checks that this node, and all its nodes recursively, do not * that this node, and all its nodes recursively, do not contain elements that were introduced
* contain elements that were introduced in more recent versions of the ASM * in more recent versions of the ASM API than the given version.
* API than the given version.
* *
* @param api * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
* an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/ */
public void check(final int api) { public void check(final int api) {
// nothing to do // nothing to do
@ -295,8 +272,7 @@ public class ClassNode extends ClassVisitor {
/** /**
* Makes the given class visitor visit this class. * Makes the given class visitor visit this class.
* *
* @param cv * @param cv a class visitor.
* a class visitor.
*/ */
public void accept(final ClassVisitor cv) { public void accept(final ClassVisitor cv) {
// visits header // visits header

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -34,8 +26,8 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a field instruction. A field instruction is an * A node that represents a field instruction. A field instruction is an instruction that loads or
* instruction that loads or stores the value of a field of an object. * stores the value of a field of an object.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@ -60,20 +52,15 @@ public class FieldInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link FieldInsnNode}. * Constructs a new {@link FieldInsnNode}.
* *
* @param opcode * @param opcode the opcode of the type instruction to be constructed. This opcode must be
* the opcode of the type instruction to be constructed. This * GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
* opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. * @param owner the internal name of the field's owner class (see
* @param owner * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
* the internal name of the field's owner class (see * @param name the field's name.
* {@link org.objectweb.asm.Type#getInternalName() * @param desc the field's descriptor (see {@link org.objectweb.asm.Type}).
* getInternalName}).
* @param name
* the field's name.
* @param desc
* the field's descriptor (see {@link org.objectweb.asm.Type}).
*/ */
public FieldInsnNode(final int opcode, final String owner, public FieldInsnNode(final int opcode, final String owner, final String name,
final String name, final String desc) { final String desc) {
super(opcode); super(opcode);
this.owner = owner; this.owner = owner;
this.name = name; this.name = name;
@ -83,9 +70,8 @@ public class FieldInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode * @param opcode the new instruction opcode. This opcode must be GETSTATIC, PUTSTATIC, GETFIELD
* the new instruction opcode. This opcode must be GETSTATIC, * or PUTFIELD.
* PUTSTATIC, GETFIELD or PUTFIELD.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -46,8 +38,8 @@ import org.objectweb.asm.Opcodes;
public class FieldNode extends FieldVisitor { public class FieldNode extends FieldVisitor {
/** /**
* The field's access flags (see {@link org.objectweb.asm.Opcodes}). This * The field's access flags (see {@link org.objectweb.asm.Opcodes}). This field also indicates
* field also indicates if the field is synthetic and/or deprecated. * if the field is synthetic and/or deprecated.
*/ */
public int access; public int access;
@ -67,15 +59,15 @@ public class FieldNode extends FieldVisitor {
public String signature; public String signature;
/** /**
* The field's initial value. This field, which may be <tt>null</tt> if the * The field's initial value. This field, which may be <tt>null</tt> if the field does not have
* field does not have an initial value, must be an {@link Integer}, a * an initial value, must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Float}, a {@link Long}, a {@link Double} or a {@link String}. * {@link Double} or a {@link String}.
*/ */
public Object value; public Object value;
/** /**
* The runtime visible annotations of this field. This list is a list of * The runtime visible annotations of this field. This list is a list of {@link AnnotationNode}
* {@link AnnotationNode} objects. May be <tt>null</tt>. * objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label visible * @label visible
@ -92,67 +84,48 @@ public class FieldNode extends FieldVisitor {
public List<AnnotationNode> invisibleAnnotations; public List<AnnotationNode> invisibleAnnotations;
/** /**
* The non standard attributes of this field. This list is a list of * The non standard attributes of this field. This list is a list of {@link Attribute} objects.
* {@link Attribute} objects. May be <tt>null</tt>. * May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.Attribute * @associates org.objectweb.asm.Attribute
*/ */
public List<Attribute> attrs; public List<Attribute> attrs;
/** /**
* Constructs a new {@link FieldNode}. <i>Subclasses must not use this * Constructs a new {@link FieldNode}. <i>Subclasses must not use this constructor</i>. Instead,
* constructor</i>. Instead, they must use the * they must use the {@link #FieldNode(int, int, String, String, String, Object)} version.
* {@link #FieldNode(int, int, String, String, String, Object)} version.
* *
* @param access * @param access the field's access flags (see {@link org.objectweb.asm.Opcodes}). This
* the field's access flags (see * parameter also indicates if the field is synthetic and/or deprecated.
* {@link org.objectweb.asm.Opcodes}). This parameter also * @param name the field's name.
* indicates if the field is synthetic and/or deprecated. * @param desc the field's descriptor (see {@link org.objectweb.asm.Type Type}).
* @param name * @param signature the field's signature.
* the field's name. * @param value the field's initial value. This parameter, which may be <tt>null</tt> if the
* @param desc * field does not have an initial value, must be an {@link Integer}, a {@link Float}, a
* the field's descriptor (see {@link org.objectweb.asm.Type * {@link Long}, a {@link Double} or a {@link String}.
* Type}).
* @param signature
* the field's signature.
* @param value
* the field's initial value. This parameter, which may be
* <tt>null</tt> if the field does not have an initial value,
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String}.
*/ */
public FieldNode(final int access, final String name, final String desc, public FieldNode(final int access, final String name, final String desc, final String signature,
final String signature, final Object value) { final Object value) {
this(Opcodes.ASM4, access, name, desc, signature, value); this(Opcodes.ASM4, access, name, desc, signature, value);
} }
/** /**
* Constructs a new {@link FieldNode}. <i>Subclasses must not use this * Constructs a new {@link FieldNode}. <i>Subclasses must not use this constructor</i>. Instead,
* constructor</i>. Instead, they must use the * they must use the {@link #FieldNode(int, int, String, String, String, Object)} version.
* {@link #FieldNode(int, int, String, String, String, Object)} version.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param access the field's access flags (see {@link org.objectweb.asm.Opcodes}). This
* @param access * parameter also indicates if the field is synthetic and/or deprecated.
* the field's access flags (see * @param name the field's name.
* {@link org.objectweb.asm.Opcodes}). This parameter also * @param desc the field's descriptor (see {@link org.objectweb.asm.Type Type}).
* indicates if the field is synthetic and/or deprecated. * @param signature the field's signature.
* @param name * @param value the field's initial value. This parameter, which may be <tt>null</tt> if the
* the field's name. * field does not have an initial value, must be an {@link Integer}, a {@link Float}, a
* @param desc * {@link Long}, a {@link Double} or a {@link String}.
* the field's descriptor (see {@link org.objectweb.asm.Type
* Type}).
* @param signature
* the field's signature.
* @param value
* the field's initial value. This parameter, which may be
* <tt>null</tt> if the field does not have an initial value,
* must be an {@link Integer}, a {@link Float}, a {@link Long}, a
* {@link Double} or a {@link String}.
*/ */
public FieldNode(final int api, final int access, final String name, public FieldNode(final int api, final int access, final String name, final String desc,
final String desc, final String signature, final Object value) { final String signature, final Object value) {
super(api); super(api);
this.access = access; this.access = access;
this.name = name; this.name = name;
@ -166,8 +139,7 @@ public class FieldNode extends FieldVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc); AnnotationNode an = new AnnotationNode(desc);
if (visible) { if (visible) {
if (visibleAnnotations == null) { if (visibleAnnotations == null) {
@ -192,21 +164,18 @@ public class FieldNode extends FieldVisitor {
} }
@Override @Override
public void visitEnd() { public void visitEnd() {}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Accept methods // Accept methods
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Checks that this field node is compatible with the given ASM API version. * Checks that this field node is compatible with the given ASM API version. This methods checks
* This methods checks that this node, and all its nodes recursively, do not * that this node, and all its nodes recursively, do not contain elements that were introduced
* contain elements that were introduced in more recent versions of the ASM * in more recent versions of the ASM API than the given version.
* API than the given version.
* *
* @param api * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
* an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/ */
public void check(final int api) { public void check(final int api) {
// nothing to do // nothing to do
@ -215,8 +184,7 @@ public class FieldNode extends FieldVisitor {
/** /**
* Makes the given class visitor visit this field. * Makes the given class visitor visit this field.
* *
* @param cv * @param cv a class visitor.
* a class visitor.
*/ */
public void accept(final ClassVisitor cv) { public void accept(final ClassVisitor cv) {
FieldVisitor fv = cv.visitField(access, name, desc, signature, value); FieldVisitor fv = cv.visitField(access, name, desc, signature, value);

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -38,42 +30,39 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
/** /**
* A node that represents a stack map frame. These nodes are pseudo instruction * A node that represents a stack map frame. These nodes are pseudo instruction nodes in order to be
* nodes in order to be inserted in an instruction list. In fact these nodes * inserted in an instruction list. In fact these nodes must(*) be inserted <i>just before</i> any
* must(*) be inserted <i>just before</i> any instruction node <b>i</b> that * instruction node <b>i</b> that follows an unconditionnal branch instruction such as GOTO or
* follows an unconditionnal branch instruction such as GOTO or THROW, that is * THROW, that is the target of a jump instruction, or that starts an exception handler block. The
* the target of a jump instruction, or that starts an exception handler block. * stack map frame types must describe the values of the local variables and of the operand stack
* The stack map frame types must describe the values of the local variables and * elements <i>just before</i> <b>i</b> is executed. <br>
* of the operand stack elements <i>just before</i> <b>i</b> is executed. <br>
* <br> * <br>
* (*) this is mandatory only for classes whose version is greater than or equal * (*) this is mandatory only for classes whose version is greater than or equal to
* to {@link Opcodes#V1_6 V1_6}. * {@link Opcodes#V1_6 V1_6}.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class FrameNode extends AbstractInsnNode { public class FrameNode extends AbstractInsnNode {
/** /**
* The type of this frame. Must be {@link Opcodes#F_NEW} for expanded * The type of this frame. Must be {@link Opcodes#F_NEW} for expanded frames, or
* frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
* {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames. * frames.
*/ */
public int type; public int type;
/** /**
* The types of the local variables of this stack map frame. Elements of * The types of the local variables of this stack map frame. Elements of this list can be
* this list can be Integer, String or LabelNode objects (for primitive, * Integer, String or LabelNode objects (for primitive, reference and uninitialized types
* reference and uninitialized types respectively - see * respectively - see {@link MethodVisitor}).
* {@link MethodVisitor}).
*/ */
public List<Object> local; public List<Object> local;
/** /**
* The types of the operand stack elements of this stack map frame. Elements * The types of the operand stack elements of this stack map frame. Elements of this list can be
* of this list can be Integer, String or LabelNode objects (for primitive, * Integer, String or LabelNode objects (for primitive, reference and uninitialized types
* reference and uninitialized types respectively - see * respectively - see {@link MethodVisitor}).
* {@link MethodVisitor}).
*/ */
public List<Object> stack; public List<Object> stack;
@ -84,48 +73,40 @@ public class FrameNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link FrameNode}. * Constructs a new {@link FrameNode}.
* *
* @param type * @param type the type of this frame. Must be {@link Opcodes#F_NEW} for expanded frames, or
* the type of this frame. Must be {@link Opcodes#F_NEW} for * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP},
* expanded frames, or {@link Opcodes#F_FULL}, * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for
* {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, * compressed frames.
* {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, * @param nLocal number of local variables of this stack map frame.
* {@link Opcodes#F_SAME1} for compressed frames. * @param local the types of the local variables of this stack map frame. Elements of this list
* @param nLocal * can be Integer, String or LabelNode objects (for primitive, reference and
* number of local variables of this stack map frame. * uninitialized types respectively - see {@link MethodVisitor}).
* @param local * @param nStack number of operand stack elements of this stack map frame.
* the types of the local variables of this stack map frame. * @param stack the types of the operand stack elements of this stack map frame. Elements of
* Elements of this list can be Integer, String or LabelNode * this list can be Integer, String or LabelNode objects (for primitive, reference and
* objects (for primitive, reference and uninitialized types * uninitialized types respectively - see {@link MethodVisitor}).
* respectively - see {@link MethodVisitor}).
* @param nStack
* number of operand stack elements of this stack map frame.
* @param stack
* the types of the operand stack elements of this stack map
* frame. Elements of this list can be Integer, String or
* LabelNode objects (for primitive, reference and uninitialized
* types respectively - see {@link MethodVisitor}).
*/ */
public FrameNode(final int type, final int nLocal, final Object[] local, public FrameNode(final int type, final int nLocal, final Object[] local, final int nStack,
final int nStack, final Object[] stack) { final Object[] stack) {
super(-1); super(-1);
this.type = type; this.type = type;
switch (type) { switch (type) {
case Opcodes.F_NEW: case Opcodes.F_NEW:
case Opcodes.F_FULL: case Opcodes.F_FULL:
this.local = asList(nLocal, local); this.local = asList(nLocal, local);
this.stack = asList(nStack, stack); this.stack = asList(nStack, stack);
break; break;
case Opcodes.F_APPEND: case Opcodes.F_APPEND:
this.local = asList(nLocal, local); this.local = asList(nLocal, local);
break; break;
case Opcodes.F_CHOP: case Opcodes.F_CHOP:
this.local = Arrays.asList(new Object[nLocal]); this.local = Arrays.asList(new Object[nLocal]);
break; break;
case Opcodes.F_SAME: case Opcodes.F_SAME:
break; break;
case Opcodes.F_SAME1: case Opcodes.F_SAME1:
this.stack = asList(1, stack); this.stack = asList(1, stack);
break; break;
} }
} }
@ -137,29 +118,27 @@ public class FrameNode extends AbstractInsnNode {
/** /**
* Makes the given visitor visit this stack map frame. * Makes the given visitor visit this stack map frame.
* *
* @param mv * @param mv a method visitor.
* a method visitor.
*/ */
@Override @Override
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
switch (type) { switch (type) {
case Opcodes.F_NEW: case Opcodes.F_NEW:
case Opcodes.F_FULL: case Opcodes.F_FULL:
mv.visitFrame(type, local.size(), asArray(local), stack.size(), mv.visitFrame(type, local.size(), asArray(local), stack.size(), asArray(stack));
asArray(stack)); break;
break; case Opcodes.F_APPEND:
case Opcodes.F_APPEND: mv.visitFrame(type, local.size(), asArray(local), 0, null);
mv.visitFrame(type, local.size(), asArray(local), 0, null); break;
break; case Opcodes.F_CHOP:
case Opcodes.F_CHOP: mv.visitFrame(type, local.size(), null, 0, null);
mv.visitFrame(type, local.size(), null, 0, null); break;
break; case Opcodes.F_SAME:
case Opcodes.F_SAME: mv.visitFrame(type, 0, null, 0, null);
mv.visitFrame(type, 0, null, 0, null); break;
break; case Opcodes.F_SAME1:
case Opcodes.F_SAME1: mv.visitFrame(type, 0, null, 1, asArray(stack));
mv.visitFrame(type, 0, null, 1, asArray(stack)); break;
break;
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -54,10 +46,8 @@ public class IincInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link IincInsnNode}. * Constructs a new {@link IincInsnNode}.
* *
* @param var * @param var index of the local variable to be incremented.
* index of the local variable to be incremented. * @param incr increment amount to increment the local variable by.
* @param incr
* increment amount to increment the local variable by.
*/ */
public IincInsnNode(final int var, final int incr) { public IincInsnNode(final int var, final int incr) {
super(Opcodes.IINC); super(Opcodes.IINC);
@ -79,4 +69,4 @@ public class IincInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new IincInsnNode(var, incr); return new IincInsnNode(var, incr);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -39,50 +31,43 @@ import org.objectweb.asm.ClassVisitor;
public class InnerClassNode { public class InnerClassNode {
/** /**
* The internal name of an inner class (see * The internal name of an inner class (see {@link org.objectweb.asm.Type#getInternalName()
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). * getInternalName}).
*/ */
public String name; public String name;
/** /**
* The internal name of the class to which the inner class belongs (see * The internal name of the class to which the inner class belongs (see
* {@link org.objectweb.asm.Type#getInternalName() getInternalName}). May be * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). May be <tt>null</tt>.
* <tt>null</tt>.
*/ */
public String outerName; public String outerName;
/** /**
* The (simple) name of the inner class inside its enclosing class. May be * The (simple) name of the inner class inside its enclosing class. May be <tt>null</tt> for
* <tt>null</tt> for anonymous inner classes. * anonymous inner classes.
*/ */
public String innerName; public String innerName;
/** /**
* The access flags of the inner class as originally declared in the * The access flags of the inner class as originally declared in the enclosing class.
* enclosing class.
*/ */
public int access; public int access;
/** /**
* Constructs a new {@link InnerClassNode}. * Constructs a new {@link InnerClassNode}.
* *
* @param name * @param name the internal name of an inner class (see
* the internal name of an inner class (see * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
* {@link org.objectweb.asm.Type#getInternalName() * @param outerName the internal name of the class to which the inner class belongs (see
* getInternalName}). * {@link org.objectweb.asm.Type#getInternalName() getInternalName}). May be
* @param outerName * <tt>null</tt>.
* the internal name of the class to which the inner class * @param innerName the (simple) name of the inner class inside its enclosing class. May be
* belongs (see {@link org.objectweb.asm.Type#getInternalName() * <tt>null</tt> for anonymous inner classes.
* getInternalName}). May be <tt>null</tt>. * @param access the access flags of the inner class as originally declared in the enclosing
* @param innerName * class.
* the (simple) name of the inner class inside its enclosing
* class. May be <tt>null</tt> for anonymous inner classes.
* @param access
* the access flags of the inner class as originally declared in
* the enclosing class.
*/ */
public InnerClassNode(final String name, final String outerName, public InnerClassNode(final String name, final String outerName, final String innerName,
final String innerName, final int access) { final int access) {
this.name = name; this.name = name;
this.outerName = outerName; this.outerName = outerName;
this.innerName = innerName; this.innerName = innerName;
@ -92,8 +77,7 @@ public class InnerClassNode {
/** /**
* Makes the given class visitor visit this inner class. * Makes the given class visitor visit this inner class.
* *
* @param cv * @param cv a class visitor.
* a class visitor.
*/ */
public void accept(final ClassVisitor cv) { public void accept(final ClassVisitor cv) {
cv.visitInnerClass(name, outerName, innerName, access); cv.visitInnerClass(name, outerName, innerName, access);

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -35,8 +27,8 @@ import java.util.NoSuchElementException;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A doubly linked list of {@link AbstractInsnNode} objects. <i>This * A doubly linked list of {@link AbstractInsnNode} objects. <i>This implementation is not thread
* implementation is not thread safe</i>. * safe</i>.
*/ */
public class InsnList { public class InsnList {
@ -56,8 +48,8 @@ public class InsnList {
private AbstractInsnNode last; private AbstractInsnNode last;
/** /**
* A cache of the instructions of this list. This cache is used to improve * A cache of the instructions of this list. This cache is used to improve the performance of
* the performance of the {@link #get} method. * the {@link #get} method.
*/ */
AbstractInsnNode[] cache; AbstractInsnNode[] cache;
@ -73,8 +65,7 @@ public class InsnList {
/** /**
* Returns the first instruction in this list. * Returns the first instruction in this list.
* *
* @return the first instruction in this list, or <tt>null</tt> if the list * @return the first instruction in this list, or <tt>null</tt> if the list is empty.
* is empty.
*/ */
public AbstractInsnNode getFirst() { public AbstractInsnNode getFirst() {
return first; return first;
@ -83,24 +74,21 @@ public class InsnList {
/** /**
* Returns the last instruction in this list. * Returns the last instruction in this list.
* *
* @return the last instruction in this list, or <tt>null</tt> if the list * @return the last instruction in this list, or <tt>null</tt> if the list is empty.
* is empty.
*/ */
public AbstractInsnNode getLast() { public AbstractInsnNode getLast() {
return last; return last;
} }
/** /**
* Returns the instruction whose index is given. This method builds a cache * Returns the instruction whose index is given. This method builds a cache of the instructions
* of the instructions in this list to avoid scanning the whole list each * in this list to avoid scanning the whole list each time it is called. Once the cache is
* time it is called. Once the cache is built, this method run in constant * built, this method run in constant time. This cache is invalidated by all the methods that
* time. This cache is invalidated by all the methods that modify the list. * modify the list.
* *
* @param index * @param index the index of the instruction that must be returned.
* the index of the instruction that must be returned.
* @return the instruction whose index is given. * @return the instruction whose index is given.
* @throws IndexOutOfBoundsException * @throws IndexOutOfBoundsException if (index < 0 || index >= size()).
* if (index < 0 || index >= size()).
*/ */
public AbstractInsnNode get(final int index) { public AbstractInsnNode get(final int index) {
if (index < 0 || index >= size) { if (index < 0 || index >= size) {
@ -113,12 +101,11 @@ public class InsnList {
} }
/** /**
* Returns <tt>true</tt> if the given instruction belongs to this list. This * Returns <tt>true</tt> if the given instruction belongs to this list. This method always scans
* method always scans the instructions of this list until it finds the * the instructions of this list until it finds the given instruction or reaches the end of the
* given instruction or reaches the end of the list. * list.
* *
* @param insn * @param insn an instruction.
* an instruction.
* @return <tt>true</tt> if the given instruction belongs to this list. * @return <tt>true</tt> if the given instruction belongs to this list.
*/ */
public boolean contains(final AbstractInsnNode insn) { public boolean contains(final AbstractInsnNode insn) {
@ -130,18 +117,16 @@ public class InsnList {
} }
/** /**
* Returns the index of the given instruction in this list. This method * Returns the index of the given instruction in this list. This method builds a cache of the
* builds a cache of the instruction indexes to avoid scanning the whole * instruction indexes to avoid scanning the whole list each time it is called. Once the cache
* list each time it is called. Once the cache is built, this method run in * is built, this method run in constant time. The cache is invalidated by all the methods that
* constant time. The cache is invalidated by all the methods that modify * modify the list.
* the list.
* *
* @param insn * @param insn an instruction <i>of this list</i>.
* an instruction <i>of this list</i>. * @return the index of the given instruction in this list. <i>The result of this method is
* @return the index of the given instruction in this list. <i>The result of * undefined if the given instruction does not belong to this list</i>. Use
* this method is undefined if the given instruction does not belong * {@link #contains contains} to test if an instruction belongs to an instruction list
* to this list</i>. Use {@link #contains contains} to test if an * or not.
* instruction belongs to an instruction list or not.
*/ */
public int indexOf(final AbstractInsnNode insn) { public int indexOf(final AbstractInsnNode insn) {
if (cache == null) { if (cache == null) {
@ -153,8 +138,7 @@ public class InsnList {
/** /**
* Makes the given visitor visit all of the instructions in this list. * Makes the given visitor visit all of the instructions in this list.
* *
* @param mv * @param mv the method visitor that must visit the instructions.
* the method visitor that must visit the instructions.
*/ */
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
AbstractInsnNode insn = first; AbstractInsnNode insn = first;
@ -203,11 +187,8 @@ public class InsnList {
/** /**
* Replaces an instruction of this list with another instruction. * Replaces an instruction of this list with another instruction.
* *
* @param location * @param location an instruction <i>of this list</i>.
* an instruction <i>of this list</i>. * @param insn another instruction, <i>which must not belong to any {@link InsnList}</i>.
* @param insn
* another instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/ */
public void set(final AbstractInsnNode location, final AbstractInsnNode insn) { public void set(final AbstractInsnNode location, final AbstractInsnNode insn) {
AbstractInsnNode next = location.next; AbstractInsnNode next = location.next;
@ -239,9 +220,7 @@ public class InsnList {
/** /**
* Adds the given instruction to the end of this list. * Adds the given instruction to the end of this list.
* *
* @param insn * @param insn an instruction, <i>which must not belong to any {@link InsnList}</i>.
* an instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/ */
public void add(final AbstractInsnNode insn) { public void add(final AbstractInsnNode insn) {
++size; ++size;
@ -260,9 +239,8 @@ public class InsnList {
/** /**
* Adds the given instructions to the end of this list. * Adds the given instructions to the end of this list.
* *
* @param insns * @param insns an instruction list, which is cleared during the process. This list must be
* an instruction list, which is cleared during the process. This * different from 'this'.
* list must be different from 'this'.
*/ */
public void add(final InsnList insns) { public void add(final InsnList insns) {
if (insns.size == 0) { if (insns.size == 0) {
@ -285,9 +263,7 @@ public class InsnList {
/** /**
* Inserts the given instruction at the begining of this list. * Inserts the given instruction at the begining of this list.
* *
* @param insn * @param insn an instruction, <i>which must not belong to any {@link InsnList}</i>.
* an instruction, <i>which must not belong to any
* {@link InsnList}</i>.
*/ */
public void insert(final AbstractInsnNode insn) { public void insert(final AbstractInsnNode insn) {
++size; ++size;
@ -306,9 +282,8 @@ public class InsnList {
/** /**
* Inserts the given instructions at the begining of this list. * Inserts the given instructions at the begining of this list.
* *
* @param insns * @param insns an instruction list, which is cleared during the process. This list must be
* an instruction list, which is cleared during the process. This * different from 'this'.
* list must be different from 'this'.
*/ */
public void insert(final InsnList insns) { public void insert(final InsnList insns) {
if (insns.size == 0) { if (insns.size == 0) {
@ -331,15 +306,11 @@ public class InsnList {
/** /**
* Inserts the given instruction after the specified instruction. * Inserts the given instruction after the specified instruction.
* *
* @param location * @param location an instruction <i>of this list</i> after which insn must be inserted.
* an instruction <i>of this list</i> after which insn must be * @param insn the instruction to be inserted, <i>which must not belong to any
* inserted. * {@link InsnList}</i>.
* @param insn
* the instruction to be inserted, <i>which must not belong to
* any {@link InsnList}</i>.
*/ */
public void insert(final AbstractInsnNode location, public void insert(final AbstractInsnNode location, final AbstractInsnNode insn) {
final AbstractInsnNode insn) {
++size; ++size;
AbstractInsnNode next = location.next; AbstractInsnNode next = location.next;
if (next == null) { if (next == null) {
@ -357,12 +328,10 @@ public class InsnList {
/** /**
* Inserts the given instructions after the specified instruction. * Inserts the given instructions after the specified instruction.
* *
* @param location * @param location an instruction <i>of this list</i> after which the instructions must be
* an instruction <i>of this list</i> after which the * inserted.
* instructions must be inserted. * @param insns the instruction list to be inserted, which is cleared during the process. This
* @param insns * list must be different from 'this'.
* the instruction list to be inserted, which is cleared during
* the process. This list must be different from 'this'.
*/ */
public void insert(final AbstractInsnNode location, final InsnList insns) { public void insert(final AbstractInsnNode location, final InsnList insns) {
if (insns.size == 0) { if (insns.size == 0) {
@ -387,15 +356,11 @@ public class InsnList {
/** /**
* Inserts the given instruction before the specified instruction. * Inserts the given instruction before the specified instruction.
* *
* @param location * @param location an instruction <i>of this list</i> before which insn must be inserted.
* an instruction <i>of this list</i> before which insn must be * @param insn the instruction to be inserted, <i>which must not belong to any
* inserted. * {@link InsnList}</i>.
* @param insn
* the instruction to be inserted, <i>which must not belong to
* any {@link InsnList}</i>.
*/ */
public void insertBefore(final AbstractInsnNode location, public void insertBefore(final AbstractInsnNode location, final AbstractInsnNode insn) {
final AbstractInsnNode insn) {
++size; ++size;
AbstractInsnNode prev = location.prev; AbstractInsnNode prev = location.prev;
if (prev == null) { if (prev == null) {
@ -413,15 +378,12 @@ public class InsnList {
/** /**
* Inserts the given instructions before the specified instruction. * Inserts the given instructions before the specified instruction.
* *
* @param location * @param location an instruction <i>of this list</i> before which the instructions must be
* an instruction <i>of this list</i> before which the * inserted.
* instructions must be inserted. * @param insns the instruction list to be inserted, which is cleared during the process. This
* @param insns * list must be different from 'this'.
* the instruction list to be inserted, which is cleared during
* the process. This list must be different from 'this'.
*/ */
public void insertBefore(final AbstractInsnNode location, public void insertBefore(final AbstractInsnNode location, final InsnList insns) {
final InsnList insns) {
if (insns.size == 0) { if (insns.size == 0) {
return; return;
} }
@ -444,8 +406,7 @@ public class InsnList {
/** /**
* Removes the given instruction from this list. * Removes the given instruction from this list.
* *
* @param insn * @param insn the instruction <i>of this list</i> that must be removed.
* the instruction <i>of this list</i> that must be removed.
*/ */
public void remove(final AbstractInsnNode insn) { public void remove(final AbstractInsnNode insn) {
--size; --size;
@ -477,9 +438,8 @@ public class InsnList {
/** /**
* Removes all of the instructions of this list. * Removes all of the instructions of this list.
* *
* @param mark * @param mark if the instructions must be marked as no longer belonging to any
* if the instructions must be marked as no longer belonging to * {@link InsnList}.
* any {@link InsnList}.
*/ */
void removeAll(final boolean mark) { void removeAll(final boolean mark) {
if (mark) { if (mark) {
@ -506,9 +466,8 @@ public class InsnList {
} }
/** /**
* Reset all labels in the instruction list. This method should be called * Reset all labels in the instruction list. This method should be called before reusing same
* before reusing same instructions list between several * instructions list between several <code>ClassWriter</code>s.
* <code>ClassWriter</code>s.
*/ */
public void resetLabels() { public void resetLabels() {
AbstractInsnNode insn = first; AbstractInsnNode insn = first;

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -43,22 +35,17 @@ public class InsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link InsnNode}. * Constructs a new {@link InsnNode}.
* *
* @param opcode * @param opcode the opcode of the instruction to be constructed. This opcode must be NOP,
* the opcode of the instruction to be constructed. This opcode * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
* must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, * LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
* ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, * FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
* FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, * AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1,
* LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL,
* IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, * IDIV, LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL,
* SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, * ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F,
* DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, * L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG,
* IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
* FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, * MONITORENTER, or MONITOREXIT.
* IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D,
* L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S,
* LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER,
* or MONITOREXIT.
*/ */
public InsnNode(final int opcode) { public InsnNode(final int opcode) {
super(opcode); super(opcode);
@ -72,8 +59,7 @@ public class InsnNode extends AbstractInsnNode {
/** /**
* Makes the given visitor visit this instruction. * Makes the given visitor visit this instruction.
* *
* @param mv * @param mv a method visitor.
* a method visitor.
*/ */
@Override @Override
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -48,11 +40,9 @@ public class IntInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link IntInsnNode}. * Constructs a new {@link IntInsnNode}.
* *
* @param opcode * @param opcode the opcode of the instruction to be constructed. This opcode must be BIPUSH,
* the opcode of the instruction to be constructed. This opcode * SIPUSH or NEWARRAY.
* must be BIPUSH, SIPUSH or NEWARRAY. * @param operand the operand of the instruction to be constructed.
* @param operand
* the operand of the instruction to be constructed.
*/ */
public IntInsnNode(final int opcode, final int operand) { public IntInsnNode(final int opcode, final int operand) {
super(opcode); super(opcode);
@ -62,9 +52,7 @@ public class IntInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode * @param opcode the new instruction opcode. This opcode must be BIPUSH, SIPUSH or NEWARRAY.
* the new instruction opcode. This opcode must be BIPUSH, SIPUSH
* or NEWARRAY.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -65,17 +57,13 @@ public class InvokeDynamicInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link InvokeDynamicInsnNode}. * Constructs a new {@link InvokeDynamicInsnNode}.
* *
* @param name * @param name invokedynamic name.
* invokedynamic name. * @param desc invokedynamic descriptor (see {@link org.objectweb.asm.Type}).
* @param desc * @param bsm the bootstrap method.
* invokedynamic descriptor (see {@link org.objectweb.asm.Type}). * @param bsmArgs the boostrap constant arguments.
* @param bsm
* the bootstrap method.
* @param bsmArgs
* the boostrap constant arguments.
*/ */
public InvokeDynamicInsnNode(final String name, final String desc, public InvokeDynamicInsnNode(final String name, final String desc, final Handle bsm,
final Handle bsm, final Object... bsmArgs) { final Object... bsmArgs) {
super(Opcodes.INVOKEDYNAMIC); super(Opcodes.INVOKEDYNAMIC);
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;
@ -97,4 +85,4 @@ public class InvokeDynamicInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs); return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -34,31 +26,27 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a jump instruction. A jump instruction is an * A node that represents a jump instruction. A jump instruction is an instruction that may jump to
* instruction that may jump to another instruction. * another instruction.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class JumpInsnNode extends AbstractInsnNode { public class JumpInsnNode extends AbstractInsnNode {
/** /**
* The operand of this instruction. This operand is a label that designates * The operand of this instruction. This operand is a label that designates the instruction to
* the instruction to which this instruction may jump. * which this instruction may jump.
*/ */
public LabelNode label; public LabelNode label;
/** /**
* Constructs a new {@link JumpInsnNode}. * Constructs a new {@link JumpInsnNode}.
* *
* @param opcode * @param opcode the opcode of the type instruction to be constructed. This opcode must be IFEQ,
* the opcode of the type instruction to be constructed. This * IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
* opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, * IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, * @param label the operand of the instruction to be constructed. This operand is a label that
* IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. * designates the instruction to which the jump instruction may jump.
* @param label
* the operand of the instruction to be constructed. This operand
* is a label that designates the instruction to which the jump
* instruction may jump.
*/ */
public JumpInsnNode(final int opcode, final LabelNode label) { public JumpInsnNode(final int opcode, final LabelNode label) {
super(opcode); super(opcode);
@ -68,11 +56,9 @@ public class JumpInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode * @param opcode the new instruction opcode. This opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT,
* the new instruction opcode. This opcode must be IFEQ, IFNE, * IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
* IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, * IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
* IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO,
* JSR, IFNULL or IFNONNULL.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -75,4 +67,4 @@ public class LabelNode extends AbstractInsnNode {
public void resetLabel() { public void resetLabel() {
label = null; label = null;
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -42,19 +34,18 @@ import org.objectweb.asm.Opcodes;
public class LdcInsnNode extends AbstractInsnNode { public class LdcInsnNode extends AbstractInsnNode {
/** /**
* The constant to be loaded on the stack. This parameter must be a non null * The constant to be loaded on the stack. This parameter must be a non null {@link Integer}, a
* {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a * {@link Float}, a {@link Long}, a {@link Double}, a {@link String} or a
* {@link String} or a {@link org.objectweb.asm.Type}. * {@link org.objectweb.asm.Type}.
*/ */
public Object cst; public Object cst;
/** /**
* Constructs a new {@link LdcInsnNode}. * Constructs a new {@link LdcInsnNode}.
* *
* @param cst * @param cst the constant to be loaded on the stack. This parameter must be a non null
* the constant to be loaded on the stack. This parameter must be * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double} or a
* a non null {@link Integer}, a {@link Float}, a {@link Long}, a * {@link String}.
* {@link Double} or a {@link String}.
*/ */
public LdcInsnNode(final Object cst) { public LdcInsnNode(final Object cst) {
super(Opcodes.LDC); super(Opcodes.LDC);
@ -75,4 +66,4 @@ public class LdcInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new LdcInsnNode(cst); return new LdcInsnNode(cst);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -34,16 +26,15 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a line number declaration. These nodes are pseudo * A node that represents a line number declaration. These nodes are pseudo instruction nodes in
* instruction nodes in order to be inserted in an instruction list. * order to be inserted in an instruction list.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class LineNumberNode extends AbstractInsnNode { public class LineNumberNode extends AbstractInsnNode {
/** /**
* A line number. This number refers to the source file from which the class * A line number. This number refers to the source file from which the class was compiled.
* was compiled.
*/ */
public int line; public int line;
@ -55,11 +46,9 @@ public class LineNumberNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link LineNumberNode}. * Constructs a new {@link LineNumberNode}.
* *
* @param line * @param line a line number. This number refers to the source file from which the class was
* a line number. This number refers to the source file from * compiled.
* which the class was compiled. * @param start the first instruction corresponding to this line number.
* @param start
* the first instruction corresponding to this line number.
*/ */
public LineNumberNode(final int line, final LabelNode start) { public LineNumberNode(final int line, final LabelNode start) {
super(-1); super(-1);

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -54,14 +46,12 @@ public class LocalVariableNode {
public String signature; public String signature;
/** /**
* The first instruction corresponding to the scope of this local variable * The first instruction corresponding to the scope of this local variable (inclusive).
* (inclusive).
*/ */
public LabelNode start; public LabelNode start;
/** /**
* The last instruction corresponding to the scope of this local variable * The last instruction corresponding to the scope of this local variable (exclusive).
* (exclusive).
*/ */
public LabelNode end; public LabelNode end;
@ -73,24 +63,17 @@ public class LocalVariableNode {
/** /**
* Constructs a new {@link LocalVariableNode}. * Constructs a new {@link LocalVariableNode}.
* *
* @param name * @param name the name of a local variable.
* the name of a local variable. * @param desc the type descriptor of this local variable.
* @param desc * @param signature the signature of this local variable. May be <tt>null</tt>.
* the type descriptor of this local variable. * @param start the first instruction corresponding to the scope of this local variable
* @param signature * (inclusive).
* the signature of this local variable. May be <tt>null</tt>. * @param end the last instruction corresponding to the scope of this local variable
* @param start * (exclusive).
* the first instruction corresponding to the scope of this local * @param index the local variable's index.
* variable (inclusive).
* @param end
* the last instruction corresponding to the scope of this local
* variable (exclusive).
* @param index
* the local variable's index.
*/ */
public LocalVariableNode(final String name, final String desc, public LocalVariableNode(final String name, final String desc, final String signature,
final String signature, final LabelNode start, final LabelNode end, final LabelNode start, final LabelNode end, final int index) {
final int index) {
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;
this.signature = signature; this.signature = signature;
@ -102,11 +85,9 @@ public class LocalVariableNode {
/** /**
* Makes the given visitor visit this local variable declaration. * Makes the given visitor visit this local variable declaration.
* *
* @param mv * @param mv a method visitor.
* a method visitor.
*/ */
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
mv.visitLocalVariable(name, desc, signature, start.getLabel(), mv.visitLocalVariable(name, desc, signature, start.getLabel(), end.getLabel(), index);
end.getLabel(), index);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -56,29 +48,23 @@ public class LookupSwitchInsnNode extends AbstractInsnNode {
public List<Integer> keys; public List<Integer> keys;
/** /**
* Beginnings of the handler blocks. This list is a list of * Beginnings of the handler blocks. This list is a list of {@link LabelNode} objects.
* {@link LabelNode} objects.
*/ */
public List<LabelNode> labels; public List<LabelNode> labels;
/** /**
* Constructs a new {@link LookupSwitchInsnNode}. * Constructs a new {@link LookupSwitchInsnNode}.
* *
* @param dflt * @param dflt beginning of the default handler block.
* beginning of the default handler block. * @param keys the values of the keys.
* @param keys * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
* the values of the keys. * handler block for the <tt>keys[i]</tt> key.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>keys[i]</tt> key.
*/ */
public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, final LabelNode[] labels) {
final LabelNode[] labels) {
super(Opcodes.LOOKUPSWITCH); super(Opcodes.LOOKUPSWITCH);
this.dflt = dflt; this.dflt = dflt;
this.keys = new ArrayList<Integer>(keys == null ? 0 : keys.length); this.keys = new ArrayList<Integer>(keys == null ? 0 : keys.length);
this.labels = new ArrayList<LabelNode>(labels == null ? 0 this.labels = new ArrayList<LabelNode>(labels == null ? 0 : labels.length);
: labels.length);
if (keys != null) { if (keys != null) {
for (int i = 0; i < keys.length; ++i) { for (int i = 0; i < keys.length; ++i) {
this.keys.add(new Integer(keys[i])); this.keys.add(new Integer(keys[i]));
@ -109,8 +95,8 @@ public class LookupSwitchInsnNode extends AbstractInsnNode {
@Override @Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt, LookupSwitchInsnNode clone =
labels), null, clone(this.labels, labels)); new LookupSwitchInsnNode(clone(dflt, labels), null, clone(this.labels, labels));
clone.keys.addAll(keys); clone.keys.addAll(keys);
return clone; return clone;
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -34,8 +26,8 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a method instruction. A method instruction is an * A node that represents a method instruction. A method instruction is an instruction that invokes
* instruction that invokes a method. * a method.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@ -60,21 +52,15 @@ public class MethodInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link MethodInsnNode}. * Constructs a new {@link MethodInsnNode}.
* *
* @param opcode * @param opcode the opcode of the type instruction to be constructed. This opcode must be
* the opcode of the type instruction to be constructed. This * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
* opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or * @param owner the internal name of the method's owner class (see
* INVOKEINTERFACE. * {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
* @param owner * @param name the method's name.
* the internal name of the method's owner class (see * @param desc the method's descriptor (see {@link org.objectweb.asm.Type}).
* {@link org.objectweb.asm.Type#getInternalName()
* getInternalName}).
* @param name
* the method's name.
* @param desc
* the method's descriptor (see {@link org.objectweb.asm.Type}).
*/ */
public MethodInsnNode(final int opcode, final String owner, public MethodInsnNode(final int opcode, final String owner, final String name,
final String name, final String desc) { final String desc) {
super(opcode); super(opcode);
this.owner = owner; this.owner = owner;
this.name = name; this.name = name;
@ -84,9 +70,8 @@ public class MethodInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode * @param opcode the new instruction opcode. This opcode must be INVOKEVIRTUAL, INVOKESPECIAL,
* the new instruction opcode. This opcode must be INVOKEVIRTUAL, * INVOKESTATIC or INVOKEINTERFACE.
* INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;
@ -106,4 +91,4 @@ public class MethodInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new MethodInsnNode(opcode, owner, name, desc); return new MethodInsnNode(opcode, owner, name, desc);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -50,8 +42,8 @@ import org.objectweb.asm.Type;
public class MethodNode extends MethodVisitor { public class MethodNode extends MethodVisitor {
/** /**
* The method's access flags (see {@link Opcodes}). This field also * The method's access flags (see {@link Opcodes}). This field also indicates if the method is
* indicates if the method is synthetic and/or deprecated. * synthetic and/or deprecated.
*/ */
public int access; public int access;
@ -71,15 +63,14 @@ public class MethodNode extends MethodVisitor {
public String signature; public String signature;
/** /**
* The internal names of the method's exception classes (see * The internal names of the method's exception classes (see {@link Type#getInternalName()
* {@link Type#getInternalName() getInternalName}). This list is a list of * getInternalName}). This list is a list of {@link String} objects.
* {@link String} objects.
*/ */
public List<String> exceptions; public List<String> exceptions;
/** /**
* The runtime visible annotations of this method. This list is a list of * The runtime visible annotations of this method. This list is a list of {@link AnnotationNode}
* {@link AnnotationNode} objects. May be <tt>null</tt>. * objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label visible * @label visible
@ -96,26 +87,25 @@ public class MethodNode extends MethodVisitor {
public List<AnnotationNode> invisibleAnnotations; public List<AnnotationNode> invisibleAnnotations;
/** /**
* The non standard attributes of this method. This list is a list of * The non standard attributes of this method. This list is a list of {@link Attribute} objects.
* {@link Attribute} objects. May be <tt>null</tt>. * May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.Attribute * @associates org.objectweb.asm.Attribute
*/ */
public List<Attribute> attrs; public List<Attribute> attrs;
/** /**
* The default value of this annotation interface method. This field must be * The default value of this annotation interface method. This field must be a {@link Byte},
* a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short}, * {@link Boolean}, {@link Character}, {@link Short}, {@link Integer}, {@link Long},
* {@link Integer}, {@link Long}, {@link Float}, {@link Double}, * {@link Float}, {@link Double}, {@link String} or {@link Type}, or an two elements String
* {@link String} or {@link Type}, or an two elements String array (for * array (for enumeration values), a {@link AnnotationNode}, or a {@link List} of values of one
* enumeration values), a {@link AnnotationNode}, or a {@link List} of * of the preceding types. May be <tt>null</tt>.
* values of one of the preceding types. May be <tt>null</tt>.
*/ */
public Object annotationDefault; public Object annotationDefault;
/** /**
* The runtime visible parameter annotations of this method. These lists are * The runtime visible parameter annotations of this method. These lists are lists of
* lists of {@link AnnotationNode} objects. May be <tt>null</tt>. * {@link AnnotationNode} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label invisible parameters * @label invisible parameters
@ -123,8 +113,8 @@ public class MethodNode extends MethodVisitor {
public List<AnnotationNode>[] visibleParameterAnnotations; public List<AnnotationNode>[] visibleParameterAnnotations;
/** /**
* The runtime invisible parameter annotations of this method. These lists * The runtime invisible parameter annotations of this method. These lists are lists of
* are lists of {@link AnnotationNode} objects. May be <tt>null</tt>. * {@link AnnotationNode} objects. May be <tt>null</tt>.
* *
* @associates org.objectweb.asm.tree.AnnotationNode * @associates org.objectweb.asm.tree.AnnotationNode
* @label visible parameters * @label visible parameters
@ -132,8 +122,7 @@ public class MethodNode extends MethodVisitor {
public List<AnnotationNode>[] invisibleParameterAnnotations; public List<AnnotationNode>[] invisibleParameterAnnotations;
/** /**
* The instructions of this method. This list is a list of * The instructions of this method. This list is a list of {@link AbstractInsnNode} objects.
* {@link AbstractInsnNode} objects.
* *
* @associates org.objectweb.asm.tree.AbstractInsnNode * @associates org.objectweb.asm.tree.AbstractInsnNode
* @label instructions * @label instructions
@ -141,8 +130,8 @@ public class MethodNode extends MethodVisitor {
public InsnList instructions; public InsnList instructions;
/** /**
* The try catch blocks of this method. This list is a list of * The try catch blocks of this method. This list is a list of {@link TryCatchBlockNode}
* {@link TryCatchBlockNode} objects. * objects.
* *
* @associates org.objectweb.asm.tree.TryCatchBlockNode * @associates org.objectweb.asm.tree.TryCatchBlockNode
*/ */
@ -159,8 +148,8 @@ public class MethodNode extends MethodVisitor {
public int maxLocals; public int maxLocals;
/** /**
* The local variables of this method. This list is a list of * The local variables of this method. This list is a list of {@link LocalVariableNode} objects.
* {@link LocalVariableNode} objects. May be <tt>null</tt> * May be <tt>null</tt>
* *
* @associates org.objectweb.asm.tree.LocalVariableNode * @associates org.objectweb.asm.tree.LocalVariableNode
*/ */
@ -172,9 +161,8 @@ public class MethodNode extends MethodVisitor {
private boolean visited; private boolean visited;
/** /**
* Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not * Constructs an uninitialized {@link MethodNode}. <i>Subclasses must not use this
* use this constructor</i>. Instead, they must use the * constructor</i>. Instead, they must use the {@link #MethodNode(int)} version.
* {@link #MethodNode(int)} version.
*/ */
public MethodNode() { public MethodNode() {
this(Opcodes.ASM4); this(Opcodes.ASM4);
@ -183,9 +171,8 @@ public class MethodNode extends MethodVisitor {
/** /**
* Constructs an uninitialized {@link MethodNode}. * Constructs an uninitialized {@link MethodNode}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}.
*/ */
public MethodNode(final int api) { public MethodNode(final int api) {
super(api); super(api);
@ -193,24 +180,17 @@ public class MethodNode extends MethodVisitor {
} }
/** /**
* Constructs a new {@link MethodNode}. <i>Subclasses must not use this * Constructs a new {@link MethodNode}. <i>Subclasses must not use this constructor</i>.
* constructor</i>. Instead, they must use the * Instead, they must use the {@link #MethodNode(int, int, String, String, String, String[])}
* {@link #MethodNode(int, int, String, String, String, String[])} version. * version.
* *
* @param access * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates
* the method's access flags (see {@link Opcodes}). This * if the method is synthetic and/or deprecated.
* parameter also indicates if the method is synthetic and/or * @param name the method's name.
* deprecated. * @param desc the method's descriptor (see {@link Type}).
* @param name * @param signature the method's signature. May be <tt>null</tt>.
* the method's name. * @param exceptions the internal names of the method's exception classes (see
* @param desc * {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>.
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public MethodNode(final int access, final String name, final String desc, public MethodNode(final int access, final String name, final String desc,
final String signature, final String[] exceptions) { final String signature, final String[] exceptions) {
@ -220,33 +200,24 @@ public class MethodNode extends MethodVisitor {
/** /**
* Constructs a new {@link MethodNode}. * Constructs a new {@link MethodNode}.
* *
* @param api * @param api the ASM API version implemented by this visitor. Must be one of
* the ASM API version implemented by this visitor. Must be one * {@link Opcodes#ASM4}.
* of {@link Opcodes#ASM4}. * @param access the method's access flags (see {@link Opcodes}). This parameter also indicates
* @param access * if the method is synthetic and/or deprecated.
* the method's access flags (see {@link Opcodes}). This * @param name the method's name.
* parameter also indicates if the method is synthetic and/or * @param desc the method's descriptor (see {@link Type}).
* deprecated. * @param signature the method's signature. May be <tt>null</tt>.
* @param name * @param exceptions the internal names of the method's exception classes (see
* the method's name. * {@link Type#getInternalName() getInternalName}). May be <tt>null</tt>.
* @param desc
* the method's descriptor (see {@link Type}).
* @param signature
* the method's signature. May be <tt>null</tt>.
* @param exceptions
* the internal names of the method's exception classes (see
* {@link Type#getInternalName() getInternalName}). May be
* <tt>null</tt>.
*/ */
public MethodNode(final int api, final int access, final String name, public MethodNode(final int api, final int access, final String name, final String desc,
final String desc, final String signature, final String[] exceptions) { final String signature, final String[] exceptions) {
super(api); super(api);
this.access = access; this.access = access;
this.name = name; this.name = name;
this.desc = desc; this.desc = desc;
this.signature = signature; this.signature = signature;
this.exceptions = new ArrayList<String>(exceptions == null ? 0 this.exceptions = new ArrayList<String>(exceptions == null ? 0 : exceptions.length);
: exceptions.length);
boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0; boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0;
if (!isAbstract) { if (!isAbstract) {
this.localVariables = new ArrayList<LocalVariableNode>(5); this.localVariables = new ArrayList<LocalVariableNode>(5);
@ -274,8 +245,7 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public AnnotationVisitor visitAnnotation(final String desc, public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
final boolean visible) {
AnnotationNode an = new AnnotationNode(desc); AnnotationNode an = new AnnotationNode(desc);
if (visible) { if (visible) {
if (visibleAnnotations == null) { if (visibleAnnotations == null) {
@ -292,8 +262,8 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public AnnotationVisitor visitParameterAnnotation(final int parameter, public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc,
final String desc, final boolean visible) { final boolean visible) {
AnnotationNode an = new AnnotationNode(desc); AnnotationNode an = new AnnotationNode(desc);
if (visible) { if (visible) {
if (visibleParameterAnnotations == null) { if (visibleParameterAnnotations == null) {
@ -301,8 +271,7 @@ public class MethodNode extends MethodVisitor {
visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; visibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
} }
if (visibleParameterAnnotations[parameter] == null) { if (visibleParameterAnnotations[parameter] == null) {
visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>( visibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1);
1);
} }
visibleParameterAnnotations[parameter].add(an); visibleParameterAnnotations[parameter].add(an);
} else { } else {
@ -311,8 +280,7 @@ public class MethodNode extends MethodVisitor {
invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params]; invisibleParameterAnnotations = (List<AnnotationNode>[]) new List<?>[params];
} }
if (invisibleParameterAnnotations[parameter] == null) { if (invisibleParameterAnnotations[parameter] == null) {
invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>( invisibleParameterAnnotations[parameter] = new ArrayList<AnnotationNode>(1);
1);
} }
invisibleParameterAnnotations[parameter].add(an); invisibleParameterAnnotations[parameter].add(an);
} }
@ -328,15 +296,13 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitCode() { public void visitCode() {}
}
@Override @Override
public void visitFrame(final int type, final int nLocal, public void visitFrame(final int type, final int nLocal, final Object[] local, final int nStack,
final Object[] local, final int nStack, final Object[] stack) { final Object[] stack) {
instructions.add(new FrameNode(type, nLocal, local == null ? null instructions.add(new FrameNode(type, nLocal, local == null ? null : getLabelNodes(local),
: getLabelNodes(local), nStack, stack == null ? null nStack, stack == null ? null : getLabelNodes(stack)));
: getLabelNodes(stack)));
} }
@Override @Override
@ -360,20 +326,19 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitFieldInsn(final int opcode, final String owner, public void visitFieldInsn(final int opcode, final String owner, final String name,
final String name, final String desc) { final String desc) {
instructions.add(new FieldInsnNode(opcode, owner, name, desc)); instructions.add(new FieldInsnNode(opcode, owner, name, desc));
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, public void visitMethodInsn(final int opcode, final String owner, final String name,
final String name, final String desc) { final String desc) {
instructions.add(new MethodInsnNode(opcode, owner, name, desc)); instructions.add(new MethodInsnNode(opcode, owner, name, desc));
} }
@Override @Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
Object... bsmArgs) {
instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)); instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs));
} }
@ -398,17 +363,15 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitTableSwitchInsn(final int min, final int max, public void visitTableSwitchInsn(final int min, final int max, final Label dflt,
final Label dflt, final Label... labels) { final Label... labels) {
instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), instructions
getLabelNodes(labels))); .add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), getLabelNodes(labels)));
} }
@Override @Override
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
final Label[] labels) { instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, getLabelNodes(labels)));
instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys,
getLabelNodes(labels)));
} }
@Override @Override
@ -417,18 +380,17 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitTryCatchBlock(final Label start, final Label end, public void visitTryCatchBlock(final Label start, final Label end, final Label handler,
final Label handler, final String type) { final String type) {
tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start), tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start), getLabelNode(end),
getLabelNode(end), getLabelNode(handler), type)); getLabelNode(handler), type));
} }
@Override @Override
public void visitLocalVariable(final String name, final String desc, public void visitLocalVariable(final String name, final String desc, final String signature,
final String signature, final Label start, final Label end, final Label start, final Label end, final int index) {
final int index) { localVariables.add(new LocalVariableNode(name, desc, signature, getLabelNode(start),
localVariables.add(new LocalVariableNode(name, desc, signature, getLabelNode(end), index));
getLabelNode(start), getLabelNode(end), index));
} }
@Override @Override
@ -443,17 +405,14 @@ public class MethodNode extends MethodVisitor {
} }
@Override @Override
public void visitEnd() { public void visitEnd() {}
}
/** /**
* Returns the LabelNode corresponding to the given Label. Creates a new * Returns the LabelNode corresponding to the given Label. Creates a new LabelNode if necessary.
* LabelNode if necessary. The default implementation of this method uses * The default implementation of this method uses the {@link Label#info} field to store
* the {@link Label#info} field to store associations between labels and * associations between labels and label nodes.
* label nodes.
* *
* @param l * @param l a Label.
* a Label.
* @return the LabelNode corresponding to l. * @return the LabelNode corresponding to l.
*/ */
protected LabelNode getLabelNode(final Label l) { protected LabelNode getLabelNode(final Label l) {
@ -488,13 +447,11 @@ public class MethodNode extends MethodVisitor {
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** /**
* Checks that this method node is compatible with the given ASM API * Checks that this method node is compatible with the given ASM API version. This methods
* version. This methods checks that this node, and all its nodes * checks that this node, and all its nodes recursively, do not contain elements that were
* recursively, do not contain elements that were introduced in more recent * introduced in more recent versions of the ASM API than the given version.
* versions of the ASM API than the given version.
* *
* @param api * @param api an ASM API version. Must be one of {@link Opcodes#ASM4}.
* an ASM API version. Must be one of {@link Opcodes#ASM4}.
*/ */
public void check(final int api) { public void check(final int api) {
// nothing to do // nothing to do
@ -503,14 +460,12 @@ public class MethodNode extends MethodVisitor {
/** /**
* Makes the given class visitor visit this method. * Makes the given class visitor visit this method.
* *
* @param cv * @param cv a class visitor.
* a class visitor.
*/ */
public void accept(final ClassVisitor cv) { public void accept(final ClassVisitor cv) {
String[] exceptions = new String[this.exceptions.size()]; String[] exceptions = new String[this.exceptions.size()];
this.exceptions.toArray(exceptions); this.exceptions.toArray(exceptions);
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
exceptions);
if (mv != null) { if (mv != null) {
accept(mv); accept(mv);
} }
@ -519,8 +474,7 @@ public class MethodNode extends MethodVisitor {
/** /**
* Makes the given method visitor visit this method. * Makes the given method visitor visit this method.
* *
* @param mv * @param mv a method visitor.
* a method visitor.
*/ */
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
// visits the method attributes // visits the method attributes
@ -542,8 +496,7 @@ public class MethodNode extends MethodVisitor {
AnnotationNode an = invisibleAnnotations.get(i); AnnotationNode an = invisibleAnnotations.get(i);
an.accept(mv.visitAnnotation(an.desc, false)); an.accept(mv.visitAnnotation(an.desc, false));
} }
n = visibleParameterAnnotations == null ? 0 n = visibleParameterAnnotations == null ? 0 : visibleParameterAnnotations.length;
: visibleParameterAnnotations.length;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
List<?> l = visibleParameterAnnotations[i]; List<?> l = visibleParameterAnnotations[i];
if (l == null) { if (l == null) {
@ -554,8 +507,7 @@ public class MethodNode extends MethodVisitor {
an.accept(mv.visitParameterAnnotation(i, an.desc, true)); an.accept(mv.visitParameterAnnotation(i, an.desc, true));
} }
} }
n = invisibleParameterAnnotations == null ? 0 n = invisibleParameterAnnotations == null ? 0 : invisibleParameterAnnotations.length;
: invisibleParameterAnnotations.length;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
List<?> l = invisibleParameterAnnotations[i]; List<?> l = invisibleParameterAnnotations[i];
if (l == null) { if (l == null) {

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -54,10 +46,8 @@ public class MultiANewArrayInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link MultiANewArrayInsnNode}. * Constructs a new {@link MultiANewArrayInsnNode}.
* *
* @param desc * @param desc an array type descriptor (see {@link org.objectweb.asm.Type}).
* an array type descriptor (see {@link org.objectweb.asm.Type}). * @param dims number of dimensions of the array to allocate.
* @param dims
* number of dimensions of the array to allocate.
*/ */
public MultiANewArrayInsnNode(final String desc, final int dims) { public MultiANewArrayInsnNode(final String desc, final int dims) {
super(Opcodes.MULTIANEWARRAY); super(Opcodes.MULTIANEWARRAY);
@ -80,4 +70,4 @@ public class MultiANewArrayInsnNode extends AbstractInsnNode {
return new MultiANewArrayInsnNode(desc, dims); return new MultiANewArrayInsnNode(desc, dims);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -61,26 +53,21 @@ public class TableSwitchInsnNode extends AbstractInsnNode {
public LabelNode dflt; public LabelNode dflt;
/** /**
* Beginnings of the handler blocks. This list is a list of * Beginnings of the handler blocks. This list is a list of {@link LabelNode} objects.
* {@link LabelNode} objects.
*/ */
public List<LabelNode> labels; public List<LabelNode> labels;
/** /**
* Constructs a new {@link TableSwitchInsnNode}. * Constructs a new {@link TableSwitchInsnNode}.
* *
* @param min * @param min the minimum key value.
* the minimum key value. * @param max the maximum key value.
* @param max * @param dflt beginning of the default handler block.
* the maximum key value. * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is the beginning of the
* @param dflt * handler block for the <tt>min + i</tt> key.
* beginning of the default handler block.
* @param labels
* beginnings of the handler blocks. <tt>labels[i]</tt> is the
* beginning of the handler block for the <tt>min + i</tt> key.
*/ */
public TableSwitchInsnNode(final int min, final int max, public TableSwitchInsnNode(final int min, final int max, final LabelNode dflt,
final LabelNode dflt, final LabelNode... labels) { final LabelNode... labels) {
super(Opcodes.TABLESWITCH); super(Opcodes.TABLESWITCH);
this.min = min; this.min = min;
this.max = max; this.max = max;
@ -107,7 +94,6 @@ public class TableSwitchInsnNode extends AbstractInsnNode {
@Override @Override
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone( return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone(this.labels, labels));
this.labels, labels));
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -54,27 +46,22 @@ public class TryCatchBlockNode {
public LabelNode handler; public LabelNode handler;
/** /**
* Internal name of the type of exceptions handled by the handler. May be * Internal name of the type of exceptions handled by the handler. May be <tt>null</tt> to catch
* <tt>null</tt> to catch any exceptions (for "finally" blocks). * any exceptions (for "finally" blocks).
*/ */
public String type; public String type;
/** /**
* Constructs a new {@link TryCatchBlockNode}. * Constructs a new {@link TryCatchBlockNode}.
* *
* @param start * @param start beginning of the exception handler's scope (inclusive).
* beginning of the exception handler's scope (inclusive). * @param end end of the exception handler's scope (exclusive).
* @param end * @param handler beginning of the exception handler's code.
* end of the exception handler's scope (exclusive). * @param type internal name of the type of exceptions handled by the handler, or <tt>null</tt>
* @param handler * to catch any exceptions (for "finally" blocks).
* beginning of the exception handler's code.
* @param type
* internal name of the type of exceptions handled by the
* handler, or <tt>null</tt> to catch any exceptions (for
* "finally" blocks).
*/ */
public TryCatchBlockNode(final LabelNode start, final LabelNode end, public TryCatchBlockNode(final LabelNode start, final LabelNode end, final LabelNode handler,
final LabelNode handler, final String type) { final String type) {
this.start = start; this.start = start;
this.end = end; this.end = end;
this.handler = handler; this.handler = handler;
@ -84,8 +71,7 @@ public class TryCatchBlockNode {
/** /**
* Makes the given visitor visit this try catch block. * Makes the given visitor visit this try catch block.
* *
* @param mv * @param mv a method visitor.
* a method visitor.
*/ */
public void accept(final MethodVisitor mv) { public void accept(final MethodVisitor mv) {
mv.visitTryCatchBlock(start.getLabel(), end.getLabel(), mv.visitTryCatchBlock(start.getLabel(), end.getLabel(),

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -34,8 +26,8 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a type instruction. A type instruction is an * A node that represents a type instruction. A type instruction is an instruction that takes a type
* instruction that takes a type descriptor as parameter. * descriptor as parameter.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
@ -50,12 +42,10 @@ public class TypeInsnNode extends AbstractInsnNode {
/** /**
* Constructs a new {@link TypeInsnNode}. * Constructs a new {@link TypeInsnNode}.
* *
* @param opcode * @param opcode the opcode of the type instruction to be constructed. This opcode must be NEW,
* the opcode of the type instruction to be constructed. This * ANEWARRAY, CHECKCAST or INSTANCEOF.
* opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. * @param desc the operand of the instruction to be constructed. This operand is an internal
* @param desc * name (see {@link org.objectweb.asm.Type}).
* the operand of the instruction to be constructed. This operand
* is an internal name (see {@link org.objectweb.asm.Type}).
*/ */
public TypeInsnNode(final int opcode, final String desc) { public TypeInsnNode(final int opcode, final String desc) {
super(opcode); super(opcode);
@ -65,9 +55,8 @@ public class TypeInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode * @param opcode the new instruction opcode. This opcode must be NEW, ANEWARRAY, CHECKCAST or
* the new instruction opcode. This opcode must be NEW, * INSTANCEOF.
* ANEWARRAY, CHECKCAST or INSTANCEOF.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;
@ -87,4 +76,4 @@ public class TypeInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new TypeInsnNode(opcode, desc); return new TypeInsnNode(opcode, desc);
} }
} }

View File

@ -1,31 +1,23 @@
/*** /***
* ASM: a very small and fast Java bytecode manipulation framework * ASM: a very small and fast Java bytecode manipulation framework Copyright (c) 2000-2011 INRIA,
* Copyright (c) 2000-2011 INRIA, France Telecom * France Telecom All rights reserved.
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without modification, are permitted
* modification, are permitted provided that the following conditions * provided that the following conditions are met: 1. Redistributions of source code must retain the
* are met: * above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions
* 1. Redistributions of source code must retain the above copyright * in binary form must reproduce the above copyright notice, this list of conditions and the
* notice, this list of conditions and the following disclaimer. * following disclaimer in the documentation and/or other materials provided with the distribution.
* 2. Redistributions in binary form must reproduce the above copyright * 3. Neither the name of the copyright holders nor the names of its contributors may be used to
* notice, this list of conditions and the following disclaimer in the * endorse or promote products derived from this software without specific prior written permission.
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders 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" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* 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.objectweb.asm.tree; package org.objectweb.asm.tree;
@ -34,30 +26,26 @@ import java.util.Map;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
/** /**
* A node that represents a local variable instruction. A local variable * A node that represents a local variable instruction. A local variable instruction is an
* instruction is an instruction that loads or stores the value of a local * instruction that loads or stores the value of a local variable.
* variable.
* *
* @author Eric Bruneton * @author Eric Bruneton
*/ */
public class VarInsnNode extends AbstractInsnNode { public class VarInsnNode extends AbstractInsnNode {
/** /**
* The operand of this instruction. This operand is the index of a local * The operand of this instruction. This operand is the index of a local variable.
* variable.
*/ */
public int var; public int var;
/** /**
* Constructs a new {@link VarInsnNode}. * Constructs a new {@link VarInsnNode}.
* *
* @param opcode * @param opcode the opcode of the local variable instruction to be constructed. This opcode
* the opcode of the local variable instruction to be * must be ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or
* constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD, * RET.
* ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. * @param var the operand of the instruction to be constructed. This operand is the index of a
* @param var * local variable.
* the operand of the instruction to be constructed. This operand
* is the index of a local variable.
*/ */
public VarInsnNode(final int opcode, final int var) { public VarInsnNode(final int opcode, final int var) {
super(opcode); super(opcode);
@ -67,10 +55,8 @@ public class VarInsnNode extends AbstractInsnNode {
/** /**
* Sets the opcode of this instruction. * Sets the opcode of this instruction.
* *
* @param opcode * @param opcode the new instruction opcode. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD,
* the new instruction opcode. This opcode must be ILOAD, LLOAD, * ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
* FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or
* RET.
*/ */
public void setOpcode(final int opcode) { public void setOpcode(final int opcode) {
this.opcode = opcode; this.opcode = opcode;
@ -90,4 +76,4 @@ public class VarInsnNode extends AbstractInsnNode {
public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) { public AbstractInsnNode clone(final Map<LabelNode, LabelNode> labels) {
return new VarInsnNode(opcode, var); return new VarInsnNode(opcode, var);
} }
} }

Some files were not shown because too many files have changed in this diff Show More