Compare commits
1 Commits
asiekierka
...
v3.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70cb74b4d6 |
19
.classpath
Normal file
19
.classpath
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src/core"/>
|
||||||
|
<classpathentry excluding="org/luaj/vm2/luajc/antlr/|org/luaj/vm2/luajc/lst/|org/luaj/vm2/luajc/JavaCodeGenerator.java" kind="src" path="src/jse"/>
|
||||||
|
<classpathentry kind="src" path="src/jme"/>
|
||||||
|
<classpathentry kind="src" path="test/java"/>
|
||||||
|
<classpathentry kind="src" path="test/junit"/>
|
||||||
|
<classpathentry kind="src" path="test/lua"/>
|
||||||
|
<classpathentry kind="src" path="examples/jse"/>
|
||||||
|
<classpathentry kind="src" path="examples/jme"/>
|
||||||
|
<classpathentry kind="src" path="examples/lua"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/>
|
||||||
|
<classpathentry kind="lib" path="lib/midpapi20.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/cldcapi11.jar"/>
|
||||||
|
<classpathentry kind="lib" path="lib/bcel-5.2.jar"/>
|
||||||
|
<classpathentry kind="var" path="JRE_LIB"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
||||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -1,4 +1,15 @@
|
|||||||
|
bin/
|
||||||
target/
|
target/
|
||||||
.classpath
|
build/
|
||||||
.project
|
lib/
|
||||||
.settings/
|
jit/
|
||||||
|
*.ser
|
||||||
|
*.gz
|
||||||
|
*.jar
|
||||||
|
*.lua
|
||||||
|
*.out
|
||||||
|
*.tar
|
||||||
|
*.txt
|
||||||
|
*.zip
|
||||||
|
docs
|
||||||
|
*.0
|
||||||
|
|||||||
138
.ide/cleanup.xml
138
.ide/cleanup.xml
@@ -1,138 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<profiles version="2">
|
|
||||||
<profile kind="CleanUpProfile" name="Default" version="2">
|
|
||||||
<setting id="cleanup.array_with_curly" value="true"/>
|
|
||||||
<setting id="cleanup.use_autoboxing" value="true"/>
|
|
||||||
<setting id="cleanup.always_use_this_for_non_static_method_access" value="false"/>
|
|
||||||
<setting id="cleanup.remove_trailing_whitespaces_ignore_empty" value="false"/>
|
|
||||||
<setting id="cleanup.primitive_comparison" value="false"/>
|
|
||||||
<setting id="cleanup.system_property_file_encoding" value="true"/>
|
|
||||||
<setting id="cleanup.format_source_code_changes_only" value="false"/>
|
|
||||||
<setting id="cleanup.remove_redundant_semicolons" value="true"/>
|
|
||||||
<setting id="cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class" value="true"/>
|
|
||||||
<setting id="cleanup.useless_continue" value="true"/>
|
|
||||||
<setting id="cleanup.remove_redundant_type_arguments" value="true"/>
|
|
||||||
<setting id="cleanup.remove_unused_imports" value="true"/>
|
|
||||||
<setting id="cleanup.break_loop" value="false"/>
|
|
||||||
<setting id="cleanup.pull_up_assignment" value="false"/>
|
|
||||||
<setting id="cleanup.stringbuilder" value="false"/>
|
|
||||||
<setting id="cleanup.no_super" value="true"/>
|
|
||||||
<setting id="cleanup.arrays_fill" value="false"/>
|
|
||||||
<setting id="cleanup.use_lambda" value="true"/>
|
|
||||||
<setting id="cleanup.operand_factorization" value="false"/>
|
|
||||||
<setting id="cleanup.simplify_lambda_expression_and_method_ref" value="true"/>
|
|
||||||
<setting id="cleanup.always_use_blocks" value="true"/>
|
|
||||||
<setting id="cleanup.sort_members_all" value="false"/>
|
|
||||||
<setting id="cleanup.system_property_path_separator" value="true"/>
|
|
||||||
<setting id="cleanup.instanceof" value="false"/>
|
|
||||||
<setting id="cleanup.add_missing_annotations" value="true"/>
|
|
||||||
<setting id="cleanup.precompile_regex" value="false"/>
|
|
||||||
<setting id="cleanup.always_use_this_for_non_static_field_access" value="false"/>
|
|
||||||
<setting id="cleanup.boolean_literal" value="true"/>
|
|
||||||
<setting id="cleanup.always_use_parentheses_in_expressions" value="false"/>
|
|
||||||
<setting id="cleanup.sort_members" value="false"/>
|
|
||||||
<setting id="cleanup.remove_unused_local_variables" value="false"/>
|
|
||||||
<setting id="cleanup.add_missing_deprecated_annotations" value="true"/>
|
|
||||||
<setting id="cleanup.no_string_creation" value="true"/>
|
|
||||||
<setting id="cleanup.use_unboxing" value="false"/>
|
|
||||||
<setting id="cleanup.use_blocks_only_for_return_and_throw" value="false"/>
|
|
||||||
<setting id="cleanup.standard_comparison" value="false"/>
|
|
||||||
<setting id="cleanup.if_condition" value="true"/>
|
|
||||||
<setting id="cleanup.system_property_line_separator" value="true"/>
|
|
||||||
<setting id="cleanup.remove_trailing_whitespaces" value="true"/>
|
|
||||||
<setting id="cleanup.map_cloning" value="true"/>
|
|
||||||
<setting id="cleanup.add_serial_version_id" value="false"/>
|
|
||||||
<setting id="cleanup.try_with_resource" value="true"/>
|
|
||||||
<setting id="cleanup.use_this_for_non_static_method_access" value="false"/>
|
|
||||||
<setting id="cleanup.use_this_for_non_static_method_access_only_if_necessary" value="true"/>
|
|
||||||
<setting id="cleanup.single_used_field" value="false"/>
|
|
||||||
<setting id="cleanup.reduce_indentation" value="false"/>
|
|
||||||
<setting id="cleanup.primitive_parsing" value="false"/>
|
|
||||||
<setting id="cleanup.make_local_variable_final" value="false"/>
|
|
||||||
<setting id="cleanup.add_missing_methods" value="false"/>
|
|
||||||
<setting id="cleanup.qualify_static_member_accesses_with_declaring_class" value="true"/>
|
|
||||||
<setting id="cleanup.add_missing_override_annotations" value="true"/>
|
|
||||||
<setting id="cleanup.use_blocks" value="false"/>
|
|
||||||
<setting id="cleanup.multi_catch" value="true"/>
|
|
||||||
<setting id="cleanup.pull_out_if_from_if_else" value="true"/>
|
|
||||||
<setting id="cleanup.collection_cloning" value="true"/>
|
|
||||||
<setting id="cleanup.convert_to_enhanced_for_loop_if_loop_var_used" value="true"/>
|
|
||||||
<setting id="cleanup.make_variable_declarations_final" value="true"/>
|
|
||||||
<setting id="cleanup.redundant_comparator" value="false"/>
|
|
||||||
<setting id="cleanup.remove_unused_private_types" value="true"/>
|
|
||||||
<setting id="cleanup.system_property_boolean" value="true"/>
|
|
||||||
<setting id="cleanup.qualify_static_method_accesses_with_declaring_class" value="false"/>
|
|
||||||
<setting id="cleanup.organize_imports" value="true"/>
|
|
||||||
<setting id="cleanup.lazy_logical_operator" value="true"/>
|
|
||||||
<setting id="cleanup.bitwise_conditional_expression" value="false"/>
|
|
||||||
<setting id="cleanup.use_directly_map_method" value="false"/>
|
|
||||||
<setting id="cleanup.add_all" value="false"/>
|
|
||||||
<setting id="cleanup.system_property_file_separator" value="true"/>
|
|
||||||
<setting id="cleanup.qualify_static_field_accesses_with_declaring_class" value="false"/>
|
|
||||||
<setting id="cleanup.add_generated_serial_version_id" value="false"/>
|
|
||||||
<setting id="cleanup.controlflow_merge" value="false"/>
|
|
||||||
<setting id="cleanup.primitive_serialization" value="false"/>
|
|
||||||
<setting id="cleanup.comparing_on_criteria" value="true"/>
|
|
||||||
<setting id="cleanup.comparison_statement" value="true"/>
|
|
||||||
<setting id="cleanup.extract_increment" value="false"/>
|
|
||||||
<setting id="cleanup.insert_inferred_type_arguments" value="false"/>
|
|
||||||
<setting id="cleanup.make_private_fields_final" value="true"/>
|
|
||||||
<setting id="cleanup.useless_return" value="true"/>
|
|
||||||
<setting id="cleanup.instanceof_keyword" value="true"/>
|
|
||||||
<setting id="cleanup.use_this_for_non_static_field_access_only_if_necessary" value="true"/>
|
|
||||||
<setting id="cleanup.remove_trailing_whitespaces_all" value="true"/>
|
|
||||||
<setting id="cleanup.one_if_rather_than_duplicate_blocks_that_fall_through" value="true"/>
|
|
||||||
<setting id="cleanup.valueof_rather_than_instantiation" value="true"/>
|
|
||||||
<setting id="cleanup.plain_replacement" value="false"/>
|
|
||||||
<setting id="cleanup.remove_unnecessary_array_creation" value="true"/>
|
|
||||||
<setting id="cleanup.remove_private_constructors" value="true"/>
|
|
||||||
<setting id="cleanup.make_parameters_final" value="false"/>
|
|
||||||
<setting id="cleanup.substring" value="false"/>
|
|
||||||
<setting id="cleanup.ternary_operator" value="false"/>
|
|
||||||
<setting id="cleanup.merge_conditional_blocks" value="false"/>
|
|
||||||
<setting id="cleanup.return_expression" value="true"/>
|
|
||||||
<setting id="cleanup.system_property" value="true"/>
|
|
||||||
<setting id="cleanup.unlooped_while" value="true"/>
|
|
||||||
<setting id="cleanup.convert_to_enhanced_for_loop" value="true"/>
|
|
||||||
<setting id="cleanup.remove_unused_private_fields" value="true"/>
|
|
||||||
<setting id="cleanup.never_use_blocks" value="false"/>
|
|
||||||
<setting id="cleanup.remove_redundant_modifiers" value="true"/>
|
|
||||||
<setting id="cleanup.unreachable_block" value="false"/>
|
|
||||||
<setting id="cleanup.redundant_falling_through_block_end" value="false"/>
|
|
||||||
<setting id="cleanup.switch" value="false"/>
|
|
||||||
<setting id="cleanup.number_suffix" value="true"/>
|
|
||||||
<setting id="cleanup.remove_unnecessary_nls_tags" value="true"/>
|
|
||||||
<setting id="cleanup.convert_to_switch_expressions" value="false"/>
|
|
||||||
<setting id="cleanup.use_this_for_non_static_field_access" value="false"/>
|
|
||||||
<setting id="cleanup.static_inner_class" value="false"/>
|
|
||||||
<setting id="cleanup.use_string_is_blank" value="true"/>
|
|
||||||
<setting id="cleanup.add_missing_nls_tags" value="false"/>
|
|
||||||
<setting id="cleanup.qualify_static_member_accesses_through_instances_with_declaring_class" value="true"/>
|
|
||||||
<setting id="cleanup.remove_unnecessary_casts" value="true"/>
|
|
||||||
<setting id="cleanup.objects_equals" value="false"/>
|
|
||||||
<setting id="cleanup.convert_functional_interfaces" value="true"/>
|
|
||||||
<setting id="cleanup.format_source_code" value="true"/>
|
|
||||||
<setting id="cleanup.else_if" value="false"/>
|
|
||||||
<setting id="cleanup.boolean_value_rather_than_comparison" value="true"/>
|
|
||||||
<setting id="cleanup.add_default_serial_version_id" value="true"/>
|
|
||||||
<setting id="cleanup.remove_unused_private_methods" value="true"/>
|
|
||||||
<setting id="cleanup.make_type_abstract_if_missing_method" value="false"/>
|
|
||||||
<setting id="cleanup.join" value="false"/>
|
|
||||||
<setting id="cleanup.embedded_if" value="false"/>
|
|
||||||
<setting id="cleanup.use_anonymous_class_creation" value="false"/>
|
|
||||||
<setting id="cleanup.invert_equals" value="false"/>
|
|
||||||
<setting id="cleanup.add_missing_override_annotations_interface_methods" value="true"/>
|
|
||||||
<setting id="cleanup.remove_unused_private_members" value="false"/>
|
|
||||||
<setting id="cleanup.strictly_equal_or_different" value="true"/>
|
|
||||||
<setting id="cleanup.never_use_parentheses_in_expressions" value="true"/>
|
|
||||||
<setting id="cleanup.push_down_negation" value="false"/>
|
|
||||||
<setting id="cleanup.evaluate_nullable" value="false"/>
|
|
||||||
<setting id="cleanup.use_parentheses_in_expressions" value="true"/>
|
|
||||||
<setting id="cleanup.hash" value="false"/>
|
|
||||||
<setting id="cleanup.double_negation" value="true"/>
|
|
||||||
<setting id="cleanup.overridden_assignment" value="true"/>
|
|
||||||
<setting id="cleanup.primitive_rather_than_wrapper" value="true"/>
|
|
||||||
<setting id="cleanup.correct_indentation" value="false"/>
|
|
||||||
<setting id="cleanup.use_var" value="false"/>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
@@ -1,390 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<profiles version="21">
|
|
||||||
<profile kind="CodeFormatterProfile" name="LuaJ" version="21">
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" 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.parentheses_positions_in_for_statment" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" 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.insert_new_line_after_annotation_on_package" value="insert"/>
|
|
||||||
<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_space_before_closing_paren_in_while" value="insert"/>
|
|
||||||
<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.comment.format_javadoc_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" 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.alignment_for_arguments_in_enum_constant" value="16"/>
|
|
||||||
<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.comment.indent_root_tags" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
|
||||||
<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.wrap_before_multiplicative_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
|
||||||
<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_after_prefix_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="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_new_line_after_annotation_on_method" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
|
|
||||||
<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.keep_annotation_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="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.insert_space_after_assignment_operator" value="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_opening_paren_in_for" 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_new_line_after_annotation_on_local_variable" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
|
|
||||||
<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.alignment_for_union_type_in_multicatch" value="16"/>
|
|
||||||
<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.keep_else_statement_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
|
||||||
<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_before_comma_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
|
|
||||||
<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_comma_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
|
||||||
<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.insert_space_after_colon_in_assert" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="49"/>
|
|
||||||
<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_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
|
|
||||||
<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_between_empty_parens_in_method_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
|
|
||||||
<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.keep_if_then_body_block_on_one_line" value="one_line_never"/>
|
|
||||||
<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_before_closing_brace_in_array_initializer" value="do not insert"/>
|
|
||||||
<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.format_guardian_clause_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
|
||||||
<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.alignment_for_conditional_expression_chain" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
|
|
||||||
<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.alignment_for_method_declaration" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
|
|
||||||
<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_space_before_colon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" 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_comma_in_allocation_expression" value="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_brace_in_array_initializer" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
|
||||||
<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_after_not_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" 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.comment.format_html" value="true"/>
|
|
||||||
<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.parentheses_positions_in_method_delcaration" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
|
|
||||||
<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_before_opening_paren_in_enum_constant" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
|
||||||
<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_annotations_on_package" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
|
||||||
<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_before_assignment_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
|
||||||
<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_colon_in_conditional" value="do not 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_before_closing_paren_in_cast" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
|
|
||||||
<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.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
|
|
||||||
<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.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
|
||||||
<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.wrap_before_bitwise_operator" value="true"/>
|
|
||||||
<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_lambda_arrow" value="insert"/>
|
|
||||||
<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.comment.indent_tag_description" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="end_of_line"/>
|
|
||||||
<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_between_brackets_in_array_type_reference" value="do not 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.alignment_for_string_concatenation" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" 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.alignment_for_multiple_fields" value="16"/>
|
|
||||||
<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_before_prefix_operator" 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_before_shift_operator" 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.insert_space_after_comma_in_type_parameters" value="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_after_shift_operator" value="do not 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.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" 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.insert_space_before_comma_in_record_components" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
|
||||||
<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_before_opening_paren_in_synchronized" value="insert"/>
|
|
||||||
<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.alignment_for_expressions_in_for_loop_header" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="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_before_string_concatenation" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" 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.blank_lines_between_import_groups" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
|
|
||||||
<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.parentheses_positions_in_switch_statement" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" 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.insert_space_after_comma_in_type_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="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.disabling_tag" value="@formatter:off"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
|
|
||||||
<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_parenthesized_expression_in_return" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
|
||||||
<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.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
|
||||||
<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_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
|
||||||
<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_question_in_wildcard" value="do not 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_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_preserve"/>
|
|
||||||
<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.keep_loop_body_block_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<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.alignment_for_additive_operator" value="16"/>
|
|
||||||
<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_opening_brace_in_record_constructor" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<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_after_question_in_conditional" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
|
||||||
<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_paren_in_catch" value="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_comma_in_method_invocation_arguments" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
|
||||||
<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_try" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
|
|
||||||
<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_relational_operator" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" 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.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
|
|
||||||
<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_annotations_on_local_variable" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="do not insert"/>
|
|
||||||
<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_opening_paren_in_while" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
|
||||||
<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.alignment_for_annotations_on_field" value="49"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
|
||||||
<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.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="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.insert_space_after_colon_in_conditional" value="insert"/>
|
|
||||||
<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_after_semicolon_in_try_resources" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
|
||||||
<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_record_declaration" 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.wrap_before_assignment_operator" value="false"/>
|
|
||||||
<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.brace_position_for_switch" value="end_of_line"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not 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.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
|
|
||||||
<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.keep_record_constructor_on_one_line" value="one_line_never"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_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.alignment_for_assertion_message" value="16"/>
|
|
||||||
<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.blank_lines_before_new_chunk" value="1"/>
|
|
||||||
<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_after_opening_paren_in_constructor_declaration" value="do not 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_before_closing_angle_bracket_in_type_arguments" 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.blank_lines_before_member_type" value="1"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="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_superinterfaces_in_record_declaration" value="16"/>
|
|
||||||
<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.insert_space_before_semicolon" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
|
||||||
<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.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
|
|
||||||
<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_space_after_comma_in_annotation" value="insert"/>
|
|
||||||
<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.parentheses_positions_in_lambda_declaration" value="common_lines"/>
|
|
||||||
<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_before_opening_bracket_in_array_reference" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_never"/>
|
|
||||||
<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.brace_position_for_enum_constant" value="end_of_line"/>
|
|
||||||
<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_multiplicative_operator" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" 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.insert_space_before_closing_paren_in_enum_constant" 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_closing_paren_in_annotation" value="do not 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_before_opening_brace_in_constructor_declaration" value="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_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="do not insert"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
|
|
||||||
<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.tabulation.char" value="tab"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
|
|
||||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
|
|
||||||
<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.insert_space_before_opening_paren_in_switch" value="insert"/>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
17
.project
Normal file
17
.project
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>luaj-vm</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
21
LICENSE
21
LICENSE
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2007 LuaJ. All rights reserved.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,24 +1,27 @@
|
|||||||
# This is a fork!
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<div style="border: 1px dotted red; margin: 1.em 0.5em; font-weight: bold; color: red;">
|
<html>
|
||||||
This repository has been forked from the original CVS sources of Luaj.
|
|
||||||
The commit history has been converted to make sure that the original work of
|
|
||||||
James Roseborough and Ian Farmer is not lost.
|
|
||||||
Unfortunately, I was not able to contact either James or Ian to hand over
|
|
||||||
ownership of the Github organization/repo as I have originally intended to.
|
|
||||||
The community however seems interested enough to continue work on the original
|
|
||||||
sources and therefore I have decided to make sure that any useful pull requests
|
|
||||||
that may add some value to the original code base shall be merged in from now
|
|
||||||
on.<br>
|
|
||||||
-- Benjamin P. Jung, Jan. 26th 2018
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h1>Getting Started with LuaJ</h1>
|
<head>
|
||||||
James Roseborough, Ian Farmer, Version 3.0.2
|
<title>Getting Started with LuaJ</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="http://www.lua.org/lua.css">
|
||||||
|
<META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h1>
|
||||||
|
<a href="README.html"><img src="http://sourceforge.net/dbimage.php?id=196139" alt="" border="0"></a>
|
||||||
|
|
||||||
|
Getting Started with LuaJ
|
||||||
|
|
||||||
|
</h1>
|
||||||
|
James Roseborough, Ian Farmer, Version 3.0.1
|
||||||
<p>
|
<p>
|
||||||
<small>
|
<small>
|
||||||
Copyright © 2009-2014 Luaj.org.
|
Copyright © 2009-2014 Luaj.org.
|
||||||
Freely available under the terms of the
|
Freely available under the terms of the
|
||||||
<a href="LICENSE">Luaj license</a>.
|
<a href="http://sourceforge.net/dbimage.php?id=196142">Luaj license</a>.
|
||||||
</small>
|
</small>
|
||||||
<hr>
|
<hr>
|
||||||
<p>
|
<p>
|
||||||
@@ -117,7 +120,7 @@ in comparison with the standard C distribution.
|
|||||||
<td>16.794</td>
|
<td>16.794</td>
|
||||||
<td>11.274</td>
|
<td>11.274</td>
|
||||||
<td>Java</td>
|
<td>Java</td>
|
||||||
<td>java -cp luaj-jse-3.0.2.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
|
<td>java -cp luaj-jse-3.0.1.jar;bcel-5.2.jar lua <b>-b</b> fannkuch.lua 10</td></tr>
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<td></td>
|
<td></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
@@ -127,7 +130,7 @@ in comparison with the standard C distribution.
|
|||||||
<td>36.894</td>
|
<td>36.894</td>
|
||||||
<td>15.163</td>
|
<td>15.163</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>java -cp luaj-jse-3.0.2.jar lua -n fannkuch.lua 10</td></tr>
|
<td>java -cp luaj-jse-3.0.1.jar lua -n fannkuch.lua 10</td></tr>
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<td>lua</td>
|
<td>lua</td>
|
||||||
<td>5.1.4</td>
|
<td>5.1.4</td>
|
||||||
@@ -183,7 +186,7 @@ It is also faster than Java-lua implementations Jill, Kahlua, and Mochalua for a
|
|||||||
From the main distribution directory line type:
|
From the main distribution directory line type:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
java -cp luaj-jse-3.0.2.jar lua examples/lua/hello.lua
|
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/hello.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -195,7 +198,7 @@ You should see the following output:
|
|||||||
To see how luaj can be used to acccess most Java API's including swing, try:
|
To see how luaj can be used to acccess most Java API's including swing, try:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
java -cp luaj-jse-3.0.2.jar lua examples/lua/swingapp.lua
|
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/swingapp.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -210,8 +213,8 @@ Links to sources:<pre>
|
|||||||
From the main distribution directory line type:
|
From the main distribution directory line type:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
java -cp luaj-jse-3.0.2.jar luac examples/lua/hello.lua
|
java -cp lib/luaj-jse-3.0.1.jar luac examples/lua/hello.lua
|
||||||
java -cp luaj-jse-3.0.2.jar lua luac.out
|
java -cp lib/luaj-jse-3.0.1.jar lua luac.out
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -225,8 +228,8 @@ Luaj can compile lua sources or binaries directly to java bytecode if the bcel l
|
|||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
ant bcel-lib
|
ant bcel-lib
|
||||||
java -cp "luaj-jse-3.0.2.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua
|
java -cp "lib/luaj-jse-3.0.1.jar;lib/bcel-5.2.jar" luajc -s examples/lua -d . hello.lua
|
||||||
java -cp "luaj-jse-3.0.2.jar;." lua -l hello
|
java -cp "lib/luaj-jse-3.0.1.jar;." lua -l hello
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -237,7 +240,7 @@ but the compiled classes must be in the class path at runtime, unless runtime ji
|
|||||||
<p>
|
<p>
|
||||||
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
|
Lua scripts can also be run directly in this mode without precompiling using the <em>lua</em> command with the <b><em>-b</em></b> option and providing the <em>bcel</em> library in the class path:
|
||||||
<pre>
|
<pre>
|
||||||
java -cp "luaj-jse-3.0.2.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua
|
java -cp "lib/luaj-jse-3.0.1.jar;lib/bcel-5.2.jar" lua -b examples/lua/hello.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
@@ -281,7 +284,7 @@ A simple example may be found in
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You must include the library <b>luaj-jse-3.0.2.jar</b> in your class path.
|
You must include the library <b>lib/luaj-jse-3.0.1.jar</b> in your class path.
|
||||||
|
|
||||||
<h2>Run a script in a MIDlet</h2>
|
<h2>Run a script in a MIDlet</h2>
|
||||||
|
|
||||||
@@ -308,7 +311,7 @@ A simple example may be found in
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You must include the library <b>luaj-jme-3.0.2.jar</b> in your midlet jar.
|
You must include the library <b>lib/luaj-jme-3.0.1.jar</b> in your midlet jar.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
An ant script to build and run the midlet is in
|
An ant script to build and run the midlet is in
|
||||||
@@ -338,7 +341,7 @@ You can also look up the engine by language "lua" or mimetypes "text/lua" or "ap
|
|||||||
All standard aspects of script engines including compiled statements are supported.
|
All standard aspects of script engines including compiled statements are supported.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You must include the library <b>luaj-jse-3.0.2.jar</b> in your class path.
|
You must include the library <b>lib/luaj-jse-3.0.1.jar</b> in your class path.
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
A working example may be found in
|
A working example may be found in
|
||||||
@@ -349,8 +352,8 @@ A working example may be found in
|
|||||||
To compile and run it using Java 1.6 or higher:
|
To compile and run it using Java 1.6 or higher:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
javac -cp luaj-jse-3.0.2.jar examples/jse/ScriptEngineSample.java
|
javac -cp lib/luaj-jse-3.0.1.jar examples/jse/ScriptEngineSample.java
|
||||||
java -cp "luaj-jse-3.0.2.jar;examples/jse" ScriptEngineSample
|
java -cp "lib/luaj-jse-3.0.1.jar;examples/jse" ScriptEngineSample
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h2>Excluding the lua bytecode compiler</h2>
|
<h2>Excluding the lua bytecode compiler</h2>
|
||||||
@@ -412,7 +415,7 @@ and the math operations include all those supported by Java SE.
|
|||||||
Android applications should use the JsePlatform, and can include the <a href="#luajava">Luajava</a> library
|
Android applications should use the JsePlatform, and can include the <a href="#luajava">Luajava</a> library
|
||||||
to simplify access to underlying Android APIs.
|
to simplify access to underlying Android APIs.
|
||||||
A specialized Globals.finder should be provided to find scripts and data for loading.
|
A specialized Globals.finder should be provided to find scripts and data for loading.
|
||||||
See <a href="examples/android/src/android/LuajView.java">examples/android/src/android/LuajView.java</a>
|
See <a href="examples/android/src/android/LuajView">examples/android/src/android/LuajView</a>
|
||||||
for an example that loads from the "res" Android project directory.
|
for an example that loads from the "res" Android project directory.
|
||||||
The ant build script is <a href="examples/android/build.xml">examples/android/build.xml</a>.
|
The ant build script is <a href="examples/android/build.xml">examples/android/build.xml</a>.
|
||||||
|
|
||||||
@@ -590,7 +593,7 @@ The following lua script will open a swing frame on Java SE:
|
|||||||
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading.
|
See a longer sample in <em>examples/lua/swingapp.lua</em> for details, including a simple animation loop, rendering graphics, mouse and key handling, and image loading.
|
||||||
Or try running it using:
|
Or try running it using:
|
||||||
<pre>
|
<pre>
|
||||||
java -cp luaj-jse-3.0.2.jar lua examples/lua/swingapp.lua
|
java -cp lib/luaj-jse-3.0.1.jar lua examples/lua/swingapp.lua
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@@ -839,7 +842,7 @@ For JSE projects, add this dependency for the luaj-jse jar:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.luaj</groupId>
|
<groupId>org.luaj</groupId>
|
||||||
<artifactId>luaj-jse</artifactId>
|
<artifactId>luaj-jse</artifactId>
|
||||||
<version>3.0.2</version>
|
<version>3.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</pre>
|
</pre>
|
||||||
while for JME projects, use the luaj-jme jar:
|
while for JME projects, use the luaj-jme jar:
|
||||||
@@ -847,7 +850,7 @@ while for JME projects, use the luaj-jme jar:
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.luaj</groupId>
|
<groupId>org.luaj</groupId>
|
||||||
<artifactId>luaj-jme</artifactId>
|
<artifactId>luaj-jme</artifactId>
|
||||||
<version>3.0.2</version>
|
<version>3.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -858,30 +861,37 @@ An example skelton maven pom file for a skeleton project is in
|
|||||||
|
|
||||||
|
|
||||||
<h2>Building the jars</h2>
|
<h2>Building the jars</h2>
|
||||||
Build the jars with maven.
|
An ant file is included in the root directory which builds the libraries by default.
|
||||||
<pre>
|
|
||||||
mvn clean verify
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
Other targets exist for creating distribution file an measuring code coverage of unit tests.
|
||||||
|
|
||||||
<h2>Unit tests</h2>
|
<h2>Unit tests</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
All unit tests are executed during the build.
|
The main luaj JUnit tests are organized into a JUnit 3 suite:
|
||||||
|
<pre>
|
||||||
|
test/junit/org/luaj/vm2/AllTests.lua
|
||||||
|
</pre>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Test scripts can be found in these locations
|
Unit test scripts can be found in these locations
|
||||||
<pre>
|
<pre>
|
||||||
luaj-test/src/test/resources
|
test/lua/*.lua
|
||||||
|
test/lua/errors/*.lua
|
||||||
|
test/lua/perf/*.lua
|
||||||
|
test/lua/luaj3.0.1-tests.zip
|
||||||
</pre>
|
</pre>
|
||||||
Executon is included in the build of luaj-test.
|
|
||||||
|
|
||||||
<h2>Code coverage</h2>
|
<h2>Code coverage</h2>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The maven build creates the coverage report in the luaj-test/target/site folder
|
A build script for running unit tests and producing code coverage statistics is in
|
||||||
during the verify phase.
|
<pre>
|
||||||
|
<a href="build-coverage.xml">build-coverage.xml</a>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
It relies on the cobertura code coverage library.
|
||||||
|
|
||||||
<h1>8 - <a name="8">Downloads</a></h1>
|
<h1>8 - <a name="8">Downloads</a></h1>
|
||||||
|
|
||||||
@@ -920,7 +930,7 @@ Files are no longer hosted at LuaForge.
|
|||||||
<li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a>
|
<li>Enhance javadoc, put it <a href="docs/api/index.html">in distribution</a>
|
||||||
and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0/</a></li>
|
and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sourceforge.net/api/2.0/</a></li>
|
||||||
<li>Major refactor of luajava type coercion logic, improve method selection.</li>
|
<li>Major refactor of luajava type coercion logic, improve method selection.</li>
|
||||||
<li>Add luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
|
<li>Add lib/luaj-sources-2.0.2.jar for easier integration into an IDE such as Netbeans </li>
|
||||||
|
|
||||||
<tr valign="top"><td> <b>2.0.3</b></td><td><ul>
|
<tr valign="top"><td> <b>2.0.3</b></td><td><ul>
|
||||||
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
|
<li>Improve coroutine state logic including let unreferenced coroutines be garbage collected </li>
|
||||||
@@ -1007,11 +1017,6 @@ and at <a href="http://luaj.sourceforge.net/api/2.0/index.html">http://luaj.sour
|
|||||||
<li>Move online docs to <a href="http://luaj.org/luaj/3.0/api/index.html">http://luaj.org/luaj/3.0/api/</a></li>
|
<li>Move online docs to <a href="http://luaj.org/luaj/3.0/api/index.html">http://luaj.org/luaj/3.0/api/</a></li>
|
||||||
<li>Fix os.time() conversions for pm times.</li>
|
<li>Fix os.time() conversions for pm times.</li>
|
||||||
|
|
||||||
<tr valign="top"><td> <b>3.0.2</b></td><td><ul>
|
|
||||||
<li>Fix JsePlatform.luaMain() to provide an "arg" table in the chunk's environment.</li>
|
|
||||||
<li>Let JsePlatform.luaMain() return values returned by the main chunk.</li>
|
|
||||||
<li>Add synchronization to CoerceJavaToLua.COERCIONS map.</li>
|
|
||||||
|
|
||||||
</ul></td></tr>
|
</ul></td></tr>
|
||||||
</table></td></tr></table>
|
</table></td></tr></table>
|
||||||
|
|
||||||
108
build-app.xml
Normal file
108
build-app.xml
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<!-- And build script to compile lua scripts into runnable jar files using the "luajc"
|
||||||
|
lua to java bytecode compiler.
|
||||||
|
|
||||||
|
Each source file is converted into a runnable jar file that takes arguments from the command line.
|
||||||
|
For example, the program test/lua/perf/binarytrees.lua is converted to a jar that can be run with
|
||||||
|
java -jar binarytrees.jar 15
|
||||||
|
-->
|
||||||
|
<project default="all">
|
||||||
|
<import file="build.xml"/>
|
||||||
|
|
||||||
|
<import file="build-libs.xml"/>
|
||||||
|
|
||||||
|
<available file="luaj-jse-${version}.jar" property="luaj.lib.exists"/>
|
||||||
|
|
||||||
|
<!-- this may need to be changed when building on mac -->
|
||||||
|
<property name="rt.jar" value="${java.home}/lib/rt.jar"/>
|
||||||
|
|
||||||
|
<target name="luaj-lib" unless="luaj.lib.exists">
|
||||||
|
<antcall target="jar-jse"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<macrodef name="perftest">
|
||||||
|
<attribute name="cmd"/>
|
||||||
|
<sequential>
|
||||||
|
<echo level="info">------ @{cmd}</echo>
|
||||||
|
<exec executable="bash">
|
||||||
|
<arg value="-c"/>
|
||||||
|
<arg value="time @{cmd}"/>
|
||||||
|
</exec>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<macrodef name="buildappjar">
|
||||||
|
<attribute name="luaprog"/>
|
||||||
|
<attribute name="arg" default=""/>
|
||||||
|
<attribute name="srcdir" default="test/lua/perf"/>
|
||||||
|
<sequential>
|
||||||
|
<echo level="info">=========== @{srcdir}/@{luaprog} =============</echo>
|
||||||
|
<delete dir="build/@{luaprog}"/>
|
||||||
|
<mkdir dir="build/@{luaprog}/class"/>
|
||||||
|
<java classname="luajc">
|
||||||
|
<classpath>
|
||||||
|
<pathelement path="luaj-jse-${version}.jar"/>
|
||||||
|
<pathelement path="lib/bcel-5.2.jar"/>
|
||||||
|
</classpath>
|
||||||
|
<arg value="-s"/>
|
||||||
|
<arg path="@{srcdir}"/>
|
||||||
|
<arg value="-d"/>
|
||||||
|
<arg path="build/@{luaprog}/class"/>
|
||||||
|
<arg value="-m"/>
|
||||||
|
<arg value="-v"/>
|
||||||
|
<arg value="@{luaprog}.lua"/>
|
||||||
|
</java>
|
||||||
|
<jar destfile="build/@{luaprog}.jar">
|
||||||
|
<fileset dir="build/@{luaprog}/class"/>
|
||||||
|
<zipfileset includes="org/luaj/vm2/*.class,org/luaj/vm2/lib/*.class,org/luaj/vm2/lib/jse/*.class,org/luaj/vm2/compiler/*.class" src="luaj-jse-${version}.jar" />
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Main-Class" value="@{luaprog}" />
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
<unjar src="build/@{luaprog}.jar" dest="build/@{luaprog}/unjarred"/>
|
||||||
|
<perftest cmd="java -jar build/@{luaprog}.jar @{arg}"/>
|
||||||
|
|
||||||
|
<!-- The following can be adapted to produce an optimized jar.
|
||||||
|
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
|
||||||
|
<proguard>
|
||||||
|
-injars build/@{luaprog}.jar
|
||||||
|
-outjars build/@{luaprog}-opt.jar
|
||||||
|
-libraryjars ${rt.jar}
|
||||||
|
-overloadaggressively
|
||||||
|
-repackageclasses ''
|
||||||
|
-allowaccessmodification
|
||||||
|
-printmapping build/@{luaprog}.map
|
||||||
|
|
||||||
|
-keep public class @{luaprog} {
|
||||||
|
public static void main(java.lang.String[]);
|
||||||
|
}
|
||||||
|
</proguard>
|
||||||
|
<unjar src="build/@{luaprog}-opt.jar" dest="build/@{luaprog}/unjarred-opt"/>
|
||||||
|
<perftest cmd="java -jar build/@{luaprog}-opt.jar @{arg}"/>
|
||||||
|
-->
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<target name="binarytrees" depends="luaj-lib,proguard-lib">
|
||||||
|
<buildappjar luaprog="binarytrees" arg="15"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="fannkuch" depends="luaj-lib,proguard-lib">
|
||||||
|
<buildappjar luaprog="fannkuch" arg="10"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="nbody" depends="luaj-lib,proguard-lib">
|
||||||
|
<buildappjar luaprog="nbody" arg="1000000"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="nsieve" depends="luaj-lib,proguard-lib">
|
||||||
|
<buildappjar luaprog="nsieve" arg="8"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="swingapp" depends="luaj-lib,proguard-lib">
|
||||||
|
<buildappjar luaprog="swingapp" srcdir="examples/lua"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="allappjars" depends="binarytrees,fannkuch,nbody,nsieve,swingapp"/>
|
||||||
|
|
||||||
|
<target name="all" depends="allappjars"/>
|
||||||
|
</project>
|
||||||
116
build-applet.xml
Normal file
116
build-applet.xml
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<project name="sample" default="main" basedir=".">
|
||||||
|
<property file="version.properties"/>
|
||||||
|
|
||||||
|
<!-- find libs -->
|
||||||
|
<import file="build-libs.xml"/>
|
||||||
|
|
||||||
|
<!-- main java class -->
|
||||||
|
<property name="java.dir" value="examples/jse"/>
|
||||||
|
<property name="java.name" value="SampleApplet"/>
|
||||||
|
|
||||||
|
<!-- main script -->
|
||||||
|
<property name="script.dir" value="examples/lua"/>
|
||||||
|
<property name="script.name" value="swingapplet"/>
|
||||||
|
<property name="image.name" value="logo.gif"/>
|
||||||
|
|
||||||
|
<!-- location of luaj jar -->
|
||||||
|
<property name="libs.dir" value="lib"/>
|
||||||
|
<property name="luaj.jar" value="${libs.dir}/luaj-jse-${version}.jar"/>
|
||||||
|
|
||||||
|
<!-- location of build results -->
|
||||||
|
<property name="build.dir" value="build/applet"/>
|
||||||
|
|
||||||
|
<target name="clean">
|
||||||
|
<delete failonerror="false" dir="${build.dir}"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="dirs">
|
||||||
|
<mkdir dir="build/applet/classes"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="classes" depends="dirs">
|
||||||
|
<copy todir="${build.dir}">
|
||||||
|
<fileset dir="${script.dir}" includes="${script.name}.lua,${image.name}"/>
|
||||||
|
</copy>
|
||||||
|
<javac destdir="${build.dir}/classes" source="1.4" target="1.4"
|
||||||
|
classpath="${luaj.jar}" srcdir="${java.dir}" includes="${java.name}.java"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="manifest" depends="dirs">
|
||||||
|
<manifest file="${build.dir}/MANIFEST.MF">
|
||||||
|
<attribute name="Permissions" value="sandbox"/>
|
||||||
|
<attribute name="Main-class" value="${java.name}"/>
|
||||||
|
</manifest>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar" depends="classes,manifest">
|
||||||
|
<jar destfile="${build.dir}/${script.name}.jar"
|
||||||
|
manifest="${build.dir}/MANIFEST.MF">
|
||||||
|
<fileset dir="${build.dir}" includes="*.lua"/>
|
||||||
|
<fileset dir="${build.dir}/classes"/>
|
||||||
|
<zipfileset
|
||||||
|
src="${luaj.jar}"
|
||||||
|
excludes="**/script/*,**/luajc/**,**/parser/**,**/ast/**,lua*"/>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="obf" depends="jar,proguard-lib">
|
||||||
|
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
|
||||||
|
<copy file="${build.dir}/${script.name}.jar"
|
||||||
|
tofile="${build.dir}/${script.name}-unobfuscated.jar"/>
|
||||||
|
<proguard>
|
||||||
|
-injars ${build.dir}/${script.name}-unobfuscated.jar
|
||||||
|
-outjars ${build.dir}/${script.name}.jar
|
||||||
|
-libraryjars ${java.home}/lib/rt.jar
|
||||||
|
-overloadaggressively
|
||||||
|
-repackageclasses ''
|
||||||
|
-allowaccessmodification
|
||||||
|
-printmapping ${build.dir}/mapping.txt
|
||||||
|
|
||||||
|
-keep public class * extends java.applet.Applet
|
||||||
|
|
||||||
|
-target 1.4
|
||||||
|
</proguard>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="sign" depends="obf">
|
||||||
|
<signjar jar="${build.dir}/${script.name}.jar"
|
||||||
|
alias="${sign.alias}"
|
||||||
|
storepass="${sign.storepass}"
|
||||||
|
keypass="${sign.keypass}"
|
||||||
|
keystore="${sign.keystore}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="html" depends="dirs">
|
||||||
|
<echoxml file="build/applet/LuajSampleApplet.html">
|
||||||
|
<html>
|
||||||
|
<head><title>Luaj Sample Applet</title></head>
|
||||||
|
<body>
|
||||||
|
<h1>Luaj Sample Applet</h1>
|
||||||
|
Requires browser that supports applets.
|
||||||
|
${script.name}
|
||||||
|
<applet archive='${script.name}.jar'
|
||||||
|
code='${java.name}.class'
|
||||||
|
width='800'
|
||||||
|
height='640' >
|
||||||
|
<param name='luaj.script' value='${script.name}.lua'/>
|
||||||
|
<param name="java_version" value="1.4+"/>
|
||||||
|
</applet>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
</echoxml>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="run" depends="jar,html">
|
||||||
|
<exec executable="open" spawn="true">
|
||||||
|
<arg value="-a Firefox"/>
|
||||||
|
<arg path="build/applet/LuajSampleApplet.html"/>
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="all" depends="clean,sign,html,run"/>
|
||||||
|
|
||||||
|
<target name="main" depends="sign,html"/>
|
||||||
|
|
||||||
|
</project>
|
||||||
119
build-coverage.xml
Normal file
119
build-coverage.xml
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<project default="all" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
|
||||||
|
<!--
|
||||||
|
Run code coverage for unit tests on the luaj vm and libraries.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<property name="classes.dir" value="build/classes-debug" />
|
||||||
|
<property name="instrumented.dir" value="build/instrumented" />
|
||||||
|
<property name="reports.xml.dir" value="build/reports-junit-xml" />
|
||||||
|
<property name="reports.html.dir" value="build/reports-junit-html" />
|
||||||
|
<property name="coverage.xml.dir" value="build/reports-coverage-xml" />
|
||||||
|
<property name="coverage.html.dir" value="build/reports-coverage-html" />
|
||||||
|
<property name="cobertura.serfile" value="cobertura.ser" />
|
||||||
|
<property name="cobertura.logfile" value="cobertura.log" />
|
||||||
|
|
||||||
|
<artifact:dependencies filesetId="cobutura.fileset">
|
||||||
|
<dependency groupId="net.sourceforge.cobertura" artifactId="cobertura" version="1.9.4.1"/>
|
||||||
|
<dependency groupId="junit" artifactId="junit" version="3.8.1"/>
|
||||||
|
</artifact:dependencies>
|
||||||
|
|
||||||
|
<path id="cobertura.classpath">
|
||||||
|
<fileset refid="cobutura.fileset" />
|
||||||
|
</path>
|
||||||
|
|
||||||
|
<taskdef classpathref="cobertura.classpath" resource="tasks.properties" />
|
||||||
|
|
||||||
|
<import file="wtk.xml"/>
|
||||||
|
|
||||||
|
<property environment="env"/>
|
||||||
|
|
||||||
|
<target name="clean" description="Remove all files created by the build/test process.">
|
||||||
|
<delete dir="${classes.dir}" failonerror="yes"/>
|
||||||
|
<delete dir="${instrumented.dir}" failonerror="yes"/>
|
||||||
|
<delete file="${cobertura.logfile}" />
|
||||||
|
<delete file="${cobertura.serfile}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="init">
|
||||||
|
<ant antfile="build.xml" target="bcel-lib"/>
|
||||||
|
<ant antfile="build.xml" target="luaj1-lib"/>
|
||||||
|
<mkdir dir="${classes.dir}" />
|
||||||
|
<mkdir dir="${instrumented.dir}" />
|
||||||
|
<mkdir dir="${reports.xml.dir}" />
|
||||||
|
<mkdir dir="${reports.html.dir}" />
|
||||||
|
<mkdir dir="${coverage.xml.dir}" />
|
||||||
|
<mkdir dir="${coverage.html.dir}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="compile" depends="init,wtk-or-fail">
|
||||||
|
<javac destdir="${classes.dir}" debug="yes" target="1.5">
|
||||||
|
<classpath refid="cobertura.classpath" />
|
||||||
|
<classpath refid="wtk-libs" />
|
||||||
|
<classpath path="lib/bcel-5.2.jar" />
|
||||||
|
<src path="src/core"/>
|
||||||
|
<src path="src/jme"/>
|
||||||
|
<src path="src/jse"/>
|
||||||
|
<src path="test/junit"/>
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="instrument" depends="compile">
|
||||||
|
<delete file="${cobertura.serfile}"/>
|
||||||
|
<delete dir="${instrumented.dir}" failonerror="no"/>
|
||||||
|
<cobertura-instrument datafile="${cobertura.serfile}" todir="${instrumented.dir}">
|
||||||
|
<fileset dir="${classes.dir}">
|
||||||
|
<include name="org/luaj/vm2/*.class" />
|
||||||
|
<include name="org/luaj/vm2/lib/*.class" />
|
||||||
|
<include name="org/luaj/vm2/lib/jse/*.class" />
|
||||||
|
<include name="org/luaj/vm2/lib/jme/*.class" />
|
||||||
|
<include name="org/luaj/vm2/compiler/*.class" />
|
||||||
|
<include name="org/luaj/vm2/luajc/*.class" />
|
||||||
|
<include name="org/luaj/vm2/lua2java/*.class" />
|
||||||
|
<include name="org/luaj/vm2/parser/*.class" />
|
||||||
|
<include name="org/luaj/vm2/ast/*.class" />
|
||||||
|
<exclude name="**/*Test*.class" />
|
||||||
|
</fileset>
|
||||||
|
</cobertura-instrument>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="test">
|
||||||
|
<junit fork="yes" dir="${basedir}" showoutput="yes">
|
||||||
|
<sysproperty key="net.sourceforge.cobertura.serfile"
|
||||||
|
file="${basedir}/${cobertura.serfile}" />
|
||||||
|
<classpath location="${instrumented.dir}" />
|
||||||
|
<classpath location="${classes.dir}" />
|
||||||
|
<classpath refid="cobertura.classpath" />
|
||||||
|
<classpath location="test/lua" />
|
||||||
|
<classpath location="test/junit/org/luaj/vm2/compiler" />
|
||||||
|
<classpath location="test/junit/org/luaj/vm2/vm1" />
|
||||||
|
<classpath path="lib/bcel-5.2.jar" />
|
||||||
|
<formatter type="xml" />
|
||||||
|
<batchtest todir="${reports.xml.dir}">
|
||||||
|
<fileset dir="test/junit">
|
||||||
|
<include name="org/luaj/vm2/AllTests.java" />
|
||||||
|
</fileset>
|
||||||
|
</batchtest>
|
||||||
|
</junit>
|
||||||
|
|
||||||
|
<junitreport todir="${reports.xml.dir}">
|
||||||
|
<fileset dir="${reports.xml.dir}">
|
||||||
|
<include name="TEST-*.xml" />
|
||||||
|
</fileset>
|
||||||
|
<report format="frames" todir="${reports.html.dir}" />
|
||||||
|
</junitreport>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="report">
|
||||||
|
<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.xml.dir}" format="xml" />
|
||||||
|
<cobertura-report datafile="${cobertura.serfile}" destdir="${coverage.html.dir}">
|
||||||
|
<fileset dir="src/core"/>
|
||||||
|
<fileset dir="src/jse"/>
|
||||||
|
<fileset dir="src/jme"/>
|
||||||
|
</cobertura-report>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="coverage" depends="clean,init,compile,instrument,test,report"/>
|
||||||
|
|
||||||
|
<target name="all" depends="coverage" />
|
||||||
|
|
||||||
|
</project>
|
||||||
56
build-libs.xml
Normal file
56
build-libs.xml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<project default="all-libs">
|
||||||
|
|
||||||
|
<available file="lib/midpapi20.jar" property="midpapi.lib.exists"/>
|
||||||
|
<available file="lib/bcel-5.2.jar" property="bcel.lib.exists"/>
|
||||||
|
<available file="lib/javacc.jar" property="javacc.lib.exists"/>
|
||||||
|
<available file="lib/proguard.jar" property="proguard.lib.exists"/>
|
||||||
|
<available file="lib/antenna-bin-1.2.0-beta.jar" property="antenna.lib.exists"/>
|
||||||
|
<available file="lib/junit.jar" property="junit.lib.exists"/>
|
||||||
|
<available file="lib/cobertura.jar" property="cobertura.lib.exists"/>
|
||||||
|
<available file="lib/microemulator.jar" property="microemulator.lib.exists"/>
|
||||||
|
|
||||||
|
<macrodef name="download">
|
||||||
|
<attribute name="zipname"/>
|
||||||
|
<attribute name="jars" default="**/*.jar"/>
|
||||||
|
<sequential>
|
||||||
|
<mkdir dir="lib"/>
|
||||||
|
<get src="http://luaj.sourceforge.net/lib/@{zipname}.tar.gz"
|
||||||
|
dest="lib/@{zipname}.tar.gz"/>
|
||||||
|
<gunzip src="lib/@{zipname}.tar.gz" dest="lib/@{zipname}.tar"/>
|
||||||
|
<untar src="lib/@{zipname}.tar" dest="lib" overwrite="true">
|
||||||
|
<patternset>
|
||||||
|
<include name="@{jars}"/>
|
||||||
|
</patternset>
|
||||||
|
<mapper type="flatten"/>
|
||||||
|
</untar>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<target name="wtk-libs" unless="midpapi.lib.exists">
|
||||||
|
<download zipname="wtk-2.5.2-api"/>
|
||||||
|
</target>
|
||||||
|
<target name="bcel-lib" unless="bcel.lib.exists">
|
||||||
|
<download zipname="/bcel-5.2"/>
|
||||||
|
</target>
|
||||||
|
<target name="javacc-lib" unless="javacc.lib.exists">
|
||||||
|
<download zipname="javacc-5.0"/>
|
||||||
|
</target>
|
||||||
|
<target name="proguard-lib" unless="proguard.lib.exists">
|
||||||
|
<download zipname="proguard4.6"/>
|
||||||
|
</target>
|
||||||
|
<target name="antenna-lib" unless="antenna.lib.exists">
|
||||||
|
<download zipname="antenna-bin-1.2.0-beta"/>
|
||||||
|
</target>
|
||||||
|
<target name="junit-lib" unless="junit.lib.exists">
|
||||||
|
<download zipname="junit-3.8.2"/>
|
||||||
|
</target>
|
||||||
|
<target name="cobertura-lib" unless="cobertura.lib.exists">
|
||||||
|
<download zipname="cobertura-1.9.4.1-bin"/>
|
||||||
|
</target>
|
||||||
|
<target name="microemulator-lib" unless="microemulator.lib.exists">
|
||||||
|
<download zipname="microemulator-2.0.4" jars="**/microemulator.jar"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="all-libs" depends="wtk-libs,bcel-lib,javacc-lib,proguard-lib,antenna-lib,junit-lib,cobertura-lib"/>
|
||||||
|
|
||||||
|
</project>
|
||||||
176
build-maven.xml
Normal file
176
build-maven.xml
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<project default="usage">
|
||||||
|
<!-- Ant file to deploy to maven once the distribution is released on sourceforge.
|
||||||
|
-->
|
||||||
|
<property file="version.properties"/>
|
||||||
|
|
||||||
|
<macrodef name="write_pom">
|
||||||
|
<attribute name="platform"/>
|
||||||
|
<attribute name="snapshot" default=""/>
|
||||||
|
<sequential>
|
||||||
|
<mkdir dir="build/maven-${version}"/>
|
||||||
|
<echo file="build/maven-${version}/luaj-@{platform}-${version}@{snapshot}.pom"><![CDATA[<project>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.luaj</groupId>
|
||||||
|
<artifactId>luaj-]]>@{platform}<![CDATA[</artifactId>
|
||||||
|
<version>]]>${version}@{snapshot}<![CDATA[</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>luaj-]]>@{platform}<![CDATA[</name>
|
||||||
|
<description>Luaj ]]>${version}<![CDATA[ for the ]]>@{platform}<![CDATA[ platform</description>
|
||||||
|
<url>http://sourceforge.net/projects/luaj/</url>
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>MIT License</name>
|
||||||
|
<url>http://luaj.sourceforge.net/license.txt</url>
|
||||||
|
<distribution>repo</distribution>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<id>jrosebor</id>
|
||||||
|
<name>James Roseborough</name>
|
||||||
|
<email>jim.roseborough@luaj.org</email>
|
||||||
|
<timezone>-8</timezone>
|
||||||
|
<roles></roles>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<id>ifarmer</id>
|
||||||
|
<name>Ian Farmer</name>
|
||||||
|
<email>ian.farmer@luaj.org</email>
|
||||||
|
<timezone>-8</timezone>
|
||||||
|
<roles></roles>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
<scm>
|
||||||
|
<url>http://luaj.cvs.sourceforge.net/viewvc/luaj/luaj-vm/</url>
|
||||||
|
</scm>
|
||||||
|
</project>
|
||||||
|
]]></echo>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<macrodef name="prepare_files">
|
||||||
|
<attribute name="platform"/>
|
||||||
|
<attribute name="snapshot" default=""/>
|
||||||
|
<sequential>
|
||||||
|
<mkdir dir="build/maven-${version}"/>
|
||||||
|
<write_pom platform="@{platform}" snapshot="@{snapshot}"/>
|
||||||
|
<copy file="luaj-${version}.zip" todir="build/maven-${version}"/>
|
||||||
|
<unzip src="build/maven-${version}/luaj-${version}.zip" dest="build/maven-${version}"/>
|
||||||
|
<copy file="build/maven-${version}/luaj-${version}/lib/luaj-@{platform}-${version}.jar" todir="build/maven-${version}"/>
|
||||||
|
|
||||||
|
<!-- make a -sources file -->
|
||||||
|
<mkdir dir="build/maven-${version}/sources-@{platform}"/>
|
||||||
|
<copy todir="build/maven-${version}/sources-@{platform}">
|
||||||
|
<fileset dir="build/maven-${version}/luaj-${version}/src/core"/>
|
||||||
|
<fileset dir="build/maven-${version}/luaj-${version}/src/@{platform}"/>
|
||||||
|
<filterchain>
|
||||||
|
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-@{platform} ${version}"'/></tokenfilter>
|
||||||
|
</filterchain>
|
||||||
|
</copy>
|
||||||
|
<zip destfile="build/maven-${version}/luaj-@{platform}-${version}-sources.jar"
|
||||||
|
basedir="build/maven-${version}/sources-@{platform}"/>
|
||||||
|
|
||||||
|
<!-- make a -javadoc file -->
|
||||||
|
<mkdir dir="build/maven-${version}/javadoc-@{platform}"/>
|
||||||
|
<javadoc defaultexcludes="yes"
|
||||||
|
destdir="build/maven-${version}/javadoc-@{platform}"
|
||||||
|
author="true"
|
||||||
|
version="true"
|
||||||
|
use="true"
|
||||||
|
windowtitle="Luaj API">
|
||||||
|
<fileset dir="build/maven-${version}/sources-@{platform}">
|
||||||
|
<include name="org/luaj/vm/*.java"/>
|
||||||
|
<include name="org/luaj/vm2/*.java"/>
|
||||||
|
<include name="org/luaj/vm2/server/*.java"/>
|
||||||
|
<include name="**/LuaC.java"/>
|
||||||
|
<include name="**/LuaJC.java"/>
|
||||||
|
<include name="**/lib/*/*.java"/>
|
||||||
|
</fileset>
|
||||||
|
<doctitle><![CDATA[<h1>Luaj API</h1>]]></doctitle>
|
||||||
|
<bottom><![CDATA[<i>Copyright © 2007-2015 Luaj.org. All Rights Reserved.</i>]]></bottom>
|
||||||
|
<tag name="todo" scope="all" description="To do:"/>
|
||||||
|
<link offline="true" href="http://sourceforge.net/projects/luaj/" packagelistLoc="C:\tmp"/>
|
||||||
|
<link href="http://sourceforge.net/projects/luaj/"/>
|
||||||
|
</javadoc>
|
||||||
|
<zip destfile="build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"
|
||||||
|
basedir="build/maven-${version}/javadoc-@{platform}"/>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<macrodef name="shapshot_files">
|
||||||
|
<attribute name="platform"/>
|
||||||
|
<sequential>
|
||||||
|
<exec executable="mvn">
|
||||||
|
<arg value="deploy:deploy-file"/>
|
||||||
|
<arg value="-Durl=https://oss.sonatype.org/content/repositories/snapshots"/>
|
||||||
|
<arg value="-DrepositoryId=nexus-releases"/>
|
||||||
|
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}-SNAPSHOT.pom"/>
|
||||||
|
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
|
||||||
|
<arg value="-Dsources=build/maven-${version}/luaj-@{platform}-${version}-sources.jar"/>
|
||||||
|
<arg value="-Djavadoc=build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"/>
|
||||||
|
</exec>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<macrodef name="sign_and_deploy">
|
||||||
|
<attribute name="platform"/>
|
||||||
|
<sequential>
|
||||||
|
<exec executable="mvn">
|
||||||
|
<arg value="gpg:sign-and-deploy-file"/>
|
||||||
|
<arg value="-Durl=http://oss.sonatype.org/service/local/staging/deploy/maven2"/>
|
||||||
|
<arg value="-DrepositoryId=nexus-releases"/>
|
||||||
|
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}.pom"/>
|
||||||
|
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
|
||||||
|
<arg value="-Dsources=build/maven-${version}/luaj-@{platform}-${version}-sources.jar"/>
|
||||||
|
<arg value="-Djavadoc=build/maven-${version}/luaj-@{platform}-${version}-javadoc.jar"/>
|
||||||
|
</exec>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<macrodef name="prepare_and_install">
|
||||||
|
<attribute name="platform"/>
|
||||||
|
<sequential>
|
||||||
|
<prepare_files platform="@{platform}"/>
|
||||||
|
<exec executable="mvn">
|
||||||
|
<arg value="install:install-file"/>
|
||||||
|
<arg value="-Dfile=build/maven-${version}/luaj-@{platform}-${version}.jar"/>
|
||||||
|
<arg value="-DpomFile=build/maven-${version}/luaj-@{platform}-${version}.pom"/>
|
||||||
|
</exec>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<macrodef name="prepare_and_snapshot">
|
||||||
|
<attribute name="platform"/>
|
||||||
|
<sequential>
|
||||||
|
<prepare_files platform="@{platform}" snapshot="-SNAPSHOT"/>
|
||||||
|
<shapshot_files platform="@{platform}"/>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<macrodef name="prepare_and_deploy">
|
||||||
|
<attribute name="platform"/>
|
||||||
|
<sequential>
|
||||||
|
<prepare_files platform="@{platform}"/>
|
||||||
|
<sign_and_deploy platform="@{platform}"/>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<target name="install">
|
||||||
|
<prepare_and_install platform="jse"/>
|
||||||
|
<prepare_and_install platform="jme"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="snapshot">
|
||||||
|
<prepare_and_snapshot platform="jse"/>
|
||||||
|
<prepare_and_snapshot platform="jme"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="deploy">
|
||||||
|
<prepare_and_deploy platform="jse"/>
|
||||||
|
<prepare_and_deploy platform="jme"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="usage">
|
||||||
|
<echo level="info">Usage: ant [-Dversion=${version}] -f build-maven.xml [install | shapshot | deploy]</echo>
|
||||||
|
</target>
|
||||||
|
</project>
|
||||||
113
build-midlet.xml
Normal file
113
build-midlet.xml
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<project name="sample" default="all" basedir=".">
|
||||||
|
<property file="version.properties"/>
|
||||||
|
|
||||||
|
<!-- find libs -->
|
||||||
|
<import file="build-libs.xml"/>
|
||||||
|
|
||||||
|
<!-- main script -->
|
||||||
|
<property name="script.name" value="hello"/>
|
||||||
|
<property name="script.dir" value="examples/lua"/>
|
||||||
|
|
||||||
|
<target name="clean">
|
||||||
|
<delete failonerror="false" dir="build"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="dirs">
|
||||||
|
<mkdir dir="build"/>
|
||||||
|
<mkdir dir="build/tool"/>
|
||||||
|
<mkdir dir="build/classes"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="tools" depends="dirs,bcel-lib,wtk-libs,microemulator-lib">
|
||||||
|
<javac destdir="build/tool" classpath="lib/bcel-5.2.jar">
|
||||||
|
<src path="src/core"/>
|
||||||
|
<src path="src/jse"/>
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- compile script into lua bytecode -->
|
||||||
|
<target name="luac" depends="tools">
|
||||||
|
<java classname="luac" classpath="build/tool">
|
||||||
|
<arg line="-o build/classes/${script.name}.lua"/>
|
||||||
|
<arg line="${script.dir}/${script.name}.lua"/>
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- compile script into java bytecode -->
|
||||||
|
<target name="luajc" depends="tools,wtk-libs">
|
||||||
|
<java classname="luajc" classpath="build/tool:lib/bcel-5.2.jar">
|
||||||
|
<arg line="-verbose"/>
|
||||||
|
<arg line="-srcdir ${script.dir}"/>
|
||||||
|
<arg line="-destdir build/classes"/>
|
||||||
|
<arg line="${script.name}.lua"/>
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="classes" depends="dirs,wtk-libs">
|
||||||
|
<mkdir dir="build/midlet/src"/>
|
||||||
|
<copy todir="build/midlet/src">
|
||||||
|
<fileset dir="src/core"/>
|
||||||
|
<fileset dir="src/jme"/>
|
||||||
|
<fileset dir="examples/jme"/>
|
||||||
|
<filterchain>
|
||||||
|
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jme ${version}"'/></tokenfilter>
|
||||||
|
</filterchain>
|
||||||
|
</copy>
|
||||||
|
<path id="wtk-libs">
|
||||||
|
<pathelement path="lib/cldcapi11.jar"/>
|
||||||
|
<pathelement path="lib/midpapi20.jar"/>
|
||||||
|
<pathelement path="lib/mmapi.jar"/>
|
||||||
|
</path>
|
||||||
|
<javac destdir="build/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
|
||||||
|
srcdir="build/midlet/src"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar" depends="luajc,classes">
|
||||||
|
<jar destfile="build/sample-plain.jar"
|
||||||
|
basedir="build/classes"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="obf" depends="jar,proguard-lib">
|
||||||
|
<taskdef resource="proguard/ant/task.properties" classpath="lib/proguard.jar" />
|
||||||
|
<proguard>
|
||||||
|
-injars build/sample-plain.jar
|
||||||
|
-outjars build/sample.jar
|
||||||
|
-libraryjars lib/midpapi20.jar
|
||||||
|
-libraryjars lib/cldcapi11.jar
|
||||||
|
-overloadaggressively
|
||||||
|
-repackageclasses ''
|
||||||
|
-microedition
|
||||||
|
|
||||||
|
-keep public class SampleMIDlet
|
||||||
|
-keep public class * extends org.luaj.vm2.LuaValue
|
||||||
|
</proguard>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jad" depends="obf">
|
||||||
|
<length file="build/sample.jar" property="sample.jar.length" />
|
||||||
|
<echo level="info">Jar file length is ${sample.jar.length}</echo>
|
||||||
|
<manifest file="build/sample.jad">
|
||||||
|
<attribute name="Built-By" value="luaj-${version}"/>
|
||||||
|
<attribute name="MIDlet-Name" value="Luaj ${script.name}"/>
|
||||||
|
<attribute name="MIDlet-Version" value="${version}"/>
|
||||||
|
<attribute name="MIDlet-Vendor" value="luaj.org"/>
|
||||||
|
<attribute name="MIDlet-Description" value="Luaj Sample Midlet"/>
|
||||||
|
<attribute name="MIDlet-1" value="${script.name}-${version}, , SampleMIDlet"/>
|
||||||
|
<attribute name="MIDlet-Jar-URL" value="sample.jar"/>
|
||||||
|
<attribute name="MIDlet-Jar-Size" value="${sample.jar.length}"/>
|
||||||
|
<attribute name="script" value="${script.name}"/>
|
||||||
|
</manifest>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="package" depends="jad,jar,obf"/>
|
||||||
|
|
||||||
|
<target name="run" depends="jad,jar,obf,microemulator-lib">
|
||||||
|
<java jar="lib/microemulator.jar" fork="true">
|
||||||
|
<arg path="build/sample.jad"/>
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="all" depends="clean,package,run"/>
|
||||||
|
|
||||||
|
</project>
|
||||||
68
build-perf.xml
Normal file
68
build-perf.xml
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<project default="all">
|
||||||
|
<import file="build.xml"/>
|
||||||
|
|
||||||
|
<property name="lua.command" value="lua"/>
|
||||||
|
<available file="luaj-jse-${version}.jar" property="luaj.lib.exists"/>
|
||||||
|
<available file="lib/jill-1.0.1.jar" property="jill.lib.exists"/>
|
||||||
|
<available file="lib/kahlua.jar" property="kahlua.lib.exists"/>
|
||||||
|
<available file="lib/mochalua-1.0.jar" property="mochalua.lib.exists"/>
|
||||||
|
|
||||||
|
<target name="luaj-lib" unless="luaj.lib.exists">
|
||||||
|
<antcall target="jar-jse"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jill-lib" unless="jill.lib.exists">
|
||||||
|
<mkdir dir="lib"/>
|
||||||
|
<get src="http://jillcode.googlecode.com/files/jill-1.0.1.zip"
|
||||||
|
dest="lib/jill-1.0.1.zip"/>
|
||||||
|
<unzip src="lib/jill-1.0.1.zip" dest="lib" overwrite="true"/>
|
||||||
|
<ant dir="lib/jill-1.0.1" target="compile"/>
|
||||||
|
<jar destfile="lib/jill-1.0.1.jar" basedir="lib/jill-1.0.1/compiled"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="kahlua-lib" unless="kahlua.lib.exists">
|
||||||
|
<get src="http://kahlua.googlecode.com/files/kahlua.jar"
|
||||||
|
dest="lib/kahlua.jar"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="mochalua-lib" unless="mochalua.lib.exists">
|
||||||
|
<get src="http://mochalua.googlecode.com/files/Mochalua%201.0.jar"
|
||||||
|
dest="lib/mochalua-1.0.jar"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="perf-libs" depends="luaj-lib,bcel-lib,jill-lib,kahlua-lib,mochalua-lib"/>
|
||||||
|
|
||||||
|
<macrodef name="perftest">
|
||||||
|
<attribute name="program" default="lua"/>
|
||||||
|
<attribute name="luaprog" default="fannkuch.lua 10"/>
|
||||||
|
<attribute name="basedir" default="test/lua/perf/"/>
|
||||||
|
<sequential>
|
||||||
|
<echo level="info">------ @{program} @{luaprog}</echo>
|
||||||
|
<exec executable="bash">
|
||||||
|
<arg value="-c"/>
|
||||||
|
<arg value="time @{program} @{basedir}@{luaprog}"/>
|
||||||
|
</exec>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
|
||||||
|
<macrodef name="testcase">
|
||||||
|
<attribute name="luaprog" default="fannkuch.lua 10"/>
|
||||||
|
<sequential>
|
||||||
|
<echo level="info">=========== @{luaprog} =============</echo>
|
||||||
|
<perftest program="java -version" luaprog="" basedir=""/>
|
||||||
|
<perftest program="${lua.command}" luaprog="@{luaprog}"/>
|
||||||
|
<perftest program="java -cp luaj-jse-${version}.jar lua -n" luaprog="@{luaprog}"/>
|
||||||
|
<perftest program="java -cp luaj-jse-${version}.jar${path.separator}lib/bcel-5.2.jar lua -b" luaprog="@{luaprog}"/>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<target name="alltests">
|
||||||
|
<testcase luaprog="binarytrees.lua 15"/>
|
||||||
|
<testcase luaprog="fannkuch.lua 10"/>
|
||||||
|
<testcase luaprog="nbody.lua 1000000"/>
|
||||||
|
<testcase luaprog="nsieve.lua 9"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="all" depends="alltests"/>
|
||||||
|
</project>
|
||||||
208
build.xml
Normal file
208
build.xml
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
<project default="all">
|
||||||
|
<property file="version.properties"/>
|
||||||
|
|
||||||
|
<property name="jar.name.jme" value="luaj-jme-${version}.jar"/>
|
||||||
|
<property name="jar.name.jse" value="luaj-jse-${version}.jar"/>
|
||||||
|
<property name="jar.name.sources" value="luaj-sources-${version}.jar"/>
|
||||||
|
|
||||||
|
<target name="clean-build">
|
||||||
|
<delete dir="build"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="clean" depends="clean-build">
|
||||||
|
<delete>
|
||||||
|
<fileset dir="." includes="luaj-*.jar"/>
|
||||||
|
</delete>
|
||||||
|
<delete dir="examples/android/bin"/>
|
||||||
|
<delete dir="examples/android/build"/>
|
||||||
|
<delete dir="examples/android/gen"/>
|
||||||
|
<delete dir="examples/android/libs"/>
|
||||||
|
<delete dir="examples/maven/target"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<import file="build-libs.xml"/>
|
||||||
|
|
||||||
|
<target name="parser" depends="javacc-lib">
|
||||||
|
<java classname="javacc" classpath="lib/javacc.jar">
|
||||||
|
<arg line="grammar/LuaParser.jj"/>
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="plain-parser" depends="javacc-lib">
|
||||||
|
<java dir="src/jse" fork="true" classname="javacc" classpath="lib/javacc.jar">
|
||||||
|
<arg line="../../grammar/Lua52.jj"/>
|
||||||
|
</java>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="compile" depends="wtk-libs,bcel-lib">
|
||||||
|
<delete dir="build/jme/src"/>
|
||||||
|
<delete dir="build/jse/src"/>
|
||||||
|
<mkdir dir="build/jme/src"/>
|
||||||
|
<mkdir dir="build/jse/src"/>
|
||||||
|
<mkdir dir="build/jme/classes"/>
|
||||||
|
<mkdir dir="build/jse/classes"/>
|
||||||
|
<copy todir="build/jme/src">
|
||||||
|
<fileset dir="src/core"/>
|
||||||
|
<fileset dir="src/jme"/>
|
||||||
|
<filterchain>
|
||||||
|
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jme ${version}"'/></tokenfilter>
|
||||||
|
</filterchain>
|
||||||
|
</copy>
|
||||||
|
<copy todir="build/jse/src">
|
||||||
|
<fileset dir="src/core"/>
|
||||||
|
<filterchain>
|
||||||
|
<tokenfilter><replacestring from='"Luaj 0.0"' to='"Luaj-jse ${version}"'/></tokenfilter>
|
||||||
|
</filterchain>
|
||||||
|
</copy>
|
||||||
|
<copy todir="build/jse/src">
|
||||||
|
<fileset dir="src/jse"/>
|
||||||
|
<filterchain>
|
||||||
|
<tokenfilter><replacestring from='<String>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Stat>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Exp>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Name>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Block>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<TableField>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<VarExp>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Exp.VarExp>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Object,String>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Double,String>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Integer,Integer>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Integer,LocalVariableGen>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<Exp,Integer>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<String,byte[]>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<String,Variable>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<LuaValue,String>' to=''/></tokenfilter>
|
||||||
|
<tokenfilter><replacestring from='<LuaString,String>' to=''/></tokenfilter>
|
||||||
|
</filterchain>
|
||||||
|
</copy>
|
||||||
|
<path id="wtk-libs">
|
||||||
|
<pathelement path="lib/cldcapi11.jar"/>
|
||||||
|
<pathelement path="lib/midpapi20.jar"/>
|
||||||
|
<pathelement path="lib/mmapi.jar"/>
|
||||||
|
</path>
|
||||||
|
<javac destdir="build/jme/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
|
||||||
|
srcdir="build/jme/src"/>
|
||||||
|
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
|
||||||
|
classpath="lib/bcel-5.2.jar"
|
||||||
|
srcdir="build/jse/src"
|
||||||
|
excludes="**/script/*,**/Lua2Java*,**/server/*,lua*"/>
|
||||||
|
<javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
|
||||||
|
classpath="build/jse/classes"
|
||||||
|
srcdir="build/jse/src"
|
||||||
|
includes="**/script/*,**/Lua2Java*,**/server/*"/>
|
||||||
|
<javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
|
||||||
|
classpath="build/jse/classes"
|
||||||
|
srcdir="build/jse/src"
|
||||||
|
includes="lua*"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar-jme" depends="compile">
|
||||||
|
<jar destfile="${jar.name.jme}" basedir="build/jme/classes"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar-jse" depends="compile">
|
||||||
|
<jar destfile="${jar.name.jse}">
|
||||||
|
<fileset dir="build/jse/classes"/>
|
||||||
|
<fileset dir="src/jse/">
|
||||||
|
<include name="META-INF/services/**"/>
|
||||||
|
</fileset>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="jar-jse-sources" depends="compile">
|
||||||
|
<jar destfile="${jar.name.sources}">
|
||||||
|
<fileset dir="build/jme/src"/>
|
||||||
|
<fileset dir="build/jse/src"/>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="doc">
|
||||||
|
<delete dir="docs/api"/>
|
||||||
|
<mkdir dir="docs/api"/>
|
||||||
|
<javadoc defaultexcludes="yes"
|
||||||
|
destdir="docs/api"
|
||||||
|
author="true"
|
||||||
|
version="true"
|
||||||
|
use="true"
|
||||||
|
windowtitle="Luaj API">
|
||||||
|
<fileset dir="src/core" defaultexcludes="yes" includes="org/luaj/vm2/*.java,org/luaj/vm2/compiler/LuaC.java,org/luaj/vm2/lib/*.java"/>
|
||||||
|
<fileset dir="src/jse" defaultexcludes="yes" includes="org/luaj/vm2/lib/jse/*.java,org/luaj/vm2/luajc/LuaJC.java,org/luaj/vm2/server/*.java"/>
|
||||||
|
<fileset dir="src/jme" defaultexcludes="yes" includes="org/luaj/vm2/lib/jme/*.java"/>
|
||||||
|
<doctitle><![CDATA[<h1>Luaj API</h1>]]></doctitle>
|
||||||
|
<bottom><![CDATA[<i>Copyright © 2007-2015 Luaj.org. All Rights Reserved.</i>]]></bottom>
|
||||||
|
<tag name="todo" scope="all" description="To do:"/>
|
||||||
|
<group title="Core VM" packages="org.luaj.vm.*"/>
|
||||||
|
<link offline="true" href="http://sourceforge.net/projects/luaj/" packagelistLoc="C:\tmp"/>
|
||||||
|
<link href="http://sourceforge.net/projects/luaj/"/>
|
||||||
|
</javadoc>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="dist" depends="all,doc">
|
||||||
|
<delete dir="build/luaj-${version}"/>
|
||||||
|
<mkdir dir="build/luaj-${version}/src"/>
|
||||||
|
<mkdir dir="build/luaj-${version}/lib"/>
|
||||||
|
<copy todir="build/luaj-${version}/src">
|
||||||
|
<fileset dir="src">
|
||||||
|
<exclude name="src/test/**"/>
|
||||||
|
<exclude name="**/antlr/**"/>
|
||||||
|
<exclude name="**/lst/**"/>
|
||||||
|
<exclude name="**/JavaCodeGenerator.java"/>
|
||||||
|
<exclude name="**/LuaJCompiler.java"/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<copy todir="build/luaj-${version}/test">
|
||||||
|
<fileset dir="test"/>
|
||||||
|
</copy>
|
||||||
|
<copy todir="build/luaj-${version}/examples">
|
||||||
|
<fileset dir="examples">
|
||||||
|
<include name="android/*.*"/>
|
||||||
|
<include name="android/assets/**"/>
|
||||||
|
<include name="android/res/**"/>
|
||||||
|
<include name="android/src/**"/>
|
||||||
|
<include name="jme/*.java"/>
|
||||||
|
<include name="jse/*.java"/>
|
||||||
|
<include name="lua/*.*"/>
|
||||||
|
<include name="maven/pom.xml"/>
|
||||||
|
<include name="maven/src/**"/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<copy todir="build/luaj-${version}/lib">
|
||||||
|
<fileset dir=".">
|
||||||
|
<include name="*-${version}.jar"/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<copy todir="build/luaj-${version}">
|
||||||
|
<fileset dir=".">
|
||||||
|
<include name="build.xml"/>
|
||||||
|
<include name="build-libs.xml"/>
|
||||||
|
<include name="build-coverage.xml"/>
|
||||||
|
<include name="version.properties"/>
|
||||||
|
<include name="wtk.xml"/>
|
||||||
|
<include name="README.html"/>
|
||||||
|
<include name="names.csv"/>
|
||||||
|
<include name=".classpath"/>
|
||||||
|
<include name=".project"/>
|
||||||
|
</fileset>
|
||||||
|
</copy>
|
||||||
|
<copy todir="build/luaj-${version}/docs">
|
||||||
|
<fileset dir="docs"/>
|
||||||
|
</copy>
|
||||||
|
<zip destfile="luaj-${version}.zip"
|
||||||
|
basedir="build" includes="luaj-${version}/**"/>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="mvn_install" depends="jar-jse">
|
||||||
|
<exec executable="mvn">
|
||||||
|
<arg value="install:install-file"/>
|
||||||
|
<arg value="-Dfile=${jar.name.jse}"/>
|
||||||
|
<arg value="-DgroupId=org.luaj"/>
|
||||||
|
<arg value="-DartifactId=luaj-jse"/>
|
||||||
|
<arg value="-Dversion=${version}"/>
|
||||||
|
<arg value="-Dpackaging=jar"/>
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<target name="all" depends="clean,jar-jme,jar-jse,jar-jse-sources"/>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -11,13 +11,13 @@ import org.luaj.vm2.lib.Bit32Lib;
|
|||||||
import org.luaj.vm2.lib.CoroutineLib;
|
import org.luaj.vm2.lib.CoroutineLib;
|
||||||
import org.luaj.vm2.lib.PackageLib;
|
import org.luaj.vm2.lib.PackageLib;
|
||||||
import org.luaj.vm2.lib.ResourceFinder;
|
import org.luaj.vm2.lib.ResourceFinder;
|
||||||
|
import org.luaj.vm2.lib.StringLib;
|
||||||
import org.luaj.vm2.lib.TableLib;
|
import org.luaj.vm2.lib.TableLib;
|
||||||
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
|
||||||
import org.luaj.vm2.lib.jse.JseBaseLib;
|
import org.luaj.vm2.lib.jse.JseBaseLib;
|
||||||
import org.luaj.vm2.lib.jse.JseIoLib;
|
import org.luaj.vm2.lib.jse.JseIoLib;
|
||||||
import org.luaj.vm2.lib.jse.JseMathLib;
|
import org.luaj.vm2.lib.jse.JseMathLib;
|
||||||
import org.luaj.vm2.lib.jse.JseOsLib;
|
import org.luaj.vm2.lib.jse.JseOsLib;
|
||||||
import org.luaj.vm2.lib.jse.JseStringLib;
|
|
||||||
import org.luaj.vm2.lib.jse.LuajavaLib;
|
import org.luaj.vm2.lib.jse.LuajavaLib;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +76,7 @@ public class SampleApplet extends Applet implements ResourceFinder {
|
|||||||
globals.load(new PackageLib());
|
globals.load(new PackageLib());
|
||||||
globals.load(new Bit32Lib());
|
globals.load(new Bit32Lib());
|
||||||
globals.load(new TableLib());
|
globals.load(new TableLib());
|
||||||
globals.load(new JseStringLib());
|
globals.load(new StringLib());
|
||||||
globals.load(new CoroutineLib());
|
globals.load(new CoroutineLib());
|
||||||
globals.load(new JseMathLib());
|
globals.load(new JseMathLib());
|
||||||
globals.load(new JseIoLib());
|
globals.load(new JseIoLib());
|
||||||
|
|||||||
@@ -1,26 +1,12 @@
|
|||||||
import org.luaj.vm2.Globals;
|
import org.luaj.vm2.*;
|
||||||
import org.luaj.vm2.LoadState;
|
|
||||||
import org.luaj.vm2.LuaBoolean;
|
|
||||||
import org.luaj.vm2.LuaString;
|
|
||||||
import org.luaj.vm2.LuaTable;
|
|
||||||
import org.luaj.vm2.LuaThread;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Varargs;
|
|
||||||
import org.luaj.vm2.compiler.LuaC;
|
import org.luaj.vm2.compiler.LuaC;
|
||||||
import org.luaj.vm2.lib.Bit32Lib;
|
import org.luaj.vm2.lib.*;
|
||||||
import org.luaj.vm2.lib.DebugLib;
|
import org.luaj.vm2.lib.jse.*;
|
||||||
import org.luaj.vm2.lib.PackageLib;
|
|
||||||
import org.luaj.vm2.lib.TableLib;
|
|
||||||
import org.luaj.vm2.lib.TwoArgFunction;
|
|
||||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
|
||||||
import org.luaj.vm2.lib.jse.JseBaseLib;
|
|
||||||
import org.luaj.vm2.lib.jse.JseMathLib;
|
|
||||||
import org.luaj.vm2.lib.jse.JseStringLib;
|
|
||||||
|
|
||||||
/** Simple program that illustrates basic sand-boxing of client scripts
|
/** Simple program that illustrates basic sand-boxing of client scripts
|
||||||
* in a server environment.
|
* in a server environment.
|
||||||
*
|
*
|
||||||
* <p>Although this sandboxing is done primarily in Java here, these
|
* <p>Although this sandboxing is done primarily in Java here, these
|
||||||
* same techniques should all be possible directly from lua using metatables,
|
* same techniques should all be possible directly from lua using metatables,
|
||||||
* and examples are shown in examples/lua/samplesandboxed.lua.
|
* and examples are shown in examples/lua/samplesandboxed.lua.
|
||||||
*
|
*
|
||||||
@@ -43,7 +29,7 @@ public class SampleSandboxed {
|
|||||||
server_globals = new Globals();
|
server_globals = new Globals();
|
||||||
server_globals.load(new JseBaseLib());
|
server_globals.load(new JseBaseLib());
|
||||||
server_globals.load(new PackageLib());
|
server_globals.load(new PackageLib());
|
||||||
server_globals.load(new JseStringLib());
|
server_globals.load(new StringLib());
|
||||||
|
|
||||||
// To load scripts, we occasionally need a math library in addition to compiler support.
|
// To load scripts, we occasionally need a math library in addition to compiler support.
|
||||||
// To limit scripts using the debug library, they must be closures, so we only install LuaC.
|
// To limit scripts using the debug library, they must be closures, so we only install LuaC.
|
||||||
@@ -61,7 +47,7 @@ public class SampleSandboxed {
|
|||||||
runScriptInSandbox( "return getmetatable('abc').len" );
|
runScriptInSandbox( "return getmetatable('abc').len" );
|
||||||
runScriptInSandbox( "return getmetatable('abc').__index" );
|
runScriptInSandbox( "return getmetatable('abc').__index" );
|
||||||
|
|
||||||
// Example user scripts that attempt rogue operations, and will fail.
|
// Example user scripts that attempt rogue operations, and will fail.
|
||||||
runScriptInSandbox( "return setmetatable('abc', {})" );
|
runScriptInSandbox( "return setmetatable('abc', {})" );
|
||||||
runScriptInSandbox( "getmetatable('abc').len = function() end" );
|
runScriptInSandbox( "getmetatable('abc').len = function() end" );
|
||||||
runScriptInSandbox( "getmetatable('abc').__index = {}" );
|
runScriptInSandbox( "getmetatable('abc').__index = {}" );
|
||||||
@@ -75,9 +61,9 @@ public class SampleSandboxed {
|
|||||||
LuaValue.ADD, new TwoArgFunction() {
|
LuaValue.ADD, new TwoArgFunction() {
|
||||||
public LuaValue call(LuaValue x, LuaValue y) {
|
public LuaValue call(LuaValue x, LuaValue y) {
|
||||||
return LuaValue.valueOf(
|
return LuaValue.valueOf(
|
||||||
(x == TRUE ? 1.0 : x.todouble()) +
|
(x == TRUE ? 1.0 : x.todouble()) +
|
||||||
(y == TRUE ? 1.0 : y.todouble()) );
|
(y == TRUE ? 1.0 : y.todouble()) );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
runScriptInSandbox( "return 5 + 6, 5 + true, false + 6" );
|
runScriptInSandbox( "return 5 + 6, 5 + true, false + 6" );
|
||||||
@@ -89,21 +75,21 @@ public class SampleSandboxed {
|
|||||||
// that contain functions that can be abused.
|
// that contain functions that can be abused.
|
||||||
static void runScriptInSandbox(String script) {
|
static void runScriptInSandbox(String script) {
|
||||||
|
|
||||||
// Each script will have it's own set of globals, which should
|
// Each script will have it's own set of globals, which should
|
||||||
// prevent leakage between scripts running on the same server.
|
// prevent leakage between scripts running on the same server.
|
||||||
Globals user_globals = new Globals();
|
Globals user_globals = new Globals();
|
||||||
user_globals.load(new JseBaseLib());
|
user_globals.load(new JseBaseLib());
|
||||||
user_globals.load(new PackageLib());
|
user_globals.load(new PackageLib());
|
||||||
user_globals.load(new Bit32Lib());
|
user_globals.load(new Bit32Lib());
|
||||||
user_globals.load(new TableLib());
|
user_globals.load(new TableLib());
|
||||||
user_globals.load(new JseStringLib());
|
user_globals.load(new StringLib());
|
||||||
user_globals.load(new JseMathLib());
|
user_globals.load(new JseMathLib());
|
||||||
|
|
||||||
// This library is dangerous as it gives unfettered access to the
|
// This library is dangerous as it gives unfettered access to the
|
||||||
// entire Java VM, so it's not suitable within this lightweight sandbox.
|
// entire Java VM, so it's not suitable within this lightweight sandbox.
|
||||||
// user_globals.load(new LuajavaLib());
|
// user_globals.load(new LuajavaLib());
|
||||||
|
|
||||||
// Starting coroutines in scripts will result in threads that are
|
// Starting coroutines in scripts will result in threads that are
|
||||||
// not under the server control, so this libary should probably remain out.
|
// not under the server control, so this libary should probably remain out.
|
||||||
// user_globals.load(new CoroutineLib());
|
// user_globals.load(new CoroutineLib());
|
||||||
|
|
||||||
@@ -112,12 +98,12 @@ public class SampleSandboxed {
|
|||||||
// user_globals.load(new JseIoLib());
|
// user_globals.load(new JseIoLib());
|
||||||
// user_globals.load(new JseOsLib());
|
// user_globals.load(new JseOsLib());
|
||||||
|
|
||||||
// Loading and compiling scripts from within scripts may also be
|
// Loading and compiling scripts from within scripts may also be
|
||||||
// prohibited, though in theory it should be fairly safe.
|
// prohibited, though in theory it should be fairly safe.
|
||||||
// LoadState.install(user_globals);
|
// LoadState.install(user_globals);
|
||||||
// LuaC.install(user_globals);
|
// LuaC.install(user_globals);
|
||||||
|
|
||||||
// The debug library must be loaded for hook functions to work, which
|
// The debug library must be loaded for hook functions to work, which
|
||||||
// allow us to limit scripts to run a certain number of instructions at a time.
|
// allow us to limit scripts to run a certain number of instructions at a time.
|
||||||
// However we don't wish to expose the library in the user globals,
|
// However we don't wish to expose the library in the user globals,
|
||||||
// so it is immediately removed from the user globals once created.
|
// so it is immediately removed from the user globals once created.
|
||||||
@@ -125,18 +111,18 @@ public class SampleSandboxed {
|
|||||||
LuaValue sethook = user_globals.get("debug").get("sethook");
|
LuaValue sethook = user_globals.get("debug").get("sethook");
|
||||||
user_globals.set("debug", LuaValue.NIL);
|
user_globals.set("debug", LuaValue.NIL);
|
||||||
|
|
||||||
// Set up the script to run in its own lua thread, which allows us
|
// Set up the script to run in its own lua thread, which allows us
|
||||||
// to set a hook function that limits the script to a specific number of cycles.
|
// to set a hook function that limits the script to a specific number of cycles.
|
||||||
// Note that the environment is set to the user globals, even though the
|
// Note that the environment is set to the user globals, even though the
|
||||||
// compiling is done with the server globals.
|
// compiling is done with the server globals.
|
||||||
LuaValue chunk = server_globals.load(script, "main", user_globals);
|
LuaValue chunk = server_globals.load(script, "main", user_globals);
|
||||||
LuaThread thread = new LuaThread(user_globals, chunk);
|
LuaThread thread = new LuaThread(user_globals, chunk);
|
||||||
|
|
||||||
// Set the hook function to immediately throw an Error, which will not be
|
// Set the hook function to immediately throw an Error, which will not be
|
||||||
// handled by any Lua code other than the coroutine.
|
// handled by any Lua code other than the coroutine.
|
||||||
LuaValue hookfunc = new ZeroArgFunction() {
|
LuaValue hookfunc = new ZeroArgFunction() {
|
||||||
public LuaValue call() {
|
public LuaValue call() {
|
||||||
// A simple lua error may be caught by the script, but a
|
// A simple lua error may be caught by the script, but a
|
||||||
// Java Error will pass through to top and stop the script.
|
// Java Error will pass through to top and stop the script.
|
||||||
throw new Error("Script overran resource limits.");
|
throw new Error("Script overran resource limits.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ options {
|
|||||||
DEBUG_LOOKAHEAD = false;
|
DEBUG_LOOKAHEAD = false;
|
||||||
DEBUG_PARSER = false;
|
DEBUG_PARSER = false;
|
||||||
DEBUG_TOKEN_MANAGER = false;
|
DEBUG_TOKEN_MANAGER = false;
|
||||||
OUTPUT_DIRECTORY = "org/luaj/vm2/parser/lua51";
|
OUTPUT_DIRECTORY = "org/luaj/vm2/parser";
|
||||||
}
|
}
|
||||||
|
|
||||||
PARSER_BEGIN(LuaParser)
|
PARSER_BEGIN(LuaParser)
|
||||||
package org.luaj.vm2.parser.lua51;
|
package org.luaj.vm2.parser;
|
||||||
|
|
||||||
public class LuaParser {
|
public class LuaParser {
|
||||||
|
|
||||||
@@ -20,11 +20,11 @@ options {
|
|||||||
DEBUG_LOOKAHEAD = false;
|
DEBUG_LOOKAHEAD = false;
|
||||||
DEBUG_PARSER = false;
|
DEBUG_PARSER = false;
|
||||||
DEBUG_TOKEN_MANAGER = false;
|
DEBUG_TOKEN_MANAGER = false;
|
||||||
OUTPUT_DIRECTORY = "org/luaj/vm2/parser/lua52";
|
OUTPUT_DIRECTORY = "org/luaj/vm2/parser";
|
||||||
}
|
}
|
||||||
|
|
||||||
PARSER_BEGIN(LuaParser)
|
PARSER_BEGIN(LuaParser)
|
||||||
package org.luaj.vm2.parser.lua52;
|
package org.luaj.vm2.parser;
|
||||||
|
|
||||||
public class LuaParser {
|
public class LuaParser {
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-parent</artifactId>
|
|
||||||
<version>3.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>luaj-core</artifactId>
|
|
||||||
|
|
||||||
<name>luaj-core</name>
|
|
||||||
<description>Core code for LuaJ</description>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@@ -1,486 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to undump compiled lua bytecode into a {@link Prototype} instances.
|
|
||||||
* <p>
|
|
||||||
* The {@link LoadState} class provides the default {@link Globals.Undumper}
|
|
||||||
* which is used to undump a string of bytes that represent a lua binary file
|
|
||||||
* using either the C-based lua compiler, or luaj's
|
|
||||||
* {@link org.luaj.vm2.compiler.LuaC} compiler.
|
|
||||||
* <p>
|
|
||||||
* The canonical method to load and execute code is done indirectly using the
|
|
||||||
* Globals:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
|
||||||
* LuaValue chunk = globasl.load("print('hello, world')", "main.lua");
|
|
||||||
* chunk.call();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* This should work regardless of which {@link Globals.Compiler} or
|
|
||||||
* {@link Globals.Undumper} have been installed.
|
|
||||||
* <p>
|
|
||||||
* By default, when using {@link org.luaj.vm2.lib.jse.JsePlatform} or
|
|
||||||
* {@link org.luaj.vm2.lib.jme.JmePlatform} to construct globals, the
|
|
||||||
* {@link LoadState} default undumper is installed as the default
|
|
||||||
* {@link Globals.Undumper}.
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* A lua binary file is created via the {@link org.luaj.vm2.compiler.DumpState}
|
|
||||||
* class :
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
|
||||||
* Prototype p = globals.compilePrototype(new StringReader("print('hello, world')"), "main.lua");
|
|
||||||
* ByteArrayOutputStream o = new ByteArrayOutputStream();
|
|
||||||
* org.luaj.vm2.compiler.DumpState.dump(p, o, false);
|
|
||||||
* byte[] lua_binary_file_bytes = o.toByteArray();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* The {@link LoadState}'s default undumper {@link #instance} may be used
|
|
||||||
* directly to undump these bytes:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {@code
|
|
||||||
* Prototypep = LoadState.instance.undump(new ByteArrayInputStream(lua_binary_file_bytes), "main.lua");
|
|
||||||
* LuaClosure c = new LuaClosure(p, globals);
|
|
||||||
* c.call();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* More commonly, the {@link Globals.Undumper} may be used to undump them:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Prototype p = globals.loadPrototype(new ByteArrayInputStream(lua_binary_file_bytes), "main.lua", "b");
|
|
||||||
* LuaClosure c = new LuaClosure(p, globals);
|
|
||||||
* c.call();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @see Globals.Compiler
|
|
||||||
* @see Globals.Undumper
|
|
||||||
* @see LuaClosure
|
|
||||||
* @see LuaFunction
|
|
||||||
* @see org.luaj.vm2.compiler.LuaC
|
|
||||||
* @see org.luaj.vm2.luajc.LuaJC
|
|
||||||
* @see Globals#compiler
|
|
||||||
* @see Globals#load(InputStream, String, LuaValue)
|
|
||||||
*/
|
|
||||||
public class LoadState {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shared instance of Globals.Undumper to use loading prototypes from binary
|
|
||||||
* lua files
|
|
||||||
*/
|
|
||||||
public static final Globals.Undumper instance = new GlobalsUndumper();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* format corresponding to non-number-patched lua, all numbers are floats or
|
|
||||||
* doubles
|
|
||||||
*/
|
|
||||||
public static final int NUMBER_FORMAT_FLOATS_OR_DOUBLES = 0;
|
|
||||||
|
|
||||||
/** format corresponding to non-number-patched lua, all numbers are ints */
|
|
||||||
public static final int NUMBER_FORMAT_INTS_ONLY = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* format corresponding to number-patched lua, all numbers are 32-bit (4
|
|
||||||
* byte) ints
|
|
||||||
*/
|
|
||||||
public static final int NUMBER_FORMAT_NUM_PATCH_INT32 = 4;
|
|
||||||
|
|
||||||
// type constants
|
|
||||||
public static final int LUA_TINT = -2;
|
|
||||||
public static final int LUA_TNONE = -1;
|
|
||||||
public static final int LUA_TNIL = 0;
|
|
||||||
public static final int LUA_TBOOLEAN = 1;
|
|
||||||
public static final int LUA_TLIGHTUSERDATA = 2;
|
|
||||||
public static final int LUA_TNUMBER = 3;
|
|
||||||
public static final int LUA_TSTRING = 4;
|
|
||||||
public static final int LUA_TTABLE = 5;
|
|
||||||
public static final int LUA_TFUNCTION = 6;
|
|
||||||
public static final int LUA_TUSERDATA = 7;
|
|
||||||
public static final int LUA_TTHREAD = 8;
|
|
||||||
public static final int LUA_TVALUE = 9;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The character encoding to use for file encoding. Null means the default
|
|
||||||
* encoding
|
|
||||||
*/
|
|
||||||
public static String encoding = null;
|
|
||||||
|
|
||||||
/** Signature byte indicating the file is a compiled binary chunk */
|
|
||||||
public static final byte[] LUA_SIGNATURE = { '\033', 'L', 'u', 'a' };
|
|
||||||
|
|
||||||
/** Data to catch conversion errors */
|
|
||||||
public static final byte[] LUAC_TAIL = { (byte) 0x19, (byte) 0x93, '\r', '\n', (byte) 0x1a, '\n', };
|
|
||||||
|
|
||||||
/** Name for compiled chunks */
|
|
||||||
public static final String SOURCE_BINARY_STRING = "binary string";
|
|
||||||
|
|
||||||
/** for header of binary files -- this is Lua 5.2 */
|
|
||||||
public static final int LUAC_VERSION = 0x52;
|
|
||||||
|
|
||||||
/** for header of binary files -- this is the official format */
|
|
||||||
public static final int LUAC_FORMAT = 0;
|
|
||||||
|
|
||||||
/** size of header of binary files */
|
|
||||||
public static final int LUAC_HEADERSIZE = 12;
|
|
||||||
|
|
||||||
// values read from the header
|
|
||||||
private int luacVersion;
|
|
||||||
private int luacFormat;
|
|
||||||
private boolean luacLittleEndian;
|
|
||||||
private int luacSizeofInt;
|
|
||||||
private int luacSizeofSizeT;
|
|
||||||
private int luacSizeofInstruction;
|
|
||||||
private int luacSizeofLuaNumber;
|
|
||||||
private int luacNumberFormat;
|
|
||||||
|
|
||||||
/** input stream from which we are loading */
|
|
||||||
public final DataInputStream is;
|
|
||||||
|
|
||||||
/** Name of what is being loaded? */
|
|
||||||
String name;
|
|
||||||
|
|
||||||
private static final LuaValue[] NOVALUES = {};
|
|
||||||
private static final Prototype[] NOPROTOS = {};
|
|
||||||
private static final LocVars[] NOLOCVARS = {};
|
|
||||||
private static final Upvaldesc[] NOUPVALDESCS = {};
|
|
||||||
private static final int[] NOINTS = {};
|
|
||||||
|
|
||||||
/** Read buffer */
|
|
||||||
private byte[] buf = new byte[512];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Install this class as the standard Globals.Undumper for the supplied
|
|
||||||
* Globals
|
|
||||||
*/
|
|
||||||
public static void install(Globals globals) {
|
|
||||||
globals.undumper = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a 4-byte int value from the input stream
|
|
||||||
*
|
|
||||||
* @return the int value laoded.
|
|
||||||
**/
|
|
||||||
int loadInt() throws IOException {
|
|
||||||
is.readFully(buf, 0, 4);
|
|
||||||
return luacLittleEndian? buf[3]<<24 | (0xff & buf[2])<<16 | (0xff & buf[1])<<8 | 0xff & buf[0]
|
|
||||||
: buf[0]<<24 | (0xff & buf[1])<<16 | (0xff & buf[2])<<8 | 0xff & buf[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load an array of int values from the input stream
|
|
||||||
*
|
|
||||||
* @return the array of int values laoded.
|
|
||||||
**/
|
|
||||||
int[] loadIntArray() throws IOException {
|
|
||||||
int n = loadInt();
|
|
||||||
if (n == 0)
|
|
||||||
return NOINTS;
|
|
||||||
|
|
||||||
// read all data at once
|
|
||||||
int m = n<<2;
|
|
||||||
if (buf.length < m)
|
|
||||||
buf = new byte[m];
|
|
||||||
is.readFully(buf, 0, m);
|
|
||||||
int[] array = new int[n];
|
|
||||||
for (int i = 0, j = 0; i < n; ++i, j += 4)
|
|
||||||
array[i] = luacLittleEndian? buf[j+3]<<24 | (0xff & buf[j+2])<<16 | (0xff & buf[j+1])<<8 | 0xff & buf[j+0]
|
|
||||||
: buf[j+0]<<24 | (0xff & buf[j+1])<<16 | (0xff & buf[j+2])<<8 | 0xff & buf[j+3];
|
|
||||||
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a long value from the input stream
|
|
||||||
*
|
|
||||||
* @return the long value laoded.
|
|
||||||
**/
|
|
||||||
long loadInt64() throws IOException {
|
|
||||||
int a, b;
|
|
||||||
if (this.luacLittleEndian) {
|
|
||||||
a = loadInt();
|
|
||||||
b = loadInt();
|
|
||||||
} else {
|
|
||||||
b = loadInt();
|
|
||||||
a = loadInt();
|
|
||||||
}
|
|
||||||
return (long) b<<32 | a & 0xffffffffL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a lua strin gvalue from the input stream
|
|
||||||
*
|
|
||||||
* @return the {@link LuaString} value laoded.
|
|
||||||
**/
|
|
||||||
LuaString loadString() throws IOException {
|
|
||||||
int size = this.luacSizeofSizeT == 8? (int) loadInt64(): loadInt();
|
|
||||||
if (size == 0)
|
|
||||||
return null;
|
|
||||||
byte[] bytes = new byte[size];
|
|
||||||
is.readFully(bytes, 0, size);
|
|
||||||
return LuaString.valueUsing(bytes, 0, bytes.length-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert bits in a long value to a {@link LuaValue}.
|
|
||||||
*
|
|
||||||
* @param bits long value containing the bits
|
|
||||||
* @return {@link LuaInteger} or {@link LuaDouble} whose value corresponds
|
|
||||||
* to the bits provided.
|
|
||||||
*/
|
|
||||||
public static LuaValue longBitsToLuaNumber(long bits) {
|
|
||||||
if ((bits & (1L<<63)-1) == 0L) {
|
|
||||||
return LuaValue.ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
int e = (int) (bits>>52 & 0x7ffL)-1023;
|
|
||||||
|
|
||||||
if (e >= 0 && e < 31) {
|
|
||||||
long f = bits & 0xFFFFFFFFFFFFFL;
|
|
||||||
int shift = 52-e;
|
|
||||||
long intPrecMask = (1L<<shift)-1;
|
|
||||||
if ((f & intPrecMask) == 0) {
|
|
||||||
int intValue = (int) (f>>shift) | 1<<e;
|
|
||||||
return LuaInteger.valueOf(bits>>63 != 0? -intValue: intValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return LuaValue.valueOf(Double.longBitsToDouble(bits));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a number from a binary chunk
|
|
||||||
*
|
|
||||||
* @return the {@link LuaValue} loaded
|
|
||||||
* @throws IOException if an i/o exception occurs
|
|
||||||
*/
|
|
||||||
LuaValue loadNumber() throws IOException {
|
|
||||||
if (luacNumberFormat == NUMBER_FORMAT_INTS_ONLY) {
|
|
||||||
return LuaInteger.valueOf(loadInt());
|
|
||||||
} else {
|
|
||||||
return longBitsToLuaNumber(loadInt64());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a list of constants from a binary chunk
|
|
||||||
*
|
|
||||||
* @param f the function prototype
|
|
||||||
* @throws IOException if an i/o exception occurs
|
|
||||||
*/
|
|
||||||
void loadConstants(Prototype f) throws IOException {
|
|
||||||
int n = loadInt();
|
|
||||||
LuaValue[] values = n > 0? new LuaValue[n]: NOVALUES;
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
switch (is.readByte()) {
|
|
||||||
case LUA_TNIL:
|
|
||||||
values[i] = LuaValue.NIL;
|
|
||||||
break;
|
|
||||||
case LUA_TBOOLEAN:
|
|
||||||
values[i] = 0 != is.readUnsignedByte()? LuaValue.TRUE: LuaValue.FALSE;
|
|
||||||
break;
|
|
||||||
case LUA_TINT:
|
|
||||||
values[i] = LuaInteger.valueOf(loadInt());
|
|
||||||
break;
|
|
||||||
case LUA_TNUMBER:
|
|
||||||
values[i] = loadNumber();
|
|
||||||
break;
|
|
||||||
case LUA_TSTRING:
|
|
||||||
values[i] = loadString();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("bad constant");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f.k = values;
|
|
||||||
|
|
||||||
n = loadInt();
|
|
||||||
Prototype[] protos = n > 0? new Prototype[n]: NOPROTOS;
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
protos[i] = loadFunction(f.source);
|
|
||||||
f.p = protos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadUpvalues(Prototype f) throws IOException {
|
|
||||||
int n = loadInt();
|
|
||||||
f.upvalues = n > 0? new Upvaldesc[n]: NOUPVALDESCS;
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
boolean instack = is.readByte() != 0;
|
|
||||||
int idx = is.readByte() & 0xff;
|
|
||||||
f.upvalues[i] = new Upvaldesc(null, instack, idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the debug info for a function prototype
|
|
||||||
*
|
|
||||||
* @param f the function Prototype
|
|
||||||
* @throws IOException if there is an i/o exception
|
|
||||||
*/
|
|
||||||
void loadDebug(Prototype f) throws IOException {
|
|
||||||
f.source = loadString();
|
|
||||||
f.lineinfo = loadIntArray();
|
|
||||||
int n = loadInt();
|
|
||||||
f.locvars = n > 0? new LocVars[n]: NOLOCVARS;
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
LuaString varname = loadString();
|
|
||||||
int startpc = loadInt();
|
|
||||||
int endpc = loadInt();
|
|
||||||
f.locvars[i] = new LocVars(varname, startpc, endpc);
|
|
||||||
}
|
|
||||||
|
|
||||||
n = loadInt();
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
f.upvalues[i].name = loadString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load a function prototype from the input stream
|
|
||||||
*
|
|
||||||
* @param p name of the source
|
|
||||||
* @return {@link Prototype} instance that was loaded
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public Prototype loadFunction(LuaString p) throws IOException {
|
|
||||||
Prototype f = new Prototype();
|
|
||||||
//// this.L.push(f);
|
|
||||||
// f.source = loadString();
|
|
||||||
// if ( f.source == null )
|
|
||||||
// f.source = p;
|
|
||||||
f.linedefined = loadInt();
|
|
||||||
f.lastlinedefined = loadInt();
|
|
||||||
f.numparams = is.readUnsignedByte();
|
|
||||||
f.is_vararg = is.readUnsignedByte();
|
|
||||||
f.maxstacksize = is.readUnsignedByte();
|
|
||||||
f.code = loadIntArray();
|
|
||||||
loadConstants(f);
|
|
||||||
loadUpvalues(f);
|
|
||||||
loadDebug(f);
|
|
||||||
|
|
||||||
// TODO: add check here, for debugging purposes, I believe
|
|
||||||
// see ldebug.c
|
|
||||||
// IF (!luaG_checkcode(f), "bad code");
|
|
||||||
|
|
||||||
// this.L.pop();
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load the lua chunk header values.
|
|
||||||
*
|
|
||||||
* @throws IOException if an i/o exception occurs.
|
|
||||||
*/
|
|
||||||
public void loadHeader() throws IOException {
|
|
||||||
luacVersion = is.readByte();
|
|
||||||
luacFormat = is.readByte();
|
|
||||||
luacLittleEndian = 0 != is.readByte();
|
|
||||||
luacSizeofInt = is.readByte();
|
|
||||||
luacSizeofSizeT = is.readByte();
|
|
||||||
luacSizeofInstruction = is.readByte();
|
|
||||||
luacSizeofLuaNumber = is.readByte();
|
|
||||||
luacNumberFormat = is.readByte();
|
|
||||||
for (int i = 0; i < LUAC_TAIL.length; ++i)
|
|
||||||
if (is.readByte() != LUAC_TAIL[i])
|
|
||||||
throw new LuaError("Unexpeted byte in luac tail of header, index=" + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load input stream as a lua binary chunk if the first 4 bytes are the lua
|
|
||||||
* binary signature.
|
|
||||||
*
|
|
||||||
* @param stream InputStream to read, after having read the first byte
|
|
||||||
* already
|
|
||||||
* @param chunkname Name to apply to the loaded chunk
|
|
||||||
* @return {@link Prototype} that was loaded, or null if the first 4 bytes
|
|
||||||
* were not the lua signature.
|
|
||||||
* @throws IOException if an IOException occurs
|
|
||||||
*/
|
|
||||||
public static Prototype undump(InputStream stream, String chunkname) throws IOException {
|
|
||||||
// check rest of signature
|
|
||||||
if (stream.read() != LUA_SIGNATURE[0] || stream.read() != LUA_SIGNATURE[1] || stream.read() != LUA_SIGNATURE[2]
|
|
||||||
|| stream.read() != LUA_SIGNATURE[3])
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// load file as a compiled chunk
|
|
||||||
String sname = getSourceName(chunkname);
|
|
||||||
LoadState s = new LoadState(stream, sname);
|
|
||||||
s.loadHeader();
|
|
||||||
|
|
||||||
// check format
|
|
||||||
switch (s.luacNumberFormat) {
|
|
||||||
case NUMBER_FORMAT_FLOATS_OR_DOUBLES:
|
|
||||||
case NUMBER_FORMAT_INTS_ONLY:
|
|
||||||
case NUMBER_FORMAT_NUM_PATCH_INT32:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new LuaError("unsupported int size");
|
|
||||||
}
|
|
||||||
return s.loadFunction(LuaString.valueOf(sname));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a source name from a supplied chunk name
|
|
||||||
*
|
|
||||||
* @param name String name that appears in the chunk
|
|
||||||
* @return source file name
|
|
||||||
*/
|
|
||||||
public static String getSourceName(String name) {
|
|
||||||
String sname = name;
|
|
||||||
if (name.startsWith("@") || name.startsWith("="))
|
|
||||||
sname = name.substring(1);
|
|
||||||
else if (name.startsWith("\033"))
|
|
||||||
sname = SOURCE_BINARY_STRING;
|
|
||||||
return sname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Private constructor for create a load state */
|
|
||||||
private LoadState(InputStream stream, String name) {
|
|
||||||
this.name = name;
|
|
||||||
this.is = new DataInputStream(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class GlobalsUndumper implements Globals.Undumper {
|
|
||||||
@Override
|
|
||||||
public Prototype undump(InputStream stream, String chunkname) throws IOException {
|
|
||||||
return LoadState.undump(stream, chunkname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,357 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants for lua limits and opcodes.
|
|
||||||
* <p>
|
|
||||||
* This is a direct translation of C lua distribution header file constants for
|
|
||||||
* bytecode creation and processing.
|
|
||||||
*/
|
|
||||||
public class Lua {
|
|
||||||
/** version is supplied by ant build task */
|
|
||||||
public static final String _VERSION = "Luaj 0.0";
|
|
||||||
|
|
||||||
/** use return values from previous op */
|
|
||||||
public static final int LUA_MULTRET = -1;
|
|
||||||
|
|
||||||
// from lopcodes.h
|
|
||||||
|
|
||||||
/*===========================================================================
|
|
||||||
We assume that instructions are unsigned numbers.
|
|
||||||
All instructions have an opcode in the first 6 bits.
|
|
||||||
Instructions can have the following fields:
|
|
||||||
`A' : 8 bits
|
|
||||||
`B' : 9 bits
|
|
||||||
`C' : 9 bits
|
|
||||||
`Bx' : 18 bits (`B' and `C' together)
|
|
||||||
`sBx' : signed Bx
|
|
||||||
|
|
||||||
A signed argument is represented in excess K; that is, the number
|
|
||||||
value is the unsigned value minus K. K is exactly the maximum value
|
|
||||||
for that argument (so that -max is represented by 0, and +max is
|
|
||||||
represented by 2*max), which is half the maximum for the corresponding
|
|
||||||
unsigned argument.
|
|
||||||
===========================================================================*/
|
|
||||||
|
|
||||||
/* basic instruction format */
|
|
||||||
public static final int iABC = 0;
|
|
||||||
public static final int iABx = 1;
|
|
||||||
public static final int iAsBx = 2;
|
|
||||||
public static final int iAx = 3;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** size and position of opcode arguments.
|
|
||||||
*/
|
|
||||||
public static final int SIZE_C = 9;
|
|
||||||
public static final int SIZE_B = 9;
|
|
||||||
public static final int SIZE_Bx = SIZE_C+SIZE_B;
|
|
||||||
public static final int SIZE_A = 8;
|
|
||||||
public static final int SIZE_Ax = SIZE_C+SIZE_B+SIZE_A;
|
|
||||||
|
|
||||||
public static final int SIZE_OP = 6;
|
|
||||||
|
|
||||||
public static final int POS_OP = 0;
|
|
||||||
public static final int POS_A = POS_OP+SIZE_OP;
|
|
||||||
public static final int POS_C = POS_A+SIZE_A;
|
|
||||||
public static final int POS_B = POS_C+SIZE_C;
|
|
||||||
public static final int POS_Bx = POS_C;
|
|
||||||
public static final int POS_Ax = POS_A;
|
|
||||||
|
|
||||||
public static final int MAX_OP = (1<<SIZE_OP)-1;
|
|
||||||
public static final int MAXARG_A = (1<<SIZE_A)-1;
|
|
||||||
public static final int MAXARG_B = (1<<SIZE_B)-1;
|
|
||||||
public static final int MAXARG_C = (1<<SIZE_C)-1;
|
|
||||||
public static final int MAXARG_Bx = (1<<SIZE_Bx)-1;
|
|
||||||
public static final int MAXARG_sBx = MAXARG_Bx>>1; /* `sBx' is signed */
|
|
||||||
public static final int MAXARG_Ax = (1<<SIZE_Ax)-1;
|
|
||||||
|
|
||||||
public static final int MASK_OP = (1<<SIZE_OP)-1<<POS_OP;
|
|
||||||
public static final int MASK_A = (1<<SIZE_A)-1<<POS_A;
|
|
||||||
public static final int MASK_B = (1<<SIZE_B)-1<<POS_B;
|
|
||||||
public static final int MASK_C = (1<<SIZE_C)-1<<POS_C;
|
|
||||||
public static final int MASK_Bx = (1<<SIZE_Bx)-1<<POS_Bx;
|
|
||||||
public static final int MASK_Ax = (1<<SIZE_Ax)-1<<POS_Ax;
|
|
||||||
|
|
||||||
public static final int MASK_NOT_OP = ~MASK_OP;
|
|
||||||
public static final int MASK_NOT_A = ~MASK_A;
|
|
||||||
public static final int MASK_NOT_B = ~MASK_B;
|
|
||||||
public static final int MASK_NOT_C = ~MASK_C;
|
|
||||||
public static final int MASK_NOT_Bx = ~MASK_Bx;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** the following macros help to manipulate instructions
|
|
||||||
*/
|
|
||||||
public static int GET_OPCODE(int i) {
|
|
||||||
return i>>POS_OP & MAX_OP;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GETARG_A(int i) {
|
|
||||||
return i>>POS_A & MAXARG_A;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GETARG_Ax(int i) {
|
|
||||||
return i>>POS_Ax & MAXARG_Ax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GETARG_B(int i) {
|
|
||||||
return i>>POS_B & MAXARG_B;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GETARG_C(int i) {
|
|
||||||
return i>>POS_C & MAXARG_C;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GETARG_Bx(int i) {
|
|
||||||
return i>>POS_Bx & MAXARG_Bx;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int GETARG_sBx(int i) {
|
|
||||||
return (i>>POS_Bx & MAXARG_Bx)-MAXARG_sBx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Macros to operate RK indices
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** this bit 1 means constant (0 means register) */
|
|
||||||
public static final int BITRK = 1<<SIZE_B-1;
|
|
||||||
|
|
||||||
/** test whether value is a constant */
|
|
||||||
public static boolean ISK(int x) {
|
|
||||||
return 0 != (x & BITRK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** gets the index of the constant */
|
|
||||||
public static int INDEXK(int r) {
|
|
||||||
return r & ~BITRK;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int MAXINDEXRK = BITRK-1;
|
|
||||||
|
|
||||||
/** code a constant index as a RK value */
|
|
||||||
public static int RKASK(int x) {
|
|
||||||
return x | BITRK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
** invalid register that fits in 8 bits
|
|
||||||
*/
|
|
||||||
public static final int NO_REG = MAXARG_A;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** R(x) - register
|
|
||||||
** Kst(x) - constant (in constant table)
|
|
||||||
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
** grep "ORDER OP" if you change these enums
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
|
||||||
name args description
|
|
||||||
------------------------------------------------------------------------*/
|
|
||||||
public static final int OP_MOVE = 0; /* A B R(A) := R(B) */
|
|
||||||
public static final int OP_LOADK = 1; /* A Bx R(A) := Kst(Bx) */
|
|
||||||
public static final int OP_LOADKX = 2; /* A R(A) := Kst(extra arg) */
|
|
||||||
public static final int OP_LOADBOOL = 3; /* A B C R(A) := (Bool)B; if (C) pc++ */
|
|
||||||
public static final int OP_LOADNIL = 4; /* A B R(A) := ... := R(A+B) := nil */
|
|
||||||
public static final int OP_GETUPVAL = 5; /* A B R(A) := UpValue[B] */
|
|
||||||
|
|
||||||
public static final int OP_GETTABUP = 6; /* A B C R(A) := UpValue[B][RK(C)] */
|
|
||||||
public static final int OP_GETTABLE = 7; /* A B C R(A) := R(B)[RK(C)] */
|
|
||||||
|
|
||||||
public static final int OP_SETTABUP = 8; /* A B C UpValue[A][RK(B)] := RK(C) */
|
|
||||||
public static final int OP_SETUPVAL = 9; /* A B UpValue[B] := R(A) */
|
|
||||||
public static final int OP_SETTABLE = 10; /* A B C R(A)[RK(B)] := RK(C) */
|
|
||||||
|
|
||||||
public static final int OP_NEWTABLE = 11; /* A B C R(A) := {} (size = B,C) */
|
|
||||||
|
|
||||||
public static final int OP_SELF = 12; /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
|
|
||||||
|
|
||||||
public static final int OP_ADD = 13; /* A B C R(A) := RK(B) + RK(C) */
|
|
||||||
public static final int OP_SUB = 14; /* A B C R(A) := RK(B) - RK(C) */
|
|
||||||
public static final int OP_MUL = 15; /* A B C R(A) := RK(B) * RK(C) */
|
|
||||||
public static final int OP_DIV = 16; /* A B C R(A) := RK(B) / RK(C) */
|
|
||||||
public static final int OP_MOD = 17; /* A B C R(A) := RK(B) % RK(C) */
|
|
||||||
public static final int OP_POW = 18; /* A B C R(A) := RK(B) ^ RK(C) */
|
|
||||||
public static final int OP_UNM = 19; /* A B R(A) := -R(B) */
|
|
||||||
public static final int OP_NOT = 20; /* A B R(A) := not R(B) */
|
|
||||||
public static final int OP_LEN = 21; /* A B R(A) := length of R(B) */
|
|
||||||
|
|
||||||
public static final int OP_CONCAT = 22; /* A B C R(A) := R(B).. ... ..R(C) */
|
|
||||||
|
|
||||||
public static final int OP_JMP = 23; /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
|
||||||
public static final int OP_EQ = 24; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
|
||||||
public static final int OP_LT = 25; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
|
||||||
public static final int OP_LE = 26; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
|
||||||
|
|
||||||
public static final int OP_TEST = 27; /* A C if not (R(A) <=> C) then pc++ */
|
|
||||||
public static final int OP_TESTSET = 28; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
|
|
||||||
|
|
||||||
public static final int OP_CALL = 29; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
|
|
||||||
public static final int OP_TAILCALL = 30; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
|
||||||
public static final int OP_RETURN = 31; /* A B return R(A), ... ,R(A+B-2) (see note) */
|
|
||||||
|
|
||||||
public static final int OP_FORLOOP = 32; /* A sBx R(A)+=R(A+2);
|
|
||||||
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
|
|
||||||
public static final int OP_FORPREP = 33; /* A sBx R(A)-=R(A+2); pc+=sBx */
|
|
||||||
|
|
||||||
public static final int OP_TFORCALL = 34; /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
|
||||||
public static final int OP_TFORLOOP = 35; /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx } */
|
|
||||||
public static final int OP_SETLIST = 36; /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
|
|
||||||
|
|
||||||
public static final int OP_CLOSURE = 37; /* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
|
|
||||||
|
|
||||||
public static final int OP_VARARG = 38; /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
|
|
||||||
|
|
||||||
public static final int OP_EXTRAARG = 39; /* Ax extra (larger) argument for previous opcode */
|
|
||||||
|
|
||||||
public static final int NUM_OPCODES = OP_EXTRAARG+1;
|
|
||||||
|
|
||||||
/* pseudo-opcodes used in parsing only. */
|
|
||||||
public static final int OP_GT = 63; // >
|
|
||||||
public static final int OP_GE = 62; // >=
|
|
||||||
public static final int OP_NEQ = 61; // ~=
|
|
||||||
public static final int OP_AND = 60; // and
|
|
||||||
public static final int OP_OR = 59; // or
|
|
||||||
|
|
||||||
/*===========================================================================
|
|
||||||
Notes:
|
|
||||||
(*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
|
|
||||||
and can be 0: OP_CALL then sets `top' to last_result+1, so
|
|
||||||
next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
|
|
||||||
|
|
||||||
(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
|
|
||||||
set top (like in OP_CALL with C == 0).
|
|
||||||
|
|
||||||
(*) In OP_RETURN, if (B == 0) then return up to `top'
|
|
||||||
|
|
||||||
(*) In OP_SETLIST, if (B == 0) then B = `top';
|
|
||||||
if (C == 0) then next `instruction' is real C
|
|
||||||
|
|
||||||
(*) For comparisons, A specifies what condition the test should accept
|
|
||||||
(true or false).
|
|
||||||
|
|
||||||
(*) All `skips' (pc++) assume that next instruction is a jump
|
|
||||||
===========================================================================*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
** masks for instruction properties. The format is:
|
|
||||||
** bits 0-1: op mode
|
|
||||||
** bits 2-3: C arg mode
|
|
||||||
** bits 4-5: B arg mode
|
|
||||||
** bit 6: instruction set register A
|
|
||||||
** bit 7: operator is a test
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static final int OpArgN = 0; /* argument is not used */
|
|
||||||
public static final int OpArgU = 1; /* argument is used */
|
|
||||||
public static final int OpArgR = 2; /* argument is a register or a jump offset */
|
|
||||||
public static final int OpArgK = 3; /* argument is a constant or register/constant */
|
|
||||||
|
|
||||||
public static final int[] luaP_opmodes = {
|
|
||||||
/* T A B C mode opcode */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgN<<2 | iABC, /* OP_MOVE */
|
|
||||||
0<<7 | 1<<6 | OpArgK<<4 | OpArgN<<2 | iABx, /* OP_LOADK */
|
|
||||||
0<<7 | 1<<6 | OpArgN<<4 | OpArgN<<2 | iABx, /* OP_LOADKX */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgU<<2 | iABC, /* OP_LOADBOOL */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgN<<2 | iABC, /* OP_LOADNIL */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgN<<2 | iABC, /* OP_GETUPVAL */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgK<<2 | iABC, /* OP_GETTABUP */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgK<<2 | iABC, /* OP_GETTABLE */
|
|
||||||
0<<7 | 0<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_SETTABUP */
|
|
||||||
0<<7 | 0<<6 | OpArgU<<4 | OpArgN<<2 | iABC, /* OP_SETUPVAL */
|
|
||||||
0<<7 | 0<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_SETTABLE */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgU<<2 | iABC, /* OP_NEWTABLE */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgK<<2 | iABC, /* OP_SELF */
|
|
||||||
0<<7 | 1<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_ADD */
|
|
||||||
0<<7 | 1<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_SUB */
|
|
||||||
0<<7 | 1<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_MUL */
|
|
||||||
0<<7 | 1<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_DIV */
|
|
||||||
0<<7 | 1<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_MOD */
|
|
||||||
0<<7 | 1<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_POW */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgN<<2 | iABC, /* OP_UNM */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgN<<2 | iABC, /* OP_NOT */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgN<<2 | iABC, /* OP_LEN */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgR<<2 | iABC, /* OP_CONCAT */
|
|
||||||
0<<7 | 0<<6 | OpArgR<<4 | OpArgN<<2 | iAsBx, /* OP_JMP */
|
|
||||||
1<<7 | 0<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_EQ */
|
|
||||||
1<<7 | 0<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_LT */
|
|
||||||
1<<7 | 0<<6 | OpArgK<<4 | OpArgK<<2 | iABC, /* OP_LE */
|
|
||||||
1<<7 | 0<<6 | OpArgN<<4 | OpArgU<<2 | iABC, /* OP_TEST */
|
|
||||||
1<<7 | 1<<6 | OpArgR<<4 | OpArgU<<2 | iABC, /* OP_TESTSET */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgU<<2 | iABC, /* OP_CALL */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgU<<2 | iABC, /* OP_TAILCALL */
|
|
||||||
0<<7 | 0<<6 | OpArgU<<4 | OpArgN<<2 | iABC, /* OP_RETURN */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgN<<2 | iAsBx, /* OP_FORLOOP */
|
|
||||||
0<<7 | 1<<6 | OpArgR<<4 | OpArgN<<2 | iAsBx, /* OP_FORPREP */
|
|
||||||
0<<7 | 0<<6 | OpArgN<<4 | OpArgU<<2 | iABC, /* OP_TFORCALL */
|
|
||||||
1<<7 | 1<<6 | OpArgR<<4 | OpArgN<<2 | iAsBx, /* OP_TFORLOOP */
|
|
||||||
0<<7 | 0<<6 | OpArgU<<4 | OpArgU<<2 | iABC, /* OP_SETLIST */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgN<<2 | iABx, /* OP_CLOSURE */
|
|
||||||
0<<7 | 1<<6 | OpArgU<<4 | OpArgN<<2 | iABC, /* OP_VARARG */
|
|
||||||
0<<7 | 0<<6 | OpArgU<<4 | OpArgU<<2 | iAx, /* OP_EXTRAARG */
|
|
||||||
};
|
|
||||||
|
|
||||||
public static int getOpMode(int m) {
|
|
||||||
return luaP_opmodes[m] & 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getBMode(int m) {
|
|
||||||
return luaP_opmodes[m]>>4 & 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getCMode(int m) {
|
|
||||||
return luaP_opmodes[m]>>2 & 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean testAMode(int m) {
|
|
||||||
return 0 != (luaP_opmodes[m] & 1<<6);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean testTMode(int m) {
|
|
||||||
return 0 != (luaP_opmodes[m] & 1<<7);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* number of list items to accumulate before a SETLIST instruction */
|
|
||||||
public static final int LFIELDS_PER_FLUSH = 50;
|
|
||||||
|
|
||||||
private static final int MAXSRC = 80;
|
|
||||||
|
|
||||||
public static String chunkid(String source) {
|
|
||||||
if (source.startsWith("="))
|
|
||||||
return source.substring(1);
|
|
||||||
String end = "";
|
|
||||||
if (source.startsWith("@")) {
|
|
||||||
source = source.substring(1);
|
|
||||||
} else {
|
|
||||||
source = "[string \"" + source;
|
|
||||||
end = "\"]";
|
|
||||||
}
|
|
||||||
int n = source.length()+end.length();
|
|
||||||
if (n > MAXSRC)
|
|
||||||
source = source.substring(0, MAXSRC-end.length()-3) + "...";
|
|
||||||
return source+end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,680 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import org.luaj.vm2.lib.DebugLib.CallFrame;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension of {@link LuaFunction} which executes lua bytecode.
|
|
||||||
* <p>
|
|
||||||
* A {@link LuaClosure} is a combination of a {@link Prototype} and a
|
|
||||||
* {@link LuaValue} to use as an environment for execution. Normally the
|
|
||||||
* {@link LuaValue} is a {@link Globals} in which case the environment will
|
|
||||||
* contain standard lua libraries.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* There are three main ways {@link LuaClosure} instances are created:
|
|
||||||
* <ul>
|
|
||||||
* <li>Construct an instance using {@link #LuaClosure(Prototype, LuaValue)}</li>
|
|
||||||
* <li>Construct it indirectly by loading a chunk via
|
|
||||||
* {@link Globals#load(java.io.Reader, String)}
|
|
||||||
* <li>Execute the lua bytecode {@link Lua#OP_CLOSURE} as part of bytecode
|
|
||||||
* processing
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* To construct it directly, the {@link Prototype} is typically created via a
|
|
||||||
* compiler such as {@link org.luaj.vm2.compiler.LuaC}:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* String script = "print( 'hello, world' )";
|
|
||||||
* InputStream is = new ByteArrayInputStream(script.getBytes());
|
|
||||||
* Prototype p = LuaC.instance.compile(is, "script");
|
|
||||||
* LuaValue globals = JsePlatform.standardGlobals();
|
|
||||||
* LuaClosure f = new LuaClosure(p, globals);
|
|
||||||
* f.call();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
* To construct it indirectly, the {@link Globals#load(java.io.Reader, String)}
|
|
||||||
* method may be used:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
|
||||||
* LuaFunction f = globals.load(new StringReader(script), "script");
|
|
||||||
* LuaClosure c = f.checkclosure(); // This may fail if LuaJC is installed.
|
|
||||||
* c.call();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
* In this example, the "checkclosure()" may fail if direct lua-to-java-bytecode
|
|
||||||
* compiling using LuaJC is installed, because no LuaClosure is created in that
|
|
||||||
* case and the value returned is a {@link LuaFunction} but not a
|
|
||||||
* {@link LuaClosure}.
|
|
||||||
* <p>
|
|
||||||
* Since a {@link LuaClosure} is a {@link LuaFunction} which is a
|
|
||||||
* {@link LuaValue}, all the value operations can be used directly such as:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link LuaValue#call()}</li>
|
|
||||||
* <li>{@link LuaValue#call(LuaValue)}</li>
|
|
||||||
* <li>{@link LuaValue#invoke()}</li>
|
|
||||||
* <li>{@link LuaValue#invoke(Varargs)}</li>
|
|
||||||
* <li>{@link LuaValue#method(String)}</li>
|
|
||||||
* <li>{@link LuaValue#method(String,LuaValue)}</li>
|
|
||||||
* <li>{@link LuaValue#invokemethod(String)}</li>
|
|
||||||
* <li>{@link LuaValue#invokemethod(String,Varargs)}</li>
|
|
||||||
* <li>...</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @see LuaValue
|
|
||||||
* @see LuaFunction
|
|
||||||
* @see LuaValue#isclosure()
|
|
||||||
* @see LuaValue#checkclosure()
|
|
||||||
* @see LuaValue#optclosure(LuaClosure)
|
|
||||||
* @see LoadState
|
|
||||||
* @see Globals#compiler
|
|
||||||
*/
|
|
||||||
public class LuaClosure extends LuaFunction {
|
|
||||||
private static final UpValue[] NOUPVALUES = {};
|
|
||||||
|
|
||||||
public final Prototype p;
|
|
||||||
|
|
||||||
public UpValue[] upValues;
|
|
||||||
|
|
||||||
final Globals globals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a closure around a Prototype with a specific environment. If the
|
|
||||||
* prototype has upvalues, the environment will be written into the first
|
|
||||||
* upvalue.
|
|
||||||
*
|
|
||||||
* @param p the Prototype to construct this Closure for.
|
|
||||||
* @param env the environment to associate with the closure.
|
|
||||||
*/
|
|
||||||
public LuaClosure(Prototype p, LuaValue env) {
|
|
||||||
this.p = p;
|
|
||||||
this.initupvalue1(env);
|
|
||||||
globals = env instanceof Globals? (Globals) env: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initupvalue1(LuaValue env) {
|
|
||||||
if (p.upvalues == null || p.upvalues.length == 0)
|
|
||||||
this.upValues = NOUPVALUES;
|
|
||||||
else {
|
|
||||||
this.upValues = new UpValue[p.upvalues.length];
|
|
||||||
this.upValues[0] = new UpValue(new LuaValue[] { env }, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isclosure() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaClosure optclosure(LuaClosure defval) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaClosure checkclosure() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String tojstring() {
|
|
||||||
return "function: " + p.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private LuaValue[] getNewStack() {
|
|
||||||
int max = p.maxstacksize;
|
|
||||||
LuaValue[] stack = new LuaValue[max];
|
|
||||||
System.arraycopy(NILS, 0, stack, 0, max);
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final LuaValue call() {
|
|
||||||
LuaValue[] stack = getNewStack();
|
|
||||||
return execute(stack, NONE).arg1();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final LuaValue call(LuaValue arg) {
|
|
||||||
LuaValue[] stack = getNewStack();
|
|
||||||
switch (p.numparams) {
|
|
||||||
default:
|
|
||||||
stack[0] = arg;
|
|
||||||
return execute(stack, NONE).arg1();
|
|
||||||
case 0:
|
|
||||||
return execute(stack, arg).arg1();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final LuaValue call(LuaValue arg1, LuaValue arg2) {
|
|
||||||
LuaValue[] stack = getNewStack();
|
|
||||||
switch (p.numparams) {
|
|
||||||
default:
|
|
||||||
stack[0] = arg1;
|
|
||||||
stack[1] = arg2;
|
|
||||||
return execute(stack, NONE).arg1();
|
|
||||||
case 1:
|
|
||||||
stack[0] = arg1;
|
|
||||||
return execute(stack, arg2).arg1();
|
|
||||||
case 0:
|
|
||||||
return execute(stack, p.is_vararg != 0? varargsOf(arg1, arg2): NONE).arg1();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
|
||||||
LuaValue[] stack = getNewStack();
|
|
||||||
switch (p.numparams) {
|
|
||||||
default:
|
|
||||||
stack[0] = arg1;
|
|
||||||
stack[1] = arg2;
|
|
||||||
stack[2] = arg3;
|
|
||||||
return execute(stack, NONE).arg1();
|
|
||||||
case 2:
|
|
||||||
stack[0] = arg1;
|
|
||||||
stack[1] = arg2;
|
|
||||||
return execute(stack, arg3).arg1();
|
|
||||||
case 1:
|
|
||||||
stack[0] = arg1;
|
|
||||||
return execute(stack, p.is_vararg != 0? varargsOf(arg2, arg3): NONE).arg1();
|
|
||||||
case 0:
|
|
||||||
return execute(stack, p.is_vararg != 0? varargsOf(arg1, arg2, arg3): NONE).arg1();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final Varargs invoke(Varargs varargs) {
|
|
||||||
return onInvoke(varargs).eval();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final Varargs onInvoke(Varargs varargs) {
|
|
||||||
LuaValue[] stack = getNewStack();
|
|
||||||
for (int i = 0; i < p.numparams; i++)
|
|
||||||
stack[i] = varargs.arg(i+1);
|
|
||||||
return execute(stack, p.is_vararg != 0? varargs.subargs(p.numparams+1): NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Varargs execute(LuaValue[] stack, Varargs varargs) {
|
|
||||||
// loop through instructions
|
|
||||||
int i, a, b, c, pc = 0, top = 0;
|
|
||||||
LuaValue o;
|
|
||||||
Varargs v = NONE;
|
|
||||||
int[] code = p.code;
|
|
||||||
LuaValue[] k = p.k;
|
|
||||||
|
|
||||||
// upvalues are only possible when closures create closures
|
|
||||||
// TODO: use linked list.
|
|
||||||
UpValue[] openups = p.p.length > 0? new UpValue[stack.length]: null;
|
|
||||||
|
|
||||||
// allow for debug hooks
|
|
||||||
if (globals != null && globals.debuglib != null)
|
|
||||||
globals.debuglib.onCall(this, varargs, stack);
|
|
||||||
|
|
||||||
// process instructions
|
|
||||||
try {
|
|
||||||
for (; true; ++pc) {
|
|
||||||
if (globals != null && globals.debuglib != null)
|
|
||||||
globals.debuglib.onInstruction(pc, v, top);
|
|
||||||
|
|
||||||
// pull out instruction
|
|
||||||
i = code[pc];
|
|
||||||
a = i>>6 & 0xff;
|
|
||||||
|
|
||||||
// process the op code
|
|
||||||
switch (i & 0x3f) {
|
|
||||||
|
|
||||||
case Lua.OP_MOVE:/* A B R(A):= R(B) */
|
|
||||||
stack[a] = stack[i>>>23];
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_LOADK:/* A Bx R(A):= Kst(Bx) */
|
|
||||||
stack[a] = k[i>>>14];
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_LOADKX:/* A R(A) := Kst(extra arg) */
|
|
||||||
++pc;
|
|
||||||
i = code[pc];
|
|
||||||
if ((i & 0x3f) != Lua.OP_EXTRAARG) {
|
|
||||||
int op = i & 0x3f;
|
|
||||||
throw new LuaError("OP_EXTRAARG expected after OP_LOADKX, got "
|
|
||||||
+ (op < Print.OPNAMES.length-1? Print.OPNAMES[op]: "UNKNOWN_OP_" + op));
|
|
||||||
}
|
|
||||||
stack[a] = k[i>>>6];
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_LOADBOOL:/* A B C R(A):= (Bool)B: if (C) pc++ */
|
|
||||||
stack[a] = i>>>23 != 0? LuaValue.TRUE: LuaValue.FALSE;
|
|
||||||
if ((i & 0x1ff<<14) != 0)
|
|
||||||
++pc; /* skip next instruction (if C) */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_LOADNIL: /* A B R(A):= ...:= R(A+B):= nil */
|
|
||||||
for (b = i>>>23; b-- >= 0;)
|
|
||||||
stack[a++] = LuaValue.NIL;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_GETUPVAL: /* A B R(A):= UpValue[B] */
|
|
||||||
stack[a] = upValues[i>>>23].getValue();
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_GETTABUP: /* A B C R(A) := UpValue[B][RK(C)] */
|
|
||||||
stack[a] = upValues[i>>>23].getValue().get((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_GETTABLE: /* A B C R(A):= R(B)[RK(C)] */
|
|
||||||
stack[a] = stack[i>>>23].get((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_SETTABUP: /* A B C UpValue[A][RK(B)] := RK(C) */
|
|
||||||
upValues[a].getValue().set((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b],
|
|
||||||
(c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_SETUPVAL: /* A B UpValue[B]:= R(A) */
|
|
||||||
upValues[i>>>23].setValue(stack[a]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_SETTABLE: /* A B C R(A)[RK(B)]:= RK(C) */
|
|
||||||
stack[a].set((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b],
|
|
||||||
(c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_NEWTABLE: /* A B C R(A):= {} (size = B,C) */
|
|
||||||
stack[a] = new LuaTable(i>>>23, i>>14 & 0x1ff);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_SELF: /* A B C R(A+1):= R(B): R(A):= R(B)[RK(C)] */
|
|
||||||
stack[a+1] = o = stack[i>>>23];
|
|
||||||
stack[a] = o.get((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_ADD: /* A B C R(A):= RK(B) + RK(C) */
|
|
||||||
stack[a] = ((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.add((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_SUB: /* A B C R(A):= RK(B) - RK(C) */
|
|
||||||
stack[a] = ((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.sub((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_MUL: /* A B C R(A):= RK(B) * RK(C) */
|
|
||||||
stack[a] = ((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.mul((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_DIV: /* A B C R(A):= RK(B) / RK(C) */
|
|
||||||
stack[a] = ((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.div((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_MOD: /* A B C R(A):= RK(B) % RK(C) */
|
|
||||||
stack[a] = ((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.mod((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_POW: /* A B C R(A):= RK(B) ^ RK(C) */
|
|
||||||
stack[a] = ((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.pow((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_UNM: /* A B R(A):= -R(B) */
|
|
||||||
stack[a] = stack[i>>>23].neg();
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_NOT: /* A B R(A):= not R(B) */
|
|
||||||
stack[a] = stack[i>>>23].not();
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_LEN: /* A B R(A):= length of R(B) */
|
|
||||||
stack[a] = stack[i>>>23].len();
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_CONCAT: /* A B C R(A):= R(B).. ... ..R(C) */
|
|
||||||
b = i>>>23;
|
|
||||||
c = i>>14 & 0x1ff; {
|
|
||||||
if (c > b+1) {
|
|
||||||
Buffer sb = stack[c].buffer();
|
|
||||||
while ( --c >= b )
|
|
||||||
sb.concatTo(stack[c]);
|
|
||||||
stack[a] = sb.value();
|
|
||||||
} else {
|
|
||||||
stack[a] = stack[c-1].concat(stack[c]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_JMP: /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
|
|
||||||
pc += (i>>>14)-0x1ffff;
|
|
||||||
if (a > 0) {
|
|
||||||
for (--a, b = openups.length; --b >= 0;)
|
|
||||||
if (openups[b] != null && openups[b].index >= a) {
|
|
||||||
openups[b].close();
|
|
||||||
openups[b] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_EQ: /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
|
|
||||||
if (((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.eq_b((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]) != (a != 0))
|
|
||||||
++pc;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_LT: /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
|
|
||||||
if (((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.lt_b((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]) != (a != 0))
|
|
||||||
++pc;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_LE: /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
|
|
||||||
if (((b = i>>>23) > 0xff? k[b & 0x0ff]: stack[b])
|
|
||||||
.lteq_b((c = i>>14 & 0x1ff) > 0xff? k[c & 0x0ff]: stack[c]) != (a != 0))
|
|
||||||
++pc;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_TEST: /* A C if not (R(A) <=> C) then pc++ */
|
|
||||||
if (stack[a].toboolean() != ((i & 0x1ff<<14) != 0))
|
|
||||||
++pc;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_TESTSET: /* A B C if (R(B) <=> C) then R(A):= R(B) else pc++ */
|
|
||||||
/* note: doc appears to be reversed */
|
|
||||||
if ((o = stack[i>>>23]).toboolean() != ((i & 0x1ff<<14) != 0))
|
|
||||||
++pc;
|
|
||||||
else
|
|
||||||
stack[a] = o; // TODO: should be sBx?
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_CALL: /* A B C R(A), ... ,R(A+C-2):= R(A)(R(A+1), ... ,R(A+B-1)) */
|
|
||||||
switch (i & (Lua.MASK_B | Lua.MASK_C)) {
|
|
||||||
case 1<<Lua.POS_B | 0<<Lua.POS_C:
|
|
||||||
v = stack[a].invoke(NONE);
|
|
||||||
top = a+v.narg();
|
|
||||||
continue;
|
|
||||||
case 2<<Lua.POS_B | 0<<Lua.POS_C:
|
|
||||||
v = stack[a].invoke(stack[a+1]);
|
|
||||||
top = a+v.narg();
|
|
||||||
continue;
|
|
||||||
case 1<<Lua.POS_B | 1<<Lua.POS_C:
|
|
||||||
stack[a].call();
|
|
||||||
continue;
|
|
||||||
case 2<<Lua.POS_B | 1<<Lua.POS_C:
|
|
||||||
stack[a].call(stack[a+1]);
|
|
||||||
continue;
|
|
||||||
case 3<<Lua.POS_B | 1<<Lua.POS_C:
|
|
||||||
stack[a].call(stack[a+1], stack[a+2]);
|
|
||||||
continue;
|
|
||||||
case 4<<Lua.POS_B | 1<<Lua.POS_C:
|
|
||||||
stack[a].call(stack[a+1], stack[a+2], stack[a+3]);
|
|
||||||
continue;
|
|
||||||
case 1<<Lua.POS_B | 2<<Lua.POS_C:
|
|
||||||
stack[a] = stack[a].call();
|
|
||||||
continue;
|
|
||||||
case 2<<Lua.POS_B | 2<<Lua.POS_C:
|
|
||||||
stack[a] = stack[a].call(stack[a+1]);
|
|
||||||
continue;
|
|
||||||
case 3<<Lua.POS_B | 2<<Lua.POS_C:
|
|
||||||
stack[a] = stack[a].call(stack[a+1], stack[a+2]);
|
|
||||||
continue;
|
|
||||||
case 4<<Lua.POS_B | 2<<Lua.POS_C:
|
|
||||||
stack[a] = stack[a].call(stack[a+1], stack[a+2], stack[a+3]);
|
|
||||||
continue;
|
|
||||||
default:
|
|
||||||
b = i>>>23;
|
|
||||||
c = i>>14 & 0x1ff;
|
|
||||||
v = stack[a].invoke(b > 0? varargsOf(stack, a+1, b-1): // exact arg count
|
|
||||||
varargsOf(stack, a+1, top-v.narg()-(a+1), v)); // from prev top
|
|
||||||
if (c > 0) {
|
|
||||||
v.copyto(stack, a, c-1);
|
|
||||||
v = NONE;
|
|
||||||
} else {
|
|
||||||
top = a+v.narg();
|
|
||||||
v = v.dealias();
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Lua.OP_TAILCALL: /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
|
|
||||||
switch (i & Lua.MASK_B) {
|
|
||||||
case 1<<Lua.POS_B:
|
|
||||||
return new TailcallVarargs(stack[a], NONE);
|
|
||||||
case 2<<Lua.POS_B:
|
|
||||||
return new TailcallVarargs(stack[a], stack[a+1]);
|
|
||||||
case 3<<Lua.POS_B:
|
|
||||||
return new TailcallVarargs(stack[a], varargsOf(stack[a+1], stack[a+2]));
|
|
||||||
case 4<<Lua.POS_B:
|
|
||||||
return new TailcallVarargs(stack[a], varargsOf(stack[a+1], stack[a+2], stack[a+3]));
|
|
||||||
default:
|
|
||||||
b = i>>>23;
|
|
||||||
v = b > 0? varargsOf(stack, a+1, b-1): // exact arg count
|
|
||||||
varargsOf(stack, a+1, top-v.narg()-(a+1), v); // from prev top
|
|
||||||
return new TailcallVarargs(stack[a], v);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Lua.OP_RETURN: /* A B return R(A), ... ,R(A+B-2) (see note) */
|
|
||||||
b = i>>>23;
|
|
||||||
switch (b) {
|
|
||||||
case 0:
|
|
||||||
return varargsOf(stack, a, top-v.narg()-a, v);
|
|
||||||
case 1:
|
|
||||||
return NONE;
|
|
||||||
case 2:
|
|
||||||
return stack[a];
|
|
||||||
default:
|
|
||||||
return varargsOf(stack, a, b-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Lua.OP_FORLOOP: /* A sBx R(A)+=R(A+2): if R(A) <?= R(A+1) then { pc+=sBx: R(A+3)=R(A) }*/
|
|
||||||
{
|
|
||||||
LuaValue limit = stack[a+1];
|
|
||||||
LuaValue step = stack[a+2];
|
|
||||||
LuaValue idx = stack[a].add(step);
|
|
||||||
if (step.gt_b(0)? idx.lteq_b(limit): idx.gteq_b(limit)) {
|
|
||||||
stack[a] = idx;
|
|
||||||
stack[a+3] = idx;
|
|
||||||
pc += (i>>>14)-0x1ffff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_FORPREP: /* A sBx R(A)-=R(A+2): pc+=sBx */
|
|
||||||
{
|
|
||||||
LuaValue init = stack[a].checknumber("'for' initial value must be a number");
|
|
||||||
LuaValue limit = stack[a+1].checknumber("'for' limit must be a number");
|
|
||||||
LuaValue step = stack[a+2].checknumber("'for' step must be a number");
|
|
||||||
stack[a] = init.sub(step);
|
|
||||||
stack[a+1] = limit;
|
|
||||||
stack[a+2] = step;
|
|
||||||
pc += (i>>>14)-0x1ffff;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_TFORCALL: /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
|
|
||||||
v = stack[a].invoke(varargsOf(stack[a+1], stack[a+2]));
|
|
||||||
c = i>>14 & 0x1ff;
|
|
||||||
while ( --c >= 0 )
|
|
||||||
stack[a+3+c] = v.arg(c+1);
|
|
||||||
v = NONE;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_TFORLOOP: /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx */
|
|
||||||
if (!stack[a+1].isnil()) { /* continue loop? */
|
|
||||||
stack[a] = stack[a+1]; /* save control varible. */
|
|
||||||
pc += (i>>>14)-0x1ffff;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_SETLIST: /* A B C R(A)[(C-1)*FPF+i]:= R(A+i), 1 <= i <= B */
|
|
||||||
{
|
|
||||||
if ((c = i>>14 & 0x1ff) == 0)
|
|
||||||
c = code[++pc];
|
|
||||||
int offset = (c-1)*Lua.LFIELDS_PER_FLUSH;
|
|
||||||
o = stack[a];
|
|
||||||
if ((b = i>>>23) == 0) {
|
|
||||||
b = top-a-1;
|
|
||||||
int m = b-v.narg();
|
|
||||||
int j = 1;
|
|
||||||
for (; j <= m; j++)
|
|
||||||
o.set(offset+j, stack[a+j]);
|
|
||||||
for (; j <= b; j++)
|
|
||||||
o.set(offset+j, v.arg(j-m));
|
|
||||||
} else {
|
|
||||||
o.presize(offset+b);
|
|
||||||
for (int j = 1; j <= b; j++)
|
|
||||||
o.set(offset+j, stack[a+j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_CLOSURE: /* A Bx R(A):= closure(KPROTO[Bx]) */
|
|
||||||
{
|
|
||||||
Prototype newp = p.p[i>>>14];
|
|
||||||
LuaClosure ncl = new LuaClosure(newp, globals);
|
|
||||||
Upvaldesc[] uv = newp.upvalues;
|
|
||||||
for (int j = 0, nup = uv.length; j < nup; ++j) {
|
|
||||||
if (uv[j].instack) /* upvalue refes to local variable? */
|
|
||||||
ncl.upValues[j] = findupval(stack, uv[j].idx, openups);
|
|
||||||
else /* get upvalue from enclosing function */
|
|
||||||
ncl.upValues[j] = upValues[uv[j].idx];
|
|
||||||
}
|
|
||||||
stack[a] = ncl;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_VARARG: /* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
|
|
||||||
b = i>>>23;
|
|
||||||
if (b == 0) {
|
|
||||||
top = a+(b = varargs.narg());
|
|
||||||
v = varargs;
|
|
||||||
} else {
|
|
||||||
for (int j = 1; j < b; ++j)
|
|
||||||
stack[a+j-1] = varargs.arg(j);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Lua.OP_EXTRAARG:
|
|
||||||
throw new java.lang.IllegalArgumentException("Uexecutable opcode: OP_EXTRAARG");
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new java.lang.IllegalArgumentException("Illegal opcode: " + (i & 0x3f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (LuaError le) {
|
|
||||||
if (le.traceback == null)
|
|
||||||
processErrorHooks(le, p, pc);
|
|
||||||
throw le;
|
|
||||||
} catch (Exception e) {
|
|
||||||
LuaError le = new LuaError(e);
|
|
||||||
processErrorHooks(le, p, pc);
|
|
||||||
throw le;
|
|
||||||
} finally {
|
|
||||||
if (openups != null)
|
|
||||||
for (int u = openups.length; --u >= 0;)
|
|
||||||
if (openups[u] != null)
|
|
||||||
openups[u].close();
|
|
||||||
if (globals != null && globals.debuglib != null)
|
|
||||||
globals.debuglib.onReturn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the error hook if there is one
|
|
||||||
*
|
|
||||||
* @param msg the message to use in error hook processing.
|
|
||||||
*/
|
|
||||||
String errorHook(String msg, int level) {
|
|
||||||
if (globals == null)
|
|
||||||
return msg;
|
|
||||||
final LuaThread r = globals.running;
|
|
||||||
if (r.errorfunc == null)
|
|
||||||
return globals.debuglib != null? msg + "\n" + globals.debuglib.traceback(level): msg;
|
|
||||||
final LuaValue e = r.errorfunc;
|
|
||||||
r.errorfunc = null;
|
|
||||||
try {
|
|
||||||
return e.call(LuaValue.valueOf(msg)).tojstring();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
return "error in error handling";
|
|
||||||
} finally {
|
|
||||||
r.errorfunc = e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processErrorHooks(LuaError le, Prototype p, int pc) {
|
|
||||||
String file = "?";
|
|
||||||
int line = -1;
|
|
||||||
{
|
|
||||||
CallFrame frame = null;
|
|
||||||
if (globals != null && globals.debuglib != null) {
|
|
||||||
frame = globals.debuglib.getCallFrame(le.level);
|
|
||||||
if (frame != null) {
|
|
||||||
String src = frame.shortsource();
|
|
||||||
file = src != null? src: "?";
|
|
||||||
line = frame.currentline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (frame == null) {
|
|
||||||
file = p.source != null? p.source.tojstring(): "?";
|
|
||||||
line = p.lineinfo != null && pc >= 0 && pc < p.lineinfo.length? p.lineinfo[pc]: -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
le.fileline = file + ": " + line;
|
|
||||||
le.traceback = errorHook(le.getMessage(), le.level);
|
|
||||||
}
|
|
||||||
|
|
||||||
private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) {
|
|
||||||
final int n = openups.length;
|
|
||||||
for (int i = 0; i < n; ++i)
|
|
||||||
if (openups[i] != null && openups[i].index == idx)
|
|
||||||
return openups[i];
|
|
||||||
for (int i = 0; i < n; ++i)
|
|
||||||
if (openups[i] == null)
|
|
||||||
return openups[i] = new UpValue(stack, idx);
|
|
||||||
error("No space for upvalue");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected LuaValue getUpvalue(int i) {
|
|
||||||
return upValues[i].getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setUpvalue(int i, LuaValue v) {
|
|
||||||
upValues[i].setValue(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return "<" + p.shortsource() + ":" + p.linedefined + ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,372 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import org.luaj.vm2.lib.MathLib;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension of {@link LuaNumber} which can hold a Java int as its value.
|
|
||||||
* <p>
|
|
||||||
* These instance are not instantiated directly by clients, but indirectly via
|
|
||||||
* the static functions {@link LuaValue#valueOf(int)} or
|
|
||||||
* {@link LuaValue#valueOf(double)} functions. This ensures that policies
|
|
||||||
* regarding pooling of instances are encapsulated.
|
|
||||||
* <p>
|
|
||||||
* There are no API's specific to LuaInteger that are useful beyond what is
|
|
||||||
* already exposed in {@link LuaValue}.
|
|
||||||
*
|
|
||||||
* @see LuaValue
|
|
||||||
* @see LuaNumber
|
|
||||||
* @see LuaDouble
|
|
||||||
* @see LuaValue#valueOf(int)
|
|
||||||
* @see LuaValue#valueOf(double)
|
|
||||||
*/
|
|
||||||
public class LuaInteger extends LuaNumber {
|
|
||||||
|
|
||||||
private static final LuaInteger[] intValues = new LuaInteger[512];
|
|
||||||
static {
|
|
||||||
for (int i = 0; i < 512; i++)
|
|
||||||
intValues[i] = new LuaInteger(i-256);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LuaInteger valueOf(int i) {
|
|
||||||
return i <= 255 && i >= -256? intValues[i+256]: new LuaInteger(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO consider moving this to LuaValue
|
|
||||||
/**
|
|
||||||
* Return a LuaNumber that represents the value provided
|
|
||||||
*
|
|
||||||
* @param l long value to represent.
|
|
||||||
* @return LuaNumber that is eithe LuaInteger or LuaDouble representing l
|
|
||||||
* @see LuaValue#valueOf(int)
|
|
||||||
* @see LuaValue#valueOf(double)
|
|
||||||
*/
|
|
||||||
public static LuaNumber valueOf(long l) {
|
|
||||||
int i = (int) l;
|
|
||||||
return l == i? i <= 255 && i >= -256? intValues[i+256]: (LuaNumber) new LuaInteger(i)
|
|
||||||
: (LuaNumber) LuaDouble.valueOf(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The value being held by this instance. */
|
|
||||||
public final int v;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Package protected constructor.
|
|
||||||
*
|
|
||||||
* @see LuaValue#valueOf(int)
|
|
||||||
**/
|
|
||||||
LuaInteger(int i) {
|
|
||||||
this.v = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isint() { return true; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isinttype() { return true; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean islong() { return true; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte tobyte() { return (byte) v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char tochar() { return (char) v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double todouble() { return v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float tofloat() { return v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int toint() { return v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long tolong() { return v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short toshort() { return (short) v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double optdouble(double defval) { return v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int optint(int defval) { return v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaInteger optinteger(LuaInteger defval) { return this; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long optlong(long defval) { return v; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String tojstring() {
|
|
||||||
return Integer.toString(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaString strvalue() {
|
|
||||||
return LuaString.valueOf(Integer.toString(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaString optstring(LuaString defval) {
|
|
||||||
return LuaString.valueOf(Integer.toString(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue tostring() {
|
|
||||||
return LuaString.valueOf(Integer.toString(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String optjstring(String defval) {
|
|
||||||
return Integer.toString(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaInteger checkinteger() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isstring() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int hashCode(int x) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unary operators
|
|
||||||
@Override
|
|
||||||
public LuaValue neg() { return valueOf(-(long) v); }
|
|
||||||
|
|
||||||
// object equality, used for key comparison
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) { return o instanceof LuaInteger? ((LuaInteger) o).v == v: false; }
|
|
||||||
|
|
||||||
// equality w/ metatable processing
|
|
||||||
@Override
|
|
||||||
public LuaValue eq(LuaValue val) { return val.raweq(v)? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean eq_b(LuaValue val) { return val.raweq(v); }
|
|
||||||
|
|
||||||
// equality w/o metatable processing
|
|
||||||
@Override
|
|
||||||
public boolean raweq(LuaValue val) { return val.raweq(v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean raweq(double val) { return v == val; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean raweq(int val) { return v == val; }
|
|
||||||
|
|
||||||
// arithmetic operators
|
|
||||||
@Override
|
|
||||||
public LuaValue add(LuaValue rhs) { return rhs.add(v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue add(double lhs) { return LuaDouble.valueOf(lhs+v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue add(int lhs) { return LuaInteger.valueOf(lhs+(long) v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue sub(LuaValue rhs) { return rhs.subFrom(v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue sub(double rhs) { return LuaDouble.valueOf(v-rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue sub(int rhs) { return LuaValue.valueOf(v-rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue subFrom(double lhs) { return LuaDouble.valueOf(lhs-v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue subFrom(int lhs) { return LuaInteger.valueOf(lhs-(long) v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue mul(LuaValue rhs) { return rhs.mul(v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue mul(double lhs) { return LuaDouble.valueOf(lhs*v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue mul(int lhs) { return LuaInteger.valueOf(lhs*(long) v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue pow(LuaValue rhs) { return rhs.powWith(v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue pow(double rhs) { return MathLib.dpow(v, rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue pow(int rhs) { return MathLib.dpow(v, rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue powWith(double lhs) { return MathLib.dpow(lhs, v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue powWith(int lhs) { return MathLib.dpow(lhs, v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue div(LuaValue rhs) { return rhs.divInto(v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue div(double rhs) { return LuaDouble.ddiv(v, rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue div(int rhs) { return LuaDouble.ddiv(v, rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue divInto(double lhs) { return LuaDouble.ddiv(lhs, v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue mod(LuaValue rhs) { return rhs.modFrom(v); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue mod(double rhs) { return LuaDouble.dmod(v, rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue mod(int rhs) { return LuaDouble.dmod(v, rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue modFrom(double lhs) { return LuaDouble.dmod(lhs, v); }
|
|
||||||
|
|
||||||
// relational operators
|
|
||||||
@Override
|
|
||||||
public LuaValue lt(LuaValue rhs) { return rhs instanceof LuaNumber? rhs.gt_b(v)? TRUE: FALSE: super.lt(rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue lt(double rhs) { return v < rhs? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue lt(int rhs) { return v < rhs? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean lt_b(LuaValue rhs) { return rhs instanceof LuaNumber? rhs.gt_b(v): super.lt_b(rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean lt_b(int rhs) { return v < rhs; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean lt_b(double rhs) { return v < rhs; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue lteq(LuaValue rhs) {
|
|
||||||
return rhs instanceof LuaNumber? rhs.gteq_b(v)? TRUE: FALSE: super.lteq(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue lteq(double rhs) { return v <= rhs? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue lteq(int rhs) { return v <= rhs? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean lteq_b(LuaValue rhs) { return rhs instanceof LuaNumber? rhs.gteq_b(v): super.lteq_b(rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean lteq_b(int rhs) { return v <= rhs; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean lteq_b(double rhs) { return v <= rhs; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue gt(LuaValue rhs) { return rhs instanceof LuaNumber? rhs.lt_b(v)? TRUE: FALSE: super.gt(rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue gt(double rhs) { return v > rhs? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue gt(int rhs) { return v > rhs? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean gt_b(LuaValue rhs) { return rhs instanceof LuaNumber? rhs.lt_b(v): super.gt_b(rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean gt_b(int rhs) { return v > rhs; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean gt_b(double rhs) { return v > rhs; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue gteq(LuaValue rhs) {
|
|
||||||
return rhs instanceof LuaNumber? rhs.lteq_b(v)? TRUE: FALSE: super.gteq(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue gteq(double rhs) { return v >= rhs? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue gteq(int rhs) { return v >= rhs? TRUE: FALSE; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean gteq_b(LuaValue rhs) { return rhs instanceof LuaNumber? rhs.lteq_b(v): super.gteq_b(rhs); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean gteq_b(int rhs) { return v >= rhs; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean gteq_b(double rhs) { return v >= rhs; }
|
|
||||||
|
|
||||||
// string comparison
|
|
||||||
@Override
|
|
||||||
public int strcmp(LuaString rhs) { typerror("attempt to compare number with string"); return 0; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int checkint() {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long checklong() {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double checkdouble() {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String checkjstring() {
|
|
||||||
return String.valueOf(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaString checkstring() {
|
|
||||||
return valueOf(String.valueOf(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,445 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debug helper class to pretty-print lua bytecodes.
|
|
||||||
*
|
|
||||||
* @see Prototype
|
|
||||||
* @see LuaClosure
|
|
||||||
*/
|
|
||||||
public class Print extends Lua {
|
|
||||||
|
|
||||||
/** opcode names */
|
|
||||||
private static final String STRING_FOR_NULL = "null";
|
|
||||||
public static PrintStream ps = System.out;
|
|
||||||
|
|
||||||
/** String names for each lua opcode value. */
|
|
||||||
public static final String[] OPNAMES = { "MOVE", "LOADK", "LOADKX", "LOADBOOL", "LOADNIL", "GETUPVAL", "GETTABUP",
|
|
||||||
"GETTABLE", "SETTABUP", "SETUPVAL", "SETTABLE", "NEWTABLE", "SELF", "ADD", "SUB", "MUL", "DIV", "MOD",
|
|
||||||
"POW", "UNM", "NOT", "LEN", "CONCAT", "JMP", "EQ", "LT", "LE", "TEST", "TESTSET", "CALL", "TAILCALL",
|
|
||||||
"RETURN", "FORLOOP", "FORPREP", "TFORCALL", "TFORLOOP", "SETLIST", "CLOSURE", "VARARG", "EXTRAARG", null, };
|
|
||||||
|
|
||||||
static void printString(PrintStream ps, final LuaString s) {
|
|
||||||
|
|
||||||
ps.print('"');
|
|
||||||
for (int i = 0, n = s.m_length; i < n; i++) {
|
|
||||||
int c = s.m_bytes[s.m_offset+i];
|
|
||||||
if (c >= ' ' && c <= '~' && c != '\"' && c != '\\')
|
|
||||||
ps.print((char) c);
|
|
||||||
else {
|
|
||||||
switch (c) {
|
|
||||||
case '"':
|
|
||||||
ps.print("\\\"");
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
ps.print("\\\\");
|
|
||||||
break;
|
|
||||||
case 0x0007: /* bell */
|
|
||||||
ps.print("\\a");
|
|
||||||
break;
|
|
||||||
case '\b': /* backspace */
|
|
||||||
ps.print("\\b");
|
|
||||||
break;
|
|
||||||
case '\f': /* form feed */
|
|
||||||
ps.print("\\f");
|
|
||||||
break;
|
|
||||||
case '\t': /* tab */
|
|
||||||
ps.print("\\t");
|
|
||||||
break;
|
|
||||||
case '\r': /* carriage return */
|
|
||||||
ps.print("\\r");
|
|
||||||
break;
|
|
||||||
case '\n': /* newline */
|
|
||||||
ps.print("\\n");
|
|
||||||
break;
|
|
||||||
case 0x000B: /* vertical tab */
|
|
||||||
ps.print("\\v");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ps.print('\\');
|
|
||||||
ps.print(Integer.toString(1000+0xff & c).substring(1));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ps.print('"');
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printValue(PrintStream ps, LuaValue v) {
|
|
||||||
if (v == null) {
|
|
||||||
ps.print("null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (v.type()) {
|
|
||||||
case LuaValue.TSTRING:
|
|
||||||
printString(ps, (LuaString) v);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ps.print(v.tojstring());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printConstant(PrintStream ps, Prototype f, int i) {
|
|
||||||
printValue(ps, i < f.k.length? f.k[i]: LuaValue.valueOf("UNKNOWN_CONST_" + i));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printUpvalue(PrintStream ps, Upvaldesc u) {
|
|
||||||
ps.print(u.idx + " ");
|
|
||||||
printValue(ps, u.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the code in a prototype
|
|
||||||
*
|
|
||||||
* @param f the {@link Prototype}
|
|
||||||
*/
|
|
||||||
public static void printCode(Prototype f) {
|
|
||||||
int[] code = f.code;
|
|
||||||
int pc, n = code.length;
|
|
||||||
for (pc = 0; pc < n; pc++) {
|
|
||||||
pc = printOpCode(f, pc);
|
|
||||||
ps.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print an opcode in a prototype
|
|
||||||
*
|
|
||||||
* @param f the {@link Prototype}
|
|
||||||
* @param pc the program counter to look up and print
|
|
||||||
* @return pc same as above or changed
|
|
||||||
*/
|
|
||||||
public static int printOpCode(Prototype f, int pc) {
|
|
||||||
return printOpCode(ps, f, pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print an opcode in a prototype
|
|
||||||
*
|
|
||||||
* @param ps the {@link PrintStream} to print to
|
|
||||||
* @param f the {@link Prototype}
|
|
||||||
* @param pc the program counter to look up and print
|
|
||||||
* @return pc same as above or changed
|
|
||||||
*/
|
|
||||||
public static int printOpCode(PrintStream ps, Prototype f, int pc) {
|
|
||||||
int[] code = f.code;
|
|
||||||
int i = code[pc];
|
|
||||||
int o = GET_OPCODE(i);
|
|
||||||
int a = GETARG_A(i);
|
|
||||||
int b = GETARG_B(i);
|
|
||||||
int c = GETARG_C(i);
|
|
||||||
int bx = GETARG_Bx(i);
|
|
||||||
int sbx = GETARG_sBx(i);
|
|
||||||
int line = getline(f, pc);
|
|
||||||
ps.print(" " + (pc+1) + " ");
|
|
||||||
if (line > 0)
|
|
||||||
ps.print("[" + line + "] ");
|
|
||||||
else
|
|
||||||
ps.print("[-] ");
|
|
||||||
if (o >= OPNAMES.length-1) {
|
|
||||||
ps.print("UNKNOWN_OP_" + o + " ");
|
|
||||||
} else {
|
|
||||||
ps.print(OPNAMES[o] + " ");
|
|
||||||
switch (getOpMode(o)) {
|
|
||||||
case iABC:
|
|
||||||
ps.print(a);
|
|
||||||
if (getBMode(o) != OpArgN)
|
|
||||||
ps.print(" " + (ISK(b)? -1-INDEXK(b): b));
|
|
||||||
if (getCMode(o) != OpArgN)
|
|
||||||
ps.print(" " + (ISK(c)? -1-INDEXK(c): c));
|
|
||||||
break;
|
|
||||||
case iABx:
|
|
||||||
if (getBMode(o) == OpArgK) {
|
|
||||||
ps.print(a + " " + (-1-bx));
|
|
||||||
} else {
|
|
||||||
ps.print(a + " " + bx);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case iAsBx:
|
|
||||||
if (o == OP_JMP)
|
|
||||||
ps.print(sbx);
|
|
||||||
else
|
|
||||||
ps.print(a + " " + sbx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (o) {
|
|
||||||
case OP_LOADK:
|
|
||||||
ps.print(" ; ");
|
|
||||||
printConstant(ps, f, bx);
|
|
||||||
break;
|
|
||||||
case OP_GETUPVAL:
|
|
||||||
case OP_SETUPVAL:
|
|
||||||
ps.print(" ; ");
|
|
||||||
if (b < f.upvalues.length) {
|
|
||||||
printUpvalue(ps, f.upvalues[b]);
|
|
||||||
} else {
|
|
||||||
ps.print("UNKNOWN_UPVALUE_" + b);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OP_GETTABUP:
|
|
||||||
ps.print(" ; ");
|
|
||||||
if (b < f.upvalues.length) {
|
|
||||||
printUpvalue(ps, f.upvalues[b]);
|
|
||||||
} else {
|
|
||||||
ps.print("UNKNOWN_UPVALUE_" + b);
|
|
||||||
}
|
|
||||||
ps.print(" ");
|
|
||||||
if (ISK(c))
|
|
||||||
printConstant(ps, f, INDEXK(c));
|
|
||||||
else
|
|
||||||
ps.print("-");
|
|
||||||
break;
|
|
||||||
case OP_SETTABUP:
|
|
||||||
ps.print(" ; ");
|
|
||||||
if (a < f.upvalues.length) {
|
|
||||||
printUpvalue(ps, f.upvalues[a]);
|
|
||||||
} else {
|
|
||||||
ps.print("UNKNOWN_UPVALUE_" + a);
|
|
||||||
}
|
|
||||||
ps.print(" ");
|
|
||||||
if (ISK(b))
|
|
||||||
printConstant(ps, f, INDEXK(b));
|
|
||||||
else
|
|
||||||
ps.print("-");
|
|
||||||
ps.print(" ");
|
|
||||||
if (ISK(c))
|
|
||||||
printConstant(ps, f, INDEXK(c));
|
|
||||||
else
|
|
||||||
ps.print("-");
|
|
||||||
break;
|
|
||||||
case OP_GETTABLE:
|
|
||||||
case OP_SELF:
|
|
||||||
if (ISK(c)) {
|
|
||||||
ps.print(" ; ");
|
|
||||||
printConstant(ps, f, INDEXK(c));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OP_SETTABLE:
|
|
||||||
case OP_ADD:
|
|
||||||
case OP_SUB:
|
|
||||||
case OP_MUL:
|
|
||||||
case OP_DIV:
|
|
||||||
case OP_POW:
|
|
||||||
case OP_EQ:
|
|
||||||
case OP_LT:
|
|
||||||
case OP_LE:
|
|
||||||
if (ISK(b) || ISK(c)) {
|
|
||||||
ps.print(" ; ");
|
|
||||||
if (ISK(b))
|
|
||||||
printConstant(ps, f, INDEXK(b));
|
|
||||||
else
|
|
||||||
ps.print("-");
|
|
||||||
ps.print(" ");
|
|
||||||
if (ISK(c))
|
|
||||||
printConstant(ps, f, INDEXK(c));
|
|
||||||
else
|
|
||||||
ps.print("-");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OP_JMP:
|
|
||||||
case OP_FORLOOP:
|
|
||||||
case OP_FORPREP:
|
|
||||||
ps.print(" ; to " + (sbx+pc+2));
|
|
||||||
break;
|
|
||||||
case OP_CLOSURE:
|
|
||||||
if (bx < f.p.length) {
|
|
||||||
ps.print(" ; " + f.p[bx].getClass().getName());
|
|
||||||
} else {
|
|
||||||
ps.print(" ; UNKNOWN_PROTYPE_" + bx);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OP_SETLIST:
|
|
||||||
if (c == 0)
|
|
||||||
ps.print(" ; " + code[++pc] + " (stored in the next OP)");
|
|
||||||
else
|
|
||||||
ps.print(" ; " + c);
|
|
||||||
break;
|
|
||||||
case OP_VARARG:
|
|
||||||
ps.print(" ; is_vararg=" + f.is_vararg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getline(Prototype f, int pc) {
|
|
||||||
return pc > 0 && f.lineinfo != null && pc < f.lineinfo.length? f.lineinfo[pc]: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printHeader(Prototype f) {
|
|
||||||
String s = String.valueOf(f.source);
|
|
||||||
if (s.startsWith("@") || s.startsWith("="))
|
|
||||||
s = s.substring(1);
|
|
||||||
else if ("\033Lua".equals(s))
|
|
||||||
s = "(bstring)";
|
|
||||||
else
|
|
||||||
s = "(string)";
|
|
||||||
String a = f.linedefined == 0? "main": "function";
|
|
||||||
ps.print("\n%" + a + " <" + s + ":" + f.linedefined + "," + f.lastlinedefined + "> (" + f.code.length
|
|
||||||
+ " instructions, " + f.code.length*4 + " bytes at " + id(f) + ")\n");
|
|
||||||
ps.print(f.numparams + " param, " + f.maxstacksize + " slot, " + f.upvalues.length + " upvalue, ");
|
|
||||||
ps.print(f.locvars.length + " local, " + f.k.length + " constant, " + f.p.length + " function\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printConstants(Prototype f) {
|
|
||||||
int i, n = f.k.length;
|
|
||||||
ps.print("constants (" + n + ") for " + id(f) + ":\n");
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
ps.print(" " + (i+1) + " ");
|
|
||||||
printValue(ps, f.k[i]);
|
|
||||||
ps.print("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printLocals(Prototype f) {
|
|
||||||
int i, n = f.locvars.length;
|
|
||||||
ps.print("locals (" + n + ") for " + id(f) + ":\n");
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
ps.println(
|
|
||||||
" " + i + " " + f.locvars[i].varname + " " + (f.locvars[i].startpc+1) + " " + (f.locvars[i].endpc+1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void printUpValues(Prototype f) {
|
|
||||||
int i, n = f.upvalues.length;
|
|
||||||
ps.print("upvalues (" + n + ") for " + id(f) + ":\n");
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
ps.print(" " + i + " " + f.upvalues[i] + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pretty-prints contents of a Prototype.
|
|
||||||
*
|
|
||||||
* @param prototype Prototype to print.
|
|
||||||
*/
|
|
||||||
public static void print(Prototype prototype) {
|
|
||||||
printFunction(prototype, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pretty-prints contents of a Prototype in short or long form.
|
|
||||||
*
|
|
||||||
* @param prototype Prototype to print.
|
|
||||||
* @param full true to print all fields, false to print short form.
|
|
||||||
*/
|
|
||||||
public static void printFunction(Prototype prototype, boolean full) {
|
|
||||||
int i, n = prototype.p.length;
|
|
||||||
printHeader(prototype);
|
|
||||||
printCode(prototype);
|
|
||||||
if (full) {
|
|
||||||
printConstants(prototype);
|
|
||||||
printLocals(prototype);
|
|
||||||
printUpValues(prototype);
|
|
||||||
}
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
printFunction(prototype.p[i], full);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void format(String s, int maxcols) {
|
|
||||||
int n = s.length();
|
|
||||||
if (n > maxcols)
|
|
||||||
ps.print(s.substring(0, maxcols));
|
|
||||||
else {
|
|
||||||
ps.print(s);
|
|
||||||
for (int i = maxcols-n; --i >= 0;)
|
|
||||||
ps.print(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String id(Prototype f) {
|
|
||||||
return "Proto";
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _assert(boolean b) {
|
|
||||||
if (!b)
|
|
||||||
throw new NullPointerException("_assert failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the state of a {@link LuaClosure} that is being executed
|
|
||||||
*
|
|
||||||
* @param cl the {@link LuaClosure}
|
|
||||||
* @param pc the program counter
|
|
||||||
* @param stack the stack of {@link LuaValue}
|
|
||||||
* @param top the top of the stack
|
|
||||||
* @param varargs any {@link Varargs} value that may apply
|
|
||||||
*/
|
|
||||||
public static void printState(LuaClosure cl, int pc, LuaValue[] stack, int top, Varargs varargs) {
|
|
||||||
// print opcode into buffer
|
|
||||||
PrintStream previous = ps;
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
ps = new PrintStream(baos);
|
|
||||||
printOpCode(cl.p, pc);
|
|
||||||
ps.flush();
|
|
||||||
ps.close();
|
|
||||||
ps = previous;
|
|
||||||
format(baos.toString(), 50);
|
|
||||||
printStack(stack, top, varargs);
|
|
||||||
ps.println();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void printStack(LuaValue[] stack, int top, Varargs varargs) {
|
|
||||||
// print stack
|
|
||||||
ps.print('[');
|
|
||||||
for (int i = 0; i < stack.length; i++) {
|
|
||||||
LuaValue v = stack[i];
|
|
||||||
if (v == null)
|
|
||||||
ps.print(STRING_FOR_NULL);
|
|
||||||
else
|
|
||||||
switch (v.type()) {
|
|
||||||
case LuaValue.TSTRING:
|
|
||||||
LuaString s = v.checkstring();
|
|
||||||
ps.print(s.length() < 48? s.tojstring()
|
|
||||||
: s.substring(0, 32).tojstring() + "...+" + (s.length()-32) + "b");
|
|
||||||
break;
|
|
||||||
case LuaValue.TFUNCTION:
|
|
||||||
ps.print(v.tojstring());
|
|
||||||
break;
|
|
||||||
case LuaValue.TUSERDATA:
|
|
||||||
Object o = v.touserdata();
|
|
||||||
if (o != null) {
|
|
||||||
String n = o.getClass().getName();
|
|
||||||
n = n.substring(n.lastIndexOf('.')+1);
|
|
||||||
ps.print(n + ": " + Integer.toHexString(o.hashCode()));
|
|
||||||
} else {
|
|
||||||
ps.print(v.toString());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ps.print(v.tojstring());
|
|
||||||
}
|
|
||||||
if (i+1 == top)
|
|
||||||
ps.print(']');
|
|
||||||
ps.print(" | ");
|
|
||||||
}
|
|
||||||
ps.print(varargs);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prototype representing compiled lua code.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* This is both a straight translation of the corresponding C type, and the main
|
|
||||||
* data structure for execution of compiled lua bytecode.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Generally, the {@link Prototype} is not constructed directly is an
|
|
||||||
* intermediate result as lua code is loaded using
|
|
||||||
* {@link Globals#load(java.io.Reader, String)}:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
|
||||||
* globals.load(new StringReader("print 'hello'"), "main.lua").call();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* To create a {@link Prototype} directly, a compiler such as
|
|
||||||
* {@link org.luaj.vm2.compiler.LuaC} may be used:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* InputStream is = new ByteArrayInputStream("print('hello,world')".getBytes());
|
|
||||||
* Prototype p = LuaC.instance.compile(is, "script");
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* To simplify loading, the
|
|
||||||
* {@link Globals#compilePrototype(java.io.InputStream, String)} method may be
|
|
||||||
* used:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Prototype p = globals.compileProtoytpe(is, "script");
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* It may also be loaded from a {@link java.io.Reader} via
|
|
||||||
* {@link Globals#compilePrototype(java.io.Reader, String)}:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Prototype p = globals.compileProtoytpe(new StringReader(script), "script");
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* To un-dump a binary file known to be a binary lua file that has been dumped
|
|
||||||
* to a string, the {@link Globals.Undumper} interface may be used:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* FileInputStream lua_binary_file = new FileInputStream("foo.lc"); // Known to be compiled lua.
|
|
||||||
* Prototype p = globals.undumper.undump(lua_binary_file, "foo.lua");
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* To execute the code represented by the {@link Prototype} it must be supplied
|
|
||||||
* to the constructor of a {@link LuaClosure}:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
|
||||||
* LuaClosure f = new LuaClosure(p, globals);
|
|
||||||
* f.call();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* To simplify the debugging of prototype values, the contents may be printed
|
|
||||||
* using {@link Print#print}:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {@code
|
|
||||||
* Print.print(p);
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* @see LuaClosure
|
|
||||||
* @see Globals
|
|
||||||
* @see Globals#undumper
|
|
||||||
* @see Globals#compiler
|
|
||||||
* @see Print#print
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class Prototype {
|
|
||||||
/* constants used by the function */
|
|
||||||
public LuaValue[] k;
|
|
||||||
public int[] code;
|
|
||||||
/* functions defined inside the function */
|
|
||||||
public Prototype[] p;
|
|
||||||
/* map from opcodes to source lines */
|
|
||||||
public int[] lineinfo;
|
|
||||||
/* information about local variables */
|
|
||||||
public LocVars[] locvars;
|
|
||||||
/* upvalue information */
|
|
||||||
public Upvaldesc[] upvalues;
|
|
||||||
public LuaString source;
|
|
||||||
public int linedefined;
|
|
||||||
public int lastlinedefined;
|
|
||||||
public int numparams;
|
|
||||||
public int is_vararg;
|
|
||||||
public int maxstacksize;
|
|
||||||
private static final Upvaldesc[] NOUPVALUES = {};
|
|
||||||
private static final Prototype[] NOSUBPROTOS = {};
|
|
||||||
|
|
||||||
public Prototype() {
|
|
||||||
p = NOSUBPROTOS;
|
|
||||||
upvalues = NOUPVALUES;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Prototype(int n_upvalues) {
|
|
||||||
p = NOSUBPROTOS;
|
|
||||||
upvalues = new Upvaldesc[n_upvalues];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return source + ":" + linedefined + "-" + lastlinedefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the name of a local variable.
|
|
||||||
*
|
|
||||||
* @param number the local variable number to look up
|
|
||||||
* @param pc the program counter
|
|
||||||
* @return the name, or null if not found
|
|
||||||
*/
|
|
||||||
public LuaString getlocalname(int number, int pc) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < locvars.length && locvars[i].startpc <= pc; i++) {
|
|
||||||
if (pc < locvars[i].endpc) { /* is variable active? */
|
|
||||||
number--;
|
|
||||||
if (number == 0)
|
|
||||||
return locvars[i].varname;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null; /* not found */
|
|
||||||
}
|
|
||||||
|
|
||||||
public String shortsource() {
|
|
||||||
String name = source.tojstring();
|
|
||||||
if (name.startsWith("@") || name.startsWith("="))
|
|
||||||
name = name.substring(1);
|
|
||||||
else if (name.startsWith("\033"))
|
|
||||||
name = "binary string";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package org.luaj.vm2.compat;
|
|
||||||
|
|
||||||
public class JavaCompat {
|
|
||||||
public static final JavaCompat INSTANCE;
|
|
||||||
|
|
||||||
static {
|
|
||||||
JavaCompat instance;
|
|
||||||
try {
|
|
||||||
instance = (JavaCompat) Class.forName("org.luaj.vm2.lib.jse.JavaCompatJSE").newInstance();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
instance = new JavaCompat();
|
|
||||||
}
|
|
||||||
INSTANCE = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long doubleToRawLongBits(double x) {
|
|
||||||
return Double.doubleToLongBits(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,748 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2.lib;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.EOFException;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaString;
|
|
||||||
import org.luaj.vm2.LuaTable;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Varargs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract base class extending {@link LibFunction} which implements the core
|
|
||||||
* of the lua standard {@code io} library.
|
|
||||||
* <p>
|
|
||||||
* It contains the implementation of the io library support that is common to
|
|
||||||
* the JSE and JME platforms. In practice on of the concrete IOLib subclasses is
|
|
||||||
* chosen: {@link org.luaj.vm2.lib.jse.JseIoLib} for the JSE platform, and
|
|
||||||
* {@link org.luaj.vm2.lib.jme.JmeIoLib} for the JME platform.
|
|
||||||
* <p>
|
|
||||||
* The JSE implementation conforms almost completely to the C-based lua library,
|
|
||||||
* while the JME implementation follows closely except in the area of
|
|
||||||
* random-access files, which are difficult to support properly on JME.
|
|
||||||
* <p>
|
|
||||||
* Typically, this library is included as part of a call to either
|
|
||||||
* {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or
|
|
||||||
* {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()}
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
|
||||||
* globals.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* In this example the platform-specific {@link org.luaj.vm2.lib.jse.JseIoLib}
|
|
||||||
* library will be loaded, which will include the base functionality provided by
|
|
||||||
* this class, whereas the {@link org.luaj.vm2.lib.jse.JsePlatform} would load
|
|
||||||
* the {@link org.luaj.vm2.lib.jse.JseIoLib}.
|
|
||||||
* <p>
|
|
||||||
* To instantiate and use it directly, link it into your globals table via
|
|
||||||
* {@link LuaValue#load(LuaValue)} using code such as:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = new Globals();
|
|
||||||
* globals.load(new JseBaseLib());
|
|
||||||
* globals.load(new PackageLib());
|
|
||||||
* globals.load(new OsLib());
|
|
||||||
* globals.get("io").get("write").call(LuaValue.valueOf("hello, world\n"));
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
* This has been implemented to match as closely as possible the behavior in the
|
|
||||||
* corresponding library in C.
|
|
||||||
*
|
|
||||||
* @see LibFunction
|
|
||||||
* @see org.luaj.vm2.lib.jse.JsePlatform
|
|
||||||
* @see org.luaj.vm2.lib.jme.JmePlatform
|
|
||||||
* @see org.luaj.vm2.lib.jse.JseIoLib
|
|
||||||
* @see org.luaj.vm2.lib.jme.JmeIoLib
|
|
||||||
* @see <a href=
|
|
||||||
* "http://www.lua.org/manual/5.1/manual.html#5.7">http://www.lua.org/manual/5.1/manual.html#5.7</a>
|
|
||||||
*/
|
|
||||||
public abstract class IoLib extends TwoArgFunction {
|
|
||||||
|
|
||||||
protected abstract class File extends LuaValue {
|
|
||||||
public abstract void write(LuaString string) throws IOException;
|
|
||||||
|
|
||||||
public abstract void flush() throws IOException;
|
|
||||||
|
|
||||||
public abstract boolean isstdfile();
|
|
||||||
|
|
||||||
public abstract void close() throws IOException;
|
|
||||||
|
|
||||||
public abstract boolean isclosed();
|
|
||||||
|
|
||||||
// returns new position
|
|
||||||
public abstract int seek(String option, int bytecount) throws IOException;
|
|
||||||
|
|
||||||
public abstract void setvbuf(String mode, int size);
|
|
||||||
|
|
||||||
// get length remaining to read
|
|
||||||
public abstract int remaining() throws IOException;
|
|
||||||
|
|
||||||
// peek ahead one character
|
|
||||||
public abstract int peek() throws IOException, EOFException;
|
|
||||||
|
|
||||||
// return char if read, -1 if eof, throw IOException on other exception
|
|
||||||
public abstract int read() throws IOException, EOFException;
|
|
||||||
|
|
||||||
// return number of bytes read if positive, false if eof, throw IOException on other exception
|
|
||||||
public abstract int read(byte[] bytes, int offset, int length) throws IOException;
|
|
||||||
|
|
||||||
public boolean eof() throws IOException {
|
|
||||||
try {
|
|
||||||
return peek() < 0;
|
|
||||||
} catch (EOFException e) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// delegate method access to file methods table
|
|
||||||
@Override
|
|
||||||
public LuaValue get(LuaValue key) {
|
|
||||||
return filemethods.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// essentially a userdata instance
|
|
||||||
@Override
|
|
||||||
public int type() {
|
|
||||||
return LuaValue.TUSERDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String typename() {
|
|
||||||
return "userdata";
|
|
||||||
}
|
|
||||||
|
|
||||||
// displays as "file" type
|
|
||||||
@Override
|
|
||||||
public String tojstring() {
|
|
||||||
return "file: " + Integer.toHexString(hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void finalize() {
|
|
||||||
if (!isclosed()) {
|
|
||||||
try {
|
|
||||||
close();
|
|
||||||
} catch (IOException ignore) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Enumerated value representing stdin */
|
|
||||||
protected static final int FTYPE_STDIN = 0;
|
|
||||||
/** Enumerated value representing stdout */
|
|
||||||
protected static final int FTYPE_STDOUT = 1;
|
|
||||||
/** Enumerated value representing stderr */
|
|
||||||
protected static final int FTYPE_STDERR = 2;
|
|
||||||
/** Enumerated value representing a file type for a named file */
|
|
||||||
protected static final int FTYPE_NAMED = 3;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap the standard input.
|
|
||||||
*
|
|
||||||
* @return File
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
abstract protected File wrapStdin() throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap the standard output.
|
|
||||||
*
|
|
||||||
* @return File
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
abstract protected File wrapStdout() throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap the standard error output.
|
|
||||||
*
|
|
||||||
* @return File
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
abstract protected File wrapStderr() throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a file in a particular mode.
|
|
||||||
*
|
|
||||||
* @param filename
|
|
||||||
* @param readMode true if opening in read mode
|
|
||||||
* @param appendMode true if opening in append mode
|
|
||||||
* @param updateMode true if opening in update mode
|
|
||||||
* @param binaryMode true if opening in binary mode
|
|
||||||
* @return File object if successful
|
|
||||||
* @throws IOException if could not be opened
|
|
||||||
*/
|
|
||||||
abstract protected File openFile(String filename, boolean readMode, boolean appendMode, boolean updateMode,
|
|
||||||
boolean binaryMode) throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a temporary file.
|
|
||||||
*
|
|
||||||
* @return File object if successful
|
|
||||||
* @throws IOException if could not be opened
|
|
||||||
*/
|
|
||||||
abstract protected File tmpFile() throws IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a new process and return a file for input or output
|
|
||||||
*
|
|
||||||
* @param prog the program to execute
|
|
||||||
* @param mode "r" to read, "w" to write
|
|
||||||
* @return File to read to or write from
|
|
||||||
* @throws IOException if an i/o exception occurs
|
|
||||||
*/
|
|
||||||
abstract protected File openProgram(String prog, String mode) throws IOException;
|
|
||||||
|
|
||||||
private File infile = null;
|
|
||||||
private File outfile = null;
|
|
||||||
private File errfile = null;
|
|
||||||
|
|
||||||
private static final LuaValue STDIN = valueOf("stdin");
|
|
||||||
private static final LuaValue STDOUT = valueOf("stdout");
|
|
||||||
private static final LuaValue STDERR = valueOf("stderr");
|
|
||||||
private static final LuaValue FILE = valueOf("file");
|
|
||||||
private static final LuaValue CLOSED_FILE = valueOf("closed file");
|
|
||||||
|
|
||||||
private static final int IO_CLOSE = 0;
|
|
||||||
private static final int IO_FLUSH = 1;
|
|
||||||
private static final int IO_INPUT = 2;
|
|
||||||
private static final int IO_LINES = 3;
|
|
||||||
private static final int IO_OPEN = 4;
|
|
||||||
private static final int IO_OUTPUT = 5;
|
|
||||||
private static final int IO_POPEN = 6;
|
|
||||||
private static final int IO_READ = 7;
|
|
||||||
private static final int IO_TMPFILE = 8;
|
|
||||||
private static final int IO_TYPE = 9;
|
|
||||||
private static final int IO_WRITE = 10;
|
|
||||||
|
|
||||||
private static final int FILE_CLOSE = 11;
|
|
||||||
private static final int FILE_FLUSH = 12;
|
|
||||||
private static final int FILE_LINES = 13;
|
|
||||||
private static final int FILE_READ = 14;
|
|
||||||
private static final int FILE_SEEK = 15;
|
|
||||||
private static final int FILE_SETVBUF = 16;
|
|
||||||
private static final int FILE_WRITE = 17;
|
|
||||||
|
|
||||||
private static final int IO_INDEX = 18;
|
|
||||||
private static final int LINES_ITER = 19;
|
|
||||||
|
|
||||||
public static final String[] IO_NAMES = { "close", "flush", "input", "lines", "open", "output", "popen", "read",
|
|
||||||
"tmpfile", "type", "write", };
|
|
||||||
|
|
||||||
public static final String[] FILE_NAMES = { "close", "flush", "lines", "read", "seek", "setvbuf", "write", };
|
|
||||||
|
|
||||||
LuaTable filemethods;
|
|
||||||
|
|
||||||
protected Globals globals;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
|
||||||
globals = env.checkglobals();
|
|
||||||
|
|
||||||
// io lib functions
|
|
||||||
LuaTable t = new LuaTable();
|
|
||||||
bind(t, IoLibV.class, IO_NAMES);
|
|
||||||
|
|
||||||
// create file methods table
|
|
||||||
filemethods = new LuaTable();
|
|
||||||
bind(filemethods, IoLibV.class, FILE_NAMES, FILE_CLOSE);
|
|
||||||
|
|
||||||
// set up file metatable
|
|
||||||
LuaTable mt = new LuaTable();
|
|
||||||
bind(mt, IoLibV.class, new String[] { "__index" }, IO_INDEX);
|
|
||||||
t.setmetatable(mt);
|
|
||||||
|
|
||||||
// all functions link to library instance
|
|
||||||
setLibInstance(t);
|
|
||||||
setLibInstance(filemethods);
|
|
||||||
setLibInstance(mt);
|
|
||||||
|
|
||||||
// return the table
|
|
||||||
env.set("io", t);
|
|
||||||
if (!env.get("package").isnil())
|
|
||||||
env.get("package").get("loaded").set("io", t);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setLibInstance(LuaTable t) {
|
|
||||||
LuaValue[] k = t.keys();
|
|
||||||
for (int i = 0, n = k.length; i < n; i++)
|
|
||||||
((IoLibV) t.get(k[i])).iolib = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class IoLibV extends VarArgFunction {
|
|
||||||
private File f;
|
|
||||||
public IoLib iolib;
|
|
||||||
private boolean toclose;
|
|
||||||
private Varargs args;
|
|
||||||
|
|
||||||
public IoLibV() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public IoLibV(File f, String name, int opcode, IoLib iolib, boolean toclose, Varargs args) {
|
|
||||||
this(f, name, opcode, iolib);
|
|
||||||
this.toclose = toclose;
|
|
||||||
this.args = args.dealias();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IoLibV(File f, String name, int opcode, IoLib iolib) {
|
|
||||||
this.f = f;
|
|
||||||
this.name = name;
|
|
||||||
this.opcode = opcode;
|
|
||||||
this.iolib = iolib;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Varargs invoke(Varargs args) {
|
|
||||||
try {
|
|
||||||
switch (opcode) {
|
|
||||||
case IO_FLUSH:
|
|
||||||
return iolib._io_flush();
|
|
||||||
case IO_TMPFILE:
|
|
||||||
return iolib._io_tmpfile();
|
|
||||||
case IO_CLOSE:
|
|
||||||
return iolib._io_close(args.arg1());
|
|
||||||
case IO_INPUT:
|
|
||||||
return iolib._io_input(args.arg1());
|
|
||||||
case IO_OUTPUT:
|
|
||||||
return iolib._io_output(args.arg1());
|
|
||||||
case IO_TYPE:
|
|
||||||
return iolib._io_type(args.arg1());
|
|
||||||
case IO_POPEN:
|
|
||||||
return iolib._io_popen(args.checkjstring(1), args.optjstring(2, "r"));
|
|
||||||
case IO_OPEN:
|
|
||||||
return iolib._io_open(args.checkjstring(1), args.optjstring(2, "r"));
|
|
||||||
case IO_LINES:
|
|
||||||
return iolib._io_lines(args);
|
|
||||||
case IO_READ:
|
|
||||||
return iolib._io_read(args);
|
|
||||||
case IO_WRITE:
|
|
||||||
return iolib._io_write(args);
|
|
||||||
|
|
||||||
case FILE_CLOSE:
|
|
||||||
return iolib._file_close(args.arg1());
|
|
||||||
case FILE_FLUSH:
|
|
||||||
return iolib._file_flush(args.arg1());
|
|
||||||
case FILE_SETVBUF:
|
|
||||||
return iolib._file_setvbuf(args.arg1(), args.checkjstring(2), args.optint(3, 8192));
|
|
||||||
case FILE_LINES:
|
|
||||||
return iolib._file_lines(args);
|
|
||||||
case FILE_READ:
|
|
||||||
return iolib._file_read(args.arg1(), args.subargs(2));
|
|
||||||
case FILE_SEEK:
|
|
||||||
return iolib._file_seek(args.arg1(), args.optjstring(2, "cur"), args.optint(3, 0));
|
|
||||||
case FILE_WRITE:
|
|
||||||
return iolib._file_write(args.arg1(), args.subargs(2));
|
|
||||||
|
|
||||||
case IO_INDEX:
|
|
||||||
return iolib._io_index(args.arg(2));
|
|
||||||
case LINES_ITER:
|
|
||||||
return iolib._lines_iter(f, toclose, this.args);
|
|
||||||
}
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
if (opcode == LINES_ITER) {
|
|
||||||
String s = ioe.getMessage();
|
|
||||||
error(s != null? s: ioe.toString());
|
|
||||||
}
|
|
||||||
return errorresult(ioe);
|
|
||||||
}
|
|
||||||
return NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private File input() {
|
|
||||||
return infile != null? infile: (infile = ioopenfile(FTYPE_STDIN, "-", "r"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.flush() -> bool
|
|
||||||
public Varargs _io_flush() throws IOException {
|
|
||||||
checkopen(output());
|
|
||||||
outfile.flush();
|
|
||||||
return LuaValue.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.tmpfile() -> file
|
|
||||||
public Varargs _io_tmpfile() throws IOException {
|
|
||||||
return tmpFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.close([file]) -> void
|
|
||||||
public Varargs _io_close(LuaValue file) throws IOException {
|
|
||||||
File f = file.isnil()? output(): checkfile(file);
|
|
||||||
checkopen(f);
|
|
||||||
return ioclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.input([file]) -> file
|
|
||||||
public Varargs _io_input(LuaValue file) {
|
|
||||||
infile = file.isnil()? input()
|
|
||||||
: file.isstring()? ioopenfile(FTYPE_NAMED, file.checkjstring(), "r"): checkfile(file);
|
|
||||||
return infile;
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.output(filename) -> file
|
|
||||||
public Varargs _io_output(LuaValue filename) {
|
|
||||||
outfile = filename.isnil()? output()
|
|
||||||
: filename.isstring()? ioopenfile(FTYPE_NAMED, filename.checkjstring(), "w"): checkfile(filename);
|
|
||||||
return outfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.type(obj) -> "file" | "closed file" | nil
|
|
||||||
public Varargs _io_type(LuaValue obj) {
|
|
||||||
File f = optfile(obj);
|
|
||||||
return f != null? f.isclosed()? CLOSED_FILE: FILE: NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.popen(prog, [mode]) -> file
|
|
||||||
public Varargs _io_popen(String prog, String mode) throws IOException {
|
|
||||||
if (!"r".equals(mode) && !"w".equals(mode))
|
|
||||||
argerror(2, "invalid value: '" + mode + "'; must be one of 'r' or 'w'");
|
|
||||||
return openProgram(prog, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.open(filename, [mode]) -> file | nil,err
|
|
||||||
public Varargs _io_open(String filename, String mode) throws IOException {
|
|
||||||
return rawopenfile(FTYPE_NAMED, filename, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.lines(filename, ...) -> iterator
|
|
||||||
public Varargs _io_lines(Varargs args) {
|
|
||||||
String filename = args.optjstring(1, null);
|
|
||||||
File infile = filename == null? input(): ioopenfile(FTYPE_NAMED, filename, "r");
|
|
||||||
checkopen(infile);
|
|
||||||
return lines(infile, filename != null, args.subargs(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.read(...) -> (...)
|
|
||||||
public Varargs _io_read(Varargs args) throws IOException {
|
|
||||||
checkopen(input());
|
|
||||||
return ioread(infile, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// io.write(...) -> void
|
|
||||||
public Varargs _io_write(Varargs args) throws IOException {
|
|
||||||
checkopen(output());
|
|
||||||
return iowrite(outfile, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// file:close() -> void
|
|
||||||
public Varargs _file_close(LuaValue file) throws IOException {
|
|
||||||
return ioclose(checkfile(file));
|
|
||||||
}
|
|
||||||
|
|
||||||
// file:flush() -> void
|
|
||||||
public Varargs _file_flush(LuaValue file) throws IOException {
|
|
||||||
checkfile(file).flush();
|
|
||||||
return LuaValue.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// file:setvbuf(mode,[size]) -> void
|
|
||||||
public Varargs _file_setvbuf(LuaValue file, String mode, int size) {
|
|
||||||
if ("no".equals(mode)) {
|
|
||||||
} else if ("full".equals(mode)) {
|
|
||||||
} else if ("line".equals(mode)) {
|
|
||||||
} else {
|
|
||||||
argerror(1, "invalid value: '" + mode + "'; must be one of 'no', 'full' or 'line'");
|
|
||||||
}
|
|
||||||
checkfile(file).setvbuf(mode, size);
|
|
||||||
return LuaValue.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// file:lines(...) -> iterator
|
|
||||||
public Varargs _file_lines(Varargs args) {
|
|
||||||
return lines(checkfile(args.arg1()), false, args.subargs(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// file:read(...) -> (...)
|
|
||||||
public Varargs _file_read(LuaValue file, Varargs subargs) throws IOException {
|
|
||||||
return ioread(checkfile(file), subargs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// file:seek([whence][,offset]) -> pos | nil,error
|
|
||||||
public Varargs _file_seek(LuaValue file, String whence, int offset) throws IOException {
|
|
||||||
if ("set".equals(whence)) {
|
|
||||||
} else if ("end".equals(whence)) {
|
|
||||||
} else if ("cur".equals(whence)) {
|
|
||||||
} else {
|
|
||||||
argerror(1, "invalid value: '" + whence + "'; must be one of 'set', 'cur' or 'end'");
|
|
||||||
}
|
|
||||||
return valueOf(checkfile(file).seek(whence, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
// file:write(...) -> void
|
|
||||||
public Varargs _file_write(LuaValue file, Varargs subargs) throws IOException {
|
|
||||||
return iowrite(checkfile(file), subargs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// __index, returns a field
|
|
||||||
public Varargs _io_index(LuaValue v) {
|
|
||||||
return v.equals(STDOUT)? output(): v.equals(STDIN)? input(): v.equals(STDERR)? errput(): NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// lines iterator(s,var) -> var'
|
|
||||||
public Varargs _lines_iter(LuaValue file, boolean toclose, Varargs args) throws IOException {
|
|
||||||
File f = optfile(file);
|
|
||||||
if (f == null)
|
|
||||||
argerror(1, "not a file: " + file);
|
|
||||||
if (f.isclosed())
|
|
||||||
error("file is already closed");
|
|
||||||
Varargs ret = ioread(f, args);
|
|
||||||
if (toclose && ret.isnil(1) && f.eof())
|
|
||||||
f.close();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private File output() {
|
|
||||||
return outfile != null? outfile: (outfile = ioopenfile(FTYPE_STDOUT, "-", "w"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private File errput() {
|
|
||||||
return errfile != null? errfile: (errfile = ioopenfile(FTYPE_STDERR, "-", "w"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private File ioopenfile(int filetype, String filename, String mode) {
|
|
||||||
try {
|
|
||||||
return rawopenfile(filetype, filename, mode);
|
|
||||||
} catch (Exception e) {
|
|
||||||
error("io error: " + e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Varargs ioclose(File f) throws IOException {
|
|
||||||
if (f.isstdfile())
|
|
||||||
return errorresult("cannot close standard file");
|
|
||||||
else {
|
|
||||||
f.close();
|
|
||||||
return successresult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Varargs successresult() {
|
|
||||||
return LuaValue.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Varargs errorresult(Exception ioe) {
|
|
||||||
String s = ioe.getMessage();
|
|
||||||
return errorresult("io error: " + (s != null? s: ioe.toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Varargs errorresult(String errortext) {
|
|
||||||
return varargsOf(NIL, valueOf(errortext));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Varargs lines(final File f, boolean toclose, Varargs args) {
|
|
||||||
try {
|
|
||||||
return new IoLibV(f, "lnext", LINES_ITER, this, toclose, args);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return error("lines: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Varargs iowrite(File f, Varargs args) throws IOException {
|
|
||||||
for (int i = 1, n = args.narg(); i <= n; i++)
|
|
||||||
f.write(args.checkstring(i));
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Varargs ioread(File f, Varargs args) throws IOException {
|
|
||||||
int i, n = args.narg();
|
|
||||||
if (n == 0)
|
|
||||||
return freadline(f, false);
|
|
||||||
LuaValue[] v = new LuaValue[n];
|
|
||||||
LuaValue ai, vi;
|
|
||||||
LuaString fmt;
|
|
||||||
for (i = 0; i < n;) {
|
|
||||||
item: switch ((ai = args.arg(i+1)).type()) {
|
|
||||||
case LuaValue.TNUMBER:
|
|
||||||
vi = freadbytes(f, ai.toint());
|
|
||||||
break item;
|
|
||||||
case LuaValue.TSTRING:
|
|
||||||
fmt = ai.checkstring();
|
|
||||||
if (fmt.m_length >= 2 && fmt.m_bytes[fmt.m_offset] == '*') {
|
|
||||||
switch (fmt.m_bytes[fmt.m_offset+1]) {
|
|
||||||
case 'n':
|
|
||||||
vi = freadnumber(f);
|
|
||||||
break item;
|
|
||||||
case 'l':
|
|
||||||
vi = freadline(f, false);
|
|
||||||
break item;
|
|
||||||
case 'L':
|
|
||||||
vi = freadline(f, true);
|
|
||||||
break item;
|
|
||||||
case 'a':
|
|
||||||
vi = freadall(f);
|
|
||||||
break item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return argerror(i+1, "(invalid format)");
|
|
||||||
}
|
|
||||||
if ((v[i++] = vi).isnil())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return i == 0? NIL: varargsOf(v, 0, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static File checkfile(LuaValue val) {
|
|
||||||
File f = optfile(val);
|
|
||||||
if (f == null)
|
|
||||||
argerror(1, "file");
|
|
||||||
checkopen(f);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static File optfile(LuaValue val) {
|
|
||||||
return (val instanceof File)? (File) val: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static File checkopen(File file) {
|
|
||||||
if (file.isclosed())
|
|
||||||
error("attempt to use a closed file");
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
private File rawopenfile(int filetype, String filename, String mode) throws IOException {
|
|
||||||
int len = mode.length();
|
|
||||||
for (int i = 0; i < len; i++) { // [rwa][+]?b*
|
|
||||||
char ch = mode.charAt(i);
|
|
||||||
if ((i == 0 && "rwa".indexOf(ch) >= 0) || (i == 1 && ch == '+'))
|
|
||||||
continue;
|
|
||||||
if (i >= 1 && ch == 'b')
|
|
||||||
continue;
|
|
||||||
len = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (len <= 0)
|
|
||||||
argerror(2, "invalid mode: '" + mode + "'");
|
|
||||||
|
|
||||||
switch (filetype) {
|
|
||||||
case FTYPE_STDIN:
|
|
||||||
return wrapStdin();
|
|
||||||
case FTYPE_STDOUT:
|
|
||||||
return wrapStdout();
|
|
||||||
case FTYPE_STDERR:
|
|
||||||
return wrapStderr();
|
|
||||||
}
|
|
||||||
boolean isreadmode = mode.startsWith("r");
|
|
||||||
boolean isappend = mode.startsWith("a");
|
|
||||||
boolean isupdate = mode.indexOf('+') > 0;
|
|
||||||
boolean isbinary = mode.endsWith("b");
|
|
||||||
return openFile(filename, isreadmode, isappend, isupdate, isbinary);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------- file reading utilitied ------------------
|
|
||||||
|
|
||||||
public static LuaValue freadbytes(File f, int count) throws IOException {
|
|
||||||
if (count == 0)
|
|
||||||
return f.eof()? NIL: EMPTYSTRING;
|
|
||||||
byte[] b = new byte[count];
|
|
||||||
int r;
|
|
||||||
if ((r = f.read(b, 0, b.length)) < 0)
|
|
||||||
return NIL;
|
|
||||||
return LuaString.valueUsing(b, 0, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LuaValue freaduntil(File f, boolean lineonly, boolean withend) throws IOException {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
int c;
|
|
||||||
try {
|
|
||||||
if (lineonly) {
|
|
||||||
loop: while ( (c = f.read()) >= 0 ) {
|
|
||||||
switch (c) {
|
|
||||||
case '\r':
|
|
||||||
if (withend)
|
|
||||||
baos.write(c);
|
|
||||||
break;
|
|
||||||
case '\n':
|
|
||||||
if (withend)
|
|
||||||
baos.write(c);
|
|
||||||
break loop;
|
|
||||||
default:
|
|
||||||
baos.write(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ( (c = f.read()) >= 0 )
|
|
||||||
baos.write(c);
|
|
||||||
}
|
|
||||||
} catch (EOFException e) {
|
|
||||||
c = -1;
|
|
||||||
}
|
|
||||||
return (c < 0 && baos.size() == 0)? (LuaValue) NIL: (LuaValue) LuaString.valueUsing(baos.toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LuaValue freadline(File f, boolean withend) throws IOException {
|
|
||||||
return freaduntil(f, true, withend);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LuaValue freadall(File f) throws IOException {
|
|
||||||
int n = f.remaining();
|
|
||||||
if (n >= 0) {
|
|
||||||
return n == 0? EMPTYSTRING: freadbytes(f, n);
|
|
||||||
} else {
|
|
||||||
return freaduntil(f, false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LuaValue freadnumber(File f) throws IOException {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
freadchars(f, " \t\r\n", null);
|
|
||||||
freadchars(f, "-+", baos);
|
|
||||||
//freadchars(f,"0",baos);
|
|
||||||
//freadchars(f,"xX",baos);
|
|
||||||
freadchars(f, "0123456789", baos);
|
|
||||||
freadchars(f, ".", baos);
|
|
||||||
freadchars(f, "0123456789", baos);
|
|
||||||
//freadchars(f,"eEfFgG",baos);
|
|
||||||
// freadchars(f,"+-",baos);
|
|
||||||
//freadchars(f,"0123456789",baos);
|
|
||||||
String s = baos.toString();
|
|
||||||
return s.length() > 0? valueOf(Double.parseDouble(s)): NIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void freadchars(File f, String chars, ByteArrayOutputStream baos) throws IOException {
|
|
||||||
int c;
|
|
||||||
while ( true ) {
|
|
||||||
c = f.peek();
|
|
||||||
if (chars.indexOf(c) < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
f.read();
|
|
||||||
if (baos != null)
|
|
||||||
baos.write(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,522 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2.lib;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.time.format.TextStyle;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.luaj.vm2.Buffer;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaTable;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Varargs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subclass of {@link LibFunction} which implements the standard lua {@code os}
|
|
||||||
* library.
|
|
||||||
* <p>
|
|
||||||
* It is a usable base with simplified stub functions for library functions that
|
|
||||||
* cannot be implemented uniformly on Jse and Jme.
|
|
||||||
* <p>
|
|
||||||
* This can be installed as-is on either platform, or extended and refined to be
|
|
||||||
* used in a complete Jse implementation.
|
|
||||||
* <p>
|
|
||||||
* Because the nature of the {@code os} library is to encapsulate os-specific
|
|
||||||
* features, the behavior of these functions varies considerably from their
|
|
||||||
* counterparts in the C platform.
|
|
||||||
* <p>
|
|
||||||
* The following functions have limited implementations of features that are not
|
|
||||||
* supported well on Jme:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code execute()}</li>
|
|
||||||
* <li>{@code remove()}</li>
|
|
||||||
* <li>{@code rename()}</li>
|
|
||||||
* <li>{@code tmpname()}</li>
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* Typically, this library is included as part of a call to either
|
|
||||||
* {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()} or
|
|
||||||
* {@link org.luaj.vm2.lib.jme.JmePlatform#standardGlobals()}
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
|
||||||
* System.out.println(globals.get("os").get("time").call());
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* In this example the platform-specific {@link org.luaj.vm2.lib.jse.JseOsLib}
|
|
||||||
* library will be loaded, which will include the base functionality provided by
|
|
||||||
* this class.
|
|
||||||
* <p>
|
|
||||||
* To instantiate and use it directly, link it into your globals table via
|
|
||||||
* {@link LuaValue#load(LuaValue)} using code such as:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = new Globals();
|
|
||||||
* globals.load(new JseBaseLib());
|
|
||||||
* globals.load(new PackageLib());
|
|
||||||
* globals.load(new OsLib());
|
|
||||||
* System.out.println(globals.get("os").get("time").call());
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* @see LibFunction
|
|
||||||
* @see org.luaj.vm2.lib.jse.JseOsLib
|
|
||||||
* @see org.luaj.vm2.lib.jse.JsePlatform
|
|
||||||
* @see org.luaj.vm2.lib.jme.JmePlatform
|
|
||||||
* @see <a href=
|
|
||||||
* "http://www.lua.org/manual/5.1/manual.html#5.8">http://www.lua.org/manual/5.1/manual.html#5.8</a>
|
|
||||||
*/
|
|
||||||
public class OsLib extends TwoArgFunction {
|
|
||||||
public static final String TMP_PREFIX = ".luaj";
|
|
||||||
public static final String TMP_SUFFIX = "tmp";
|
|
||||||
|
|
||||||
private static final int CLOCK = 0;
|
|
||||||
private static final int DATE = 1;
|
|
||||||
private static final int DIFFTIME = 2;
|
|
||||||
private static final int EXECUTE = 3;
|
|
||||||
private static final int EXIT = 4;
|
|
||||||
private static final int GETENV = 5;
|
|
||||||
private static final int REMOVE = 6;
|
|
||||||
private static final int RENAME = 7;
|
|
||||||
private static final int SETLOCALE = 8;
|
|
||||||
private static final int TIME = 9;
|
|
||||||
private static final int TMPNAME = 10;
|
|
||||||
|
|
||||||
private static final String[] NAMES = { "clock", "date", "difftime", "execute", "exit", "getenv", "remove",
|
|
||||||
"rename", "setlocale", "time", "tmpname", };
|
|
||||||
|
|
||||||
private static final long t0 = System.currentTimeMillis();
|
|
||||||
private static long tmpnames = t0;
|
|
||||||
|
|
||||||
protected Globals globals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and OsLib instance.
|
|
||||||
*/
|
|
||||||
public OsLib() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform one-time initialization on the library by creating a table
|
|
||||||
* containing the library functions, adding that table to the supplied
|
|
||||||
* environment, adding the table to package.loaded, and returning table as
|
|
||||||
* the return value.
|
|
||||||
*
|
|
||||||
* @param modname the module name supplied if this is loaded via 'require'.
|
|
||||||
* @param env the environment to load into, typically a Globals
|
|
||||||
* instance.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
|
||||||
globals = env.checkglobals();
|
|
||||||
LuaTable os = new LuaTable();
|
|
||||||
for (int i = 0; i < NAMES.length; ++i)
|
|
||||||
os.set(NAMES[i], new OsLibFunc(i, NAMES[i]));
|
|
||||||
env.set("os", os);
|
|
||||||
if (!env.get("package").isnil())
|
|
||||||
env.get("package").get("loaded").set("os", os);
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
class OsLibFunc extends VarArgFunction {
|
|
||||||
public OsLibFunc(int opcode, String name) {
|
|
||||||
this.opcode = opcode;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Varargs invoke(Varargs args) {
|
|
||||||
try {
|
|
||||||
switch (opcode) {
|
|
||||||
case CLOCK:
|
|
||||||
return valueOf(clock());
|
|
||||||
case DATE: {
|
|
||||||
String s = args.optjstring(1, "%c");
|
|
||||||
long t = args.isnumber(2)? args.tolong(2): time(null);
|
|
||||||
if (s.equals("*t")) {
|
|
||||||
Calendar d = Calendar.getInstance();
|
|
||||||
d.setTime(new Date(t*1000));
|
|
||||||
LuaTable tbl = LuaValue.tableOf();
|
|
||||||
tbl.set("year", LuaValue.valueOf(d.get(Calendar.YEAR)));
|
|
||||||
tbl.set("month", LuaValue.valueOf(d.get(Calendar.MONTH)+1));
|
|
||||||
tbl.set("day", LuaValue.valueOf(d.get(Calendar.DAY_OF_MONTH)));
|
|
||||||
tbl.set("hour", LuaValue.valueOf(d.get(Calendar.HOUR_OF_DAY)));
|
|
||||||
tbl.set("min", LuaValue.valueOf(d.get(Calendar.MINUTE)));
|
|
||||||
tbl.set("sec", LuaValue.valueOf(d.get(Calendar.SECOND)));
|
|
||||||
tbl.set("wday", LuaValue.valueOf(d.get(Calendar.DAY_OF_WEEK)));
|
|
||||||
tbl.set("yday", LuaValue.valueOf(d.get(0x6))); // Day of year
|
|
||||||
tbl.set("isdst", LuaValue.valueOf(isDaylightSavingsTime(d)));
|
|
||||||
return tbl;
|
|
||||||
}
|
|
||||||
return valueOf(date(s, t == -1? time(null): t));
|
|
||||||
}
|
|
||||||
case DIFFTIME:
|
|
||||||
return valueOf(difftime(args.checkdouble(1), args.checkdouble(2)));
|
|
||||||
case EXECUTE:
|
|
||||||
return execute(args.optjstring(1, null));
|
|
||||||
case EXIT:
|
|
||||||
exit(args.optint(1, 0));
|
|
||||||
return NONE;
|
|
||||||
case GETENV: {
|
|
||||||
final String val = getenv(args.checkjstring(1));
|
|
||||||
return val != null? valueOf(val): NIL;
|
|
||||||
}
|
|
||||||
case REMOVE:
|
|
||||||
remove(args.checkjstring(1));
|
|
||||||
return LuaValue.TRUE;
|
|
||||||
case RENAME:
|
|
||||||
rename(args.checkjstring(1), args.checkjstring(2));
|
|
||||||
return LuaValue.TRUE;
|
|
||||||
case SETLOCALE: {
|
|
||||||
String s = setlocale(args.optjstring(1, null), args.optjstring(2, "all"));
|
|
||||||
return s != null? valueOf(s): NIL;
|
|
||||||
}
|
|
||||||
case TIME:
|
|
||||||
return valueOf(time(args.opttable(1, null)));
|
|
||||||
case TMPNAME:
|
|
||||||
return valueOf(tmpname());
|
|
||||||
}
|
|
||||||
return NONE;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return varargsOf(NIL, valueOf(e.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return an approximation of the amount in seconds of CPU time used by the
|
|
||||||
* program. For luaj this simple returns the elapsed time since the
|
|
||||||
* OsLib class was loaded.
|
|
||||||
*/
|
|
||||||
protected double clock() {
|
|
||||||
return (System.currentTimeMillis()-t0)/1000.;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of seconds from time t1 to time t2. In POSIX, Windows,
|
|
||||||
* and some other systems, this value is exactly t2-t1.
|
|
||||||
*
|
|
||||||
* @param t2
|
|
||||||
* @param t1
|
|
||||||
* @return diffeence in time values, in seconds
|
|
||||||
*/
|
|
||||||
protected double difftime(double t2, double t1) {
|
|
||||||
return t2-t1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the time argument is present, this is the time to be formatted (see
|
|
||||||
* the os.time function for a description of this value). Otherwise, date
|
|
||||||
* formats the current time.
|
|
||||||
*
|
|
||||||
* Date returns the date as a string, formatted according to the same rules
|
|
||||||
* as ANSII strftime, but without support for %g, %G, or %V.
|
|
||||||
*
|
|
||||||
* When called without arguments, date returns a reasonable date and time
|
|
||||||
* representation that depends on the host system and on the current locale
|
|
||||||
* (that is, os.date() is equivalent to os.date("%c")).
|
|
||||||
*
|
|
||||||
* @param format
|
|
||||||
* @param timeInSec time since epoch, or -1 if not supplied
|
|
||||||
* @return a LString or a LTable containing date and time, formatted
|
|
||||||
* according to the given string format.
|
|
||||||
*/
|
|
||||||
private static String date(String format, long timeInSec) {
|
|
||||||
Calendar d = Calendar.getInstance();
|
|
||||||
d.setTime(new Date(timeInSec*1000));
|
|
||||||
if (format.startsWith("!")) {
|
|
||||||
timeInSec -= timeZoneOffset(d);
|
|
||||||
d.setTime(new Date(timeInSec*1000));
|
|
||||||
format = format.substring(1);
|
|
||||||
}
|
|
||||||
byte[] fmt = format.getBytes();
|
|
||||||
final int n = fmt.length;
|
|
||||||
|
|
||||||
Buffer result = new Buffer(n);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
byte c = fmt[i];
|
|
||||||
switch (c) {
|
|
||||||
case '\n':
|
|
||||||
result.append("\n");
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
if (++i >= n)
|
|
||||||
break;
|
|
||||||
String conv = Character.toString((char) fmt[i]);
|
|
||||||
if (CONVERTERS.containsKey(conv)) {
|
|
||||||
result.append(CONVERTERS.get(conv).convert(d));
|
|
||||||
} else {
|
|
||||||
LuaValue.argerror(1, "invalid conversion specifier '%" + conv + "'");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result.append(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result.tojstring();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String[] WeekdayNameAbbrev = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
|
||||||
private static final String[] WeekdayName = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
|
|
||||||
"Friday", "Saturday" };
|
|
||||||
private static final String[] MonthNameAbbrev = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
|
|
||||||
"Oct", "Nov", "Dec" };
|
|
||||||
private static final String[] MonthName = { "January", "February", "March", "April", "May", "June", "July",
|
|
||||||
"August", "September", "October", "November", "December" };
|
|
||||||
|
|
||||||
private static interface DateConversion {
|
|
||||||
public String convert(Calendar d);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Map<String, DateConversion> CONVERTERS = new HashMap<>();
|
|
||||||
static {
|
|
||||||
CONVERTERS.put("%", d -> "%");
|
|
||||||
CONVERTERS.put("a", d -> WeekdayNameAbbrev[d.get(Calendar.DAY_OF_WEEK)-1]);
|
|
||||||
CONVERTERS.put("A", d -> WeekdayName[d.get(Calendar.DAY_OF_WEEK)-1]);
|
|
||||||
CONVERTERS.put("b", d -> MonthNameAbbrev[d.get(Calendar.MONTH)]);
|
|
||||||
CONVERTERS.put("B", d -> MonthName[d.get(Calendar.MONTH)]);
|
|
||||||
CONVERTERS.put("c", d -> date("%a %b %e %H:%M:%S %Y", d.getTimeInMillis()/1000L));
|
|
||||||
CONVERTERS.put("C", d -> String.valueOf(d.get(Calendar.YEAR)).substring(0, 2));
|
|
||||||
CONVERTERS.put("d", d -> String.valueOf(100+d.get(Calendar.DAY_OF_MONTH)).substring(1));
|
|
||||||
CONVERTERS.put("D", d -> date("%m/%d/%y", d.getTimeInMillis()/1000L));
|
|
||||||
CONVERTERS.put("e", d -> String.format("%2d", d.get(Calendar.DAY_OF_MONTH)));
|
|
||||||
CONVERTERS.put("F", d -> date("%Y-%m-%d", d.getTimeInMillis()/1000L));
|
|
||||||
CONVERTERS.put("g", d -> String.valueOf(d.get(Calendar.YEAR)).substring(2));
|
|
||||||
CONVERTERS.put("G", d -> String.valueOf(d.get(Calendar.YEAR)));
|
|
||||||
CONVERTERS.put("h", d -> MonthNameAbbrev[d.get(Calendar.MONTH)]);
|
|
||||||
CONVERTERS.put("H", d -> String.valueOf(100+d.get(Calendar.HOUR_OF_DAY)).substring(1));
|
|
||||||
CONVERTERS.put("I", d -> String.valueOf(100+d.get(Calendar.HOUR_OF_DAY)%12).substring(1));
|
|
||||||
// day of year
|
|
||||||
CONVERTERS.put("j", d -> {
|
|
||||||
Calendar y0 = beginningOfYear(d);
|
|
||||||
int dayOfYear = (int) ((d.getTimeInMillis()-y0.getTimeInMillis())/(24*3600L*1000L));
|
|
||||||
return String.valueOf(1001+dayOfYear).substring(1);
|
|
||||||
});
|
|
||||||
CONVERTERS.put("m", d -> String.valueOf(101+d.get(Calendar.MONTH)).substring(1));
|
|
||||||
CONVERTERS.put("M", d -> String.valueOf(100+d.get(Calendar.MINUTE)).substring(1));
|
|
||||||
CONVERTERS.put("n", d -> "\n");
|
|
||||||
CONVERTERS.put("p", d -> d.get(Calendar.HOUR_OF_DAY) < 12? "AM": "PM");
|
|
||||||
CONVERTERS.put("r", d -> date("%I:%M:%S %p", d.getTimeInMillis()/1000L));
|
|
||||||
CONVERTERS.put("R", d -> date("%H:%M", d.getTimeInMillis()/1000L));
|
|
||||||
CONVERTERS.put("S", d -> String.valueOf(100+d.get(Calendar.SECOND)).substring(1));
|
|
||||||
CONVERTERS.put("t", d -> "\t");
|
|
||||||
CONVERTERS.put("T", d -> date("%H:%M:%S", d.getTimeInMillis()/1000L));
|
|
||||||
CONVERTERS.put("u", d -> String.valueOf((d.get(Calendar.DAY_OF_WEEK)+6)%7));
|
|
||||||
CONVERTERS.put("U", d -> String.valueOf(weekNumber(d, 0)));
|
|
||||||
CONVERTERS.put("V", d -> String.valueOf(weekNumber(d, 0)));
|
|
||||||
CONVERTERS.put("w", d -> String.valueOf((d.get(Calendar.DAY_OF_WEEK)+6)%7));
|
|
||||||
CONVERTERS.put("W", d -> String.valueOf(weekNumber(d, 1)));
|
|
||||||
CONVERTERS.put("x", d -> date("%m/%d/%y", d.getTimeInMillis()/1000L));
|
|
||||||
CONVERTERS.put("X", d -> date("%H:%M:%S", d.getTimeInMillis()/1000L));
|
|
||||||
CONVERTERS.put("y", d -> String.valueOf(d.get(Calendar.YEAR)).substring(2));
|
|
||||||
CONVERTERS.put("Y", d -> String.valueOf(d.get(Calendar.YEAR)));
|
|
||||||
CONVERTERS.put("z", d -> {
|
|
||||||
final int tzo = timeZoneOffset(d)/60;
|
|
||||||
final int a = Math.abs(tzo);
|
|
||||||
final String h = String.valueOf(100+a/60).substring(1);
|
|
||||||
final String m = String.valueOf(100+a%60).substring(1);
|
|
||||||
return (tzo >= 0? "+": "-")+h+m;
|
|
||||||
});
|
|
||||||
CONVERTERS.put("Z", d -> d.getTimeZone().toZoneId().getDisplayName(TextStyle.SHORT, Locale.getDefault()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Calendar beginningOfYear(Calendar d) {
|
|
||||||
Calendar y0 = Calendar.getInstance();
|
|
||||||
y0.setTime(d.getTime());
|
|
||||||
y0.set(Calendar.MONTH, 0);
|
|
||||||
y0.set(Calendar.DAY_OF_MONTH, 1);
|
|
||||||
y0.set(Calendar.HOUR_OF_DAY, 0);
|
|
||||||
y0.set(Calendar.MINUTE, 0);
|
|
||||||
y0.set(Calendar.SECOND, 0);
|
|
||||||
y0.set(Calendar.MILLISECOND, 0);
|
|
||||||
return y0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int weekNumber(Calendar d, int startDay) {
|
|
||||||
Calendar y0 = beginningOfYear(d);
|
|
||||||
y0.set(Calendar.DAY_OF_MONTH, 1+(startDay+8-y0.get(Calendar.DAY_OF_WEEK))%7);
|
|
||||||
if (y0.after(d)) {
|
|
||||||
y0.set(Calendar.YEAR, y0.get(Calendar.YEAR)-1);
|
|
||||||
y0.set(Calendar.DAY_OF_MONTH, 1+(startDay+8-y0.get(Calendar.DAY_OF_WEEK))%7);
|
|
||||||
}
|
|
||||||
long dt = d.getTime().getTime()-y0.getTime().getTime();
|
|
||||||
return 1+(int) (dt/(7L*24L*3600L*1000L));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int timeZoneOffset(Calendar d) {
|
|
||||||
int localStandarTimeMillis = (d.get(Calendar.HOUR_OF_DAY)*3600+d.get(Calendar.MINUTE)*60+d.get(Calendar.SECOND))
|
|
||||||
*1000;
|
|
||||||
return d.getTimeZone().getOffset(1, d.get(Calendar.YEAR), d.get(Calendar.MONTH), d.get(Calendar.DAY_OF_MONTH),
|
|
||||||
d.get(Calendar.DAY_OF_WEEK), localStandarTimeMillis)/1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDaylightSavingsTime(Calendar d) {
|
|
||||||
return timeZoneOffset(d) != d.getTimeZone().getRawOffset()/1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function is equivalent to the C function system. It passes command
|
|
||||||
* to be executed by an operating system shell. It returns a status code,
|
|
||||||
* which is system-dependent. If command is absent, then it returns nonzero
|
|
||||||
* if a shell is available and zero otherwise.
|
|
||||||
*
|
|
||||||
* @param command command to pass to the system
|
|
||||||
*/
|
|
||||||
protected Varargs execute(String command) {
|
|
||||||
return varargsOf(NIL, valueOf("exit"), ONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the C function exit, with an optional code, to terminate the host
|
|
||||||
* program.
|
|
||||||
*
|
|
||||||
* @param code
|
|
||||||
*/
|
|
||||||
protected void exit(int code) {
|
|
||||||
System.exit(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value of the process environment variable varname, or the
|
|
||||||
* System property value for varname, or null if the variable is not defined
|
|
||||||
* in either environment.
|
|
||||||
*
|
|
||||||
* The default implementation, which is used by the JmePlatform, only
|
|
||||||
* queryies System.getProperty().
|
|
||||||
*
|
|
||||||
* The JsePlatform overrides this behavior and returns the environment
|
|
||||||
* variable value using System.getenv() if it exists, or the System property
|
|
||||||
* value if it does not.
|
|
||||||
*
|
|
||||||
* A SecurityException may be thrown if access is not allowed for 'varname'.
|
|
||||||
*
|
|
||||||
* @param varname
|
|
||||||
* @return String value, or null if not defined
|
|
||||||
*/
|
|
||||||
protected String getenv(String varname) {
|
|
||||||
return System.getProperty(varname);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes the file or directory with the given name. Directories must be
|
|
||||||
* empty to be removed. If this function fails, it throws and IOException
|
|
||||||
*
|
|
||||||
* @param filename
|
|
||||||
* @throws IOException if it fails
|
|
||||||
*/
|
|
||||||
protected void remove(String filename) throws IOException {
|
|
||||||
throw new IOException("not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renames file or directory named oldname to newname. If this function
|
|
||||||
* fails,it throws and IOException
|
|
||||||
*
|
|
||||||
* @param oldname old file name
|
|
||||||
* @param newname new file name
|
|
||||||
* @throws IOException if it fails
|
|
||||||
*/
|
|
||||||
protected void rename(String oldname, String newname) throws IOException {
|
|
||||||
throw new IOException("not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current locale of the program. locale is a string specifying a
|
|
||||||
* locale; category is an optional string describing which category to
|
|
||||||
* change: "all", "collate", "ctype", "monetary", "numeric", or "time"; the
|
|
||||||
* default category is "all".
|
|
||||||
*
|
|
||||||
* If locale is the empty string, the current locale is set to an
|
|
||||||
* implementation- defined native locale. If locale is the string "C", the
|
|
||||||
* current locale is set to the standard C locale.
|
|
||||||
*
|
|
||||||
* When called with null as the first argument, this function only returns
|
|
||||||
* the name of the current locale for the given category.
|
|
||||||
*
|
|
||||||
* @param locale
|
|
||||||
* @param category
|
|
||||||
* @return the name of the new locale, or null if the request cannot be
|
|
||||||
* honored.
|
|
||||||
*/
|
|
||||||
protected String setlocale(String locale, String category) {
|
|
||||||
return "C";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current time when called without arguments, or a time
|
|
||||||
* representing the date and time specified by the given table. This table
|
|
||||||
* must have fields year, month, and day, and may have fields hour, min,
|
|
||||||
* sec, and isdst (for a description of these fields, see the os.date
|
|
||||||
* function).
|
|
||||||
*
|
|
||||||
* @param table
|
|
||||||
* @return long value for the time
|
|
||||||
*/
|
|
||||||
protected long time(LuaTable table) {
|
|
||||||
java.util.Date d;
|
|
||||||
if (table == null) {
|
|
||||||
d = new java.util.Date();
|
|
||||||
} else {
|
|
||||||
Calendar c = Calendar.getInstance();
|
|
||||||
c.set(Calendar.YEAR, table.get("year").checkint());
|
|
||||||
c.set(Calendar.MONTH, table.get("month").checkint()-1);
|
|
||||||
c.set(Calendar.DAY_OF_MONTH, table.get("day").checkint());
|
|
||||||
c.set(Calendar.HOUR_OF_DAY, table.get("hour").optint(12));
|
|
||||||
c.set(Calendar.MINUTE, table.get("min").optint(0));
|
|
||||||
c.set(Calendar.SECOND, table.get("sec").optint(0));
|
|
||||||
c.set(Calendar.MILLISECOND, 0);
|
|
||||||
d = c.getTime();
|
|
||||||
}
|
|
||||||
return d.getTime()/1000L;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string with a file name that can be used for a temporary file.
|
|
||||||
* The file must be explicitly opened before its use and explicitly removed
|
|
||||||
* when no longer needed.
|
|
||||||
*
|
|
||||||
* On some systems (POSIX), this function also creates a file with that
|
|
||||||
* name, to avoid security risks. (Someone else might create the file with
|
|
||||||
* wrong permissions in the time between getting the name and creating the
|
|
||||||
* file.) You still have to open the file to use it and to remove it (even
|
|
||||||
* if you do not use it).
|
|
||||||
*
|
|
||||||
* @return String filename to use
|
|
||||||
*/
|
|
||||||
protected String tmpname() {
|
|
||||||
synchronized (OsLib.class) {
|
|
||||||
return TMP_PREFIX+tmpnames+++TMP_SUFFIX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package org.luaj.vm2.lib;
|
|
||||||
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
|
|
||||||
class TableLibFunction extends LibFunction {
|
|
||||||
@Override
|
|
||||||
public LuaValue call() {
|
|
||||||
return argerror(1, "table expected, got no value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.TypeTest.MyData;
|
|
||||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
|
||||||
|
|
||||||
class LuaOperationsTest {
|
|
||||||
|
|
||||||
private final int sampleint = 77;
|
|
||||||
private final long samplelong = 123400000000L;
|
|
||||||
private final double sampledouble = 55.25;
|
|
||||||
private final String samplestringstring = "abcdef";
|
|
||||||
private final String samplestringint = String.valueOf(sampleint);
|
|
||||||
private final String samplestringlong = String.valueOf(samplelong);
|
|
||||||
private final String samplestringdouble = String.valueOf(sampledouble);
|
|
||||||
private final Object sampleobject = new Object();
|
|
||||||
private final MyData sampledata = new MyData();
|
|
||||||
|
|
||||||
private final LuaValue somenil = LuaValue.NIL;
|
|
||||||
private final LuaValue sometrue = LuaValue.TRUE;
|
|
||||||
private final LuaValue somefalse = LuaValue.FALSE;
|
|
||||||
private final LuaValue zero = LuaValue.ZERO;
|
|
||||||
private final LuaValue intint = LuaValue.valueOf(sampleint);
|
|
||||||
private final LuaValue longdouble = LuaValue.valueOf(samplelong);
|
|
||||||
private final LuaValue doubledouble = LuaValue.valueOf(sampledouble);
|
|
||||||
private final LuaValue stringstring = LuaValue.valueOf(samplestringstring);
|
|
||||||
private final LuaValue stringint = LuaValue.valueOf(samplestringint);
|
|
||||||
private final LuaValue stringlong = LuaValue.valueOf(samplestringlong);
|
|
||||||
private final LuaValue stringdouble = LuaValue.valueOf(samplestringdouble);
|
|
||||||
private final LuaTable table = LuaValue
|
|
||||||
.listOf(new LuaValue[] { LuaValue.valueOf("aaa"), LuaValue.valueOf("bbb") });
|
|
||||||
private final LuaValue somefunc = new ZeroArgFunction() {
|
|
||||||
@Override
|
|
||||||
public LuaValue call() { return NONE; }
|
|
||||||
};
|
|
||||||
private final LuaThread thread = new LuaThread(new Globals(), somefunc);
|
|
||||||
private final Prototype proto = new Prototype(1);
|
|
||||||
private final LuaClosure someclosure = new LuaClosure(proto, table);
|
|
||||||
private final LuaUserdata userdataobj = LuaValue.userdataOf(sampleobject);
|
|
||||||
private final LuaUserdata userdatacls = LuaValue.userdataOf(sampledata);
|
|
||||||
|
|
||||||
private void throwsLuaError(String methodName, Object obj) {
|
|
||||||
try {
|
|
||||||
LuaValue.class.getMethod(methodName).invoke(obj);
|
|
||||||
fail("failed to throw LuaError as required");
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
if (!(e.getTargetException() instanceof LuaError))
|
|
||||||
fail("not a LuaError: " + e.getTargetException());
|
|
||||||
return; // pass
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail("bad exception: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void throwsLuaError(String methodName, Object obj, Object arg) {
|
|
||||||
try {
|
|
||||||
LuaValue.class.getMethod(methodName, LuaValue.class).invoke(obj, arg);
|
|
||||||
fail("failed to throw LuaError as required");
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
if (!(e.getTargetException() instanceof LuaError))
|
|
||||||
fail("not a LuaError: " + e.getTargetException());
|
|
||||||
return; // pass
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail("bad exception: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLen() {
|
|
||||||
throwsLuaError("len", somenil);
|
|
||||||
throwsLuaError("len", sometrue);
|
|
||||||
throwsLuaError("len", somefalse);
|
|
||||||
throwsLuaError("len", zero);
|
|
||||||
throwsLuaError("len", intint);
|
|
||||||
throwsLuaError("len", longdouble);
|
|
||||||
throwsLuaError("len", doubledouble);
|
|
||||||
assertEquals(LuaInteger.valueOf(samplestringstring.length()), stringstring.len());
|
|
||||||
assertEquals(LuaInteger.valueOf(samplestringint.length()), stringint.len());
|
|
||||||
assertEquals(LuaInteger.valueOf(samplestringlong.length()), stringlong.len());
|
|
||||||
assertEquals(LuaInteger.valueOf(samplestringdouble.length()), stringdouble.len());
|
|
||||||
assertEquals(LuaInteger.valueOf(2), table.len());
|
|
||||||
throwsLuaError("len", somefunc);
|
|
||||||
throwsLuaError("len", thread);
|
|
||||||
throwsLuaError("len", someclosure);
|
|
||||||
throwsLuaError("len", userdataobj);
|
|
||||||
throwsLuaError("len", userdatacls);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLength() {
|
|
||||||
throwsLuaError("length", somenil);
|
|
||||||
throwsLuaError("length", sometrue);
|
|
||||||
throwsLuaError("length", somefalse);
|
|
||||||
throwsLuaError("length", zero);
|
|
||||||
throwsLuaError("length", intint);
|
|
||||||
throwsLuaError("length", longdouble);
|
|
||||||
throwsLuaError("length", doubledouble);
|
|
||||||
assertEquals(samplestringstring.length(), stringstring.length());
|
|
||||||
assertEquals(samplestringint.length(), stringint.length());
|
|
||||||
assertEquals(samplestringlong.length(), stringlong.length());
|
|
||||||
assertEquals(samplestringdouble.length(), stringdouble.length());
|
|
||||||
assertEquals(2, table.length());
|
|
||||||
throwsLuaError("length", somefunc);
|
|
||||||
throwsLuaError("length", thread);
|
|
||||||
throwsLuaError("length", someclosure);
|
|
||||||
throwsLuaError("length", userdataobj);
|
|
||||||
throwsLuaError("length", userdatacls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,372 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.TypeTest.MyData;
|
|
||||||
import org.luaj.vm2.lib.StringLib;
|
|
||||||
import org.luaj.vm2.lib.ThreeArgFunction;
|
|
||||||
import org.luaj.vm2.lib.TwoArgFunction;
|
|
||||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
|
||||||
|
|
||||||
class MetatableTest {
|
|
||||||
|
|
||||||
private final String samplestring = "abcdef";
|
|
||||||
private final Object sampleobject = new Object();
|
|
||||||
private final MyData sampledata = new MyData();
|
|
||||||
|
|
||||||
private final LuaValue string = LuaValue.valueOf(samplestring);
|
|
||||||
private final LuaTable table = LuaValue.tableOf();
|
|
||||||
private final LuaFunction function = new ZeroArgFunction() {
|
|
||||||
@Override
|
|
||||||
public LuaValue call() { return NONE; }
|
|
||||||
};
|
|
||||||
private final LuaThread thread = new LuaThread(new Globals(), function);
|
|
||||||
private final LuaClosure closure = new LuaClosure(new Prototype(), new LuaTable());
|
|
||||||
private final LuaUserdata userdata = LuaValue.userdataOf(sampleobject);
|
|
||||||
private final LuaUserdata userdatamt = LuaValue.userdataOf(sampledata, table);
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
// needed for metatable ops to work on strings
|
|
||||||
new StringLib();
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
protected void tearDown() throws Exception {
|
|
||||||
LuaBoolean.s_metatable = null;
|
|
||||||
LuaFunction.s_metatable = null;
|
|
||||||
LuaNil.s_metatable = null;
|
|
||||||
LuaNumber.s_metatable = null;
|
|
||||||
// LuaString.s_metatable = null;
|
|
||||||
LuaThread.s_metatable = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetMetatable() {
|
|
||||||
assertEquals(null, LuaValue.NIL.getmetatable());
|
|
||||||
assertEquals(null, LuaValue.TRUE.getmetatable());
|
|
||||||
assertEquals(null, LuaValue.ONE.getmetatable());
|
|
||||||
// assertEquals( null, string.getmetatable() );
|
|
||||||
assertEquals(null, table.getmetatable());
|
|
||||||
assertEquals(null, function.getmetatable());
|
|
||||||
assertEquals(null, thread.getmetatable());
|
|
||||||
assertEquals(null, closure.getmetatable());
|
|
||||||
assertEquals(null, userdata.getmetatable());
|
|
||||||
assertEquals(table, userdatamt.getmetatable());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSetMetatable() {
|
|
||||||
LuaValue mt = LuaValue.tableOf();
|
|
||||||
assertEquals(null, table.getmetatable());
|
|
||||||
assertEquals(null, userdata.getmetatable());
|
|
||||||
assertEquals(table, userdatamt.getmetatable());
|
|
||||||
assertEquals(table, table.setmetatable(mt));
|
|
||||||
assertEquals(userdata, userdata.setmetatable(mt));
|
|
||||||
assertEquals(userdatamt, userdatamt.setmetatable(mt));
|
|
||||||
assertEquals(mt, table.getmetatable());
|
|
||||||
assertEquals(mt, userdata.getmetatable());
|
|
||||||
assertEquals(mt, userdatamt.getmetatable());
|
|
||||||
|
|
||||||
// these all get metatable behind-the-scenes
|
|
||||||
assertEquals(null, LuaValue.NIL.getmetatable());
|
|
||||||
assertEquals(null, LuaValue.TRUE.getmetatable());
|
|
||||||
assertEquals(null, LuaValue.ONE.getmetatable());
|
|
||||||
// assertEquals( null, string.getmetatable() );
|
|
||||||
assertEquals(null, function.getmetatable());
|
|
||||||
assertEquals(null, thread.getmetatable());
|
|
||||||
assertEquals(null, closure.getmetatable());
|
|
||||||
LuaNil.s_metatable = mt;
|
|
||||||
assertEquals(mt, LuaValue.NIL.getmetatable());
|
|
||||||
assertEquals(null, LuaValue.TRUE.getmetatable());
|
|
||||||
assertEquals(null, LuaValue.ONE.getmetatable());
|
|
||||||
// assertEquals( null, string.getmetatable() );
|
|
||||||
assertEquals(null, function.getmetatable());
|
|
||||||
assertEquals(null, thread.getmetatable());
|
|
||||||
assertEquals(null, closure.getmetatable());
|
|
||||||
LuaBoolean.s_metatable = mt;
|
|
||||||
assertEquals(mt, LuaValue.TRUE.getmetatable());
|
|
||||||
assertEquals(null, LuaValue.ONE.getmetatable());
|
|
||||||
// assertEquals( null, string.getmetatable() );
|
|
||||||
assertEquals(null, function.getmetatable());
|
|
||||||
assertEquals(null, thread.getmetatable());
|
|
||||||
assertEquals(null, closure.getmetatable());
|
|
||||||
LuaNumber.s_metatable = mt;
|
|
||||||
assertEquals(mt, LuaValue.ONE.getmetatable());
|
|
||||||
assertEquals(mt, LuaValue.valueOf(1.25).getmetatable());
|
|
||||||
// assertEquals( null, string.getmetatable() );
|
|
||||||
assertEquals(null, function.getmetatable());
|
|
||||||
assertEquals(null, thread.getmetatable());
|
|
||||||
assertEquals(null, closure.getmetatable());
|
|
||||||
// LuaString.s_metatable = mt;
|
|
||||||
// assertEquals( mt, string.getmetatable() );
|
|
||||||
assertEquals(null, function.getmetatable());
|
|
||||||
assertEquals(null, thread.getmetatable());
|
|
||||||
assertEquals(null, closure.getmetatable());
|
|
||||||
LuaFunction.s_metatable = mt;
|
|
||||||
assertEquals(mt, function.getmetatable());
|
|
||||||
assertEquals(null, thread.getmetatable());
|
|
||||||
LuaThread.s_metatable = mt;
|
|
||||||
assertEquals(mt, thread.getmetatable());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMetatableIndex() {
|
|
||||||
assertEquals(table, table.setmetatable(null));
|
|
||||||
assertEquals(userdata, userdata.setmetatable(null));
|
|
||||||
assertEquals(userdatamt, userdatamt.setmetatable(null));
|
|
||||||
assertEquals(LuaValue.NIL, table.get(1));
|
|
||||||
assertEquals(LuaValue.NIL, userdata.get(1));
|
|
||||||
assertEquals(LuaValue.NIL, userdatamt.get(1));
|
|
||||||
|
|
||||||
// empty metatable
|
|
||||||
LuaValue mt = LuaValue.tableOf();
|
|
||||||
assertEquals(table, table.setmetatable(mt));
|
|
||||||
assertEquals(userdata, userdata.setmetatable(mt));
|
|
||||||
LuaBoolean.s_metatable = mt;
|
|
||||||
LuaFunction.s_metatable = mt;
|
|
||||||
LuaNil.s_metatable = mt;
|
|
||||||
LuaNumber.s_metatable = mt;
|
|
||||||
// LuaString.s_metatable = mt;
|
|
||||||
LuaThread.s_metatable = mt;
|
|
||||||
assertEquals(mt, table.getmetatable());
|
|
||||||
assertEquals(mt, userdata.getmetatable());
|
|
||||||
assertEquals(mt, LuaValue.NIL.getmetatable());
|
|
||||||
assertEquals(mt, LuaValue.TRUE.getmetatable());
|
|
||||||
assertEquals(mt, LuaValue.ONE.getmetatable());
|
|
||||||
// assertEquals( StringLib.instance, string.getmetatable() );
|
|
||||||
assertEquals(mt, function.getmetatable());
|
|
||||||
assertEquals(mt, thread.getmetatable());
|
|
||||||
|
|
||||||
// plain metatable
|
|
||||||
LuaValue abc = LuaValue.valueOf("abc");
|
|
||||||
mt.set(LuaValue.INDEX, LuaValue.listOf(new LuaValue[] { abc }));
|
|
||||||
assertEquals(abc, table.get(1));
|
|
||||||
assertEquals(abc, userdata.get(1));
|
|
||||||
assertEquals(abc, LuaValue.NIL.get(1));
|
|
||||||
assertEquals(abc, LuaValue.TRUE.get(1));
|
|
||||||
assertEquals(abc, LuaValue.ONE.get(1));
|
|
||||||
// assertEquals( abc, string.get(1) );
|
|
||||||
assertEquals(abc, function.get(1));
|
|
||||||
assertEquals(abc, thread.get(1));
|
|
||||||
|
|
||||||
// plain metatable
|
|
||||||
mt.set(LuaValue.INDEX, new TwoArgFunction() {
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
|
||||||
return LuaValue.valueOf(arg1.typename() + "[" + arg2.tojstring() + "]=xyz");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
assertEquals("table[1]=xyz", table.get(1).tojstring());
|
|
||||||
assertEquals("userdata[1]=xyz", userdata.get(1).tojstring());
|
|
||||||
assertEquals("nil[1]=xyz", LuaValue.NIL.get(1).tojstring());
|
|
||||||
assertEquals("boolean[1]=xyz", LuaValue.TRUE.get(1).tojstring());
|
|
||||||
assertEquals("number[1]=xyz", LuaValue.ONE.get(1).tojstring());
|
|
||||||
// assertEquals( "string[1]=xyz", string.get(1).tojstring() );
|
|
||||||
assertEquals("function[1]=xyz", function.get(1).tojstring());
|
|
||||||
assertEquals("thread[1]=xyz", thread.get(1).tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMetatableNewIndex() {
|
|
||||||
// empty metatable
|
|
||||||
LuaValue mt = LuaValue.tableOf();
|
|
||||||
assertEquals(table, table.setmetatable(mt));
|
|
||||||
assertEquals(userdata, userdata.setmetatable(mt));
|
|
||||||
LuaBoolean.s_metatable = mt;
|
|
||||||
LuaFunction.s_metatable = mt;
|
|
||||||
LuaNil.s_metatable = mt;
|
|
||||||
LuaNumber.s_metatable = mt;
|
|
||||||
// LuaString.s_metatable = mt;
|
|
||||||
LuaThread.s_metatable = mt;
|
|
||||||
|
|
||||||
// plain metatable
|
|
||||||
final LuaValue fallback = LuaValue.tableOf();
|
|
||||||
LuaValue abc = LuaValue.valueOf("abc");
|
|
||||||
mt.set(LuaValue.NEWINDEX, fallback);
|
|
||||||
table.set(2, abc);
|
|
||||||
userdata.set(3, abc);
|
|
||||||
LuaValue.NIL.set(4, abc);
|
|
||||||
LuaValue.TRUE.set(5, abc);
|
|
||||||
LuaValue.ONE.set(6, abc);
|
|
||||||
// string.set(7,abc);
|
|
||||||
function.set(8, abc);
|
|
||||||
thread.set(9, abc);
|
|
||||||
assertEquals(abc, fallback.get(2));
|
|
||||||
assertEquals(abc, fallback.get(3));
|
|
||||||
assertEquals(abc, fallback.get(4));
|
|
||||||
assertEquals(abc, fallback.get(5));
|
|
||||||
assertEquals(abc, fallback.get(6));
|
|
||||||
// assertEquals( abc, StringLib.instance.get(7) );
|
|
||||||
assertEquals(abc, fallback.get(8));
|
|
||||||
assertEquals(abc, fallback.get(9));
|
|
||||||
|
|
||||||
// metatable with function call
|
|
||||||
mt.set(LuaValue.NEWINDEX, new ThreeArgFunction() {
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
|
||||||
fallback.rawset(arg2, LuaValue.valueOf("via-func-" + arg3));
|
|
||||||
return NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
table.set(12, abc);
|
|
||||||
userdata.set(13, abc);
|
|
||||||
LuaValue.NIL.set(14, abc);
|
|
||||||
LuaValue.TRUE.set(15, abc);
|
|
||||||
LuaValue.ONE.set(16, abc);
|
|
||||||
// string.set(17,abc);
|
|
||||||
function.set(18, abc);
|
|
||||||
thread.set(19, abc);
|
|
||||||
LuaValue via = LuaValue.valueOf("via-func-abc");
|
|
||||||
assertEquals(via, fallback.get(12));
|
|
||||||
assertEquals(via, fallback.get(13));
|
|
||||||
assertEquals(via, fallback.get(14));
|
|
||||||
assertEquals(via, fallback.get(15));
|
|
||||||
assertEquals(via, fallback.get(16));
|
|
||||||
// assertEquals( via, StringLib.instance.get(17) );
|
|
||||||
assertEquals(via, fallback.get(18));
|
|
||||||
assertEquals(via, fallback.get(19));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkTable(LuaValue t, LuaValue aa, LuaValue bb, LuaValue cc, LuaValue dd, LuaValue ee, LuaValue ff,
|
|
||||||
LuaValue gg, LuaValue ra, LuaValue rb, LuaValue rc, LuaValue rd, LuaValue re, LuaValue rf, LuaValue rg) {
|
|
||||||
assertEquals(aa, t.get("aa"));
|
|
||||||
assertEquals(bb, t.get("bb"));
|
|
||||||
assertEquals(cc, t.get("cc"));
|
|
||||||
assertEquals(dd, t.get("dd"));
|
|
||||||
assertEquals(ee, t.get("ee"));
|
|
||||||
assertEquals(ff, t.get("ff"));
|
|
||||||
assertEquals(gg, t.get("gg"));
|
|
||||||
assertEquals(ra, t.rawget("aa"));
|
|
||||||
assertEquals(rb, t.rawget("bb"));
|
|
||||||
assertEquals(rc, t.rawget("cc"));
|
|
||||||
assertEquals(rd, t.rawget("dd"));
|
|
||||||
assertEquals(re, t.rawget("ee"));
|
|
||||||
assertEquals(rf, t.rawget("ff"));
|
|
||||||
assertEquals(rg, t.rawget("gg"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private LuaValue makeTable(String key1, String val1, String key2, String val2) {
|
|
||||||
return LuaValue.tableOf(new LuaValue[] { LuaValue.valueOf(key1), LuaValue.valueOf(val1), LuaValue.valueOf(key2),
|
|
||||||
LuaValue.valueOf(val2), });
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRawsetMetatableSet() {
|
|
||||||
// set up tables
|
|
||||||
LuaValue m = makeTable("aa", "aaa", "bb", "bbb");
|
|
||||||
m.set(LuaValue.INDEX, m);
|
|
||||||
m.set(LuaValue.NEWINDEX, m);
|
|
||||||
LuaValue s = makeTable("cc", "ccc", "dd", "ddd");
|
|
||||||
LuaValue t = makeTable("cc", "ccc", "dd", "ddd");
|
|
||||||
t.setmetatable(m);
|
|
||||||
LuaValue aaa = LuaValue.valueOf("aaa");
|
|
||||||
LuaValue bbb = LuaValue.valueOf("bbb");
|
|
||||||
LuaValue ccc = LuaValue.valueOf("ccc");
|
|
||||||
LuaValue ddd = LuaValue.valueOf("ddd");
|
|
||||||
LuaValue ppp = LuaValue.valueOf("ppp");
|
|
||||||
LuaValue qqq = LuaValue.valueOf("qqq");
|
|
||||||
LuaValue rrr = LuaValue.valueOf("rrr");
|
|
||||||
LuaValue sss = LuaValue.valueOf("sss");
|
|
||||||
LuaValue ttt = LuaValue.valueOf("ttt");
|
|
||||||
LuaValue www = LuaValue.valueOf("www");
|
|
||||||
LuaValue xxx = LuaValue.valueOf("xxx");
|
|
||||||
LuaValue yyy = LuaValue.valueOf("yyy");
|
|
||||||
LuaValue zzz = LuaValue.valueOf("zzz");
|
|
||||||
LuaValue nil = LuaValue.NIL;
|
|
||||||
|
|
||||||
// check initial values
|
|
||||||
// values via "bet()" values via "rawget()"
|
|
||||||
checkTable(s, nil, nil, ccc, ddd, nil, nil, nil, nil, nil, ccc, ddd, nil, nil, nil);
|
|
||||||
checkTable(t, aaa, bbb, ccc, ddd, nil, nil, nil, nil, nil, ccc, ddd, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, nil, nil, aaa, bbb, nil, nil, nil, nil, nil);
|
|
||||||
|
|
||||||
// rawset()
|
|
||||||
s.rawset("aa", www);
|
|
||||||
checkTable(s, www, nil, ccc, ddd, nil, nil, nil, www, nil, ccc, ddd, nil, nil, nil);
|
|
||||||
checkTable(t, aaa, bbb, ccc, ddd, nil, nil, nil, nil, nil, ccc, ddd, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, nil, nil, aaa, bbb, nil, nil, nil, nil, nil);
|
|
||||||
s.rawset("cc", xxx);
|
|
||||||
checkTable(s, www, nil, xxx, ddd, nil, nil, nil, www, nil, xxx, ddd, nil, nil, nil);
|
|
||||||
checkTable(t, aaa, bbb, ccc, ddd, nil, nil, nil, nil, nil, ccc, ddd, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, nil, nil, aaa, bbb, nil, nil, nil, nil, nil);
|
|
||||||
t.rawset("bb", yyy);
|
|
||||||
checkTable(s, www, nil, xxx, ddd, nil, nil, nil, www, nil, xxx, ddd, nil, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, ddd, nil, nil, nil, nil, yyy, ccc, ddd, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, nil, nil, aaa, bbb, nil, nil, nil, nil, nil);
|
|
||||||
t.rawset("dd", zzz);
|
|
||||||
checkTable(s, www, nil, xxx, ddd, nil, nil, nil, www, nil, xxx, ddd, nil, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, zzz, nil, nil, nil, nil, yyy, ccc, zzz, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, nil, nil, aaa, bbb, nil, nil, nil, nil, nil);
|
|
||||||
|
|
||||||
// set() invoking metatables
|
|
||||||
s.set("ee", ppp);
|
|
||||||
checkTable(s, www, nil, xxx, ddd, ppp, nil, nil, www, nil, xxx, ddd, ppp, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, zzz, nil, nil, nil, nil, yyy, ccc, zzz, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, nil, nil, aaa, bbb, nil, nil, nil, nil, nil);
|
|
||||||
s.set("cc", qqq);
|
|
||||||
checkTable(s, www, nil, qqq, ddd, ppp, nil, nil, www, nil, qqq, ddd, ppp, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, zzz, nil, nil, nil, nil, yyy, ccc, zzz, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, nil, nil, aaa, bbb, nil, nil, nil, nil, nil);
|
|
||||||
t.set("ff", rrr);
|
|
||||||
checkTable(s, www, nil, qqq, ddd, ppp, nil, nil, www, nil, qqq, ddd, ppp, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, zzz, nil, rrr, nil, nil, yyy, ccc, zzz, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, rrr, nil, aaa, bbb, nil, nil, nil, rrr, nil);
|
|
||||||
t.set("dd", sss);
|
|
||||||
checkTable(s, www, nil, qqq, ddd, ppp, nil, nil, www, nil, qqq, ddd, ppp, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, sss, nil, rrr, nil, nil, yyy, ccc, sss, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, rrr, nil, aaa, bbb, nil, nil, nil, rrr, nil);
|
|
||||||
m.set("gg", ttt);
|
|
||||||
checkTable(s, www, nil, qqq, ddd, ppp, nil, nil, www, nil, qqq, ddd, ppp, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, sss, nil, rrr, ttt, nil, yyy, ccc, sss, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, rrr, ttt, aaa, bbb, nil, nil, nil, rrr, ttt);
|
|
||||||
|
|
||||||
// make s fall back to t
|
|
||||||
s.setmetatable(LuaValue.tableOf(new LuaValue[] { LuaValue.INDEX, t, LuaValue.NEWINDEX, t }));
|
|
||||||
checkTable(s, www, yyy, qqq, ddd, ppp, rrr, ttt, www, nil, qqq, ddd, ppp, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, sss, nil, rrr, ttt, nil, yyy, ccc, sss, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, rrr, ttt, aaa, bbb, nil, nil, nil, rrr, ttt);
|
|
||||||
s.set("aa", www);
|
|
||||||
checkTable(s, www, yyy, qqq, ddd, ppp, rrr, ttt, www, nil, qqq, ddd, ppp, nil, nil);
|
|
||||||
checkTable(t, aaa, yyy, ccc, sss, nil, rrr, ttt, nil, yyy, ccc, sss, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, rrr, ttt, aaa, bbb, nil, nil, nil, rrr, ttt);
|
|
||||||
s.set("bb", zzz);
|
|
||||||
checkTable(s, www, zzz, qqq, ddd, ppp, rrr, ttt, www, nil, qqq, ddd, ppp, nil, nil);
|
|
||||||
checkTable(t, aaa, zzz, ccc, sss, nil, rrr, ttt, nil, zzz, ccc, sss, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, rrr, ttt, aaa, bbb, nil, nil, nil, rrr, ttt);
|
|
||||||
s.set("ee", xxx);
|
|
||||||
checkTable(s, www, zzz, qqq, ddd, xxx, rrr, ttt, www, nil, qqq, ddd, xxx, nil, nil);
|
|
||||||
checkTable(t, aaa, zzz, ccc, sss, nil, rrr, ttt, nil, zzz, ccc, sss, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, rrr, ttt, aaa, bbb, nil, nil, nil, rrr, ttt);
|
|
||||||
s.set("ff", yyy);
|
|
||||||
checkTable(s, www, zzz, qqq, ddd, xxx, yyy, ttt, www, nil, qqq, ddd, xxx, nil, nil);
|
|
||||||
checkTable(t, aaa, zzz, ccc, sss, nil, yyy, ttt, nil, zzz, ccc, sss, nil, nil, nil);
|
|
||||||
checkTable(m, aaa, bbb, nil, nil, nil, yyy, ttt, aaa, bbb, nil, nil, nil, yyy, ttt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,325 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.lib.TwoArgFunction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for tables used as lists.
|
|
||||||
*/
|
|
||||||
public class TableHashTest {
|
|
||||||
|
|
||||||
protected LuaTable new_Table() {
|
|
||||||
return new LuaTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected LuaTable new_Table(int n, int m) {
|
|
||||||
return new LuaTable(n, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSetRemove() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
assertEquals(0, t.getHashLength());
|
|
||||||
assertEquals(0, t.length());
|
|
||||||
assertEquals(0, t.keyCount());
|
|
||||||
|
|
||||||
String[] keys = { "abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "wxy", "z01", "cd", "ef", "g", "hi", "jk",
|
|
||||||
"lm", "no", "pq", "rs", };
|
|
||||||
int[] capacities = { 0, 2, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32 };
|
|
||||||
for (int i = 0; i < keys.length; ++i) {
|
|
||||||
assertEquals(capacities[i], t.getHashLength());
|
|
||||||
String si = "Test Value! " + i;
|
|
||||||
t.set(keys[i], si);
|
|
||||||
assertEquals(0, t.length());
|
|
||||||
assertEquals(i+1, t.keyCount());
|
|
||||||
}
|
|
||||||
assertEquals(capacities[keys.length], t.getHashLength());
|
|
||||||
for (int i = 0; i < keys.length; ++i) {
|
|
||||||
LuaValue vi = LuaString.valueOf("Test Value! " + i);
|
|
||||||
assertEquals(vi, t.get(keys[i]));
|
|
||||||
assertEquals(vi, t.get(LuaString.valueOf(keys[i])));
|
|
||||||
assertEquals(vi, t.rawget(keys[i]));
|
|
||||||
assertEquals(vi, t.rawget(keys[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace with new values
|
|
||||||
for (int i = 0; i < keys.length; ++i) {
|
|
||||||
t.set(keys[i], LuaString.valueOf("Replacement Value! " + i));
|
|
||||||
assertEquals(0, t.length());
|
|
||||||
assertEquals(keys.length, t.keyCount());
|
|
||||||
assertEquals(capacities[keys.length], t.getHashLength());
|
|
||||||
}
|
|
||||||
for (int i = 0; i < keys.length; ++i) {
|
|
||||||
LuaValue vi = LuaString.valueOf("Replacement Value! " + i);
|
|
||||||
assertEquals(vi, t.get(keys[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove
|
|
||||||
for (int i = 0; i < keys.length; ++i) {
|
|
||||||
t.set(keys[i], LuaValue.NIL);
|
|
||||||
assertEquals(0, t.length());
|
|
||||||
assertEquals(keys.length-i-1, t.keyCount());
|
|
||||||
if (i < keys.length-1)
|
|
||||||
assertEquals(capacities[keys.length], t.getHashLength());
|
|
||||||
else
|
|
||||||
assertTrue(0 <= t.getHashLength());
|
|
||||||
}
|
|
||||||
for (int i = 0; i < keys.length; ++i) {
|
|
||||||
assertEquals(LuaValue.NIL, t.get(keys[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testIndexMetatag() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
LuaTable mt = new_Table();
|
|
||||||
LuaTable fb = new_Table();
|
|
||||||
|
|
||||||
// set basic values
|
|
||||||
t.set("ppp", "abc");
|
|
||||||
t.set(123, "def");
|
|
||||||
mt.set(LuaValue.INDEX, fb);
|
|
||||||
fb.set("qqq", "ghi");
|
|
||||||
fb.set(456, "jkl");
|
|
||||||
|
|
||||||
// check before setting metatable
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("nil", t.get("qqq").tojstring());
|
|
||||||
assertEquals("nil", t.get(456).tojstring());
|
|
||||||
assertEquals("nil", fb.get("ppp").tojstring());
|
|
||||||
assertEquals("nil", fb.get(123).tojstring());
|
|
||||||
assertEquals("ghi", fb.get("qqq").tojstring());
|
|
||||||
assertEquals("jkl", fb.get(456).tojstring());
|
|
||||||
assertEquals("nil", mt.get("ppp").tojstring());
|
|
||||||
assertEquals("nil", mt.get(123).tojstring());
|
|
||||||
assertEquals("nil", mt.get("qqq").tojstring());
|
|
||||||
assertEquals("nil", mt.get(456).tojstring());
|
|
||||||
|
|
||||||
// check before setting metatable
|
|
||||||
t.setmetatable(mt);
|
|
||||||
assertEquals(mt, t.getmetatable());
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("ghi", t.get("qqq").tojstring());
|
|
||||||
assertEquals("jkl", t.get(456).tojstring());
|
|
||||||
assertEquals("nil", fb.get("ppp").tojstring());
|
|
||||||
assertEquals("nil", fb.get(123).tojstring());
|
|
||||||
assertEquals("ghi", fb.get("qqq").tojstring());
|
|
||||||
assertEquals("jkl", fb.get(456).tojstring());
|
|
||||||
assertEquals("nil", mt.get("ppp").tojstring());
|
|
||||||
assertEquals("nil", mt.get(123).tojstring());
|
|
||||||
assertEquals("nil", mt.get("qqq").tojstring());
|
|
||||||
assertEquals("nil", mt.get(456).tojstring());
|
|
||||||
|
|
||||||
// set metatable to metatable without values
|
|
||||||
t.setmetatable(fb);
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("nil", t.get("qqq").tojstring());
|
|
||||||
assertEquals("nil", t.get(456).tojstring());
|
|
||||||
|
|
||||||
// set metatable to null
|
|
||||||
t.setmetatable(null);
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("nil", t.get("qqq").tojstring());
|
|
||||||
assertEquals("nil", t.get(456).tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testIndexFunction() {
|
|
||||||
final LuaTable t = new_Table();
|
|
||||||
final LuaTable mt = new_Table();
|
|
||||||
|
|
||||||
final TwoArgFunction fb = new TwoArgFunction() {
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue tbl, LuaValue key) {
|
|
||||||
assertEquals(tbl, t);
|
|
||||||
return valueOf("from mt: " + key);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// set basic values
|
|
||||||
t.set("ppp", "abc");
|
|
||||||
t.set(123, "def");
|
|
||||||
mt.set(LuaValue.INDEX, fb);
|
|
||||||
|
|
||||||
// check before setting metatable
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("nil", t.get("qqq").tojstring());
|
|
||||||
assertEquals("nil", t.get(456).tojstring());
|
|
||||||
|
|
||||||
// check before setting metatable
|
|
||||||
t.setmetatable(mt);
|
|
||||||
assertEquals(mt, t.getmetatable());
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("from mt: qqq", t.get("qqq").tojstring());
|
|
||||||
assertEquals("from mt: 456", t.get(456).tojstring());
|
|
||||||
|
|
||||||
// use raw set
|
|
||||||
t.rawset("qqq", "alt-qqq");
|
|
||||||
t.rawset(456, "alt-456");
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("alt-qqq", t.get("qqq").tojstring());
|
|
||||||
assertEquals("alt-456", t.get(456).tojstring());
|
|
||||||
|
|
||||||
// remove using raw set
|
|
||||||
t.rawset("qqq", LuaValue.NIL);
|
|
||||||
t.rawset(456, LuaValue.NIL);
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("from mt: qqq", t.get("qqq").tojstring());
|
|
||||||
assertEquals("from mt: 456", t.get(456).tojstring());
|
|
||||||
|
|
||||||
// set metatable to null
|
|
||||||
t.setmetatable(null);
|
|
||||||
assertEquals("abc", t.get("ppp").tojstring());
|
|
||||||
assertEquals("def", t.get(123).tojstring());
|
|
||||||
assertEquals("nil", t.get("qqq").tojstring());
|
|
||||||
assertEquals("nil", t.get(456).tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testNext() {
|
|
||||||
final LuaTable t = new_Table();
|
|
||||||
assertEquals(LuaValue.NIL, t.next(LuaValue.NIL));
|
|
||||||
|
|
||||||
// insert array elements
|
|
||||||
t.set(1, "one");
|
|
||||||
assertEquals(LuaValue.valueOf(1), t.next(LuaValue.NIL).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("one"), t.next(LuaValue.NIL).arg(2));
|
|
||||||
assertEquals(LuaValue.NIL, t.next(LuaValue.ONE));
|
|
||||||
t.set(2, "two");
|
|
||||||
assertEquals(LuaValue.valueOf(1), t.next(LuaValue.NIL).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("one"), t.next(LuaValue.NIL).arg(2));
|
|
||||||
assertEquals(LuaValue.valueOf(2), t.next(LuaValue.ONE).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("two"), t.next(LuaValue.ONE).arg(2));
|
|
||||||
assertEquals(LuaValue.NIL, t.next(LuaValue.valueOf(2)));
|
|
||||||
|
|
||||||
// insert hash elements
|
|
||||||
t.set("aa", "aaa");
|
|
||||||
assertEquals(LuaValue.valueOf(1), t.next(LuaValue.NIL).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("one"), t.next(LuaValue.NIL).arg(2));
|
|
||||||
assertEquals(LuaValue.valueOf(2), t.next(LuaValue.ONE).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("two"), t.next(LuaValue.ONE).arg(2));
|
|
||||||
assertEquals(LuaValue.valueOf("aa"), t.next(LuaValue.valueOf(2)).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("aaa"), t.next(LuaValue.valueOf(2)).arg(2));
|
|
||||||
assertEquals(LuaValue.NIL, t.next(LuaValue.valueOf("aa")));
|
|
||||||
t.set("bb", "bbb");
|
|
||||||
assertEquals(LuaValue.valueOf(1), t.next(LuaValue.NIL).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("one"), t.next(LuaValue.NIL).arg(2));
|
|
||||||
assertEquals(LuaValue.valueOf(2), t.next(LuaValue.ONE).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("two"), t.next(LuaValue.ONE).arg(2));
|
|
||||||
assertEquals(LuaValue.valueOf("aa"), t.next(LuaValue.valueOf(2)).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("aaa"), t.next(LuaValue.valueOf(2)).arg(2));
|
|
||||||
assertEquals(LuaValue.valueOf("bb"), t.next(LuaValue.valueOf("aa")).arg(1));
|
|
||||||
assertEquals(LuaValue.valueOf("bbb"), t.next(LuaValue.valueOf("aa")).arg(2));
|
|
||||||
assertEquals(LuaValue.NIL, t.next(LuaValue.valueOf("bb")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLoopWithRemoval() {
|
|
||||||
final LuaTable t = new_Table();
|
|
||||||
|
|
||||||
t.set(LuaValue.valueOf(1), LuaValue.valueOf("1"));
|
|
||||||
t.set(LuaValue.valueOf(3), LuaValue.valueOf("3"));
|
|
||||||
t.set(LuaValue.valueOf(8), LuaValue.valueOf("4"));
|
|
||||||
t.set(LuaValue.valueOf(17), LuaValue.valueOf("5"));
|
|
||||||
t.set(LuaValue.valueOf(26), LuaValue.valueOf("6"));
|
|
||||||
t.set(LuaValue.valueOf(35), LuaValue.valueOf("7"));
|
|
||||||
t.set(LuaValue.valueOf(42), LuaValue.valueOf("8"));
|
|
||||||
t.set(LuaValue.valueOf(60), LuaValue.valueOf("10"));
|
|
||||||
t.set(LuaValue.valueOf(63), LuaValue.valueOf("11"));
|
|
||||||
|
|
||||||
Varargs entry = t.next(LuaValue.NIL);
|
|
||||||
while ( !entry.isnil(1) ) {
|
|
||||||
LuaValue k = entry.arg1();
|
|
||||||
LuaValue v = entry.arg(2);
|
|
||||||
if ((k.toint() & 1) == 0) {
|
|
||||||
t.set(k, LuaValue.NIL);
|
|
||||||
}
|
|
||||||
entry = t.next(k);
|
|
||||||
}
|
|
||||||
|
|
||||||
int numEntries = 0;
|
|
||||||
entry = t.next(LuaValue.NIL);
|
|
||||||
while ( !entry.isnil(1) ) {
|
|
||||||
LuaValue k = entry.arg1();
|
|
||||||
// Only odd keys should remain
|
|
||||||
assertTrue((k.toint() & 1) == 1);
|
|
||||||
numEntries++;
|
|
||||||
entry = t.next(k);
|
|
||||||
}
|
|
||||||
assertEquals(5, numEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLoopWithRemovalAndSet() {
|
|
||||||
final LuaTable t = new_Table();
|
|
||||||
|
|
||||||
t.set(LuaValue.valueOf(1), LuaValue.valueOf("1"));
|
|
||||||
t.set(LuaValue.valueOf(3), LuaValue.valueOf("3"));
|
|
||||||
t.set(LuaValue.valueOf(8), LuaValue.valueOf("4"));
|
|
||||||
t.set(LuaValue.valueOf(17), LuaValue.valueOf("5"));
|
|
||||||
t.set(LuaValue.valueOf(26), LuaValue.valueOf("6"));
|
|
||||||
t.set(LuaValue.valueOf(35), LuaValue.valueOf("7"));
|
|
||||||
t.set(LuaValue.valueOf(42), LuaValue.valueOf("8"));
|
|
||||||
t.set(LuaValue.valueOf(60), LuaValue.valueOf("10"));
|
|
||||||
t.set(LuaValue.valueOf(63), LuaValue.valueOf("11"));
|
|
||||||
|
|
||||||
Varargs entry = t.next(LuaValue.NIL);
|
|
||||||
Varargs entry2 = entry;
|
|
||||||
while ( !entry.isnil(1) ) {
|
|
||||||
LuaValue k = entry.arg1();
|
|
||||||
LuaValue v = entry.arg(2);
|
|
||||||
if ((k.toint() & 1) == 0) {
|
|
||||||
t.set(k, LuaValue.NIL);
|
|
||||||
} else {
|
|
||||||
t.set(k, v.tonumber());
|
|
||||||
entry2 = t.next(entry2.arg1());
|
|
||||||
}
|
|
||||||
entry = t.next(k);
|
|
||||||
}
|
|
||||||
|
|
||||||
int numEntries = 0;
|
|
||||||
entry = t.next(LuaValue.NIL);
|
|
||||||
while ( !entry.isnil(1) ) {
|
|
||||||
LuaValue k = entry.arg1();
|
|
||||||
// Only odd keys should remain
|
|
||||||
assertTrue((k.toint() & 1) == 1);
|
|
||||||
assertTrue(entry.arg(2).type() == LuaValue.TNUMBER);
|
|
||||||
numEntries++;
|
|
||||||
entry = t.next(k);
|
|
||||||
}
|
|
||||||
assertEquals(5, numEntries);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,437 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class TableTest {
|
|
||||||
|
|
||||||
protected LuaTable new_Table() {
|
|
||||||
return new LuaTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected LuaTable new_Table(int n, int m) {
|
|
||||||
return new LuaTable(n, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int keyCount(LuaTable t) {
|
|
||||||
return keys(t).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LuaValue[] keys(LuaTable t) {
|
|
||||||
ArrayList<LuaValue> l = new ArrayList<LuaValue>();
|
|
||||||
LuaValue k = LuaValue.NIL;
|
|
||||||
while ( true ) {
|
|
||||||
Varargs n = t.next(k);
|
|
||||||
if ((k = n.arg1()).isnil())
|
|
||||||
break;
|
|
||||||
l.add(k);
|
|
||||||
}
|
|
||||||
return l.toArray(new LuaValue[t.length()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInOrderIntegerKeyInsertion() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
t.set(i, LuaValue.valueOf("Test Value! " + i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure all keys are still there.
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
assertEquals("Test Value! " + i, t.get(i).tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure capacities make sense
|
|
||||||
assertEquals(0, t.getHashLength());
|
|
||||||
|
|
||||||
assertTrue(t.getArrayLength() >= 32);
|
|
||||||
assertTrue(t.getArrayLength() <= 64);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRekeyCount() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
// NOTE: This order of insertion is important.
|
|
||||||
t.set(3, LuaInteger.valueOf(3));
|
|
||||||
t.set(1, LuaInteger.valueOf(1));
|
|
||||||
t.set(5, LuaInteger.valueOf(5));
|
|
||||||
t.set(4, LuaInteger.valueOf(4));
|
|
||||||
t.set(6, LuaInteger.valueOf(6));
|
|
||||||
t.set(2, LuaInteger.valueOf(2));
|
|
||||||
|
|
||||||
for (int i = 1; i < 6; ++i) {
|
|
||||||
assertEquals(LuaInteger.valueOf(i), t.get(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
assertTrue(t.getArrayLength() >= 3);
|
|
||||||
assertTrue(t.getArrayLength() <= 12);
|
|
||||||
assertTrue(t.getHashLength() <= 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOutOfOrderIntegerKeyInsertion() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
for (int i = 32; i > 0; --i) {
|
|
||||||
t.set(i, LuaValue.valueOf("Test Value! " + i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure all keys are still there.
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
assertEquals("Test Value! " + i, t.get(i).tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure capacities make sense
|
|
||||||
assertEquals(32, t.getArrayLength());
|
|
||||||
assertEquals(0, t.getHashLength());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringAndIntegerKeys() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
LuaString str = LuaValue.valueOf(String.valueOf(i));
|
|
||||||
t.set(i, str);
|
|
||||||
t.set(str, LuaInteger.valueOf(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
assertTrue(t.getArrayLength() >= 8); // 1, 2, ..., 9
|
|
||||||
assertTrue(t.getArrayLength() <= 16);
|
|
||||||
assertTrue(t.getHashLength() >= 11); // 0, "0", "1", ..., "9"
|
|
||||||
assertTrue(t.getHashLength() <= 33);
|
|
||||||
|
|
||||||
LuaValue[] keys = keys(t);
|
|
||||||
|
|
||||||
int intKeys = 0;
|
|
||||||
int stringKeys = 0;
|
|
||||||
|
|
||||||
assertEquals(20, keys.length);
|
|
||||||
for (int i = 0; i < keys.length; ++i) {
|
|
||||||
LuaValue k = keys[i];
|
|
||||||
|
|
||||||
if (k instanceof LuaInteger) {
|
|
||||||
final int ik = k.toint();
|
|
||||||
assertTrue(ik >= 0 && ik < 10);
|
|
||||||
final int mask = 1<<ik;
|
|
||||||
assertTrue((intKeys & mask) == 0);
|
|
||||||
intKeys |= mask;
|
|
||||||
} else if (k instanceof LuaString) {
|
|
||||||
final int ik = Integer.parseInt(k.strvalue().tojstring());
|
|
||||||
assertEquals(String.valueOf(ik), k.strvalue().tojstring());
|
|
||||||
assertTrue(ik >= 0 && ik < 10);
|
|
||||||
final int mask = 1<<ik;
|
|
||||||
assertTrue((stringKeys & mask) == 0, "Key \"" + ik + "\" found more than once");
|
|
||||||
stringKeys |= mask;
|
|
||||||
} else {
|
|
||||||
fail("Unexpected type of key found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertEquals(0x03FF, intKeys);
|
|
||||||
assertEquals(0x03FF, stringKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBadInitialCapacity() {
|
|
||||||
LuaTable t = new_Table(0, 1);
|
|
||||||
|
|
||||||
t.set("test", LuaValue.valueOf("foo"));
|
|
||||||
t.set("explode", LuaValue.valueOf("explode"));
|
|
||||||
assertEquals(2, keyCount(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRemove0() {
|
|
||||||
LuaTable t = new_Table(2, 0);
|
|
||||||
|
|
||||||
t.set(1, LuaValue.valueOf("foo"));
|
|
||||||
t.set(2, LuaValue.valueOf("bah"));
|
|
||||||
assertNotSame(LuaValue.NIL, t.get(1));
|
|
||||||
assertNotSame(LuaValue.NIL, t.get(2));
|
|
||||||
assertEquals(LuaValue.NIL, t.get(3));
|
|
||||||
|
|
||||||
t.set(1, LuaValue.NIL);
|
|
||||||
t.set(2, LuaValue.NIL);
|
|
||||||
t.set(3, LuaValue.NIL);
|
|
||||||
assertEquals(LuaValue.NIL, t.get(1));
|
|
||||||
assertEquals(LuaValue.NIL, t.get(2));
|
|
||||||
assertEquals(LuaValue.NIL, t.get(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRemove1() {
|
|
||||||
LuaTable t = new_Table(0, 1);
|
|
||||||
|
|
||||||
t.set("test", LuaValue.valueOf("foo"));
|
|
||||||
t.set("explode", LuaValue.NIL);
|
|
||||||
t.set(42, LuaValue.NIL);
|
|
||||||
t.set(new_Table(), LuaValue.NIL);
|
|
||||||
t.set("test", LuaValue.NIL);
|
|
||||||
assertEquals(0, keyCount(t));
|
|
||||||
|
|
||||||
t.set(10, LuaInteger.valueOf(5));
|
|
||||||
t.set(10, LuaValue.NIL);
|
|
||||||
assertEquals(0, keyCount(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRemove2() {
|
|
||||||
LuaTable t = new_Table(0, 1);
|
|
||||||
|
|
||||||
t.set("test", LuaValue.valueOf("foo"));
|
|
||||||
t.set("string", LuaInteger.valueOf(10));
|
|
||||||
assertEquals(2, keyCount(t));
|
|
||||||
|
|
||||||
t.set("string", LuaValue.NIL);
|
|
||||||
t.set("three", LuaValue.valueOf(3.14));
|
|
||||||
assertEquals(2, keyCount(t));
|
|
||||||
|
|
||||||
t.set("test", LuaValue.NIL);
|
|
||||||
assertEquals(1, keyCount(t));
|
|
||||||
|
|
||||||
t.set(10, LuaInteger.valueOf(5));
|
|
||||||
assertEquals(2, keyCount(t));
|
|
||||||
|
|
||||||
t.set(10, LuaValue.NIL);
|
|
||||||
assertEquals(1, keyCount(t));
|
|
||||||
|
|
||||||
t.set("three", LuaValue.NIL);
|
|
||||||
assertEquals(0, keyCount(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testShrinkNonPowerOfTwoArray() {
|
|
||||||
LuaTable t = new_Table(6, 2);
|
|
||||||
|
|
||||||
t.set(1, "one");
|
|
||||||
t.set(2, "two");
|
|
||||||
t.set(3, "three");
|
|
||||||
t.set(4, "four");
|
|
||||||
t.set(5, "five");
|
|
||||||
t.set(6, "six");
|
|
||||||
|
|
||||||
t.set("aa", "aaa");
|
|
||||||
t.set("bb", "bbb");
|
|
||||||
|
|
||||||
t.set(3, LuaValue.NIL);
|
|
||||||
t.set(4, LuaValue.NIL);
|
|
||||||
t.set(6, LuaValue.NIL);
|
|
||||||
|
|
||||||
t.set("cc", "ccc");
|
|
||||||
t.set("dd", "ddd");
|
|
||||||
|
|
||||||
assertEquals(4, t.getArrayLength());
|
|
||||||
assertTrue(t.getHashLength() < 10);
|
|
||||||
assertEquals(5, t.hashEntries);
|
|
||||||
assertEquals("one", t.get(1).tojstring());
|
|
||||||
assertEquals("two", t.get(2).tojstring());
|
|
||||||
assertEquals(LuaValue.NIL, t.get(3));
|
|
||||||
assertEquals(LuaValue.NIL, t.get(4));
|
|
||||||
assertEquals("five", t.get(5).tojstring());
|
|
||||||
assertEquals(LuaValue.NIL, t.get(6));
|
|
||||||
assertEquals("aaa", t.get("aa").tojstring());
|
|
||||||
assertEquals("bbb", t.get("bb").tojstring());
|
|
||||||
assertEquals("ccc", t.get("cc").tojstring());
|
|
||||||
assertEquals("ddd", t.get("dd").tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInOrderLuaLength() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
t.set(i, LuaValue.valueOf("Test Value! " + i));
|
|
||||||
assertEquals(i, t.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOutOfOrderLuaLength() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
for (int j = 8; j < 32; j += 8) {
|
|
||||||
for (int i = j; i > 0; --i) {
|
|
||||||
t.set(i, LuaValue.valueOf("Test Value! " + i));
|
|
||||||
}
|
|
||||||
assertEquals(j, t.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringKeysLuaLength() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
t.set("str-" + i, LuaValue.valueOf("String Key Test Value! " + i));
|
|
||||||
assertEquals(0, t.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMixedKeysLuaLength() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
t.set("str-" + i, LuaValue.valueOf("String Key Test Value! " + i));
|
|
||||||
t.set(i, LuaValue.valueOf("Int Key Test Value! " + i));
|
|
||||||
assertEquals(i, t.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final void compareLists(LuaTable t, Vector<LuaString> v) {
|
|
||||||
int n = v.size();
|
|
||||||
assertEquals(v.size(), t.length());
|
|
||||||
for (int j = 0; j < n; j++) {
|
|
||||||
LuaString vj = v.elementAt(j);
|
|
||||||
String tj = t.get(j+1).tojstring();
|
|
||||||
assertEquals(vj.tojstring(), tj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInsertBeginningOfList() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
Vector<LuaString> v = new Vector<>();
|
|
||||||
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
LuaString test = LuaValue.valueOf("Test Value! " + i);
|
|
||||||
t.insert(1, test);
|
|
||||||
v.insertElementAt(test, 0);
|
|
||||||
compareLists(t, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInsertEndOfList() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
Vector<LuaString> v = new Vector<>();
|
|
||||||
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
LuaString test = LuaValue.valueOf("Test Value! " + i);
|
|
||||||
t.insert(0, test);
|
|
||||||
v.insertElementAt(test, v.size());
|
|
||||||
compareLists(t, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInsertMiddleOfList() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
Vector<LuaString> v = new Vector<>();
|
|
||||||
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
LuaString test = LuaValue.valueOf("Test Value! " + i);
|
|
||||||
int m = i/2;
|
|
||||||
t.insert(m+1, test);
|
|
||||||
v.insertElementAt(test, m);
|
|
||||||
compareLists(t, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final void prefillLists(LuaTable t, Vector<LuaString> v) {
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
LuaString test = LuaValue.valueOf("Test Value! " + i);
|
|
||||||
t.insert(0, test);
|
|
||||||
v.insertElementAt(test, v.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRemoveBeginningOfList() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
Vector<LuaString> v = new Vector<>();
|
|
||||||
prefillLists(t, v);
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
t.remove(1);
|
|
||||||
v.removeElementAt(0);
|
|
||||||
compareLists(t, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRemoveEndOfList() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
Vector<LuaString> v = new Vector<>();
|
|
||||||
prefillLists(t, v);
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
t.remove(0);
|
|
||||||
v.removeElementAt(v.size()-1);
|
|
||||||
compareLists(t, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRemoveMiddleOfList() {
|
|
||||||
LuaTable t = new_Table();
|
|
||||||
Vector<LuaString> v = new Vector<>();
|
|
||||||
prefillLists(t, v);
|
|
||||||
for (int i = 1; i <= 32; ++i) {
|
|
||||||
int m = v.size()/2;
|
|
||||||
t.remove(m+1);
|
|
||||||
v.removeElementAt(m);
|
|
||||||
compareLists(t, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRemoveWhileIterating() {
|
|
||||||
LuaTable t = LuaValue.tableOf(
|
|
||||||
new LuaValue[] { LuaValue.valueOf("a"), LuaValue.valueOf("aa"), LuaValue.valueOf("b"),
|
|
||||||
LuaValue.valueOf("bb"), LuaValue.valueOf("c"), LuaValue.valueOf("cc"), LuaValue.valueOf("d"),
|
|
||||||
LuaValue.valueOf("dd"), LuaValue.valueOf("e"), LuaValue.valueOf("ee"), },
|
|
||||||
new LuaValue[] { LuaValue.valueOf("11"), LuaValue.valueOf("22"), LuaValue.valueOf("33"),
|
|
||||||
LuaValue.valueOf("44"), LuaValue.valueOf("55"), });
|
|
||||||
// Find expected order after removal.
|
|
||||||
List<String> expected = new ArrayList<>();
|
|
||||||
Varargs n;
|
|
||||||
int i;
|
|
||||||
for (n = t.next(LuaValue.NIL), i = 0; !n.arg1().isnil(); n = t.next(n.arg1()), ++i) {
|
|
||||||
if (i%2 == 0)
|
|
||||||
expected.add(n.arg1() + "=" + n.arg(2));
|
|
||||||
}
|
|
||||||
// Remove every other key while iterating over the table.
|
|
||||||
for (n = t.next(LuaValue.NIL), i = 0; !n.arg1().isnil(); n = t.next(n.arg1()), ++i) {
|
|
||||||
if (i%2 != 0)
|
|
||||||
t.set(n.arg1(), LuaValue.NIL);
|
|
||||||
}
|
|
||||||
// Iterate over remaining table, and form list of entries still in table.
|
|
||||||
List<String> actual = new ArrayList<>();
|
|
||||||
for (n = t.next(LuaValue.NIL); !n.arg1().isnil(); n = t.next(n.arg1())) {
|
|
||||||
actual.add(n.arg1() + "=" + n.arg(2));
|
|
||||||
}
|
|
||||||
assertEquals(expected, actual);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,262 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class WeakTableTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testWeakValuesTable() {
|
|
||||||
LuaTable t = WeakTable.make(false, true);
|
|
||||||
|
|
||||||
Object obj = new Object();
|
|
||||||
LuaTable tableValue = new LuaTable();
|
|
||||||
LuaString stringValue = LuaString.valueOf("this is a test");
|
|
||||||
LuaTable tableValue2 = new LuaTable();
|
|
||||||
|
|
||||||
t.set("table", tableValue);
|
|
||||||
t.set("userdata", LuaValue.userdataOf(obj, null));
|
|
||||||
t.set("string", stringValue);
|
|
||||||
t.set("string2", LuaValue.valueOf("another string"));
|
|
||||||
t.set(1, tableValue2);
|
|
||||||
assertTrue(t.getHashLength() >= 4, "table must have at least 4 elements");
|
|
||||||
// TODO fix assert
|
|
||||||
// assertTrue(t.getArrayLength() >= 1, "array part must have 1 element");
|
|
||||||
|
|
||||||
// check that table can be used to get elements
|
|
||||||
assertEquals(tableValue, t.get("table"));
|
|
||||||
assertEquals(stringValue, t.get("string"));
|
|
||||||
assertEquals(obj, t.get("userdata").checkuserdata());
|
|
||||||
assertEquals(tableValue2, t.get(1));
|
|
||||||
|
|
||||||
// nothing should be collected, since we have strong references here
|
|
||||||
collectGarbage();
|
|
||||||
|
|
||||||
// check that elements are still there
|
|
||||||
assertEquals(tableValue, t.get("table"));
|
|
||||||
assertEquals(stringValue, t.get("string"));
|
|
||||||
assertEquals(obj, t.get("userdata").checkuserdata());
|
|
||||||
assertEquals(tableValue2, t.get(1));
|
|
||||||
|
|
||||||
// drop our strong references
|
|
||||||
obj = null;
|
|
||||||
tableValue = null;
|
|
||||||
tableValue2 = null;
|
|
||||||
stringValue = null;
|
|
||||||
|
|
||||||
// Garbage collection should cause weak entries to be dropped.
|
|
||||||
collectGarbage();
|
|
||||||
|
|
||||||
// check that they are dropped
|
|
||||||
assertEquals(LuaValue.NIL, t.get("table"));
|
|
||||||
assertEquals(LuaValue.NIL, t.get("userdata"));
|
|
||||||
assertEquals(LuaValue.NIL, t.get(1));
|
|
||||||
assertFalse(t.get("string").isnil(), "strings should not be in weak references");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testWeakKeysTable() {
|
|
||||||
LuaTable t = WeakTable.make(true, false);
|
|
||||||
|
|
||||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
|
||||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
|
||||||
|
|
||||||
// set up the table
|
|
||||||
t.set(key, val);
|
|
||||||
assertEquals(val, t.get(key));
|
|
||||||
System.gc();
|
|
||||||
assertEquals(val, t.get(key));
|
|
||||||
|
|
||||||
// drop key and value references, replace them with new ones
|
|
||||||
WeakReference<LuaValue> origkey = new WeakReference<>(key);
|
|
||||||
WeakReference<LuaValue> origval = new WeakReference<>(val);
|
|
||||||
key = LuaValue.userdataOf(new MyData(111));
|
|
||||||
val = LuaValue.userdataOf(new MyData(222));
|
|
||||||
|
|
||||||
// new key and value should be interchangeable (feature of this test class)
|
|
||||||
assertEquals(key, origkey.get());
|
|
||||||
assertEquals(val, origval.get());
|
|
||||||
assertEquals(val, t.get(key));
|
|
||||||
assertEquals(val, t.get(origkey.get()));
|
|
||||||
assertEquals(origval.get(), t.get(key));
|
|
||||||
|
|
||||||
// value should not be reachable after gc
|
|
||||||
collectGarbage();
|
|
||||||
assertEquals(null, origkey.get());
|
|
||||||
assertEquals(LuaValue.NIL, t.get(key));
|
|
||||||
collectGarbage();
|
|
||||||
assertEquals(null, origval.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testNext() {
|
|
||||||
LuaTable t = WeakTable.make(true, true);
|
|
||||||
|
|
||||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
|
||||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
|
||||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
|
||||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
|
||||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
|
||||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
|
||||||
|
|
||||||
// set up the table
|
|
||||||
t.set(key, val);
|
|
||||||
t.set(key2, val2);
|
|
||||||
t.set(key3, val3);
|
|
||||||
|
|
||||||
// forget one of the keys
|
|
||||||
key2 = null;
|
|
||||||
val2 = null;
|
|
||||||
collectGarbage();
|
|
||||||
|
|
||||||
// table should have 2 entries
|
|
||||||
int size = 0;
|
|
||||||
for (LuaValue k = t.next(LuaValue.NIL).arg1(); !k.isnil(); k = t.next(k).arg1()) {
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
assertEquals(2, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testWeakKeysValuesTable() {
|
|
||||||
LuaTable t = WeakTable.make(true, true);
|
|
||||||
|
|
||||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
|
||||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
|
||||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
|
||||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
|
||||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
|
||||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
|
||||||
|
|
||||||
// set up the table
|
|
||||||
t.set(key, val);
|
|
||||||
t.set(key2, val2);
|
|
||||||
t.set(key3, val3);
|
|
||||||
assertEquals(val, t.get(key));
|
|
||||||
assertEquals(val2, t.get(key2));
|
|
||||||
assertEquals(val3, t.get(key3));
|
|
||||||
System.gc();
|
|
||||||
assertEquals(val, t.get(key));
|
|
||||||
assertEquals(val2, t.get(key2));
|
|
||||||
assertEquals(val3, t.get(key3));
|
|
||||||
|
|
||||||
// drop key and value references, replace them with new ones
|
|
||||||
WeakReference<LuaValue> origkey = new WeakReference<>(key);
|
|
||||||
WeakReference<LuaValue> origval = new WeakReference<>(val);
|
|
||||||
WeakReference<LuaValue> origkey2 = new WeakReference<>(key2);
|
|
||||||
WeakReference<LuaValue> origval2 = new WeakReference<>(val2);
|
|
||||||
WeakReference<LuaValue> origkey3 = new WeakReference<>(key3);
|
|
||||||
WeakReference<LuaValue> origval3 = new WeakReference<>(val3);
|
|
||||||
key = LuaValue.userdataOf(new MyData(111));
|
|
||||||
val = LuaValue.userdataOf(new MyData(222));
|
|
||||||
key2 = LuaValue.userdataOf(new MyData(333));
|
|
||||||
// don't drop val2, or key3
|
|
||||||
val3 = LuaValue.userdataOf(new MyData(666));
|
|
||||||
|
|
||||||
// no values should be reachable after gc
|
|
||||||
collectGarbage();
|
|
||||||
assertEquals(null, origkey.get());
|
|
||||||
assertEquals(null, origval.get());
|
|
||||||
assertEquals(null, origkey2.get());
|
|
||||||
assertEquals(null, origval3.get());
|
|
||||||
assertEquals(LuaValue.NIL, t.get(key));
|
|
||||||
assertEquals(LuaValue.NIL, t.get(key2));
|
|
||||||
assertEquals(LuaValue.NIL, t.get(key3));
|
|
||||||
|
|
||||||
// all originals should be gone after gc, then access
|
|
||||||
val2 = null;
|
|
||||||
key3 = null;
|
|
||||||
collectGarbage();
|
|
||||||
assertEquals(null, origval2.get());
|
|
||||||
assertEquals(null, origkey3.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testReplace() {
|
|
||||||
LuaTable t = WeakTable.make(true, true);
|
|
||||||
|
|
||||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
|
||||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
|
||||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
|
||||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
|
||||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
|
||||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
|
||||||
|
|
||||||
// set up the table
|
|
||||||
t.set(key, val);
|
|
||||||
t.set(key2, val2);
|
|
||||||
t.set(key3, val3);
|
|
||||||
|
|
||||||
LuaValue val4 = LuaValue.userdataOf(new MyData(777));
|
|
||||||
t.set(key2, val4);
|
|
||||||
|
|
||||||
// table should have 3 entries
|
|
||||||
int size = 0;
|
|
||||||
for (LuaValue k = t.next(LuaValue.NIL).arg1(); !k.isnil() && size < 1000; k = t.next(k).arg1()) {
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
assertEquals(3, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MyData {
|
|
||||||
public final int value;
|
|
||||||
|
|
||||||
public MyData(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
return (o instanceof MyData) && ((MyData) o).value == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "mydata-" + value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void collectGarbage() {
|
|
||||||
Runtime rt = Runtime.getRuntime();
|
|
||||||
rt.gc();
|
|
||||||
try {
|
|
||||||
Thread.sleep(20);
|
|
||||||
rt.gc();
|
|
||||||
Thread.sleep(20);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
rt.gc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,39 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-parent</artifactId>
|
|
||||||
<version>3.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>luaj-jme</artifactId>
|
|
||||||
|
|
||||||
<name>luaj-jme</name>
|
|
||||||
<description>LuaJ for Java ME</description>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.bcel</groupId>
|
|
||||||
<artifactId>bcel</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.mcpat.apistubs</groupId>
|
|
||||||
<artifactId>cldc-1.1-stub</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jme;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
|
|
||||||
class OsLibTest {
|
|
||||||
|
|
||||||
LuaValue jme_lib;
|
|
||||||
double time;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
jme_lib = JmePlatform.standardGlobals().get("os");
|
|
||||||
time = 998571302000L/1000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test(String format, String expected) {
|
|
||||||
String actual = jme_lib.get("date").call(LuaValue.valueOf(format), LuaValue.valueOf(time)).tojstring();
|
|
||||||
assertEquals(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDateChars() { test("foo", "foo"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_a() { test("%a", "Thu"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_A() { test("%A", "Thursday"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_b() { test("%b", "Aug"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_B() { test("%B", "August"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_c() { test("%c", "Thu Aug 23 14:55:02 2001"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_d() { test("%d", "23"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_H() { test("%H", "14"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_I() { test("%I", "02"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_j() { test("%j", "235"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_m() { test("%m", "08"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_M() { test("%M", "55"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_p() { test("%p", "PM"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_S() { test("%S", "02"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_U() { test("%U", "33"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_w() { test("%w", "4"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_W() { test("%W", "34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_x() { test("%x", "08/23/01"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_X() { test("%X", "14:55:02"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_y() { test("%y", "01"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_Y() { test("%Y", "2001"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_Pct() { test("%%", "%"); }
|
|
||||||
|
|
||||||
static final double DAY = 24.*3600.;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_neg4() { time -= 4*DAY; test("%c %U %W", "Sun Aug 19 14:55:02 2001 33 33"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_neg3() { time -= 3*DAY; test("%c %U %W", "Mon Aug 20 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_neg2() { time -= 2*DAY; test("%c %U %W", "Tue Aug 21 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_neg1() { time -= DAY; test("%c %U %W", "Wed Aug 22 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos0() { time += 0; test("%c %U %W", "Thu Aug 23 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos1() { time += DAY; test("%c %U %W", "Fri Aug 24 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos2() { time += 2*DAY; test("%c %U %W", "Sat Aug 25 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos3() { time += 3*DAY; test("%c %U %W", "Sun Aug 26 14:55:02 2001 34 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos4() { time += 4*DAY; test("%c %U %W", "Mon Aug 27 14:55:02 2001 34 35"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testJseOsGetenvForEnvVariables() {
|
|
||||||
LuaValue USER = LuaValue.valueOf("USER");
|
|
||||||
LuaValue jme_user = jme_lib.get("getenv").call(USER);
|
|
||||||
assertTrue(jme_user.isnil());
|
|
||||||
System.out.println("User: " + jme_user);
|
|
||||||
}
|
|
||||||
|
|
||||||
void testJseOsGetenvForSystemProperties() {
|
|
||||||
// System.setProperty("test.key.foo", "test.value.bar");
|
|
||||||
LuaValue key = LuaValue.valueOf("test.key.foo");
|
|
||||||
LuaValue value = LuaValue.valueOf("test.value.bar");
|
|
||||||
LuaValue jme_value = jme_lib.get("getenv").call(key);
|
|
||||||
assertEquals(value, jme_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
@@ -1,77 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-parent</artifactId>
|
|
||||||
<version>3.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>luaj-jse</artifactId>
|
|
||||||
|
|
||||||
<name>luaj-jse</name>
|
|
||||||
<description>LuaJ for Java SE</description>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.bcel</groupId>
|
|
||||||
<artifactId>bcel</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>com.helger.maven</groupId>
|
|
||||||
<artifactId>ph-javacc-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>generate-grammar</id>
|
|
||||||
<phase>generate-sources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>javacc</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<jdkVersion>1.8</jdkVersion>
|
|
||||||
<javadocFriendlyComments>true</javadocFriendlyComments>
|
|
||||||
<packageName>org.luaj.vm2.parser</packageName>
|
|
||||||
<sourceDirectory>src/main/javacc</sourceDirectory>
|
|
||||||
<outputDirectory>${project.build.directory}/generated-sources/javacc</outputDirectory>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>build-helper-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>add-source</id>
|
|
||||||
<phase>generate-sources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>add-source</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<sources>
|
|
||||||
<source>${project.build.directory}/generated-sources/javacc</source>
|
|
||||||
</sources>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@@ -1,270 +0,0 @@
|
|||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009-2012 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.Lua;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
import org.luaj.vm2.luajc.LuaJC;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiler for lua files to compile lua sources or lua binaries into java
|
|
||||||
* classes.
|
|
||||||
*/
|
|
||||||
public class luajc {
|
|
||||||
private static final String version = Lua._VERSION + " Copyright (C) 2012 luaj.org";
|
|
||||||
|
|
||||||
private static final String usage = "usage: java -cp luaj-jse.jar,bcel-5.2.jar luajc [options] fileordir [, fileordir ...]\n"
|
|
||||||
+ "Available options are:\n" + " - process stdin\n" + " -s src source directory\n"
|
|
||||||
+ " -d dir destination directory\n" + " -p pkg package prefix to apply to all classes\n"
|
|
||||||
+ " -m generate main(String[]) function for JSE\n" + " -r recursively compile all\n"
|
|
||||||
+ " -l load classes to verify generated bytecode\n"
|
|
||||||
+ " -c enc use the supplied encoding 'enc' for input files\n" + " -v verbose\n";
|
|
||||||
|
|
||||||
private static void usageExit() {
|
|
||||||
System.out.println(usage);
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String srcdir = ".";
|
|
||||||
private String destdir = ".";
|
|
||||||
private boolean genmain = false;
|
|
||||||
private boolean recurse = false;
|
|
||||||
private boolean verbose = false;
|
|
||||||
private boolean loadclasses = false;
|
|
||||||
private String encoding = null;
|
|
||||||
private String pkgprefix = null;
|
|
||||||
private final List files = new ArrayList();
|
|
||||||
private final Globals globals;
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
|
||||||
new luajc(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private luajc(String[] args) throws IOException {
|
|
||||||
|
|
||||||
// process args
|
|
||||||
List seeds = new ArrayList();
|
|
||||||
|
|
||||||
// get stateful args
|
|
||||||
for (int i = 0; i < args.length; i++) {
|
|
||||||
if (!args[i].startsWith("-")) {
|
|
||||||
seeds.add(args[i]);
|
|
||||||
} else {
|
|
||||||
switch (args[i].charAt(1)) {
|
|
||||||
case 's':
|
|
||||||
if (++i >= args.length)
|
|
||||||
usageExit();
|
|
||||||
srcdir = args[i];
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
if (++i >= args.length)
|
|
||||||
usageExit();
|
|
||||||
destdir = args[i];
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
loadclasses = true;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
if (++i >= args.length)
|
|
||||||
usageExit();
|
|
||||||
pkgprefix = args[i];
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
genmain = true;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
recurse = true;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
if (++i >= args.length)
|
|
||||||
usageExit();
|
|
||||||
encoding = args[i];
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
verbose = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
usageExit();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// echo version
|
|
||||||
if (verbose) {
|
|
||||||
System.out.println(version);
|
|
||||||
System.out.println("srcdir: " + srcdir);
|
|
||||||
System.out.println("destdir: " + destdir);
|
|
||||||
System.out.println("files: " + seeds);
|
|
||||||
System.out.println("recurse: " + recurse);
|
|
||||||
}
|
|
||||||
|
|
||||||
// need at least one seed
|
|
||||||
if (seeds.size() <= 0) {
|
|
||||||
System.err.println(usage);
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect up files to process
|
|
||||||
for (Object seed : seeds)
|
|
||||||
collectFiles(srcdir + "/" + seed);
|
|
||||||
|
|
||||||
// check for at least one file
|
|
||||||
if (files.size() <= 0) {
|
|
||||||
System.err.println("no files found in " + seeds);
|
|
||||||
System.exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// process input files
|
|
||||||
globals = JsePlatform.standardGlobals();
|
|
||||||
for (Object file : files)
|
|
||||||
processFile((InputFile) file);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void collectFiles(String path) {
|
|
||||||
File f = new File(path);
|
|
||||||
if (f.isDirectory() && recurse)
|
|
||||||
scandir(f, pkgprefix);
|
|
||||||
else if (f.isFile()) {
|
|
||||||
File dir = f.getAbsoluteFile().getParentFile();
|
|
||||||
if (dir != null)
|
|
||||||
scanfile(dir, f, pkgprefix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scandir(File dir, String javapackage) {
|
|
||||||
File[] f = dir.listFiles();
|
|
||||||
for (File element : f)
|
|
||||||
scanfile(dir, element, javapackage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scanfile(File dir, File f, String javapackage) {
|
|
||||||
if (f.exists()) {
|
|
||||||
if (f.isDirectory() && recurse)
|
|
||||||
scandir(f, javapackage != null? javapackage + "." + f.getName(): f.getName());
|
|
||||||
else if (f.isFile() && f.getName().endsWith(".lua"))
|
|
||||||
files.add(new InputFile(dir, f, javapackage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class LocalClassLoader extends ClassLoader {
|
|
||||||
private final Hashtable t;
|
|
||||||
|
|
||||||
private LocalClassLoader(Hashtable t) {
|
|
||||||
this.t = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class findClass(String classname) throws ClassNotFoundException {
|
|
||||||
byte[] bytes = (byte[]) t.get(classname);
|
|
||||||
if (bytes != null)
|
|
||||||
return defineClass(classname, bytes, 0, bytes.length);
|
|
||||||
return super.findClass(classname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class InputFile {
|
|
||||||
public String luachunkname;
|
|
||||||
public String srcfilename;
|
|
||||||
public File infile;
|
|
||||||
public File outdir;
|
|
||||||
public String javapackage;
|
|
||||||
|
|
||||||
public InputFile(File dir, File f, String javapackage) {
|
|
||||||
this.infile = f;
|
|
||||||
String subdir = javapackage != null? javapackage.replace('.', '/'): null;
|
|
||||||
String outdirpath = subdir != null? destdir + "/" + subdir: destdir;
|
|
||||||
this.javapackage = javapackage;
|
|
||||||
this.srcfilename = (subdir != null? subdir + "/": "")+infile.getName();
|
|
||||||
this.luachunkname = (subdir != null? subdir + "/": "")
|
|
||||||
+infile.getName().substring(0, infile.getName().lastIndexOf('.'));
|
|
||||||
this.infile = f;
|
|
||||||
this.outdir = new File(outdirpath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processFile(InputFile inf) {
|
|
||||||
inf.outdir.mkdirs();
|
|
||||||
try {
|
|
||||||
if (verbose)
|
|
||||||
System.out.println("chunk=" + inf.luachunkname + " srcfile=" + inf.srcfilename);
|
|
||||||
|
|
||||||
// create the chunk
|
|
||||||
FileInputStream fis = new FileInputStream(inf.infile);
|
|
||||||
final Hashtable t = encoding != null
|
|
||||||
? LuaJC.instance.compileAll(new InputStreamReader(fis, encoding), inf.luachunkname, inf.srcfilename,
|
|
||||||
globals, genmain)
|
|
||||||
: LuaJC.instance.compileAll(fis, inf.luachunkname, inf.srcfilename, globals, genmain);
|
|
||||||
fis.close();
|
|
||||||
|
|
||||||
// write out the chunk
|
|
||||||
for (Enumeration e = t.keys(); e.hasMoreElements();) {
|
|
||||||
String key = (String) e.nextElement();
|
|
||||||
byte[] bytes = (byte[]) t.get(key);
|
|
||||||
if (key.indexOf('/') >= 0) {
|
|
||||||
String d = (destdir != null? destdir + "/": "")+key.substring(0, key.lastIndexOf('/'));
|
|
||||||
new File(d).mkdirs();
|
|
||||||
}
|
|
||||||
String destpath = (destdir != null? destdir + "/": "") + key + ".class";
|
|
||||||
if (verbose)
|
|
||||||
System.out.println(" " + destpath + " (" + bytes.length + " bytes)");
|
|
||||||
FileOutputStream fos = new FileOutputStream(destpath);
|
|
||||||
fos.write(bytes);
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to load the files
|
|
||||||
if (loadclasses) {
|
|
||||||
ClassLoader loader = new LocalClassLoader(t);
|
|
||||||
for (Enumeration e = t.keys(); e.hasMoreElements();) {
|
|
||||||
String classname = (String) e.nextElement();
|
|
||||||
try {
|
|
||||||
Class c = loader.loadClass(classname);
|
|
||||||
Object o = c.newInstance();
|
|
||||||
if (verbose)
|
|
||||||
System.out.println(" loaded " + classname + " as " + o);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
System.out.flush();
|
|
||||||
System.err.println(" failed to load " + classname + ": " + ex);
|
|
||||||
System.err.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println(" failed to load " + inf.srcfilename + ": " + e);
|
|
||||||
e.printStackTrace(System.err);
|
|
||||||
System.err.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
import org.luaj.vm2.compat.JavaCompat;
|
|
||||||
|
|
||||||
public class JavaCompatJSE extends JavaCompat {
|
|
||||||
public long doubleToRawLongBits(double x) {
|
|
||||||
return Double.doubleToRawLongBits(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009-2011 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.lib.LibFunction;
|
|
||||||
import org.luaj.vm2.lib.TwoArgFunction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subclass of {@link LibFunction} which implements the lua standard
|
|
||||||
* {@code math} library.
|
|
||||||
* <p>
|
|
||||||
* It contains all lua math functions, including those not available on the JME
|
|
||||||
* platform. See {@link org.luaj.vm2.lib.MathLib} for the exception list.
|
|
||||||
* <p>
|
|
||||||
* Typically, this library is included as part of a call to
|
|
||||||
* {@link org.luaj.vm2.lib.jse.JsePlatform#standardGlobals()}
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = JsePlatform.standardGlobals();
|
|
||||||
* System.out.println(globals.get("math").get("sqrt").call(LuaValue.valueOf(2)));
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
* For special cases where the smallest possible footprint is desired, a minimal
|
|
||||||
* set of libraries could be loaded directly via {@link Globals#load(LuaValue)}
|
|
||||||
* using code such as:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* {
|
|
||||||
* @code
|
|
||||||
* Globals globals = new Globals();
|
|
||||||
* globals.load(new JseBaseLib());
|
|
||||||
* globals.load(new PackageLib());
|
|
||||||
* globals.load(new JseMathLib());
|
|
||||||
* System.out.println(globals.get("math").get("sqrt").call(LuaValue.valueOf(2)));
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
* <p>
|
|
||||||
* However, other libraries such as <em>CoroutineLib</em> are not loaded in this
|
|
||||||
* case.
|
|
||||||
* <p>
|
|
||||||
* This has been implemented to match as closely as possible the behavior in the
|
|
||||||
* corresponding library in C.
|
|
||||||
*
|
|
||||||
* @see LibFunction
|
|
||||||
* @see org.luaj.vm2.lib.jse.JsePlatform
|
|
||||||
* @see org.luaj.vm2.lib.jme.JmePlatform
|
|
||||||
* @see org.luaj.vm2.lib.jse.JseMathLib
|
|
||||||
* @see <a href="http://www.lua.org/manual/5.2/manual.html#6.6">Lua 5.2 Math Lib
|
|
||||||
* Reference</a>
|
|
||||||
*/
|
|
||||||
public class JseMathLib extends org.luaj.vm2.lib.MathLib {
|
|
||||||
|
|
||||||
public JseMathLib() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform one-time initialization on the library by creating a table
|
|
||||||
* containing the library functions, adding that table to the supplied
|
|
||||||
* environment, adding the table to package.loaded, and returning table as
|
|
||||||
* the return value.
|
|
||||||
* <P>
|
|
||||||
* Specifically, adds all library functions that can be implemented directly
|
|
||||||
* in JSE but not JME: acos, asin, atan, atan2, cosh, exp, log, pow, sinh,
|
|
||||||
* and tanh.
|
|
||||||
*
|
|
||||||
* @param modname the module name supplied if this is loaded via 'require'.
|
|
||||||
* @param env the environment to load into, which must be a Globals
|
|
||||||
* instance.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
|
||||||
super.call(modname, env);
|
|
||||||
LuaValue math = env.get("math");
|
|
||||||
math.set("acos", new acos());
|
|
||||||
math.set("asin", new asin());
|
|
||||||
math.set("atan", new atan());
|
|
||||||
math.set("atan2", new atan2());
|
|
||||||
math.set("cosh", new cosh());
|
|
||||||
math.set("exp", new exp());
|
|
||||||
math.set("log", new log());
|
|
||||||
math.set("pow", new pow());
|
|
||||||
math.set("sinh", new sinh());
|
|
||||||
math.set("tanh", new tanh());
|
|
||||||
return math;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class acos extends UnaryOp {
|
|
||||||
@Override
|
|
||||||
protected double call(double d) { return Math.acos(d); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class asin extends UnaryOp {
|
|
||||||
@Override
|
|
||||||
protected double call(double d) { return Math.asin(d); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class atan extends TwoArgFunction {
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue x, LuaValue y) {
|
|
||||||
return valueOf(Math.atan2(x.checkdouble(), y.optdouble(1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class atan2 extends TwoArgFunction {
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue x, LuaValue y) {
|
|
||||||
return valueOf(Math.atan2(x.checkdouble(), y.checkdouble()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class cosh extends UnaryOp {
|
|
||||||
@Override
|
|
||||||
protected double call(double d) { return Math.cosh(d); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class exp extends UnaryOp {
|
|
||||||
@Override
|
|
||||||
protected double call(double d) { return Math.exp(d); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class log extends TwoArgFunction {
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue x, LuaValue base) {
|
|
||||||
double nat = Math.log(x.checkdouble());
|
|
||||||
double b = base.optdouble(Math.E);
|
|
||||||
if (b != Math.E)
|
|
||||||
nat /= Math.log(b);
|
|
||||||
return valueOf(nat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class pow extends BinaryOp {
|
|
||||||
@Override
|
|
||||||
protected double call(double x, double y) { return Math.pow(x, y); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class sinh extends UnaryOp {
|
|
||||||
@Override
|
|
||||||
protected double call(double d) { return Math.sinh(d); }
|
|
||||||
}
|
|
||||||
|
|
||||||
static final class tanh extends UnaryOp {
|
|
||||||
@Override
|
|
||||||
protected double call(double d) { return Math.tanh(d); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Faster, better version of pow() used by arithmetic operator ^ */
|
|
||||||
@Override
|
|
||||||
public double dpow_lib(double a, double b) {
|
|
||||||
return Math.pow(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
public class JseStringLib extends org.luaj.vm2.lib.StringLib {
|
|
||||||
|
|
||||||
/** public constructor */
|
|
||||||
public JseStringLib() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String format(String src, double x) {
|
|
||||||
String out;
|
|
||||||
try {
|
|
||||||
out = String.format(src, Double.valueOf(x));
|
|
||||||
} catch (Throwable e) {
|
|
||||||
out = super.format(src, x);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package org.luaj.vm2.luajc;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.luaj.vm2.LuaFunction;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Prototype;
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2010 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
public class JavaLoader extends ClassLoader {
|
|
||||||
|
|
||||||
private final Map<String, byte[]> unloaded = new HashMap<>();
|
|
||||||
|
|
||||||
public JavaLoader() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public LuaFunction load(Prototype p, String classname, String filename, LuaValue env) {
|
|
||||||
JavaGen jg = new JavaGen(p, classname, filename, false);
|
|
||||||
return load(jg, env);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LuaFunction load(JavaGen jg, LuaValue env) {
|
|
||||||
include(jg);
|
|
||||||
return load(jg.classname, env);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LuaFunction load(String classname, LuaValue env) {
|
|
||||||
try {
|
|
||||||
Class c = loadClass(classname);
|
|
||||||
LuaFunction v = (LuaFunction) c.newInstance();
|
|
||||||
v.initupvalue1(env);
|
|
||||||
return v;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new IllegalStateException("bad class gen: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void include(JavaGen jg) {
|
|
||||||
unloaded.put(jg.classname, jg.bytecode);
|
|
||||||
for (int i = 0, n = jg.inners != null? jg.inners.length: 0; i < n; i++)
|
|
||||||
include(jg.inners[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class findClass(String classname) throws ClassNotFoundException {
|
|
||||||
byte[] bytes = unloaded.get(classname);
|
|
||||||
if (bytes != null)
|
|
||||||
return defineClass(classname, bytes, 0, bytes.length);
|
|
||||||
return super.findClass(classname);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package org.luaj.vm2.luajc;
|
|
||||||
|
|
||||||
import org.luaj.vm2.Lua;
|
|
||||||
|
|
||||||
public class UpvalInfo {
|
|
||||||
ProtoInfo pi; // where defined
|
|
||||||
int slot; // where defined
|
|
||||||
int nvars; // number of vars involved
|
|
||||||
VarInfo var[]; // list of vars
|
|
||||||
boolean rw; // read-write
|
|
||||||
|
|
||||||
// Upval info representing the implied context containing only the environment.
|
|
||||||
public UpvalInfo(ProtoInfo pi) {
|
|
||||||
this.pi = pi;
|
|
||||||
this.slot = 0;
|
|
||||||
this.nvars = 1;
|
|
||||||
this.var = new VarInfo[] { VarInfo.PARAM(0) };
|
|
||||||
this.rw = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UpvalInfo(ProtoInfo pi, int pc, int slot) {
|
|
||||||
this.pi = pi;
|
|
||||||
this.slot = slot;
|
|
||||||
this.nvars = 0;
|
|
||||||
this.var = null;
|
|
||||||
includeVarAndPosteriorVars(pi.vars[slot][pc]);
|
|
||||||
for (int i = 0; i < nvars; i++)
|
|
||||||
var[i].allocupvalue = testIsAllocUpvalue(var[i]);
|
|
||||||
this.rw = nvars > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean includeVarAndPosteriorVars(VarInfo var) {
|
|
||||||
if (var == null || var == VarInfo.INVALID)
|
|
||||||
return false;
|
|
||||||
if (var.upvalue == this)
|
|
||||||
return true;
|
|
||||||
var.upvalue = this;
|
|
||||||
appendVar(var);
|
|
||||||
if (isLoopVariable(var))
|
|
||||||
return false;
|
|
||||||
boolean loopDetected = includePosteriorVarsCheckLoops(var);
|
|
||||||
if (loopDetected)
|
|
||||||
includePriorVarsIgnoreLoops(var);
|
|
||||||
return loopDetected;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isLoopVariable(VarInfo var) {
|
|
||||||
if (var.pc >= 0) {
|
|
||||||
switch (Lua.GET_OPCODE(pi.prototype.code[var.pc])) {
|
|
||||||
case Lua.OP_TFORLOOP:
|
|
||||||
case Lua.OP_FORLOOP:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean includePosteriorVarsCheckLoops(VarInfo prior) {
|
|
||||||
boolean loopDetected = false;
|
|
||||||
for (BasicBlock b : pi.blocklist) {
|
|
||||||
VarInfo v = pi.vars[slot][b.pc1];
|
|
||||||
if (v == prior) {
|
|
||||||
for (int j = 0, m = b.next != null? b.next.length: 0; j < m; j++) {
|
|
||||||
BasicBlock b1 = b.next[j];
|
|
||||||
VarInfo v1 = pi.vars[slot][b1.pc0];
|
|
||||||
if (v1 != prior) {
|
|
||||||
loopDetected |= includeVarAndPosteriorVars(v1);
|
|
||||||
if (v1.isPhiVar())
|
|
||||||
includePriorVarsIgnoreLoops(v1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int pc = b.pc1-1; pc >= b.pc0; pc--) {
|
|
||||||
if (pi.vars[slot][pc] == prior) {
|
|
||||||
loopDetected |= includeVarAndPosteriorVars(pi.vars[slot][pc+1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return loopDetected;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void includePriorVarsIgnoreLoops(VarInfo poster) {
|
|
||||||
for (BasicBlock b : pi.blocklist) {
|
|
||||||
VarInfo v = pi.vars[slot][b.pc0];
|
|
||||||
if (v == poster) {
|
|
||||||
for (int j = 0, m = b.prev != null? b.prev.length: 0; j < m; j++) {
|
|
||||||
BasicBlock b0 = b.prev[j];
|
|
||||||
VarInfo v0 = pi.vars[slot][b0.pc1];
|
|
||||||
if (v0 != poster)
|
|
||||||
includeVarAndPosteriorVars(v0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int pc = b.pc0+1; pc <= b.pc1; pc++) {
|
|
||||||
if (pi.vars[slot][pc] == poster) {
|
|
||||||
includeVarAndPosteriorVars(pi.vars[slot][pc-1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void appendVar(VarInfo v) {
|
|
||||||
if (nvars == 0) {
|
|
||||||
var = new VarInfo[1];
|
|
||||||
} else if (nvars+1 >= var.length) {
|
|
||||||
VarInfo[] s = var;
|
|
||||||
var = new VarInfo[nvars*2+1];
|
|
||||||
System.arraycopy(s, 0, var, 0, nvars);
|
|
||||||
}
|
|
||||||
var[nvars++] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
sb.append(pi.name);
|
|
||||||
for (int i = 0; i < nvars; i++) {
|
|
||||||
sb.append(i > 0? ",": " ");
|
|
||||||
sb.append(String.valueOf(var[i]));
|
|
||||||
}
|
|
||||||
if (rw)
|
|
||||||
sb.append("(rw)");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean testIsAllocUpvalue(VarInfo v) {
|
|
||||||
if (v.pc < 0)
|
|
||||||
return true;
|
|
||||||
BasicBlock b = pi.blocks[v.pc];
|
|
||||||
if (v.pc > b.pc0)
|
|
||||||
return pi.vars[slot][v.pc-1].upvalue != this;
|
|
||||||
if (b.prev == null) {
|
|
||||||
v = pi.params[slot];
|
|
||||||
if (v != null && v.upvalue != this)
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
for (BasicBlock element : b.prev) {
|
|
||||||
v = pi.vars[slot][element.pc1];
|
|
||||||
if (v != null && v.upvalue != this)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2008 LuaJ. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptEngineFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jsr 223 scripting engine factory.
|
|
||||||
*
|
|
||||||
* Exposes metadata to support the lua language, and constructs instances of
|
|
||||||
* LuaScriptEngine to handl lua scripts.
|
|
||||||
*/
|
|
||||||
public class LuaScriptEngineFactory implements ScriptEngineFactory {
|
|
||||||
|
|
||||||
private static final String[] EXTENSIONS = { "lua", ".lua", };
|
|
||||||
|
|
||||||
private static final String[] MIMETYPES = { "text/lua", "application/lua" };
|
|
||||||
|
|
||||||
private static final String[] NAMES = { "lua", "luaj", };
|
|
||||||
|
|
||||||
private final List<String> extensions;
|
|
||||||
private final List<String> mimeTypes;
|
|
||||||
private final List<String> names;
|
|
||||||
|
|
||||||
public LuaScriptEngineFactory() {
|
|
||||||
extensions = Arrays.asList(EXTENSIONS);
|
|
||||||
mimeTypes = Arrays.asList(MIMETYPES);
|
|
||||||
names = Arrays.asList(NAMES);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEngineName() { return getScriptEngine().get(ScriptEngine.ENGINE).toString(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getEngineVersion() { return getScriptEngine().get(ScriptEngine.ENGINE_VERSION).toString(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getExtensions() { return extensions; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getMimeTypes() { return mimeTypes; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> getNames() { return names; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLanguageName() { return getScriptEngine().get(ScriptEngine.LANGUAGE).toString(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLanguageVersion() { return getScriptEngine().get(ScriptEngine.LANGUAGE_VERSION).toString(); }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getParameter(String key) {
|
|
||||||
return getScriptEngine().get(key).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getMethodCallSyntax(String obj, String m, String... args) {
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
sb.append(obj + ":" + m + "(");
|
|
||||||
int len = args.length;
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
if (i > 0) {
|
|
||||||
sb.append(',');
|
|
||||||
}
|
|
||||||
sb.append(args[i]);
|
|
||||||
}
|
|
||||||
sb.append(")");
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getOutputStatement(String toDisplay) {
|
|
||||||
return "print(" + toDisplay + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getProgram(String... statements) {
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
int len = statements.length;
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
if (i > 0) {
|
|
||||||
sb.append('\n');
|
|
||||||
}
|
|
||||||
sb.append(statements[i]);
|
|
||||||
}
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ScriptEngine getScriptEngine() { return new LuaScriptEngine(); }
|
|
||||||
}
|
|
||||||
@@ -1,148 +0,0 @@
|
|||||||
package org.luaj.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.StringReader;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaClosure;
|
|
||||||
import org.luaj.vm2.LuaFunction;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Prototype;
|
|
||||||
import org.luaj.vm2.compiler.DumpState;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
|
|
||||||
class DumpLoadEndianIntTest {
|
|
||||||
private static final String SAVECHUNKS = "SAVECHUNKS";
|
|
||||||
|
|
||||||
private static final boolean SHOULDPASS = true;
|
|
||||||
private static final boolean SHOULDFAIL = false;
|
|
||||||
private static final String mixedscript = "return tostring(1234)..'-#!-'..tostring(23.75)";
|
|
||||||
private static final String intscript = "return tostring(1234)..'-#!-'..tostring(23)";
|
|
||||||
private static final String withdoubles = "1234-#!-23.75";
|
|
||||||
private static final String withints = "1234-#!-23";
|
|
||||||
|
|
||||||
private Globals globals;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
globals = JsePlatform.standardGlobals();
|
|
||||||
DumpState.ALLOW_INTEGER_CASTING = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBigDoubleCompile() {
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES, false, mixedscript, withdoubles, withdoubles,
|
|
||||||
SHOULDPASS);
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES, true, mixedscript, withdoubles, withdoubles,
|
|
||||||
SHOULDPASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLittleDoubleCompile() {
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES, false, mixedscript, withdoubles, withdoubles,
|
|
||||||
SHOULDPASS);
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES, true, mixedscript, withdoubles, withdoubles,
|
|
||||||
SHOULDPASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBigIntCompile() {
|
|
||||||
DumpState.ALLOW_INTEGER_CASTING = true;
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_INTS_ONLY, false, mixedscript, withdoubles, withints, SHOULDPASS);
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_INTS_ONLY, true, mixedscript, withdoubles, withints, SHOULDPASS);
|
|
||||||
DumpState.ALLOW_INTEGER_CASTING = false;
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_INTS_ONLY, false, mixedscript, withdoubles, withints, SHOULDFAIL);
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_INTS_ONLY, true, mixedscript, withdoubles, withints, SHOULDFAIL);
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_INTS_ONLY, false, intscript, withints, withints, SHOULDPASS);
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_INTS_ONLY, true, intscript, withints, withints, SHOULDPASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLittleIntCompile() {
|
|
||||||
DumpState.ALLOW_INTEGER_CASTING = true;
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_INTS_ONLY, false, mixedscript, withdoubles, withints, SHOULDPASS);
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_INTS_ONLY, true, mixedscript, withdoubles, withints, SHOULDPASS);
|
|
||||||
DumpState.ALLOW_INTEGER_CASTING = false;
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_INTS_ONLY, false, mixedscript, withdoubles, withints, SHOULDFAIL);
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_INTS_ONLY, true, mixedscript, withdoubles, withints, SHOULDFAIL);
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_INTS_ONLY, false, intscript, withints, withints, SHOULDPASS);
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_INTS_ONLY, true, intscript, withints, withints, SHOULDPASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBigNumpatchCompile() {
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_NUM_PATCH_INT32, false, mixedscript, withdoubles, withdoubles,
|
|
||||||
SHOULDPASS);
|
|
||||||
doTest(false, DumpState.NUMBER_FORMAT_NUM_PATCH_INT32, true, mixedscript, withdoubles, withdoubles, SHOULDPASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLittleNumpatchCompile() {
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_NUM_PATCH_INT32, false, mixedscript, withdoubles, withdoubles, SHOULDPASS);
|
|
||||||
doTest(true, DumpState.NUMBER_FORMAT_NUM_PATCH_INT32, true, mixedscript, withdoubles, withdoubles, SHOULDPASS);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTest(boolean littleEndian, int numberFormat, boolean stripDebug, String script,
|
|
||||||
String expectedPriorDump, String expectedPostDump, boolean shouldPass) {
|
|
||||||
try {
|
|
||||||
|
|
||||||
// compile into prototype
|
|
||||||
Reader reader = new StringReader(script);
|
|
||||||
Prototype p = globals.compilePrototype(reader, "script");
|
|
||||||
|
|
||||||
// double check script result before dumping
|
|
||||||
LuaFunction f = new LuaClosure(p, globals);
|
|
||||||
LuaValue r = f.call();
|
|
||||||
String actual = r.tojstring();
|
|
||||||
assertEquals(expectedPriorDump, actual);
|
|
||||||
|
|
||||||
// dump into bytes
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
try {
|
|
||||||
DumpState.dump(p, baos, stripDebug, numberFormat, littleEndian);
|
|
||||||
if (!shouldPass)
|
|
||||||
fail("dump should not have succeeded");
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (shouldPass)
|
|
||||||
fail("dump threw " + e);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
byte[] dumped = baos.toByteArray();
|
|
||||||
|
|
||||||
// load again using compiler
|
|
||||||
InputStream is = new ByteArrayInputStream(dumped);
|
|
||||||
f = globals.load(is, "dumped", "b", globals).checkfunction();
|
|
||||||
r = f.call();
|
|
||||||
actual = r.tojstring();
|
|
||||||
assertEquals(expectedPostDump, actual);
|
|
||||||
|
|
||||||
// write test chunk
|
|
||||||
if (System.getProperty(SAVECHUNKS) != null && script.equals(mixedscript)) {
|
|
||||||
new File("build").mkdirs();
|
|
||||||
String filename = "build/test-" + (littleEndian? "little-": "big-")
|
|
||||||
+ (numberFormat == DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES? "double-"
|
|
||||||
: numberFormat == DumpState.NUMBER_FORMAT_INTS_ONLY? "int-"
|
|
||||||
: numberFormat == DumpState.NUMBER_FORMAT_NUM_PATCH_INT32? "numpatch4-": "???-")
|
|
||||||
+ (stripDebug? "nodebug-": "debug-") + "bin.lua";
|
|
||||||
FileOutputStream fos = new FileOutputStream(filename);
|
|
||||||
fos.write(dumped);
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
fail(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,460 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.StringReader;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Nested;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaClosure;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Print;
|
|
||||||
import org.luaj.vm2.Prototype;
|
|
||||||
import org.luaj.vm2.Varargs;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
import org.luaj.vm2.luajc.LuaJC;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test compilation of various fragments that have caused problems for jit
|
|
||||||
* compiling during development.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class FragmentsTest {
|
|
||||||
|
|
||||||
static final int TEST_TYPE_LUAC = 0;
|
|
||||||
static final int TEST_TYPE_LUAJC = 1;
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
public static class JseFragmentsTest extends FragmentsTestCase {
|
|
||||||
public JseFragmentsTest() { super(TEST_TYPE_LUAC); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
public static class LuaJCFragmentsTest extends FragmentsTestCase {
|
|
||||||
public LuaJCFragmentsTest() { super(TEST_TYPE_LUAJC); }
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected static class FragmentsTestCase {
|
|
||||||
|
|
||||||
final int TEST_TYPE;
|
|
||||||
|
|
||||||
protected FragmentsTestCase(int testType) {
|
|
||||||
this.TEST_TYPE = testType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runFragment(Varargs expected, String script) {
|
|
||||||
try {
|
|
||||||
String name = this.getClass().getName();
|
|
||||||
Globals globals = JsePlatform.debugGlobals();
|
|
||||||
Reader reader = new StringReader(script);
|
|
||||||
LuaValue chunk;
|
|
||||||
switch (TEST_TYPE) {
|
|
||||||
case TEST_TYPE_LUAJC:
|
|
||||||
LuaJC.install(globals);
|
|
||||||
chunk = globals.load(reader, name);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Prototype p = globals.compilePrototype(reader, name);
|
|
||||||
chunk = new LuaClosure(p, globals);
|
|
||||||
Print.print(p);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Varargs actual = chunk.invoke();
|
|
||||||
assertEquals(expected.narg(), actual.narg());
|
|
||||||
for (int i = 1; i <= actual.narg(); i++)
|
|
||||||
assertEquals(expected.arg(i), actual.arg(i));
|
|
||||||
} catch (Exception e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
fail(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFirstArgNilExtended() {
|
|
||||||
runFragment(LuaValue.NIL, "function f1(a) print( 'f1:', a ) return a end\n" + "b = f1()\n" + "return b");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSimpleForloop() {
|
|
||||||
runFragment(LuaValue.valueOf(77),
|
|
||||||
"for n,p in ipairs({77}) do\n" + " print('n,p',n,p)\n" + " return p\n" + "end\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testForloopParamUpvalues() {
|
|
||||||
runFragment(LuaValue.varargsOf(new LuaValue[] { LuaValue.valueOf(77), LuaValue.valueOf(1) }),
|
|
||||||
"for n,p in ipairs({77}) do\n" + " print('n,p',n,p)\n" + " foo = function()\n" + " return p,n\n"
|
|
||||||
+ " end\n" + " return foo()\n" + "end\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testArgVarargsUseBoth() {
|
|
||||||
runFragment(
|
|
||||||
LuaValue
|
|
||||||
.varargsOf(new LuaValue[] { LuaValue.valueOf("a"), LuaValue.valueOf("b"), LuaValue.valueOf("c") }),
|
|
||||||
"function v(arg,...)\n" + " return arg,...\n" + "end\n" + "return v('a','b','c')\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testArgParamUseNone() {
|
|
||||||
runFragment(LuaValue.valueOf("string"),
|
|
||||||
"function v(arg,...)\n" + " return type(arg)\n" + "end\n" + "return v('abc')\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSetlistVarargs() {
|
|
||||||
runFragment(LuaValue.valueOf("abc"),
|
|
||||||
"local f = function() return 'abc' end\n" + "local g = { f() }\n" + "return g[1]\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSelfOp() {
|
|
||||||
runFragment(LuaValue.valueOf("bcd"), "local s = 'abcde'\n" + "return s:sub(2,4)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSetListWithOffsetAndVarargs() {
|
|
||||||
runFragment(LuaValue.valueOf(1003), "local bar = {1000, math.sqrt(9)}\n" + "return bar[1]+bar[2]\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMultiAssign() {
|
|
||||||
// arargs evaluations are all done before assignments
|
|
||||||
runFragment(
|
|
||||||
LuaValue
|
|
||||||
.varargsOf(new LuaValue[] { LuaValue.valueOf(111), LuaValue.valueOf(111), LuaValue.valueOf(111) }),
|
|
||||||
"a,b,c = 1,10,100\n" + "a,b,c = a+b+c, a+b+c, a+b+c\n" + "return a,b,c\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpvalues() {
|
|
||||||
runFragment(LuaValue.valueOf(999),
|
|
||||||
"local a = function(x)\n" + " return function(y)\n" + " return x + y\n" + " end\n" + "end\n"
|
|
||||||
+ "local b = a(222)\n" + "local c = b(777)\n" + "print( 'c=', c )\n" + "return c\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNonAsciiStringLiterals() {
|
|
||||||
runFragment(LuaValue.valueOf("7,8,12,10,9,11,133,222"), "local a='\\a\\b\\f\\n\\t\\v\\133\\222'\n"
|
|
||||||
+ "local t={string.byte(a,1,#a)}\n" + "return table.concat(t,',')\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testControlCharStringLiterals() {
|
|
||||||
runFragment(LuaValue.valueOf("97,0,98,18,99,18,100,18,48,101"), "local a='a\\0b\\18c\\018d\\0180e'\n"
|
|
||||||
+ "local t={string.byte(a,1,#a)}\n" + "return table.concat(t,',')\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLoopVarNames() {
|
|
||||||
runFragment(LuaValue.valueOf(" 234,1,aa 234,2,bb"),
|
|
||||||
"local w = ''\n" + "function t()\n" + " for f,var in ipairs({'aa','bb'}) do\n" + " local s = 234\n"
|
|
||||||
+ " w = w..' '..s..','..f..','..var\n" + " end\n" + "end\n" + "t()\n" + "return w\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testForLoops() {
|
|
||||||
runFragment(LuaValue.valueOf("12345 357 963"),
|
|
||||||
"local s,t,u = '','',''\n" + "for m=1,5 do\n" + " s = s..m\n" + "end\n" + "for m=3,7,2 do\n"
|
|
||||||
+ " t = t..m\n" + "end\n" + "for m=9,3,-3 do\n" + " u = u..m\n" + "end\n"
|
|
||||||
+ "return s..' '..t..' '..u\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLocalFunctionDeclarations() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("function"), LuaValue.valueOf("nil")),
|
|
||||||
"local function aaa()\n" + " return type(aaa)\n" + "end\n" + "local bbb = function()\n"
|
|
||||||
+ " return type(bbb)\n" + "end\n" + "return aaa(),bbb()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNilsInTableConstructor() {
|
|
||||||
runFragment(LuaValue.valueOf("1=111 2=222 3=333 "),
|
|
||||||
"local t = { 111, 222, 333, nil, nil }\n" + "local s = ''\n" + "for i,v in ipairs(t) do \n"
|
|
||||||
+ " s=s..tostring(i)..'='..tostring(v)..' '\n" + "end\n" + "return s\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUnreachableCode() {
|
|
||||||
runFragment(LuaValue.valueOf(66),
|
|
||||||
"local function foo(x) return x * 2 end\n" + "local function bar(x, y)\n" + " if x==y then\n"
|
|
||||||
+ " return y\n" + " else\n" + " return foo(x)\n" + " end\n" + "end\n"
|
|
||||||
+ "return bar(33,44)\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVarargsWithParameters() {
|
|
||||||
runFragment(LuaValue.valueOf(222),
|
|
||||||
"local func = function(t,...)\n" + " return (...)\n" + "end\n" + "return func(111,222,333)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoReturnValuesPlainCall() {
|
|
||||||
runFragment(LuaValue.TRUE, "local testtable = {}\n" + "return pcall( function() testtable[1]=2 end )\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVarargsInTableConstructor() {
|
|
||||||
runFragment(LuaValue.valueOf(222), "local function foo() return 111,222,333 end\n"
|
|
||||||
+ "local t = {'a','b',c='c',foo()}\n" + "return t[4]\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVarargsInFirstArg() {
|
|
||||||
runFragment(LuaValue.valueOf(123), "function aaa(x) return x end\n" + "function bbb(y) return y end\n"
|
|
||||||
+ "function ccc(z) return z end\n" + "return ccc( aaa(bbb(123)), aaa(456) )\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSetUpvalueTableInitializer() {
|
|
||||||
runFragment(LuaValue.valueOf("b"), "local aliases = {a='b'}\n" + "local foo = function()\n"
|
|
||||||
+ " return aliases\n" + "end\n" + "return foo().a\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLoadNilUpvalue() {
|
|
||||||
runFragment(LuaValue.NIL, "tostring = function() end\n" + "local pc \n" + "local pcall = function(...)\n"
|
|
||||||
+ " pc(...)\n" + "end\n" + "return NIL\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpvalueClosure() {
|
|
||||||
runFragment(LuaValue.NIL, "print()\n" + "local function f2() end\n" + "local function f3()\n"
|
|
||||||
+ " return f3\n" + "end\n" + "return NIL\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUninitializedUpvalue() {
|
|
||||||
runFragment(LuaValue.NIL, "local f\n" + "do\n" + " function g()\n" + " print(f())\n" + " end\n"
|
|
||||||
+ "end\n" + "return NIL\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTestOpUpvalues() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf(1), LuaValue.valueOf(2), LuaValue.valueOf(3)),
|
|
||||||
"print( nil and 'T' or 'F' )\n" + "local a,b,c = 1,2,3\n" + "function foo()\n" + " return a,b,c\n"
|
|
||||||
+ "end\n" + "return foo()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTestSimpleBinops() {
|
|
||||||
runFragment(
|
|
||||||
LuaValue.varargsOf(
|
|
||||||
new LuaValue[] { LuaValue.FALSE, LuaValue.FALSE, LuaValue.TRUE, LuaValue.TRUE, LuaValue.FALSE }),
|
|
||||||
"local a,b,c = 2,-2.5,0\n" + "return (a==c), (b==c), (a==a), (a>c), (b>0)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNumericForUpvalues() {
|
|
||||||
runFragment(LuaValue.valueOf(8), "for i = 3,4 do\n" + " i = i + 5\n" + " local a = function()\n"
|
|
||||||
+ " return i\n" + " end\n" + " return a()\n" + "end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNumericForUpvalues2() {
|
|
||||||
runFragment(LuaValue.valueOf("222 222"),
|
|
||||||
"local t = {}\n" + "local template = [[123 456]]\n" + "for i = 1,2 do\n"
|
|
||||||
+ " t[i] = template:gsub('%d', function(s)\n" + " return i\n" + " end)\n" + "end\n"
|
|
||||||
+ "return t[2]\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReturnUpvalue() {
|
|
||||||
runFragment(LuaValue.varargsOf(new LuaValue[] { LuaValue.ONE, LuaValue.valueOf(5), }), "local a = 1\n"
|
|
||||||
+ "local b\n" + "function c()\n" + " b=5\n" + " return a\n" + "end\n" + "return c(),b\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUninitializedAroundBranch() {
|
|
||||||
runFragment(LuaValue.valueOf(333),
|
|
||||||
"local state\n" + "if _G then\n" + " state = 333\n" + "end\n" + "return state\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLoadedNilUpvalue() {
|
|
||||||
runFragment(LuaValue.NIL, "local a = print()\n" + "local b = c and { d = e }\n" + "local f\n"
|
|
||||||
+ "local function g()\n" + " return f\n" + "end\n" + "return g()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpvalueInFirstSlot() {
|
|
||||||
runFragment(LuaValue.valueOf("foo"), "local p = {'foo'}\n" + "bar = function()\n" + " return p \n"
|
|
||||||
+ "end\n" + "for i,key in ipairs(p) do\n" + " print()\n" + "end\n" + "return bar()[1]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReadOnlyAndReadWriteUpvalues() {
|
|
||||||
runFragment(LuaValue.varargsOf(new LuaValue[] { LuaValue.valueOf(333), LuaValue.valueOf(222) }),
|
|
||||||
"local a = 111\n" + "local b = 222\n" + "local c = function()\n" + " a = a + b\n"
|
|
||||||
+ " return a,b\n" + "end\n" + "return c()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNestedUpvalues() {
|
|
||||||
runFragment(
|
|
||||||
LuaValue.varargsOf(new LuaValue[] { LuaValue.valueOf(5), LuaValue.valueOf(8), LuaValue.valueOf(9) }),
|
|
||||||
"local x = 3\n" + "local y = 5\n" + "local function f()\n" + " return y\n" + "end\n"
|
|
||||||
+ "local function g(x1, y1)\n" + " x = x1\n" + " y = y1\n" + " return x,y\n" + "end\n"
|
|
||||||
+ "return f(), g(8,9)\n" + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLoadBool() {
|
|
||||||
runFragment(LuaValue.NONE, "print( type(foo)=='string' )\n" + "local a,b\n" + "if print() then\n"
|
|
||||||
+ " b = function()\n" + " return a\n" + " end\n" + "end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBasicForLoop() {
|
|
||||||
runFragment(LuaValue.valueOf(2), "local data\n" + "for i = 1, 2 do\n" + " data = i\n" + "end\n"
|
|
||||||
+ "local bar = function()\n" + " return data\n" + "end\n" + "return bar()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGenericForMultipleValues() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf(3), LuaValue.valueOf(2), LuaValue.valueOf(1)),
|
|
||||||
"local iter = function() return 1,2,3,4 end\n" + "local foo = function() return iter,5 end\n"
|
|
||||||
+ "for a,b,c in foo() do\n" + " return c,b,a\n" + "end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPhiUpvalue() {
|
|
||||||
runFragment(LuaValue.valueOf(6), "local a = foo or 0\n" + "local function b(c)\n"
|
|
||||||
+ " if c > a then a = c end\n" + " return a\n" + "end\n" + "b(6)\n" + "return a\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAssignReferUpvalues() {
|
|
||||||
runFragment(LuaValue.valueOf(123), "local entity = 234\n" + "local function c()\n" + " return entity\n"
|
|
||||||
+ "end\n" + "entity = (a == b) and 123\n" + "if entity then\n" + " return entity\n" + "end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSimpleRepeatUntil() {
|
|
||||||
runFragment(LuaValue.valueOf(5),
|
|
||||||
"local a\n" + "local w\n" + "repeat\n" + " a = w\n" + "until not a\n" + "return 5\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testLoopVarUpvalues() {
|
|
||||||
runFragment(LuaValue.valueOf("b"),
|
|
||||||
"local env = {}\n" + "for a,b in pairs(_G) do\n" + " c = function()\n" + " return b\n"
|
|
||||||
+ " end\n" + "end\n" + "local e = env\n" + "local f = {a='b'}\n" + "for k,v in pairs(f) do\n"
|
|
||||||
+ " return env[k] or v\n" + "end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPhiVarUpvalue() {
|
|
||||||
runFragment(LuaValue.valueOf(2), "local a = 1\n" + "local function b()\n" + " a = a + 1\n"
|
|
||||||
+ " return function() end\n" + "end\n" + "for i in b() do\n" + " a = 3\n" + "end\n" + "return a\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpvaluesInElseClauses() {
|
|
||||||
runFragment(LuaValue.valueOf(111),
|
|
||||||
"if a then\n" + " foo(bar)\n" + "elseif _G then\n" + " local x = 111\n" + " if d then\n"
|
|
||||||
+ " foo(bar)\n" + " else\n" + " local y = function()\n" + " return x\n"
|
|
||||||
+ " end\n" + " return y()\n" + " end\n" + "end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUpvalueInDoBlock() {
|
|
||||||
runFragment(LuaValue.NONE,
|
|
||||||
"do\n" + " local x = 10\n" + " function g()\n" + " return x\n" + " end\n" + "end\n" + "g()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNullError() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.FALSE, LuaValue.NIL), "return pcall(error)\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFindWithOffset() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf(8), LuaValue.valueOf(5)), "string = \"abcdef:ghi\"\n"
|
|
||||||
+ "substring = string:sub(3)\n" + "idx = substring:find(\":\")\n" + "return #substring, idx\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testErrorArgIsString() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("string"), LuaValue.valueOf("c")),
|
|
||||||
"a,b = pcall(error, 'c'); return type(b), b\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testErrorArgIsNil() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("nil"), LuaValue.NIL),
|
|
||||||
"a,b = pcall(error); return type(b), b\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testErrorArgIsTable() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("table"), LuaValue.valueOf("d")),
|
|
||||||
"a,b = pcall(error, {c='d'}); return type(b), b.c\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testErrorArgIsNumber() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("string"), LuaValue.valueOf("1")),
|
|
||||||
"a,b = pcall(error, 1); return type(b), b\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testErrorArgIsBool() {
|
|
||||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("boolean"), LuaValue.TRUE),
|
|
||||||
"a,b = pcall(error, true); return type(b), b\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBalancedMatchOnEmptyString() {
|
|
||||||
runFragment(LuaValue.NIL, "return (\"\"):match(\"%b''\")\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReturnValueForTableRemove() {
|
|
||||||
runFragment(LuaValue.NONE, "return table.remove({ })");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTypeOfTableRemoveReturnValue() {
|
|
||||||
runFragment(LuaValue.valueOf("nil"), "local k = table.remove({ }) return type(k)");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testVarargBugReport() {
|
|
||||||
runFragment(
|
|
||||||
LuaValue.varargsOf(new LuaValue[] { LuaValue.valueOf(1), LuaValue.valueOf(2), LuaValue.valueOf(3) }),
|
|
||||||
"local i = function(...) return ... end\n" + "local v1, v2, v3 = i(1, 2, 3)\n" + "return v1, v2, v3");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.StringReader;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaClosure;
|
|
||||||
import org.luaj.vm2.LuaFunction;
|
|
||||||
import org.luaj.vm2.LuaTable;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Prototype;
|
|
||||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
|
|
||||||
class LuaPrototypeTest {
|
|
||||||
|
|
||||||
private Prototype createPrototype(String script, String name) {
|
|
||||||
try {
|
|
||||||
Globals globals = JsePlatform.standardGlobals();
|
|
||||||
Reader reader = new StringReader(script);
|
|
||||||
return globals.compilePrototype(reader, name);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
fail(e.toString());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testFunctionClosureThreadEnv() {
|
|
||||||
|
|
||||||
// set up suitable environments for execution
|
|
||||||
LuaValue aaa = LuaValue.valueOf("aaa");
|
|
||||||
LuaValue eee = LuaValue.valueOf("eee");
|
|
||||||
final Globals globals = JsePlatform.standardGlobals();
|
|
||||||
LuaTable newenv = LuaValue.tableOf(new LuaValue[] { LuaValue.valueOf("a"), LuaValue.valueOf("aaa"),
|
|
||||||
LuaValue.valueOf("b"), LuaValue.valueOf("bbb"), });
|
|
||||||
LuaTable mt = LuaValue.tableOf(new LuaValue[] { LuaValue.INDEX, globals });
|
|
||||||
newenv.setmetatable(mt);
|
|
||||||
globals.set("a", aaa);
|
|
||||||
newenv.set("a", eee);
|
|
||||||
|
|
||||||
// function tests
|
|
||||||
{
|
|
||||||
LuaFunction f = new ZeroArgFunction() {
|
|
||||||
@Override
|
|
||||||
public LuaValue call() { return globals.get("a"); }
|
|
||||||
};
|
|
||||||
assertEquals(aaa, f.call());
|
|
||||||
}
|
|
||||||
|
|
||||||
// closure tests
|
|
||||||
{
|
|
||||||
Prototype p = createPrototype("return a\n", "closuretester");
|
|
||||||
LuaClosure c = new LuaClosure(p, globals);
|
|
||||||
|
|
||||||
// Test that a clusure with a custom enviroment uses that environment.
|
|
||||||
assertEquals(aaa, c.call());
|
|
||||||
c = new LuaClosure(p, newenv);
|
|
||||||
assertEquals(newenv, c.upValues[0].getValue());
|
|
||||||
assertEquals(eee, c.call());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package org.luaj.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.jse.require.RequireSampleClassCastExcep;
|
|
||||||
import org.luaj.jse.require.RequireSampleLoadLuaError;
|
|
||||||
import org.luaj.jse.require.RequireSampleLoadRuntimeExcep;
|
|
||||||
import org.luaj.jse.require.RequireSampleSuccess;
|
|
||||||
import org.luaj.vm2.LuaError;
|
|
||||||
import org.luaj.vm2.LuaTable;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
|
|
||||||
class RequireClassTest {
|
|
||||||
|
|
||||||
private LuaTable globals;
|
|
||||||
private LuaValue require;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
globals = JsePlatform.standardGlobals();
|
|
||||||
require = globals.get("require");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLoadClass() {
|
|
||||||
LuaValue result = globals.load(new RequireSampleSuccess());
|
|
||||||
assertEquals("require-sample-success-", result.tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRequireClassSuccess() {
|
|
||||||
LuaValue result = require.call(LuaValue.valueOf(RequireSampleSuccess.class.getName()));
|
|
||||||
assertEquals("require-sample-success-" + RequireSampleSuccess.class.getName(), result.tojstring());
|
|
||||||
result = require.call(LuaValue.valueOf(RequireSampleSuccess.class.getName()));
|
|
||||||
assertEquals("require-sample-success-" + RequireSampleSuccess.class.getName(), result.tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRequireClassLoadLuaError() {
|
|
||||||
try {
|
|
||||||
LuaValue result = require.call(LuaValue.valueOf(RequireSampleLoadLuaError.class.getName()));
|
|
||||||
fail("incorrectly loaded class that threw lua error");
|
|
||||||
} catch (LuaError le) {
|
|
||||||
assertEquals("sample-load-lua-error", le.getMessage());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
LuaValue result = require.call(LuaValue.valueOf(RequireSampleLoadLuaError.class.getName()));
|
|
||||||
fail("incorrectly loaded class that threw lua error");
|
|
||||||
} catch (LuaError le) {
|
|
||||||
assertEquals("loop or previous error loading module '" + RequireSampleLoadLuaError.class.getName() + "'",
|
|
||||||
le.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRequireClassLoadRuntimeException() {
|
|
||||||
try {
|
|
||||||
LuaValue result = require.call(LuaValue.valueOf(RequireSampleLoadRuntimeExcep.class.getName()));
|
|
||||||
fail("incorrectly loaded class that threw runtime exception");
|
|
||||||
} catch (RuntimeException le) {
|
|
||||||
assertEquals("sample-load-runtime-exception", le.getMessage());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
LuaValue result = require.call(LuaValue.valueOf(RequireSampleLoadRuntimeExcep.class.getName()));
|
|
||||||
fail("incorrectly loaded class that threw runtime exception");
|
|
||||||
} catch (LuaError le) {
|
|
||||||
assertEquals(
|
|
||||||
"loop or previous error loading module '" + RequireSampleLoadRuntimeExcep.class.getName() + "'",
|
|
||||||
le.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRequireClassClassCastException() {
|
|
||||||
try {
|
|
||||||
LuaValue result = require.call(LuaValue.valueOf(RequireSampleClassCastExcep.class.getName()));
|
|
||||||
fail("incorrectly loaded class that threw class cast exception");
|
|
||||||
} catch (LuaError le) {
|
|
||||||
String msg = le.getMessage();
|
|
||||||
if (msg.indexOf("not found") < 0)
|
|
||||||
fail("expected 'not found' message but got " + msg);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
LuaValue result = require.call(LuaValue.valueOf(RequireSampleClassCastExcep.class.getName()));
|
|
||||||
fail("incorrectly loaded class that threw class cast exception");
|
|
||||||
} catch (LuaError le) {
|
|
||||||
String msg = le.getMessage();
|
|
||||||
if (msg.indexOf("not found") < 0)
|
|
||||||
fail("expected 'not found' message but got " + msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package org.luaj.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaDouble;
|
|
||||||
import org.luaj.vm2.LuaInteger;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
|
|
||||||
class SimpleLuaCallsTest {
|
|
||||||
|
|
||||||
private Globals globals;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
globals = JsePlatform.standardGlobals();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTest(String script) {
|
|
||||||
try {
|
|
||||||
LuaValue c = globals.load(script, "script");
|
|
||||||
c.call();
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail("i/o exception: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testTrivial() {
|
|
||||||
String s = "print( 2 )\n";
|
|
||||||
doTest(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAlmostTrivial() {
|
|
||||||
String s = "print( 2 )\n" + "print( 3 )\n";
|
|
||||||
doTest(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSimple() {
|
|
||||||
String s = "print( 'hello, world' )\n" + "for i = 2,4 do\n" + " print( 'i', i )\n" + "end\n";
|
|
||||||
doTest(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBreak() {
|
|
||||||
String s = "a=1\n" + "while true do\n" + " if a>10 then\n" + " break\n" + " end\n" + " a=a+1\n"
|
|
||||||
+ " print( a )\n" + "end\n";
|
|
||||||
doTest(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testShebang() {
|
|
||||||
String s = "#!../lua\n" + "print( 2 )\n";
|
|
||||||
doTest(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInlineTable() {
|
|
||||||
String s = "A = {g=10}\n" + "print( A )\n";
|
|
||||||
doTest(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testEqualsAnd() {
|
|
||||||
String s = "print( 1 == b and b )\n";
|
|
||||||
doTest(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int[] samehash = { 0, 1, -1, 2, -2, 4, 8, 16, 32, Integer.MAX_VALUE, Integer.MIN_VALUE };
|
|
||||||
private static final double[] diffhash = { .5, 1, 1.5, 1, .5, 1.5, 1.25, 2.5 };
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testDoubleHashCode() {
|
|
||||||
for (int i = 0; i < samehash.length; i++) {
|
|
||||||
LuaValue j = LuaInteger.valueOf(samehash[i]);
|
|
||||||
LuaValue d = LuaDouble.valueOf(samehash[i]);
|
|
||||||
int hj = j.hashCode();
|
|
||||||
int hd = d.hashCode();
|
|
||||||
assertEquals(hj, hd);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < diffhash.length; i += 2) {
|
|
||||||
LuaValue c = LuaValue.valueOf(diffhash[i+0]);
|
|
||||||
LuaValue d = LuaValue.valueOf(diffhash[i+1]);
|
|
||||||
int hc = c.hashCode();
|
|
||||||
int hd = d.hashCode();
|
|
||||||
assertTrue(hc != hd, "hash codes are same: " + hc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package org.luaj.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaString;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
|
|
||||||
class StringMatchingTest {
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
JsePlatform.standardGlobals();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMatchShortPatterns() {
|
|
||||||
LuaValue[] args = { LuaString.valueOf("%bxy") };
|
|
||||||
LuaString empty = LuaString.valueOf("");
|
|
||||||
|
|
||||||
LuaString a = LuaString.valueOf("a");
|
|
||||||
LuaString ax = LuaString.valueOf("ax");
|
|
||||||
LuaString axb = LuaString.valueOf("axb");
|
|
||||||
LuaString axby = LuaString.valueOf("axby");
|
|
||||||
LuaString xbya = LuaString.valueOf("xbya");
|
|
||||||
LuaString bya = LuaString.valueOf("bya");
|
|
||||||
LuaString xby = LuaString.valueOf("xby");
|
|
||||||
LuaString axbya = LuaString.valueOf("axbya");
|
|
||||||
LuaValue nil = LuaValue.NIL;
|
|
||||||
|
|
||||||
assertEquals(nil, empty.invokemethod("match", args));
|
|
||||||
assertEquals(nil, a.invokemethod("match", args));
|
|
||||||
assertEquals(nil, ax.invokemethod("match", args));
|
|
||||||
assertEquals(nil, axb.invokemethod("match", args));
|
|
||||||
assertEquals(xby, axby.invokemethod("match", args));
|
|
||||||
assertEquals(xby, xbya.invokemethod("match", args));
|
|
||||||
assertEquals(nil, bya.invokemethod("match", args));
|
|
||||||
assertEquals(xby, xby.invokemethod("match", args));
|
|
||||||
assertEquals(xby, axbya.invokemethod("match", args));
|
|
||||||
assertEquals(xby, axbya.substring(0, 4).invokemethod("match", args));
|
|
||||||
assertEquals(nil, axbya.substring(0, 3).invokemethod("match", args));
|
|
||||||
assertEquals(xby, axbya.substring(1, 5).invokemethod("match", args));
|
|
||||||
assertEquals(nil, axbya.substring(2, 5).invokemethod("match", args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Varargs;
|
|
||||||
|
|
||||||
class JsePlatformTest {
|
|
||||||
@Test
|
|
||||||
void testLuaMainPassesArguments() {
|
|
||||||
Globals globals = JsePlatform.standardGlobals();
|
|
||||||
LuaValue chunk = globals.load("return #arg, arg.n, arg[2], arg[1]");
|
|
||||||
Varargs results = JsePlatform.luaMain(chunk, new String[] { "aaa", "bbb" });
|
|
||||||
assertEquals(results.narg(), 4);
|
|
||||||
assertEquals(results.arg(1), LuaValue.valueOf(2));
|
|
||||||
assertEquals(results.arg(2), LuaValue.valueOf(2));
|
|
||||||
assertEquals(results.arg(3), LuaValue.valueOf("bbb"));
|
|
||||||
assertEquals(results.arg(4), LuaValue.valueOf("aaa"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,531 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaError;
|
|
||||||
import org.luaj.vm2.LuaInteger;
|
|
||||||
import org.luaj.vm2.LuaString;
|
|
||||||
import org.luaj.vm2.LuaTable;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.Varargs;
|
|
||||||
|
|
||||||
class LuaJavaCoercionTest {
|
|
||||||
|
|
||||||
private static LuaValue globals;
|
|
||||||
private static LuaValue ZERO = LuaValue.ZERO;
|
|
||||||
private static LuaValue ONE = LuaValue.ONE;
|
|
||||||
private static LuaValue TWO = LuaValue.valueOf(2);
|
|
||||||
private static LuaValue THREE = LuaValue.valueOf(3);
|
|
||||||
private static LuaString LENGTH = LuaString.valueOf("length");
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
globals = JsePlatform.standardGlobals();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testJavaIntToLuaInt() {
|
|
||||||
Integer i = Integer.valueOf(777);
|
|
||||||
LuaValue v = CoerceJavaToLua.coerce(i);
|
|
||||||
assertEquals(LuaInteger.class, v.getClass());
|
|
||||||
assertEquals(777, v.toint());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLuaIntToJavaInt() {
|
|
||||||
LuaInteger i = LuaInteger.valueOf(777);
|
|
||||||
Object o = CoerceLuaToJava.coerce(i, int.class);
|
|
||||||
assertEquals(Integer.class, o.getClass());
|
|
||||||
assertEquals(777, ((Number) o).intValue());
|
|
||||||
o = CoerceLuaToJava.coerce(i, Integer.class);
|
|
||||||
assertEquals(Integer.class, o.getClass());
|
|
||||||
assertEquals(new Integer(777), o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testJavaStringToLuaString() {
|
|
||||||
String s = new String("777");
|
|
||||||
LuaValue v = CoerceJavaToLua.coerce(s);
|
|
||||||
assertEquals(LuaString.class, v.getClass());
|
|
||||||
assertEquals("777", v.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLuaStringToJavaString() {
|
|
||||||
LuaString s = LuaValue.valueOf("777");
|
|
||||||
Object o = CoerceLuaToJava.coerce(s, String.class);
|
|
||||||
assertEquals(String.class, o.getClass());
|
|
||||||
assertEquals("777", o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testJavaClassToLuaUserdata() {
|
|
||||||
LuaValue va = CoerceJavaToLua.coerce(ClassA.class);
|
|
||||||
LuaValue va1 = CoerceJavaToLua.coerce(ClassA.class);
|
|
||||||
LuaValue vb = CoerceJavaToLua.coerce(ClassB.class);
|
|
||||||
assertSame(va, va1);
|
|
||||||
assertNotSame(va, vb);
|
|
||||||
LuaValue vi = CoerceJavaToLua.coerce(new ClassA());
|
|
||||||
assertNotSame(va, vi);
|
|
||||||
assertTrue(vi.isuserdata());
|
|
||||||
assertTrue(vi.isuserdata(ClassA.class));
|
|
||||||
assertFalse(vi.isuserdata(ClassB.class));
|
|
||||||
LuaValue vj = CoerceJavaToLua.coerce(new ClassB());
|
|
||||||
assertNotSame(vb, vj);
|
|
||||||
assertTrue(vj.isuserdata());
|
|
||||||
assertFalse(vj.isuserdata(ClassA.class));
|
|
||||||
assertTrue(vj.isuserdata(ClassB.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ClassA {
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ClassB {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testJavaIntArrayToLuaTable() {
|
|
||||||
int[] i = { 222, 333 };
|
|
||||||
LuaValue v = CoerceJavaToLua.coerce(i);
|
|
||||||
assertEquals(JavaArray.class, v.getClass());
|
|
||||||
assertEquals(LuaInteger.valueOf(222), v.get(ONE));
|
|
||||||
assertEquals(LuaInteger.valueOf(333), v.get(TWO));
|
|
||||||
assertEquals(TWO, v.get(LENGTH));
|
|
||||||
assertEquals(LuaValue.NIL, v.get(THREE));
|
|
||||||
assertEquals(LuaValue.NIL, v.get(ZERO));
|
|
||||||
v.set(ONE, LuaInteger.valueOf(444));
|
|
||||||
v.set(TWO, LuaInteger.valueOf(555));
|
|
||||||
assertEquals(444, i[0]);
|
|
||||||
assertEquals(555, i[1]);
|
|
||||||
assertEquals(LuaInteger.valueOf(444), v.get(ONE));
|
|
||||||
assertEquals(LuaInteger.valueOf(555), v.get(TWO));
|
|
||||||
try {
|
|
||||||
v.set(ZERO, LuaInteger.valueOf(777));
|
|
||||||
fail("array bound exception not thrown");
|
|
||||||
} catch (LuaError lee) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
v.set(THREE, LuaInteger.valueOf(777));
|
|
||||||
fail("array bound exception not thrown");
|
|
||||||
} catch (LuaError lee) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLuaTableToJavaIntArray() {
|
|
||||||
LuaTable t = new LuaTable();
|
|
||||||
t.set(1, LuaInteger.valueOf(222));
|
|
||||||
t.set(2, LuaInteger.valueOf(333));
|
|
||||||
int[] i = null;
|
|
||||||
Object o = CoerceLuaToJava.coerce(t, int[].class);
|
|
||||||
assertEquals(int[].class, o.getClass());
|
|
||||||
i = (int[]) o;
|
|
||||||
assertEquals(2, i.length);
|
|
||||||
assertEquals(222, i[0]);
|
|
||||||
assertEquals(333, i[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testIntArrayScoringTables() {
|
|
||||||
int a = 5;
|
|
||||||
LuaValue la = LuaInteger.valueOf(a);
|
|
||||||
LuaTable tb = new LuaTable();
|
|
||||||
tb.set(1, la);
|
|
||||||
LuaTable tc = new LuaTable();
|
|
||||||
tc.set(1, tb);
|
|
||||||
|
|
||||||
int saa = CoerceLuaToJava.getCoercion(int.class).score(la);
|
|
||||||
int sab = CoerceLuaToJava.getCoercion(int[].class).score(la);
|
|
||||||
int sac = CoerceLuaToJava.getCoercion(int[][].class).score(la);
|
|
||||||
assertTrue(saa < sab);
|
|
||||||
assertTrue(saa < sac);
|
|
||||||
int sba = CoerceLuaToJava.getCoercion(int.class).score(tb);
|
|
||||||
int sbb = CoerceLuaToJava.getCoercion(int[].class).score(tb);
|
|
||||||
int sbc = CoerceLuaToJava.getCoercion(int[][].class).score(tb);
|
|
||||||
assertTrue(sbb < sba);
|
|
||||||
assertTrue(sbb < sbc);
|
|
||||||
int sca = CoerceLuaToJava.getCoercion(int.class).score(tc);
|
|
||||||
int scb = CoerceLuaToJava.getCoercion(int[].class).score(tc);
|
|
||||||
int scc = CoerceLuaToJava.getCoercion(int[][].class).score(tc);
|
|
||||||
assertTrue(scc < sca);
|
|
||||||
assertTrue(scc < scb);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testIntArrayScoringUserdata() {
|
|
||||||
int a = 5;
|
|
||||||
int[] b = { 44, 66 };
|
|
||||||
int[][] c = { { 11, 22 }, { 33, 44 } };
|
|
||||||
LuaValue va = CoerceJavaToLua.coerce(a);
|
|
||||||
LuaValue vb = CoerceJavaToLua.coerce(b);
|
|
||||||
LuaValue vc = CoerceJavaToLua.coerce(c);
|
|
||||||
|
|
||||||
int vaa = CoerceLuaToJava.getCoercion(int.class).score(va);
|
|
||||||
int vab = CoerceLuaToJava.getCoercion(int[].class).score(va);
|
|
||||||
int vac = CoerceLuaToJava.getCoercion(int[][].class).score(va);
|
|
||||||
assertTrue(vaa < vab);
|
|
||||||
assertTrue(vaa < vac);
|
|
||||||
int vba = CoerceLuaToJava.getCoercion(int.class).score(vb);
|
|
||||||
int vbb = CoerceLuaToJava.getCoercion(int[].class).score(vb);
|
|
||||||
int vbc = CoerceLuaToJava.getCoercion(int[][].class).score(vb);
|
|
||||||
assertTrue(vbb < vba);
|
|
||||||
assertTrue(vbb < vbc);
|
|
||||||
int vca = CoerceLuaToJava.getCoercion(int.class).score(vc);
|
|
||||||
int vcb = CoerceLuaToJava.getCoercion(int[].class).score(vc);
|
|
||||||
int vcc = CoerceLuaToJava.getCoercion(int[][].class).score(vc);
|
|
||||||
assertTrue(vcc < vca);
|
|
||||||
assertTrue(vcc < vcb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SampleClass {
|
|
||||||
public String sample() { return "void-args"; }
|
|
||||||
|
|
||||||
public String sample(int a) { return "int-args " + a; }
|
|
||||||
|
|
||||||
public String sample(int[] a) { return "int-array-args " + a[0] + "," + a[1]; }
|
|
||||||
|
|
||||||
public String sample(int[][] a) {
|
|
||||||
return "int-array-array-args " + a[0][0] + "," + a[0][1] + "," + a[1][0] + "," + a[1][1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMatchVoidArgs() {
|
|
||||||
LuaValue v = CoerceJavaToLua.coerce(new SampleClass());
|
|
||||||
LuaValue result = v.method("sample");
|
|
||||||
assertEquals("void-args", result.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMatchIntArgs() {
|
|
||||||
LuaValue v = CoerceJavaToLua.coerce(new SampleClass());
|
|
||||||
LuaValue arg = CoerceJavaToLua.coerce(new Integer(123));
|
|
||||||
LuaValue result = v.method("sample", arg);
|
|
||||||
assertEquals("int-args 123", result.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMatchIntArrayArgs() {
|
|
||||||
LuaValue v = CoerceJavaToLua.coerce(new SampleClass());
|
|
||||||
LuaValue arg = CoerceJavaToLua.coerce(new int[] { 345, 678 });
|
|
||||||
LuaValue result = v.method("sample", arg);
|
|
||||||
assertEquals("int-array-args 345,678", result.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMatchIntArrayArrayArgs() {
|
|
||||||
LuaValue v = CoerceJavaToLua.coerce(new SampleClass());
|
|
||||||
LuaValue arg = CoerceJavaToLua.coerce(new int[][] { { 22, 33 }, { 44, 55 } });
|
|
||||||
LuaValue result = v.method("sample", arg);
|
|
||||||
assertEquals("int-array-array-args 22,33,44,55", result.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class SomeException extends RuntimeException {
|
|
||||||
public SomeException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class SomeClass {
|
|
||||||
public static void someMethod() {
|
|
||||||
throw new SomeException("this is some message");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testExceptionMessage() {
|
|
||||||
String script = "local c = luajava.bindClass( \"" + SomeClass.class.getName() + "\" )\n"
|
|
||||||
+ "return pcall( c.someMethod, c )";
|
|
||||||
Varargs vresult = globals.get("load").call(LuaValue.valueOf(script)).invoke(LuaValue.NONE);
|
|
||||||
LuaValue status = vresult.arg1();
|
|
||||||
LuaValue message = vresult.arg(2);
|
|
||||||
assertEquals(LuaValue.FALSE, status);
|
|
||||||
int index = message.toString().indexOf("this is some message");
|
|
||||||
assertTrue(index >= 0, "bad message: " + message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLuaErrorCause() {
|
|
||||||
String script = "luajava.bindClass( \"" + SomeClass.class.getName() + "\"):someMethod()";
|
|
||||||
LuaValue chunk = globals.get("load").call(LuaValue.valueOf(script));
|
|
||||||
try {
|
|
||||||
chunk.invoke(LuaValue.NONE);
|
|
||||||
fail("call should not have succeeded");
|
|
||||||
} catch (LuaError lee) {
|
|
||||||
Throwable c = lee.getCause();
|
|
||||||
assertEquals(SomeException.class, c.getClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface VarArgsInterface {
|
|
||||||
public String varargsMethod(String a, String... v);
|
|
||||||
|
|
||||||
public String arrayargsMethod(String a, String[] v);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testVarArgsProxy() {
|
|
||||||
String script = "return luajava.createProxy( \"" + VarArgsInterface.class.getName() + "\", \n" + "{\n"
|
|
||||||
+ " varargsMethod = function(a,...)\n" + " return table.concat({a,...},'-')\n" + " end,\n"
|
|
||||||
+ " arrayargsMethod = function(a,array)\n" + " return tostring(a)..(array and \n"
|
|
||||||
+ " ('-'..tostring(array.length)\n" + " ..'-'..tostring(array[1])\n"
|
|
||||||
+ " ..'-'..tostring(array[2])\n" + " ) or '-nil')\n" + " end,\n" + "} )\n";
|
|
||||||
Varargs chunk = globals.get("load").call(LuaValue.valueOf(script));
|
|
||||||
if (!chunk.arg1().toboolean())
|
|
||||||
fail(chunk.arg(2).toString());
|
|
||||||
LuaValue result = chunk.arg1().call();
|
|
||||||
Object u = result.touserdata();
|
|
||||||
VarArgsInterface v = (VarArgsInterface) u;
|
|
||||||
assertEquals("foo", v.varargsMethod("foo"));
|
|
||||||
assertEquals("foo-bar", v.varargsMethod("foo", "bar"));
|
|
||||||
assertEquals("foo-bar-etc", v.varargsMethod("foo", "bar", "etc"));
|
|
||||||
assertEquals("foo-0-nil-nil", v.arrayargsMethod("foo", new String[0]));
|
|
||||||
assertEquals("foo-1-bar-nil", v.arrayargsMethod("foo", new String[] { "bar" }));
|
|
||||||
assertEquals("foo-2-bar-etc", v.arrayargsMethod("foo", new String[] { "bar", "etc" }));
|
|
||||||
assertEquals("foo-3-bar-etc", v.arrayargsMethod("foo", new String[] { "bar", "etc", "etc" }));
|
|
||||||
assertEquals("foo-nil", v.arrayargsMethod("foo", null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBigNum() {
|
|
||||||
String script = "bigNumA = luajava.newInstance('java.math.BigDecimal','12345678901234567890');\n"
|
|
||||||
+ "bigNumB = luajava.newInstance('java.math.BigDecimal','12345678901234567890');\n"
|
|
||||||
+ "bigNumC = bigNumA:multiply(bigNumB);\n" +
|
|
||||||
//"print(bigNumA:toString())\n" +
|
|
||||||
//"print(bigNumB:toString())\n" +
|
|
||||||
//"print(bigNumC:toString())\n" +
|
|
||||||
"return bigNumA:toString(), bigNumB:toString(), bigNumC:toString()";
|
|
||||||
Varargs chunk = globals.get("load").call(LuaValue.valueOf(script));
|
|
||||||
if (!chunk.arg1().toboolean())
|
|
||||||
fail(chunk.arg(2).toString());
|
|
||||||
Varargs results = chunk.arg1().invoke();
|
|
||||||
int nresults = results.narg();
|
|
||||||
String sa = results.tojstring(1);
|
|
||||||
String sb = results.tojstring(2);
|
|
||||||
String sc = results.tojstring(3);
|
|
||||||
assertEquals(3, nresults);
|
|
||||||
assertEquals("12345678901234567890", sa);
|
|
||||||
assertEquals("12345678901234567890", sb);
|
|
||||||
assertEquals("152415787532388367501905199875019052100", sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IA {
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IB extends IA {
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IC extends IB {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class A implements IA {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class B extends A implements IB {
|
|
||||||
public String set(Object x) { return "set(Object) "; }
|
|
||||||
|
|
||||||
public String set(String x) { return "set(String) " + x; }
|
|
||||||
|
|
||||||
public String set(A x) { return "set(A) "; }
|
|
||||||
|
|
||||||
public String set(B x) { return "set(B) "; }
|
|
||||||
|
|
||||||
public String set(C x) { return "set(C) "; }
|
|
||||||
|
|
||||||
public String set(byte x) { return "set(byte) " + x; }
|
|
||||||
|
|
||||||
public String set(char x) { return "set(char) " + (int) x; }
|
|
||||||
|
|
||||||
public String set(short x) { return "set(short) " + x; }
|
|
||||||
|
|
||||||
public String set(int x) { return "set(int) " + x; }
|
|
||||||
|
|
||||||
public String set(long x) { return "set(long) " + x; }
|
|
||||||
|
|
||||||
public String set(float x) { return "set(float) " + x; }
|
|
||||||
|
|
||||||
public String set(double x) { return "set(double) " + x; }
|
|
||||||
|
|
||||||
public String setr(double x) { return "setr(double) " + x; }
|
|
||||||
|
|
||||||
public String setr(float x) { return "setr(float) " + x; }
|
|
||||||
|
|
||||||
public String setr(long x) { return "setr(long) " + x; }
|
|
||||||
|
|
||||||
public String setr(int x) { return "setr(int) " + x; }
|
|
||||||
|
|
||||||
public String setr(short x) { return "setr(short) " + x; }
|
|
||||||
|
|
||||||
public String setr(char x) { return "setr(char) " + (int) x; }
|
|
||||||
|
|
||||||
public String setr(byte x) { return "setr(byte) " + x; }
|
|
||||||
|
|
||||||
public String setr(C x) { return "setr(C) "; }
|
|
||||||
|
|
||||||
public String setr(B x) { return "setr(B) "; }
|
|
||||||
|
|
||||||
public String setr(A x) { return "setr(A) "; }
|
|
||||||
|
|
||||||
public String setr(String x) { return "setr(String) " + x; }
|
|
||||||
|
|
||||||
public String setr(Object x) { return "setr(Object) "; }
|
|
||||||
|
|
||||||
public Object getObject() { return new Object(); }
|
|
||||||
|
|
||||||
public String getString() { return "abc"; }
|
|
||||||
|
|
||||||
public byte[] getbytearray() { return new byte[] { 1, 2, 3 }; }
|
|
||||||
|
|
||||||
public A getA() { return new A(); }
|
|
||||||
|
|
||||||
public B getB() { return new B(); }
|
|
||||||
|
|
||||||
public C getC() { return new C(); }
|
|
||||||
|
|
||||||
public byte getbyte() { return 1; }
|
|
||||||
|
|
||||||
public char getchar() { return 65000; }
|
|
||||||
|
|
||||||
public short getshort() { return -32000; }
|
|
||||||
|
|
||||||
public int getint() { return 100000; }
|
|
||||||
|
|
||||||
public long getlong() { return 50000000000L; }
|
|
||||||
|
|
||||||
public float getfloat() { return 6.5f; }
|
|
||||||
|
|
||||||
public double getdouble() { return Math.PI; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class C extends B implements IC {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class D extends C implements IA {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodObject() { doOverloadedMethodTest("Object", ""); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodString() { doOverloadedMethodTest("String", "abc"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodA() { doOverloadedMethodTest("A", ""); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodB() { doOverloadedMethodTest("B", ""); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodC() { doOverloadedMethodTest("C", ""); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodByte() { doOverloadedMethodTest("byte", "1"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodChar() { doOverloadedMethodTest("char", "65000"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodShort() { doOverloadedMethodTest("short", "-32000"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodInt() { doOverloadedMethodTest("int", "100000"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodLong() { doOverloadedMethodTest("long", "50000000000"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodFloat() { doOverloadedMethodTest("float", "6.5"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedJavaMethodDouble() { doOverloadedMethodTest("double", "3.141592653589793"); }
|
|
||||||
|
|
||||||
private void doOverloadedMethodTest(String typename, String value) {
|
|
||||||
String script = "local a = luajava.newInstance('" + B.class.getName() + "');\n" + "local b = a:set(a:get"
|
|
||||||
+ typename + "())\n" + "local c = a:setr(a:get" + typename + "())\n" + "return b,c";
|
|
||||||
Varargs chunk = globals.get("load").call(LuaValue.valueOf(script));
|
|
||||||
if (!chunk.arg1().toboolean())
|
|
||||||
fail(chunk.arg(2).toString());
|
|
||||||
Varargs results = chunk.arg1().invoke();
|
|
||||||
int nresults = results.narg();
|
|
||||||
assertEquals(2, nresults);
|
|
||||||
LuaValue b = results.arg(1);
|
|
||||||
LuaValue c = results.arg(2);
|
|
||||||
String sb = b.tojstring();
|
|
||||||
String sc = c.tojstring();
|
|
||||||
assertEquals("set(" + typename + ") " + value, sb);
|
|
||||||
assertEquals("setr(" + typename + ") " + value, sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testClassInheritanceLevels() {
|
|
||||||
assertEquals(0, CoerceLuaToJava.inheritanceLevels(Object.class, Object.class));
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(Object.class, String.class));
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(Object.class, A.class));
|
|
||||||
assertEquals(2, CoerceLuaToJava.inheritanceLevels(Object.class, B.class));
|
|
||||||
assertEquals(3, CoerceLuaToJava.inheritanceLevels(Object.class, C.class));
|
|
||||||
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(A.class, Object.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(A.class, String.class));
|
|
||||||
assertEquals(0, CoerceLuaToJava.inheritanceLevels(A.class, A.class));
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(A.class, B.class));
|
|
||||||
assertEquals(2, CoerceLuaToJava.inheritanceLevels(A.class, C.class));
|
|
||||||
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, Object.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, String.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, A.class));
|
|
||||||
assertEquals(0, CoerceLuaToJava.inheritanceLevels(B.class, B.class));
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(B.class, C.class));
|
|
||||||
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, Object.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, String.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, A.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, B.class));
|
|
||||||
assertEquals(0, CoerceLuaToJava.inheritanceLevels(C.class, C.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInterfaceInheritanceLevels() {
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(IA.class, A.class));
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(IB.class, B.class));
|
|
||||||
assertEquals(2, CoerceLuaToJava.inheritanceLevels(IA.class, B.class));
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(IC.class, C.class));
|
|
||||||
assertEquals(2, CoerceLuaToJava.inheritanceLevels(IB.class, C.class));
|
|
||||||
assertEquals(3, CoerceLuaToJava.inheritanceLevels(IA.class, C.class));
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(IA.class, D.class));
|
|
||||||
assertEquals(2, CoerceLuaToJava.inheritanceLevels(IC.class, D.class));
|
|
||||||
assertEquals(3, CoerceLuaToJava.inheritanceLevels(IB.class, D.class));
|
|
||||||
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IB.class, A.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IC.class, A.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IC.class, B.class));
|
|
||||||
assertEquals(CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IB.class, IA.class));
|
|
||||||
assertEquals(1, CoerceLuaToJava.inheritanceLevels(IA.class, IB.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCoerceJavaToLuaLuaValue() {
|
|
||||||
assertSame(LuaValue.NIL, CoerceJavaToLua.coerce(LuaValue.NIL));
|
|
||||||
assertSame(LuaValue.ZERO, CoerceJavaToLua.coerce(LuaValue.ZERO));
|
|
||||||
assertSame(LuaValue.ONE, CoerceJavaToLua.coerce(LuaValue.ONE));
|
|
||||||
assertSame(LuaValue.INDEX, CoerceJavaToLua.coerce(LuaValue.INDEX));
|
|
||||||
LuaTable table = LuaValue.tableOf();
|
|
||||||
assertSame(table, CoerceJavaToLua.coerce(table));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCoerceJavaToLuaByeArray() {
|
|
||||||
byte[] bytes = "abcd".getBytes();
|
|
||||||
LuaValue value = CoerceJavaToLua.coerce(bytes);
|
|
||||||
assertEquals(LuaString.class, value.getClass());
|
|
||||||
assertEquals(LuaValue.valueOf("abcd"), value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
|
|
||||||
class LuajavaAccessibleMembersTest {
|
|
||||||
|
|
||||||
private Globals globals;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
globals = JsePlatform.standardGlobals();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String invokeScript(String script) {
|
|
||||||
try {
|
|
||||||
LuaValue c = globals.load(script, "script");
|
|
||||||
return c.call().tojstring();
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail("exception: " + e);
|
|
||||||
return "failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAccessFromPrivateClassImplementedMethod() {
|
|
||||||
assertEquals("privateImpl-aaa-interface_method(bar)",
|
|
||||||
invokeScript("b = luajava.newInstance('" + TestClass.class.getName() + "');"
|
|
||||||
+ "a = b:create_PrivateImpl('aaa');" + "return a:interface_method('bar');"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAccessFromPrivateClassPublicMethod() {
|
|
||||||
assertEquals("privateImpl-aaa-public_method", invokeScript("b = luajava.newInstance('"
|
|
||||||
+ TestClass.class.getName() + "');" + "a = b:create_PrivateImpl('aaa');" + "return a:public_method();"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAccessFromPrivateClassGetPublicField() {
|
|
||||||
assertEquals("aaa", invokeScript("b = luajava.newInstance('" + TestClass.class.getName() + "');"
|
|
||||||
+ "a = b:create_PrivateImpl('aaa');" + "return a.public_field;"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAccessFromPrivateClassSetPublicField() {
|
|
||||||
assertEquals("foo", invokeScript("b = luajava.newInstance('" + TestClass.class.getName() + "');"
|
|
||||||
+ "a = b:create_PrivateImpl('aaa');" + "a.public_field = 'foo';" + "return a.public_field;"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAccessFromPrivateClassPublicConstructor() {
|
|
||||||
assertEquals("privateImpl-constructor", invokeScript("b = luajava.newInstance('" + TestClass.class.getName()
|
|
||||||
+ "');" + "c = b:get_PrivateImplClass();" + "return luajava.new(c);"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAccessPublicEnum() {
|
|
||||||
assertEquals("class org.luaj.vm2.lib.jse.TestClass$SomeEnum",
|
|
||||||
invokeScript("b = luajava.newInstance('" + TestClass.class.getName() + "');" + "return b.SomeEnum"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,318 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaError;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
|
|
||||||
class LuajavaClassMembersTest {
|
|
||||||
public static class A {
|
|
||||||
protected A() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class B extends A {
|
|
||||||
public byte m_byte_field;
|
|
||||||
public int m_int_field;
|
|
||||||
public double m_double_field;
|
|
||||||
public String m_string_field;
|
|
||||||
|
|
||||||
protected B() {}
|
|
||||||
|
|
||||||
public B(int i) { m_int_field = i; }
|
|
||||||
|
|
||||||
public String setString(String x) { return "setString(String) " + x; }
|
|
||||||
|
|
||||||
public String getString() { return "abc"; }
|
|
||||||
|
|
||||||
public int getint() { return 100000; }
|
|
||||||
|
|
||||||
public String uniq() { return "uniq()"; }
|
|
||||||
|
|
||||||
public String uniqs(String s) { return "uniqs(string:" + s + ")"; }
|
|
||||||
|
|
||||||
public String uniqi(int i) { return "uniqi(int:" + i + ")"; }
|
|
||||||
|
|
||||||
public String uniqsi(String s, int i) { return "uniqsi(string:" + s + ",int:" + i + ")"; }
|
|
||||||
|
|
||||||
public String uniqis(int i, String s) { return "uniqis(int:" + i + ",string:" + s + ")"; }
|
|
||||||
|
|
||||||
public String pick() { return "pick()"; }
|
|
||||||
|
|
||||||
public String pick(String s) { return "pick(string:" + s + ")"; }
|
|
||||||
|
|
||||||
public String pick(int i) { return "pick(int:" + i + ")"; }
|
|
||||||
|
|
||||||
public String pick(String s, int i) { return "pick(string:" + s + ",int:" + i + ")"; }
|
|
||||||
|
|
||||||
public String pick(int i, String s) { return "pick(int:" + i + ",string:" + s + ")"; }
|
|
||||||
|
|
||||||
public static String staticpick() { return "static-pick()"; }
|
|
||||||
|
|
||||||
public static String staticpick(String s) { return "static-pick(string:" + s + ")"; }
|
|
||||||
|
|
||||||
public static String staticpick(int i) { return "static-pick(int:" + i + ")"; }
|
|
||||||
|
|
||||||
public static String staticpick(String s, int i) { return "static-pick(string:" + s + ",int:" + i + ")"; }
|
|
||||||
|
|
||||||
public static String staticpick(int i, String s) { return "static-pick(int:" + i + ",string:" + s + ")"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class C extends B {
|
|
||||||
public C() {}
|
|
||||||
|
|
||||||
public C(String s) { m_string_field = s; }
|
|
||||||
|
|
||||||
public C(int i) { m_int_field = i; }
|
|
||||||
|
|
||||||
public C(String s, int i) { m_string_field = s; m_int_field = i; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getint() { return 200000; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String pick(String s) { return "class-c-pick(string:" + s + ")"; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String pick(int i) { return "class-c-pick(int:" + i + ")"; }
|
|
||||||
|
|
||||||
public static class D {
|
|
||||||
public static String name() { return "name-of-D"; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static LuaValue ZERO = LuaValue.ZERO;
|
|
||||||
static LuaValue ONE = LuaValue.ONE;
|
|
||||||
static LuaValue PI = LuaValue.valueOf(Math.PI);
|
|
||||||
static LuaValue THREE = LuaValue.valueOf(3);
|
|
||||||
static LuaValue NUMS = LuaValue.valueOf(123);
|
|
||||||
static LuaValue ABC = LuaValue.valueOf("abc");
|
|
||||||
static LuaValue SOMEA = CoerceJavaToLua.coerce(new A());
|
|
||||||
static LuaValue SOMEB = CoerceJavaToLua.coerce(new B());
|
|
||||||
static LuaValue SOMEC = CoerceJavaToLua.coerce(new C());
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSetByteField() {
|
|
||||||
B b = new B();
|
|
||||||
JavaInstance i = new JavaInstance(b);
|
|
||||||
i.set("m_byte_field", ONE);
|
|
||||||
assertEquals(1, b.m_byte_field);
|
|
||||||
assertEquals(ONE, i.get("m_byte_field"));
|
|
||||||
i.set("m_byte_field", PI);
|
|
||||||
assertEquals(3, b.m_byte_field);
|
|
||||||
assertEquals(THREE, i.get("m_byte_field"));
|
|
||||||
i.set("m_byte_field", ABC);
|
|
||||||
assertEquals(0, b.m_byte_field);
|
|
||||||
assertEquals(ZERO, i.get("m_byte_field"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSetDoubleField() {
|
|
||||||
B b = new B();
|
|
||||||
JavaInstance i = new JavaInstance(b);
|
|
||||||
i.set("m_double_field", ONE);
|
|
||||||
assertEquals(1., b.m_double_field);
|
|
||||||
assertEquals(ONE, i.get("m_double_field"));
|
|
||||||
i.set("m_double_field", PI);
|
|
||||||
assertEquals(Math.PI, b.m_double_field);
|
|
||||||
assertEquals(PI, i.get("m_double_field"));
|
|
||||||
i.set("m_double_field", ABC);
|
|
||||||
assertEquals(0., b.m_double_field);
|
|
||||||
assertEquals(ZERO, i.get("m_double_field"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testNoFactory() {
|
|
||||||
JavaClass c = JavaClass.forClass(A.class);
|
|
||||||
try {
|
|
||||||
c.call();
|
|
||||||
fail("did not throw lua error as expected");
|
|
||||||
} catch (LuaError e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUniqueFactoryCoercible() {
|
|
||||||
JavaClass c = JavaClass.forClass(B.class);
|
|
||||||
assertEquals(JavaClass.class, c.getClass());
|
|
||||||
LuaValue constr = c.get("new");
|
|
||||||
assertEquals(JavaConstructor.class, constr.getClass());
|
|
||||||
LuaValue v = constr.call(NUMS);
|
|
||||||
Object b = v.touserdata();
|
|
||||||
assertEquals(B.class, b.getClass());
|
|
||||||
assertEquals(123, ((B) b).m_int_field);
|
|
||||||
Object b0 = constr.call().touserdata();
|
|
||||||
assertEquals(B.class, b0.getClass());
|
|
||||||
assertEquals(0, ((B) b0).m_int_field);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUniqueFactoryUncoercible() {
|
|
||||||
JavaClass f = JavaClass.forClass(B.class);
|
|
||||||
LuaValue constr = f.get("new");
|
|
||||||
assertEquals(JavaConstructor.class, constr.getClass());
|
|
||||||
try {
|
|
||||||
LuaValue v = constr.call(LuaValue.userdataOf(new Object()));
|
|
||||||
Object b = v.touserdata();
|
|
||||||
// fail( "did not throw lua error as expected" );
|
|
||||||
assertEquals(0, ((B) b).m_int_field);
|
|
||||||
} catch (LuaError e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedFactoryCoercible() {
|
|
||||||
JavaClass f = JavaClass.forClass(C.class);
|
|
||||||
LuaValue constr = f.get("new");
|
|
||||||
assertEquals(JavaConstructor.Overload.class, constr.getClass());
|
|
||||||
Object c = constr.call().touserdata();
|
|
||||||
Object ci = constr.call(LuaValue.valueOf(123)).touserdata();
|
|
||||||
Object cs = constr.call(LuaValue.valueOf("abc")).touserdata();
|
|
||||||
Object csi = constr.call(LuaValue.valueOf("def"), LuaValue.valueOf(456)).touserdata();
|
|
||||||
assertEquals(C.class, c.getClass());
|
|
||||||
assertEquals(C.class, ci.getClass());
|
|
||||||
assertEquals(C.class, cs.getClass());
|
|
||||||
assertEquals(C.class, csi.getClass());
|
|
||||||
assertEquals(null, ((C) c).m_string_field);
|
|
||||||
assertEquals(0, ((C) c).m_int_field);
|
|
||||||
assertEquals("abc", ((C) cs).m_string_field);
|
|
||||||
assertEquals(0, ((C) cs).m_int_field);
|
|
||||||
assertEquals(null, ((C) ci).m_string_field);
|
|
||||||
assertEquals(123, ((C) ci).m_int_field);
|
|
||||||
assertEquals("def", ((C) csi).m_string_field);
|
|
||||||
assertEquals(456, ((C) csi).m_int_field);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedFactoryUncoercible() {
|
|
||||||
JavaClass f = JavaClass.forClass(C.class);
|
|
||||||
try {
|
|
||||||
Object c = f.call(LuaValue.userdataOf(new Object()));
|
|
||||||
// fail( "did not throw lua error as expected" );
|
|
||||||
assertEquals(0, ((C) c).m_int_field);
|
|
||||||
assertEquals(null, ((C) c).m_string_field);
|
|
||||||
} catch (LuaError e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testNoAttribute() {
|
|
||||||
JavaClass f = JavaClass.forClass(A.class);
|
|
||||||
LuaValue v = f.get("bogus");
|
|
||||||
assertEquals(v, LuaValue.NIL);
|
|
||||||
try {
|
|
||||||
f.set("bogus", ONE);
|
|
||||||
fail("did not throw lua error as expected");
|
|
||||||
} catch (LuaError e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testFieldAttributeCoercible() {
|
|
||||||
JavaInstance i = new JavaInstance(new B());
|
|
||||||
i.set("m_int_field", ONE);
|
|
||||||
assertEquals(1, i.get("m_int_field").toint());
|
|
||||||
i.set("m_int_field", THREE);
|
|
||||||
assertEquals(3, i.get("m_int_field").toint());
|
|
||||||
i = new JavaInstance(new C());
|
|
||||||
i.set("m_int_field", ONE);
|
|
||||||
assertEquals(1, i.get("m_int_field").toint());
|
|
||||||
i.set("m_int_field", THREE);
|
|
||||||
assertEquals(3, i.get("m_int_field").toint());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUniqueMethodAttributeCoercible() {
|
|
||||||
B b = new B();
|
|
||||||
JavaInstance ib = new JavaInstance(b);
|
|
||||||
LuaValue b_getString = ib.get("getString");
|
|
||||||
LuaValue b_getint = ib.get("getint");
|
|
||||||
assertEquals(JavaMethod.class, b_getString.getClass());
|
|
||||||
assertEquals(JavaMethod.class, b_getint.getClass());
|
|
||||||
assertEquals("abc", b_getString.call(SOMEB).tojstring());
|
|
||||||
assertEquals(100000, b_getint.call(SOMEB).toint());
|
|
||||||
assertEquals("abc", b_getString.call(SOMEC).tojstring());
|
|
||||||
assertEquals(200000, b_getint.call(SOMEC).toint());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUniqueMethodAttributeArgsCoercible() {
|
|
||||||
B b = new B();
|
|
||||||
JavaInstance ib = new JavaInstance(b);
|
|
||||||
LuaValue uniq = ib.get("uniq");
|
|
||||||
LuaValue uniqs = ib.get("uniqs");
|
|
||||||
LuaValue uniqi = ib.get("uniqi");
|
|
||||||
LuaValue uniqsi = ib.get("uniqsi");
|
|
||||||
LuaValue uniqis = ib.get("uniqis");
|
|
||||||
assertEquals(JavaMethod.class, uniq.getClass());
|
|
||||||
assertEquals(JavaMethod.class, uniqs.getClass());
|
|
||||||
assertEquals(JavaMethod.class, uniqi.getClass());
|
|
||||||
assertEquals(JavaMethod.class, uniqsi.getClass());
|
|
||||||
assertEquals(JavaMethod.class, uniqis.getClass());
|
|
||||||
assertEquals("uniq()", uniq.call(SOMEB).tojstring());
|
|
||||||
assertEquals("uniqs(string:abc)", uniqs.call(SOMEB, ABC).tojstring());
|
|
||||||
assertEquals("uniqi(int:1)", uniqi.call(SOMEB, ONE).tojstring());
|
|
||||||
assertEquals("uniqsi(string:abc,int:1)", uniqsi.call(SOMEB, ABC, ONE).tojstring());
|
|
||||||
assertEquals("uniqis(int:1,string:abc)", uniqis.call(SOMEB, ONE, ABC).tojstring());
|
|
||||||
assertEquals("uniqis(int:1,string:abc)",
|
|
||||||
uniqis.invoke(LuaValue.varargsOf(new LuaValue[] { SOMEB, ONE, ABC, ONE })).arg1().tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedMethodAttributeCoercible() {
|
|
||||||
B b = new B();
|
|
||||||
JavaInstance ib = new JavaInstance(b);
|
|
||||||
LuaValue p = ib.get("pick");
|
|
||||||
assertEquals("pick()", p.call(SOMEB).tojstring());
|
|
||||||
assertEquals("pick(string:abc)", p.call(SOMEB, ABC).tojstring());
|
|
||||||
assertEquals("pick(int:1)", p.call(SOMEB, ONE).tojstring());
|
|
||||||
assertEquals("pick(string:abc,int:1)", p.call(SOMEB, ABC, ONE).tojstring());
|
|
||||||
assertEquals("pick(int:1,string:abc)", p.call(SOMEB, ONE, ABC).tojstring());
|
|
||||||
assertEquals("pick(int:1,string:abc)",
|
|
||||||
p.invoke(LuaValue.varargsOf(new LuaValue[] { SOMEB, ONE, ABC, ONE })).arg1().tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUnboundOverloadedMethodAttributeCoercible() {
|
|
||||||
B b = new B();
|
|
||||||
JavaInstance ib = new JavaInstance(b);
|
|
||||||
LuaValue p = ib.get("pick");
|
|
||||||
assertEquals(JavaMethod.Overload.class, p.getClass());
|
|
||||||
assertEquals("pick()", p.call(SOMEC).tojstring());
|
|
||||||
assertEquals("class-c-pick(string:abc)", p.call(SOMEC, ABC).tojstring());
|
|
||||||
assertEquals("class-c-pick(int:1)", p.call(SOMEC, ONE).tojstring());
|
|
||||||
assertEquals("pick(string:abc,int:1)", p.call(SOMEC, ABC, ONE).tojstring());
|
|
||||||
assertEquals("pick(int:1,string:abc)", p.call(SOMEC, ONE, ABC).tojstring());
|
|
||||||
assertEquals("pick(int:1,string:abc)",
|
|
||||||
p.invoke(LuaValue.varargsOf(new LuaValue[] { SOMEC, ONE, ABC, ONE })).arg1().tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOverloadedStaticMethodAttributeCoercible() {
|
|
||||||
B b = new B();
|
|
||||||
JavaInstance ib = new JavaInstance(b);
|
|
||||||
LuaValue p = ib.get("staticpick");
|
|
||||||
assertEquals("static-pick()", p.call(SOMEB).tojstring());
|
|
||||||
assertEquals("static-pick(string:abc)", p.call(SOMEB, ABC).tojstring());
|
|
||||||
assertEquals("static-pick(int:1)", p.call(SOMEB, ONE).tojstring());
|
|
||||||
assertEquals("static-pick(string:abc,int:1)", p.call(SOMEB, ABC, ONE).tojstring());
|
|
||||||
assertEquals("static-pick(int:1,string:abc)", p.call(SOMEB, ONE, ABC).tojstring());
|
|
||||||
assertEquals("static-pick(int:1,string:abc)",
|
|
||||||
p.invoke(LuaValue.varargsOf(new LuaValue[] { SOMEB, ONE, ABC, ONE })).arg1().tojstring());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetInnerClass() {
|
|
||||||
C c = new C();
|
|
||||||
JavaInstance ic = new JavaInstance(c);
|
|
||||||
LuaValue d = ic.get("D");
|
|
||||||
assertFalse(d.isnil());
|
|
||||||
assertSame(d, JavaClass.forClass(C.D.class));
|
|
||||||
LuaValue e = ic.get("E");
|
|
||||||
assertTrue(e.isnil());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
|
|
||||||
class OsLibTest {
|
|
||||||
|
|
||||||
LuaValue jse_lib;
|
|
||||||
double time;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
jse_lib = JsePlatform.standardGlobals().get("os");
|
|
||||||
time = new Date(2001-1900, 7, 23, 14, 55, 02).getTime()/1000.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void test(String format, String expected) {
|
|
||||||
String actual = jse_lib.get("date").call(LuaValue.valueOf(format), LuaValue.valueOf(time)).tojstring();
|
|
||||||
assertEquals(expected, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDateChars() { test("foo", "foo"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_a() { test("%a", "Thu"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_A() { test("%A", "Thursday"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_b() { test("%b", "Aug"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_B() { test("%B", "August"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_c() { test("%c", "Thu Aug 23 14:55:02 2001"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_d() { test("%d", "23"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_H() { test("%H", "14"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_I() { test("%I", "02"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_j() { test("%j", "235"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_m() { test("%m", "08"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_M() { test("%M", "55"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_p() { test("%p", "PM"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_S() { test("%S", "02"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_U() { test("%U", "33"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_w() { test("%w", "4"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_W() { test("%W", "34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_x() { test("%x", "08/23/01"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_X() { test("%X", "14:55:02"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_y() { test("%y", "01"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_Y() { test("%Y", "2001"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_Pct() { test("%%", "%"); }
|
|
||||||
|
|
||||||
static final double DAY = 24.*3600.;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_neg4() { time -= 4*DAY; test("%c %U %W", "Sun Aug 19 14:55:02 2001 33 33"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_neg3() { time -= 3*DAY; test("%c %U %W", "Mon Aug 20 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_neg2() { time -= 2*DAY; test("%c %U %W", "Tue Aug 21 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_neg1() { time -= DAY; test("%c %U %W", "Wed Aug 22 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos0() { time += 0; test("%c %U %W", "Thu Aug 23 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos1() { time += DAY; test("%c %U %W", "Fri Aug 24 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos2() { time += 2*DAY; test("%c %U %W", "Sat Aug 25 14:55:02 2001 33 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos3() { time += 3*DAY; test("%c %U %W", "Sun Aug 26 14:55:02 2001 34 34"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringDate_UW_pos4() { time += 4*DAY; test("%c %U %W", "Mon Aug 27 14:55:02 2001 34 35"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testJseOsGetenvForEnvVariables() {
|
|
||||||
LuaValue USER = LuaValue.valueOf("USER");
|
|
||||||
LuaValue jse_user = jse_lib.get("getenv").call(USER);
|
|
||||||
assertFalse(jse_user.isnil());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testJseOsGetenvForSystemProperties() {
|
|
||||||
System.setProperty("test.key.foo", "test.value.bar");
|
|
||||||
LuaValue key = LuaValue.valueOf("test.key.foo");
|
|
||||||
LuaValue value = LuaValue.valueOf("test.value.bar");
|
|
||||||
LuaValue jse_value = jse_lib.get("getenv").call(key);
|
|
||||||
assertEquals(value, jse_value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
package org.luaj.vm2.lib.jse;
|
|
||||||
|
|
||||||
public class TestClass {
|
|
||||||
private static class PrivateImpl implements TestInterface {
|
|
||||||
public String public_field;
|
|
||||||
|
|
||||||
public PrivateImpl() {
|
|
||||||
this.public_field = "privateImpl-constructor";
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivateImpl(String f) {
|
|
||||||
this.public_field = f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String public_method() { return "privateImpl-" + public_field + "-public_method"; }
|
|
||||||
|
|
||||||
public String interface_method(String x) {
|
|
||||||
return "privateImpl-" + public_field + "-interface_method(" + x + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() { return public_field; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestInterface create_PrivateImpl(String f) { return new PrivateImpl(f); }
|
|
||||||
|
|
||||||
public Class get_PrivateImplClass() { return PrivateImpl.class; }
|
|
||||||
|
|
||||||
public enum SomeEnum {
|
|
||||||
ValueOne, ValueTwo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import javax.script.Compilable;
|
|
||||||
import javax.script.CompiledScript;
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
|
|
||||||
class CompileClosureTest extends DefaultBindingsTestCase {
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
System.setProperty("org.luaj.luajc", "false");
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCompiledFunctionIsClosure() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("return 'foo'");
|
|
||||||
LuaValue value = ((LuaScriptEngine.LuajCompiledScript) cs).function;
|
|
||||||
assertTrue(value.isclosure());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
|
|
||||||
import javax.script.Compilable;
|
|
||||||
import javax.script.CompiledScript;
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
|
|
||||||
class CompileNonClosureTest extends DefaultBindingsTestCase {
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
System.setProperty("org.luaj.luajc", "true");
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCompiledFunctionIsNotClosure() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("return 'foo'");
|
|
||||||
LuaValue value = ((LuaScriptEngine.LuajCompiledScript) cs).function;
|
|
||||||
assertFalse(value.isclosure());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import javax.script.Bindings;
|
|
||||||
|
|
||||||
abstract class DefaultBindingsTestCase extends EngineTestCase {
|
|
||||||
@Override
|
|
||||||
protected Bindings createBindings() {
|
|
||||||
return e.createBindings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.io.CharArrayReader;
|
|
||||||
import java.io.CharArrayWriter;
|
|
||||||
import java.io.Reader;
|
|
||||||
|
|
||||||
import javax.script.Bindings;
|
|
||||||
import javax.script.Compilable;
|
|
||||||
import javax.script.CompiledScript;
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptEngineManager;
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaFunction;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.lib.OneArgFunction;
|
|
||||||
|
|
||||||
abstract class EngineTestCase {
|
|
||||||
protected ScriptEngine e;
|
|
||||||
protected Bindings b;
|
|
||||||
|
|
||||||
protected abstract Bindings createBindings();
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
this.e = new ScriptEngineManager().getEngineByName("luaj");
|
|
||||||
this.b = createBindings();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSqrtIntResult() throws ScriptException {
|
|
||||||
e.put("x", 25);
|
|
||||||
e.eval("y = math.sqrt(x)");
|
|
||||||
Object y = e.get("y");
|
|
||||||
assertEquals(5, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOneArgFunction() throws ScriptException {
|
|
||||||
e.put("x", 25);
|
|
||||||
e.eval("y = math.sqrt(x)");
|
|
||||||
Object y = e.get("y");
|
|
||||||
assertEquals(5, y);
|
|
||||||
e.put("f", new OneArgFunction() {
|
|
||||||
@Override
|
|
||||||
public LuaValue call(LuaValue arg) {
|
|
||||||
return LuaValue.valueOf(arg.toString() + "123");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Object r = e.eval("return f('abc')");
|
|
||||||
assertEquals("abc123", r);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCompiledScript() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("y = math.sqrt(x); return y");
|
|
||||||
b.put("x", 144);
|
|
||||||
assertEquals(12, cs.eval(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBuggyLuaScript() {
|
|
||||||
try {
|
|
||||||
e.eval("\n\nbuggy lua code\n\n");
|
|
||||||
} catch (ScriptException se) {
|
|
||||||
assertEquals("eval threw javax.script.ScriptException: [string \"script\"]:3: syntax error",
|
|
||||||
se.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fail("buggy script did not throw ScriptException as expected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testScriptRedirection() throws ScriptException {
|
|
||||||
Reader input = new CharArrayReader("abcdefg\nhijk".toCharArray());
|
|
||||||
CharArrayWriter output = new CharArrayWriter();
|
|
||||||
CharArrayWriter errors = new CharArrayWriter();
|
|
||||||
String script = "print(\"string written using 'print'\")\n"
|
|
||||||
+ "io.write(\"string written using 'io.write()'\\n\")\n"
|
|
||||||
+ "io.stdout:write(\"string written using 'io.stdout:write()'\\n\")\n"
|
|
||||||
+ "io.stderr:write(\"string written using 'io.stderr:write()'\\n\")\n"
|
|
||||||
+ "io.write([[string read using 'io.stdin:read(\"*l\")':]]..io.stdin:read(\"*l\")..\"\\n\")\n";
|
|
||||||
|
|
||||||
// Evaluate script with redirection set
|
|
||||||
e.getContext().setReader(input);
|
|
||||||
e.getContext().setWriter(output);
|
|
||||||
e.getContext().setErrorWriter(errors);
|
|
||||||
e.eval(script);
|
|
||||||
final String expectedOutput = "string written using 'print'\n" + "string written using 'io.write()'\n"
|
|
||||||
+ "string written using 'io.stdout:write()'\n" + "string read using 'io.stdin:read(\"*l\")':abcdefg\n";
|
|
||||||
assertEquals(expectedOutput, output.toString());
|
|
||||||
final String expectedErrors = "string written using 'io.stderr:write()'\n";
|
|
||||||
assertEquals(expectedErrors, errors.toString());
|
|
||||||
|
|
||||||
// Evaluate script with redirection reset
|
|
||||||
output.reset();
|
|
||||||
errors.reset();
|
|
||||||
// e.getContext().setReader(null); // This will block if using actual STDIN
|
|
||||||
e.getContext().setWriter(null);
|
|
||||||
e.getContext().setErrorWriter(null);
|
|
||||||
e.eval(script);
|
|
||||||
assertEquals("", output.toString());
|
|
||||||
assertEquals("", errors.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBindingJavaInt() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("y = x; return 'x '..type(x)..' '..tostring(x)\n");
|
|
||||||
b.put("x", 111);
|
|
||||||
assertEquals("x number 111", cs.eval(b));
|
|
||||||
assertEquals(111, b.get("y"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBindingJavaDouble() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("y = x; return 'x '..type(x)..' '..tostring(x)\n");
|
|
||||||
b.put("x", 125.125);
|
|
||||||
assertEquals("x number 125.125", cs.eval(b));
|
|
||||||
assertEquals(125.125, b.get("y"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBindingJavaString() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("y = x; return 'x '..type(x)..' '..tostring(x)\n");
|
|
||||||
b.put("x", "foo");
|
|
||||||
assertEquals("x string foo", cs.eval(b));
|
|
||||||
assertEquals("foo", b.get("y"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBindingJavaObject() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("y = x; return 'x '..type(x)..' '..tostring(x)\n");
|
|
||||||
b.put("x", new SomeUserClass());
|
|
||||||
assertEquals("x userdata some-user-value", cs.eval(b));
|
|
||||||
assertEquals(SomeUserClass.class, b.get("y").getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBindingJavaArray() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("y = x; return 'x '..type(x)..' '..#x..' '..x[1]..' '..x[2]\n");
|
|
||||||
b.put("x", new int[] { 777, 888 });
|
|
||||||
assertEquals("x userdata 2 777 888", cs.eval(b));
|
|
||||||
assertEquals(int[].class, b.get("y").getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBindingLuaFunction() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("y = function(x) return 678 + x end; return 'foo'");
|
|
||||||
assertEquals("foo", cs.eval(b).toString());
|
|
||||||
assertTrue(b.get("y") instanceof LuaFunction);
|
|
||||||
assertEquals(LuaValue.valueOf(801), ((LuaFunction) b.get("y")).call(LuaValue.valueOf(123)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUserClasses() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("x = x or luajava.newInstance('java.lang.String', 'test')\n"
|
|
||||||
+ "return 'x ' .. type(x) .. ' ' .. tostring(x)\n");
|
|
||||||
assertEquals("x string test", cs.eval(b));
|
|
||||||
b.put("x", new SomeUserClass());
|
|
||||||
assertEquals("x userdata some-user-value", cs.eval(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testReturnMultipleValues() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("return 'foo', 'bar'\n");
|
|
||||||
Object o = cs.eval();
|
|
||||||
assertEquals(Object[].class, o.getClass());
|
|
||||||
Object[] array = (Object[]) o;
|
|
||||||
assertEquals(2, array.length);
|
|
||||||
assertEquals("foo", array[0]);
|
|
||||||
assertEquals("bar", array[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SomeUserClass {
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "some-user-value";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptEngineFactory;
|
|
||||||
import javax.script.ScriptEngineManager;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class LookupEngineTest {
|
|
||||||
@Test
|
|
||||||
void testGetEngineByExtension() {
|
|
||||||
ScriptEngine e = new ScriptEngineManager().getEngineByExtension(".lua");
|
|
||||||
assertNotNull(e);
|
|
||||||
assertEquals(LuaScriptEngine.class, e.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetEngineByName() {
|
|
||||||
ScriptEngine e = new ScriptEngineManager().getEngineByName("luaj");
|
|
||||||
assertNotNull(e);
|
|
||||||
assertEquals(LuaScriptEngine.class, e.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetEngineByMimeType() {
|
|
||||||
ScriptEngine e = new ScriptEngineManager().getEngineByMimeType("text/lua");
|
|
||||||
assertNotNull(e);
|
|
||||||
assertEquals(LuaScriptEngine.class, e.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testFactoryMetadata() {
|
|
||||||
ScriptEngine e = new ScriptEngineManager().getEngineByName("luaj");
|
|
||||||
ScriptEngineFactory f = e.getFactory();
|
|
||||||
assertEquals("Luaj", f.getEngineName());
|
|
||||||
assertEquals("Luaj 0.0", f.getEngineVersion());
|
|
||||||
assertEquals("lua", f.getLanguageName());
|
|
||||||
assertEquals("5.2", f.getLanguageVersion());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import javax.script.Bindings;
|
|
||||||
import javax.script.SimpleBindings;
|
|
||||||
|
|
||||||
class SimpleBindingsTest extends EngineTestCase {
|
|
||||||
@Override
|
|
||||||
protected Bindings createBindings() {
|
|
||||||
return new SimpleBindings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import javax.script.Bindings;
|
|
||||||
import javax.script.Compilable;
|
|
||||||
import javax.script.CompiledScript;
|
|
||||||
import javax.script.ScriptContext;
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptEngineManager;
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class UserContextTest {
|
|
||||||
protected ScriptEngine e;
|
|
||||||
protected Bindings b;
|
|
||||||
protected ScriptContext c;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
this.e = new ScriptEngineManager().getEngineByName("luaj");
|
|
||||||
this.c = new LuajContext();
|
|
||||||
this.b = c.getBindings(ScriptContext.ENGINE_SCOPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUncompiledScript() throws ScriptException {
|
|
||||||
b.put("x", 144);
|
|
||||||
assertEquals(12, e.eval("z = math.sqrt(x); return z", b));
|
|
||||||
assertEquals(12, b.get("z"));
|
|
||||||
assertEquals(null, e.getBindings(ScriptContext.ENGINE_SCOPE).get("z"));
|
|
||||||
assertEquals(null, e.getBindings(ScriptContext.GLOBAL_SCOPE).get("z"));
|
|
||||||
|
|
||||||
b.put("x", 25);
|
|
||||||
assertEquals(5, e.eval("z = math.sqrt(x); return z", c));
|
|
||||||
assertEquals(5, b.get("z"));
|
|
||||||
assertEquals(null, e.getBindings(ScriptContext.ENGINE_SCOPE).get("z"));
|
|
||||||
assertEquals(null, e.getBindings(ScriptContext.GLOBAL_SCOPE).get("z"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCompiledScript() throws ScriptException {
|
|
||||||
CompiledScript cs = ((Compilable) e).compile("z = math.sqrt(x); return z");
|
|
||||||
|
|
||||||
b.put("x", 144);
|
|
||||||
assertEquals(12, cs.eval(b));
|
|
||||||
assertEquals(12, b.get("z"));
|
|
||||||
|
|
||||||
b.put("x", 25);
|
|
||||||
assertEquals(5, cs.eval(c));
|
|
||||||
assertEquals(5, b.get("z"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package org.luaj.vm2.script;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
import java.io.CharArrayWriter;
|
|
||||||
|
|
||||||
import javax.script.Bindings;
|
|
||||||
import javax.script.ScriptContext;
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptEngineManager;
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class WriterTest {
|
|
||||||
protected ScriptEngine e;
|
|
||||||
protected Bindings b;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
this.e = new ScriptEngineManager().getEngineByName("luaj");
|
|
||||||
this.b = e.getBindings(ScriptContext.ENGINE_SCOPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testWriter() throws ScriptException {
|
|
||||||
CharArrayWriter output = new CharArrayWriter();
|
|
||||||
CharArrayWriter errors = new CharArrayWriter();
|
|
||||||
e.getContext().setWriter(output);
|
|
||||||
e.getContext().setErrorWriter(errors);
|
|
||||||
e.eval("io.write( [[line]] )");
|
|
||||||
assertEquals("line", output.toString());
|
|
||||||
e.eval("io.write( [[ one\nline two\n]] )");
|
|
||||||
assertEquals("line one\nline two\n", output.toString());
|
|
||||||
output.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
4
luaj-test/.gitignore
vendored
4
luaj-test/.gitignore
vendored
@@ -1,4 +0,0 @@
|
|||||||
abc.txt
|
|
||||||
seektest.txt
|
|
||||||
tmp1.out
|
|
||||||
tmp2.out
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-parent</artifactId>
|
|
||||||
<version>3.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>luaj-test</artifactId>
|
|
||||||
|
|
||||||
<name>LuaJ-Tests</name>
|
|
||||||
<description>Testsuites for LuaJ</description>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-core</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-jme</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.luaj</groupId>
|
|
||||||
<artifactId>luaj-jse</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.microemu</groupId>
|
|
||||||
<artifactId>microemulator</artifactId>
|
|
||||||
<version>2.0.4</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.microemu</groupId>
|
|
||||||
<artifactId>microemu-jsr-75</artifactId>
|
|
||||||
<version>2.0.4</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>report-aggregate</id>
|
|
||||||
<phase>verify</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>report-aggregate</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Disabled;
|
|
||||||
import org.junit.jupiter.api.Nested;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaBoolean;
|
|
||||||
import org.luaj.vm2.LuaFunction;
|
|
||||||
import org.luaj.vm2.LuaNil;
|
|
||||||
import org.luaj.vm2.LuaNumber;
|
|
||||||
import org.luaj.vm2.LuaString;
|
|
||||||
import org.luaj.vm2.LuaThread;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.luajc.LuaJC;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compatibility tests for the Luaj VM
|
|
||||||
*
|
|
||||||
* Results are compared for exact match with the installed C-based lua
|
|
||||||
* environment.
|
|
||||||
*/
|
|
||||||
public class CompatibiltyTest {
|
|
||||||
|
|
||||||
abstract static class CompatibiltyTestCase extends PlatformTestCase {
|
|
||||||
LuaValue savedStringMetatable;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() {
|
|
||||||
savedStringMetatable = LuaString.s_metatable;
|
|
||||||
setBaseDir("compatibility");
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
protected void tearDown() {
|
|
||||||
LuaNil.s_metatable = null;
|
|
||||||
LuaBoolean.s_metatable = null;
|
|
||||||
LuaNumber.s_metatable = null;
|
|
||||||
LuaFunction.s_metatable = null;
|
|
||||||
LuaThread.s_metatable = null;
|
|
||||||
LuaString.s_metatable = savedStringMetatable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBaseLib() { runTest("baselib"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCoroutineLib() { runTest("coroutinelib"); }
|
|
||||||
|
|
||||||
@Disabled("Too many failing tests")
|
|
||||||
@Test
|
|
||||||
void testDebugLib() { runTest("debuglib"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testErrors() { runTest("errors"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testFunctions() { runTest("functions"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testIoLib() { runTest("iolib"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testManyUpvals() { runTest("manyupvals"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMathLib() { runTest("mathlib"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMetatags() { runTest("metatags"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOsLib() { runTest("oslib"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStringLib() { runTest("stringlib"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testTableLib() { runTest("tablelib"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testTailcalls() { runTest("tailcalls"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUpvalues() { runTest("upvalues"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testVm() { runTest("vm"); }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
public static class JmeCompatibilityTest extends CompatibiltyTestCase {
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() {
|
|
||||||
setPlatform(PlatformTestCase.PlatformType.JME);
|
|
||||||
System.setProperty("JME", "true");
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emulator cannot create files for writing
|
|
||||||
@Override
|
|
||||||
void testIoLib() {}
|
|
||||||
|
|
||||||
// Emulator cannot create files for writing
|
|
||||||
@Override
|
|
||||||
void testOsLib() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
public static class JseCompatibilityTest extends CompatibiltyTestCase {
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() {
|
|
||||||
setPlatform(PlatformTestCase.PlatformType.JSE);
|
|
||||||
System.setProperty("JME", "false");
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
public static class LuaJCCompatibilityTest extends CompatibiltyTestCase {
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() {
|
|
||||||
setPlatform(PlatformTestCase.PlatformType.LUAJIT);
|
|
||||||
System.setProperty("JME", "false");
|
|
||||||
super.setUp();
|
|
||||||
LuaJC.install(globals);
|
|
||||||
}
|
|
||||||
|
|
||||||
// not supported on this platform - don't test
|
|
||||||
@Override
|
|
||||||
void testDebugLib() {}
|
|
||||||
|
|
||||||
// FIXME Test failures
|
|
||||||
@Override
|
|
||||||
void testBaseLib() {}
|
|
||||||
|
|
||||||
// FIXME Test failures
|
|
||||||
@Override
|
|
||||||
void testCoroutineLib() {}
|
|
||||||
|
|
||||||
// FIXME Test failures
|
|
||||||
@Override
|
|
||||||
void testIoLib() {}
|
|
||||||
|
|
||||||
// FIXME Test failures
|
|
||||||
@Override
|
|
||||||
void testMetatags() {}
|
|
||||||
|
|
||||||
// FIXME Test failures
|
|
||||||
@Override
|
|
||||||
void testOsLib() {}
|
|
||||||
|
|
||||||
// FIXME Test failures
|
|
||||||
@Override
|
|
||||||
void testStringLib() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
package org.luaj;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class CompilerTest extends CompilingTestCase {
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() {
|
|
||||||
setBaseDir("lua5.2.1-tests");
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAll() { doTest("all"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testApi() { doTest("api"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAttrib() { doTest("attrib"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBig() { doTest("big"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBitwise() { doTest("bitwise"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCalls() { doTest("calls"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testChecktable() { doTest("checktable"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testClosure() { doTest("closure"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCode() { doTest("code"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConstruct() { doTest("constructs"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCoroutine() { doTest("coroutine"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testDb() { doTest("db"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testErrors() { doTest("errors"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testEvents() { doTest("events"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testFiles() { doTest("files"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGc() { doTest("gc"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGoto() { doTest("goto"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLiterals() { doTest("literals"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLocals() { doTest("locals"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMain() { doTest("main"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMath() { doTest("math"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testNextvar() { doTest("nextvar"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testPm() { doTest("pm"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSort() { doTest("sort"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStrings() { doTest("strings"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testVararg() { doTest("vararg"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testVerybig() { doTest("verybig"); }
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package org.luaj;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
|
|
||||||
import org.luaj.vm2.Print;
|
|
||||||
import org.luaj.vm2.Prototype;
|
|
||||||
import org.luaj.vm2.compiler.DumpState;
|
|
||||||
|
|
||||||
abstract class CompilingTestCase extends ResourcesTestCase {
|
|
||||||
|
|
||||||
protected void doTest(String name) {
|
|
||||||
try {
|
|
||||||
// compile in memory
|
|
||||||
Prototype p = globals.loadPrototype(inputStreamOfLua(name), "@" + name + ".lua", "bt");
|
|
||||||
String actual = protoToString(p);
|
|
||||||
|
|
||||||
// load expected value from jar
|
|
||||||
Prototype e = globals.loadPrototype(inputStreamOfBytecode(name), name, "b");
|
|
||||||
String expected = protoToString(e);
|
|
||||||
|
|
||||||
// compare results
|
|
||||||
assertEquals(expected, actual);
|
|
||||||
|
|
||||||
// dump into memory
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
DumpState.dump(p, baos, false);
|
|
||||||
ByteArrayInputStream dumped = new ByteArrayInputStream(baos.toByteArray());
|
|
||||||
|
|
||||||
// re-undump
|
|
||||||
Prototype p2 = globals.loadPrototype(dumped, name, "b");
|
|
||||||
String actual2 = protoToString(p2);
|
|
||||||
|
|
||||||
// compare again
|
|
||||||
assertEquals(actual, actual2);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String protoToString(Prototype p) {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
PrintStream ps = new PrintStream(baos);
|
|
||||||
Print.ps = ps;
|
|
||||||
Print.printFunction(p, true);
|
|
||||||
return baos.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.luaj;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.ISO_8859_1;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import org.luaj.vm2.parser.LuaParser;
|
|
||||||
|
|
||||||
public class LuaParserTest extends CompilerTest {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doTest(String name) {
|
|
||||||
try {
|
|
||||||
LuaParser parser = new LuaParser(inputStreamOfLua(name), ISO_8859_1);
|
|
||||||
parser.Chunk();
|
|
||||||
} catch (Exception e) {
|
|
||||||
fail(e.getMessage());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2009 Luaj.org. All rights reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
******************************************************************************/
|
|
||||||
package org.luaj;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.OpenOption;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.lib.jme.JmePlatform;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
import org.luaj.vm2.lib.jse.JseProcess;
|
|
||||||
import org.luaj.vm2.luajc.LuaJC;
|
|
||||||
|
|
||||||
abstract class PlatformTestCase extends ResourcesTestCase {
|
|
||||||
public static final boolean nocompile = "true".equals(System.getProperty("nocompile"));
|
|
||||||
|
|
||||||
public enum PlatformType {
|
|
||||||
JME, JSE, LUAJIT,
|
|
||||||
}
|
|
||||||
|
|
||||||
private PlatformType platform;
|
|
||||||
|
|
||||||
private void initGlobals() {
|
|
||||||
switch (platform) {
|
|
||||||
default:
|
|
||||||
case JSE:
|
|
||||||
case LUAJIT:
|
|
||||||
globals = JsePlatform.debugGlobals();
|
|
||||||
break;
|
|
||||||
case JME:
|
|
||||||
globals = JmePlatform.debugGlobals();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() {
|
|
||||||
initGlobals();
|
|
||||||
globals.finder = filename -> {
|
|
||||||
try {
|
|
||||||
return inputStreamOfFile(filename);
|
|
||||||
} catch (IOException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setPlatform(PlatformType platform) { this.platform = platform; }
|
|
||||||
|
|
||||||
protected void runTest(String testName) {
|
|
||||||
try {
|
|
||||||
// override print()
|
|
||||||
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
|
||||||
final PrintStream oldps = globals.STDOUT;
|
|
||||||
final PrintStream ps = new PrintStream(output);
|
|
||||||
globals.STDOUT = ps;
|
|
||||||
|
|
||||||
// run the script
|
|
||||||
try {
|
|
||||||
LuaValue chunk = loadScript(testName, globals);
|
|
||||||
chunk.call(LuaValue.valueOf(platform.toString()));
|
|
||||||
|
|
||||||
ps.flush();
|
|
||||||
String actualOutput = new String(output.toByteArray());
|
|
||||||
String expectedOutput = getExpectedOutput(testName);
|
|
||||||
actualOutput = actualOutput.replaceAll("\r\n", "\n");
|
|
||||||
expectedOutput = expectedOutput.replaceAll("\r\n", "\n");
|
|
||||||
|
|
||||||
if (!expectedOutput.equals(actualOutput))
|
|
||||||
Files.write(new File(testName + ".out").toPath(), actualOutput.getBytes(), new OpenOption[0]);
|
|
||||||
assertEquals(expectedOutput, actualOutput);
|
|
||||||
} finally {
|
|
||||||
globals.STDOUT = oldps;
|
|
||||||
ps.close();
|
|
||||||
}
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new RuntimeException(ioe.toString());
|
|
||||||
} catch (InterruptedException ie) {
|
|
||||||
throw new RuntimeException(ie.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LuaValue loadScript(String name, Globals globals) throws IOException {
|
|
||||||
InputStream script = inputStreamOfLua(name);
|
|
||||||
if (script == null)
|
|
||||||
fail("Could not load script for test case: " + name);
|
|
||||||
try {
|
|
||||||
switch (this.platform) {
|
|
||||||
case LUAJIT:
|
|
||||||
if (nocompile) {
|
|
||||||
LuaValue c = (LuaValue) Class.forName(name).newInstance();
|
|
||||||
return c;
|
|
||||||
} else {
|
|
||||||
LuaJC.install(globals);
|
|
||||||
return globals.load(script, name, "bt", globals);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return globals.load(script, "@" + name + ".lua", "bt", globals);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new IOException(e.toString());
|
|
||||||
} finally {
|
|
||||||
script.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getExpectedOutput(final String name) throws IOException, InterruptedException {
|
|
||||||
InputStream output = inputStreamOfResult(platform.name().toLowerCase() + "/" + name);
|
|
||||||
if (output != null)
|
|
||||||
try {
|
|
||||||
return readString(output);
|
|
||||||
} finally {
|
|
||||||
output.close();
|
|
||||||
}
|
|
||||||
String expectedOutput = executeLuaProcess(name);
|
|
||||||
if (expectedOutput == null)
|
|
||||||
throw new IOException("Failed to get comparison output or run process for " + name);
|
|
||||||
return expectedOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String executeLuaProcess(String name) throws IOException, InterruptedException {
|
|
||||||
InputStream script = inputStreamOfLua(name);
|
|
||||||
if (script == null)
|
|
||||||
throw new IOException("Failed to find source file " + script);
|
|
||||||
try {
|
|
||||||
String luaCommand = System.getProperty("LUA_COMMAND");
|
|
||||||
if (luaCommand == null)
|
|
||||||
luaCommand = "lua";
|
|
||||||
String[] args = new String[] { luaCommand, "-", platform.toString() };
|
|
||||||
return collectProcessOutput(args, script);
|
|
||||||
} finally {
|
|
||||||
script.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String collectProcessOutput(String[] cmd, final InputStream input)
|
|
||||||
throws IOException, InterruptedException {
|
|
||||||
Runtime r = Runtime.getRuntime();
|
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
new JseProcess(cmd, input, baos, System.err).waitFor();
|
|
||||||
return new String(baos.toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String readString(InputStream is) throws IOException {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
copy(is, baos);
|
|
||||||
return new String(baos.toByteArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void copy(InputStream is, OutputStream os) throws IOException {
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int r;
|
|
||||||
while ( (r = is.read(buf)) >= 0 ) {
|
|
||||||
os.write(buf, 0, r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package org.luaj;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Framework to add regression tests as problem areas are found.
|
|
||||||
*
|
|
||||||
* To add a new regression test: 1) run "unpack.sh" in the project root 2) add a
|
|
||||||
* new "lua" file in the "regressions" subdirectory 3) run "repack.sh" in the
|
|
||||||
* project root 4) add a line to the source file naming the new test
|
|
||||||
*
|
|
||||||
* After adding a test, check in the zip file rather than the individual
|
|
||||||
* regression test files.
|
|
||||||
*
|
|
||||||
* @author jrosebor
|
|
||||||
*/
|
|
||||||
class RegressionsTest extends CompilingTestCase {
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
@Override
|
|
||||||
protected void setUp() {
|
|
||||||
setBaseDir("regressions");
|
|
||||||
super.setUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testModulo() { doTest("modulo"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testConstruct() { doTest("construct"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testBigAttrs() { doTest("bigattr"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testControlChars() { doTest("controlchars"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testComparators() { doTest("comparators"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMathRandomseed() { doTest("mathrandomseed"); }
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testVarargs() { doTest("varargs"); }
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package org.luaj;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.luaj.vm2.Globals;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
|
|
||||||
abstract class ResourcesTestCase {
|
|
||||||
|
|
||||||
private String baseDir;
|
|
||||||
|
|
||||||
protected Globals globals;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() {
|
|
||||||
globals = JsePlatform.standardGlobals();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setBaseDir(String baseDir) { this.baseDir = baseDir; }
|
|
||||||
|
|
||||||
protected InputStream inputStreamOfFile(String file) throws IOException {
|
|
||||||
return getClass().getClassLoader().getResourceAsStream(baseDir + "/" + file);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected InputStream inputStreamOfLua(String name) throws IOException {
|
|
||||||
return inputStreamOfFile(name + ".lua");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected InputStream inputStreamOfResult(String name) throws IOException {
|
|
||||||
return inputStreamOfFile(name + ".out");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected InputStream inputStreamOfBytecode(String name) throws IOException {
|
|
||||||
return inputStreamOfFile(name + ".lc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
package org.luaj.math;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.luaj.vm2.LuaError;
|
|
||||||
import org.luaj.vm2.LuaValue;
|
|
||||||
import org.luaj.vm2.lib.jme.JmePlatform;
|
|
||||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
|
||||||
|
|
||||||
class MathLibComparisonTest {
|
|
||||||
|
|
||||||
private LuaValue j2se;
|
|
||||||
private LuaValue j2me;
|
|
||||||
private boolean supportedOnJ2me;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
protected void setUp() {
|
|
||||||
j2se = JsePlatform.standardGlobals().get("math");
|
|
||||||
j2me = JmePlatform.standardGlobals().get("math");
|
|
||||||
supportedOnJ2me = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMathDPow() {
|
|
||||||
assertEquals(1, j2mepow(2, 0), 0);
|
|
||||||
assertEquals(2, j2mepow(2, 1), 0);
|
|
||||||
assertEquals(8, j2mepow(2, 3), 0);
|
|
||||||
assertEquals(-8, j2mepow(-2, 3), 0);
|
|
||||||
assertEquals(1/8., j2mepow(2, -3), 0);
|
|
||||||
assertEquals(-1/8., j2mepow(-2, -3), 0);
|
|
||||||
assertEquals(16, j2mepow(256, .5), 0);
|
|
||||||
assertEquals(4, j2mepow(256, .25), 0);
|
|
||||||
assertEquals(64, j2mepow(256, .75), 0);
|
|
||||||
assertEquals(1./16, j2mepow(256, -.5), 0);
|
|
||||||
assertEquals(1./4, j2mepow(256, -.25), 0);
|
|
||||||
assertEquals(1./64, j2mepow(256, -.75), 0);
|
|
||||||
assertEquals(Double.NaN, j2mepow(-256, .5), 0);
|
|
||||||
assertEquals(1, j2mepow(.5, 0), 0);
|
|
||||||
assertEquals(.5, j2mepow(.5, 1), 0);
|
|
||||||
assertEquals(.125, j2mepow(.5, 3), 0);
|
|
||||||
assertEquals(2, j2mepow(.5, -1), 0);
|
|
||||||
assertEquals(8, j2mepow(.5, -3), 0);
|
|
||||||
assertEquals(1, j2mepow(0.0625, 0), 0);
|
|
||||||
assertEquals(0.00048828125, j2mepow(0.0625, 2.75), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private double j2mepow(double x, double y) {
|
|
||||||
return j2me.get("pow").call(LuaValue.valueOf(x), LuaValue.valueOf(y)).todouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAbs() {
|
|
||||||
tryMathOp("abs", 23.45);
|
|
||||||
tryMathOp("abs", -23.45);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCos() {
|
|
||||||
tryTrigOps("cos");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCosh() {
|
|
||||||
supportedOnJ2me = false;
|
|
||||||
tryTrigOps("cosh");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testDeg() {
|
|
||||||
tryTrigOps("deg");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testExp() {
|
|
||||||
tryMathOp("exp", 0);
|
|
||||||
tryMathOp("exp", 0.1);
|
|
||||||
tryMathOp("exp", .9);
|
|
||||||
tryMathOp("exp", 1.);
|
|
||||||
tryMathOp("exp", 9);
|
|
||||||
tryMathOp("exp", -.1);
|
|
||||||
tryMathOp("exp", -.9);
|
|
||||||
tryMathOp("exp", -1.);
|
|
||||||
tryMathOp("exp", -9);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLog() {
|
|
||||||
supportedOnJ2me = false;
|
|
||||||
tryMathOp("log", 0.1);
|
|
||||||
tryMathOp("log", .9);
|
|
||||||
tryMathOp("log", 1.);
|
|
||||||
tryMathOp("log", 9);
|
|
||||||
tryMathOp("log", -.1);
|
|
||||||
tryMathOp("log", -.9);
|
|
||||||
tryMathOp("log", -1.);
|
|
||||||
tryMathOp("log", -9);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRad() {
|
|
||||||
tryMathOp("rad", 0);
|
|
||||||
tryMathOp("rad", 0.1);
|
|
||||||
tryMathOp("rad", .9);
|
|
||||||
tryMathOp("rad", 1.);
|
|
||||||
tryMathOp("rad", 9);
|
|
||||||
tryMathOp("rad", 10);
|
|
||||||
tryMathOp("rad", 100);
|
|
||||||
tryMathOp("rad", -.1);
|
|
||||||
tryMathOp("rad", -.9);
|
|
||||||
tryMathOp("rad", -1.);
|
|
||||||
tryMathOp("rad", -9);
|
|
||||||
tryMathOp("rad", -10);
|
|
||||||
tryMathOp("rad", -100);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSin() {
|
|
||||||
tryTrigOps("sin");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSinh() {
|
|
||||||
supportedOnJ2me = false;
|
|
||||||
tryTrigOps("sinh");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSqrt() {
|
|
||||||
tryMathOp("sqrt", 0);
|
|
||||||
tryMathOp("sqrt", 0.1);
|
|
||||||
tryMathOp("sqrt", .9);
|
|
||||||
tryMathOp("sqrt", 1.);
|
|
||||||
tryMathOp("sqrt", 9);
|
|
||||||
tryMathOp("sqrt", 10);
|
|
||||||
tryMathOp("sqrt", 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testTan() {
|
|
||||||
tryTrigOps("tan");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testTanh() {
|
|
||||||
supportedOnJ2me = false;
|
|
||||||
tryTrigOps("tanh");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAtan2() {
|
|
||||||
supportedOnJ2me = false;
|
|
||||||
tryDoubleOps("atan2", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testFmod() {
|
|
||||||
tryDoubleOps("fmod", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testPow() {
|
|
||||||
tryDoubleOps("pow", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryDoubleOps(String op, boolean positiveOnly) {
|
|
||||||
// y>0, x>0
|
|
||||||
tryMathOp(op, 0.1, 4.0);
|
|
||||||
tryMathOp(op, .9, 4.0);
|
|
||||||
tryMathOp(op, 1., 4.0);
|
|
||||||
tryMathOp(op, 9, 4.0);
|
|
||||||
tryMathOp(op, 10, 4.0);
|
|
||||||
tryMathOp(op, 100, 4.0);
|
|
||||||
|
|
||||||
// y>0, x<0
|
|
||||||
tryMathOp(op, 0.1, -4.0);
|
|
||||||
tryMathOp(op, .9, -4.0);
|
|
||||||
tryMathOp(op, 1., -4.0);
|
|
||||||
tryMathOp(op, 9, -4.0);
|
|
||||||
tryMathOp(op, 10, -4.0);
|
|
||||||
tryMathOp(op, 100, -4.0);
|
|
||||||
|
|
||||||
if (!positiveOnly) {
|
|
||||||
// y<0, x>0
|
|
||||||
tryMathOp(op, -0.1, 4.0);
|
|
||||||
tryMathOp(op, -.9, 4.0);
|
|
||||||
tryMathOp(op, -1., 4.0);
|
|
||||||
tryMathOp(op, -9, 4.0);
|
|
||||||
tryMathOp(op, -10, 4.0);
|
|
||||||
tryMathOp(op, -100, 4.0);
|
|
||||||
|
|
||||||
// y<0, x<0
|
|
||||||
tryMathOp(op, -0.1, -4.0);
|
|
||||||
tryMathOp(op, -.9, -4.0);
|
|
||||||
tryMathOp(op, -1., -4.0);
|
|
||||||
tryMathOp(op, -9, -4.0);
|
|
||||||
tryMathOp(op, -10, -4.0);
|
|
||||||
tryMathOp(op, -100, -4.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// degenerate cases
|
|
||||||
tryMathOp(op, 0, 1);
|
|
||||||
tryMathOp(op, 1, 0);
|
|
||||||
tryMathOp(op, -1, 0);
|
|
||||||
tryMathOp(op, 0, -1);
|
|
||||||
tryMathOp(op, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryTrigOps(String op) {
|
|
||||||
tryMathOp(op, 0);
|
|
||||||
tryMathOp(op, Math.PI/8);
|
|
||||||
tryMathOp(op, Math.PI*7/8);
|
|
||||||
tryMathOp(op, Math.PI*8/8);
|
|
||||||
tryMathOp(op, Math.PI*9/8);
|
|
||||||
tryMathOp(op, -Math.PI/8);
|
|
||||||
tryMathOp(op, -Math.PI*7/8);
|
|
||||||
tryMathOp(op, -Math.PI*8/8);
|
|
||||||
tryMathOp(op, -Math.PI*9/8);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryMathOp(String op, double x) {
|
|
||||||
try {
|
|
||||||
double expected = j2se.get(op).call(LuaValue.valueOf(x)).todouble();
|
|
||||||
double actual = j2me.get(op).call(LuaValue.valueOf(x)).todouble();
|
|
||||||
if (supportedOnJ2me)
|
|
||||||
assertEquals(expected, actual, 1.e-4);
|
|
||||||
else
|
|
||||||
fail("j2me should throw exception for math." + op + " but returned " + actual);
|
|
||||||
} catch (LuaError lee) {
|
|
||||||
if (supportedOnJ2me)
|
|
||||||
throw lee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tryMathOp(String op, double a, double b) {
|
|
||||||
try {
|
|
||||||
double expected = j2se.get(op).call(LuaValue.valueOf(a), LuaValue.valueOf(b)).todouble();
|
|
||||||
double actual = j2me.get(op).call(LuaValue.valueOf(a), LuaValue.valueOf(b)).todouble();
|
|
||||||
if (supportedOnJ2me)
|
|
||||||
assertEquals(expected, actual, 1.e-5);
|
|
||||||
else
|
|
||||||
fail("j2me should throw exception for math." + op + " but returned " + actual);
|
|
||||||
} catch (LuaError lee) {
|
|
||||||
if (supportedOnJ2me)
|
|
||||||
throw lee;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,279 +0,0 @@
|
|||||||
|
|
||||||
-- tostring replacement that assigns ids
|
|
||||||
local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'}
|
|
||||||
tostring = function(x)
|
|
||||||
if not x or not types[type(x)] then return ts(x) end
|
|
||||||
if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end
|
|
||||||
return id[x]
|
|
||||||
end
|
|
||||||
|
|
||||||
-- wrap pcall to return one result
|
|
||||||
-- error message are tested elsewhere
|
|
||||||
local pc = pcall
|
|
||||||
local pcall = function(...)
|
|
||||||
local s,e = pc(...)
|
|
||||||
if s then return e end
|
|
||||||
return false, type(e)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- print
|
|
||||||
print()
|
|
||||||
print(11)
|
|
||||||
print("abc",123,nil,"pqr")
|
|
||||||
print( nil and 'T' or 'F' )
|
|
||||||
print( false and 'T' or 'F' )
|
|
||||||
print( 0 and 'T' or 'F' )
|
|
||||||
|
|
||||||
-- assert
|
|
||||||
print( 'assert(true)', assert(true) )
|
|
||||||
print( 'pcall(assert,true)', pcall(assert,true) )
|
|
||||||
print( 'pcall(assert,false)', pcall(assert,false) )
|
|
||||||
print( 'pcall(assert,nil)', pcall(assert,nil) )
|
|
||||||
print( 'pcall(assert,true,"msg")', pcall(assert,true,"msg") )
|
|
||||||
print( 'pcall(assert,false,"msg")', pcall(assert,false,"msg") )
|
|
||||||
print( 'pcall(assert,nil,"msg")', pcall(assert,nil,"msg") )
|
|
||||||
print( 'pcall(assert,false,"msg","msg2")', pcall(assert,false,"msg","msg2") )
|
|
||||||
|
|
||||||
-- collectgarbage (not supported)
|
|
||||||
print( 'collectgarbage("count")', type(collectgarbage("count")))
|
|
||||||
print( 'collectgarbage("collect")', type(collectgarbage("collect")))
|
|
||||||
print( 'collectgarbage("count")', type(collectgarbage("count")))
|
|
||||||
|
|
||||||
-- dofile (not supported)
|
|
||||||
-- ipairs
|
|
||||||
print( 'pcall(ipairs)', pcall(ipairs) )
|
|
||||||
print( 'pcall(ipairs,nil)', pcall(ipairs,nil) )
|
|
||||||
print( 'pcall(ipairs,"a")', pcall(ipairs,"a") )
|
|
||||||
print( 'pcall(ipairs,1)', pcall(ipairs,1) )
|
|
||||||
for k,v in ipairs({}) do print('ipairs1',k,v)end
|
|
||||||
for k,v in ipairs({'one','two'}) do print('ipairs2',k,v)end
|
|
||||||
for k,v in ipairs({aa='aaa',bb='bbb'}) do print('ipairs3',k,v)end
|
|
||||||
for k,v in ipairs({aa='aaa',bb='bbb','one','two'}) do print('ipairs4',k,v)end
|
|
||||||
for k,v in ipairs({[30]='30',[20]='20'}) do print('ipairs5',k,v)end
|
|
||||||
|
|
||||||
-- load
|
|
||||||
-- FIXME after empty string is printed which it shouldmt
|
|
||||||
-- t = { "print ", "'table ", "loaded'", "", " print'after empty string'" }
|
|
||||||
-- i = 0
|
|
||||||
-- f = function() i = i + 1; return t[i]; end
|
|
||||||
-- c,e = load(f)
|
|
||||||
-- if c then print('load: ', pcall(c)) else print('load failed:', e) end
|
|
||||||
|
|
||||||
-- loadfile
|
|
||||||
-- load
|
|
||||||
local lst = "print(3+4); return 8"
|
|
||||||
local chunk, err = load( lst )
|
|
||||||
print( 'load("'..lst..'")', chunk, err )
|
|
||||||
print( 'load("'..lst..'")()', chunk() )
|
|
||||||
|
|
||||||
-- pairs
|
|
||||||
print( 'pcall(pairs)', pcall(pairs) )
|
|
||||||
print( 'pcall(pairs,nil)', pcall(pairs,nil) )
|
|
||||||
print( 'pcall(pairs,"a")', pcall(pairs,"a") )
|
|
||||||
print( 'pcall(pairs,1)', pcall(pairs,1) )
|
|
||||||
for k,v in pairs({}) do print('pairs1',k,v)end
|
|
||||||
for k,v in pairs({'one','two'}) do print('pairs2',k,v)end
|
|
||||||
for k,v in pairs({aa='aaa'}) do print('pairs3',k,v)end
|
|
||||||
for k,v in pairs({aa='aaa','one','two'}) do print('pairs4',k,v)end
|
|
||||||
for k,v in pairs({[20]='30',[30]='20'}) do print('pairs5',k,v)end
|
|
||||||
|
|
||||||
-- _G
|
|
||||||
print( '_G["abc"] (before)', _G["abc"] )
|
|
||||||
abc='def'
|
|
||||||
print( '_G["abc"] (after)', _G["abc"] )
|
|
||||||
|
|
||||||
-- type
|
|
||||||
print( 'type(nil)', type(nil) )
|
|
||||||
print( 'type("a")', type("a") )
|
|
||||||
print( 'type(1)', type(1) )
|
|
||||||
print( 'type(1.5)', type(1.5) )
|
|
||||||
print( 'type(function() end)', type(function() end) )
|
|
||||||
print( 'type({})', type({}) )
|
|
||||||
print( 'type(true)', type(true) )
|
|
||||||
print( 'type(false)', type(false) )
|
|
||||||
print( 'pcall(type,type)', pcall(type,type) )
|
|
||||||
print( 'pcall(type)', pcall(type) )
|
|
||||||
print( '(function() return pcall(type) end)()', (function() return pcall(type) end)() )
|
|
||||||
local function la() return pcall(type) end
|
|
||||||
print( 'la()', la() )
|
|
||||||
function ga() return pcall(type) end
|
|
||||||
print( 'ga()', ga() )
|
|
||||||
|
|
||||||
-- getmetatable, setmetatable
|
|
||||||
ta = { aa1="aaa1", aa2="aaa2" }
|
|
||||||
tb = { bb1="bbb1", bb2="bbb2" }
|
|
||||||
print( 'getmetatable(ta)', getmetatable(ta) )
|
|
||||||
print( 'getmetatable(tb)', getmetatable(tb) )
|
|
||||||
print( 'setmetatable(ta),{cc1="ccc1"}', type( setmetatable(ta,{cc1="ccc1"}) ) )
|
|
||||||
print( 'setmetatable(tb),{dd1="ddd1"}', type( setmetatable(tb,{dd1="ddd1"}) ) )
|
|
||||||
print( 'getmetatable(ta)["cc1"]', getmetatable(ta)["cc1"] )
|
|
||||||
print( 'getmetatable(tb)["dd1"]', getmetatable(tb)["dd1"] )
|
|
||||||
print( 'getmetatable(1)', getmetatable(1) )
|
|
||||||
print( 'pcall(setmetatable,1)', pcall(setmetatable,1) )
|
|
||||||
print( 'pcall(setmetatable,nil)', pcall(setmetatable,nil) )
|
|
||||||
print( 'pcall(setmetatable,"ABC")', pcall(setmetatable,"ABC") )
|
|
||||||
print( 'pcall(setmetatable,function() end)', pcall(setmetatable,function() end) )
|
|
||||||
|
|
||||||
-- rawget,rawset
|
|
||||||
local mt = {aa="aaa", bb="bbb"}
|
|
||||||
mt.__index = mt
|
|
||||||
mt.__newindex = mt
|
|
||||||
local s = {cc="ccc", dd="ddd", }
|
|
||||||
local t = {cc="ccc", dd="ddd"}
|
|
||||||
setmetatable(t,mt)
|
|
||||||
print( 'pcall(rawget)', pcall(rawget))
|
|
||||||
print( 'pcall(rawget,"a")', pcall(rawget,"a"))
|
|
||||||
print( 'pcall(rawget,s)', pcall(rawget,s))
|
|
||||||
print( 'pcall(rawget,t)', pcall(rawget,t))
|
|
||||||
|
|
||||||
function printtables()
|
|
||||||
function printtable(name,t)
|
|
||||||
print( ' '..name, t["aa"], t["bb"], t["cc"], t["dd"], t["ee"], t["ff"], t["gg"] )
|
|
||||||
print( ' '..name,
|
|
||||||
rawget(t,"aa"),
|
|
||||||
rawget(t,"bb"),
|
|
||||||
rawget(t,"cc"),
|
|
||||||
rawget(t,"dd"),
|
|
||||||
rawget(t,"ee"),
|
|
||||||
rawget(t,"ff"),
|
|
||||||
rawget(t,"gg") )
|
|
||||||
end
|
|
||||||
printtable( 's', s )
|
|
||||||
printtable( 't', t )
|
|
||||||
printtable( 'mt', mt )
|
|
||||||
end
|
|
||||||
printtables()
|
|
||||||
print( 'pcall(rawset,s,"aa","www")', rawset(s,"aa","www"))
|
|
||||||
printtables()
|
|
||||||
print( 'pcall(rawset,s,"cc","xxx")', rawset(s,"cc","xxx"))
|
|
||||||
printtables()
|
|
||||||
print( 'pcall(rawset,t,"aa","yyy")', rawset(t,"aa","yyy"))
|
|
||||||
printtables()
|
|
||||||
print( 'pcall(rawset,t,"dd","zzz")', rawset(t,"dd","zzz"))
|
|
||||||
printtables()
|
|
||||||
|
|
||||||
-- rawlen
|
|
||||||
print( 'pcall(rawlen, {})', pcall(rawlen, {}))
|
|
||||||
print( 'pcall(rawlen, {"a"})', pcall(rawlen, {'a'}))
|
|
||||||
print( 'pcall(rawlen, {"a","b"})', pcall(rawlen, {'a','b'}))
|
|
||||||
print( 'pcall(rawlen, "")', pcall(rawlen, ""))
|
|
||||||
print( 'pcall(rawlen, "a")', pcall(rawlen, 'a'))
|
|
||||||
print( 'pcall(rawlen, "ab")', pcall(rawlen, 'ab'))
|
|
||||||
print( 'pcall(rawlen, 1)', pcall(rawlen, 1))
|
|
||||||
print( 'pcall(rawlen, nil)', pcall(rawlen, nil))
|
|
||||||
print( 'pcall(rawlen)', pcall(rawlen))
|
|
||||||
|
|
||||||
printtables()
|
|
||||||
print( 's["ee"]="ppp"' ); s["ee"]="ppp"
|
|
||||||
printtables()
|
|
||||||
print( 's["cc"]="qqq"' ); s["cc"]="qqq"
|
|
||||||
printtables()
|
|
||||||
print( 't["ff"]="rrr"' ); t["ff"]="rrr"
|
|
||||||
printtables()
|
|
||||||
print( 't["dd"]="sss"' ); t["dd"]="sss"
|
|
||||||
printtables()
|
|
||||||
print( 'mt["gg"]="ttt"' ); mt["gg"]="ttt"
|
|
||||||
printtables()
|
|
||||||
|
|
||||||
|
|
||||||
-- select
|
|
||||||
print( 'pcall(select)', pcall(select) )
|
|
||||||
print( 'select(1,11,22,33,44,55)', select(1,11,22,33,44,55) )
|
|
||||||
print( 'select(2,11,22,33,44,55)', select(2,11,22,33,44,55) )
|
|
||||||
print( 'select(3,11,22,33,44,55)', select(3,11,22,33,44,55) )
|
|
||||||
print( 'select(4,11,22,33,44,55)', select(4,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,5,11,22,33,44,55)', pcall(select,5,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,6,11,22,33,44,55)', pcall(select,6,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,7,11,22,33,44,55)', pcall(select,7,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,0,11,22,33,44,55)', pcall(select,0,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,-1,11,22,33,44,55)', pcall(select,-1,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,-2,11,22,33,44,55)', pcall(select,-2,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,-4,11,22,33,44,55)', pcall(select,-4,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,-5,11,22,33,44,55)', pcall(select,-5,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,-6,11,22,33,44,55)', pcall(select,-6,11,22,33,44,55) )
|
|
||||||
print( 'pcall(select,1)', pcall(select,1) )
|
|
||||||
print( 'pcall(select,select)', pcall(select,select) )
|
|
||||||
print( 'pcall(select,{})', pcall(select,{}) )
|
|
||||||
print( 'pcall(select,"2",11,22,33)', pcall(select,"2",11,22,33) )
|
|
||||||
print( 'pcall(select,"abc",11,22,33)', pcall(select,"abc",11,22,33) )
|
|
||||||
|
|
||||||
|
|
||||||
-- tonumber
|
|
||||||
print( 'pcall(tonumber)', pcall(tostring) )
|
|
||||||
print( 'pcall(tonumber,nil)', pcall(tonumber,nil) )
|
|
||||||
print( 'pcall(tonumber,"abc")', pcall(tonumber,"abc") )
|
|
||||||
print( 'pcall(tonumber,"123")', pcall(tonumber,"123") )
|
|
||||||
print( 'pcall(tonumber,"123",10)', pcall(tonumber,"123", 10) )
|
|
||||||
print( 'pcall(tonumber,"123",8)', pcall(tonumber,"123", 8) )
|
|
||||||
print( 'pcall(tonumber,"123",6)', pcall(tonumber,"123", 6) )
|
|
||||||
print( 'pcall(tonumber,"10101",4)', pcall(tonumber,"10101", 4) )
|
|
||||||
print( 'pcall(tonumber,"10101",3)', pcall(tonumber,"10101", 3) )
|
|
||||||
print( 'pcall(tonumber,"10101",2)', pcall(tonumber,"10101", 2) )
|
|
||||||
print( 'pcall(tonumber,"1a1",16)', pcall(tonumber,"1a1", 16) )
|
|
||||||
print( 'pcall(tonumber,"1a1",32)', pcall(tonumber,"1a1", 32) )
|
|
||||||
print( 'pcall(tonumber,"1a1",54)', pcall(tonumber,"1a1", 54) )
|
|
||||||
print( 'pcall(tonumber,"1a1",1)', pcall(tonumber,"1a1", 1) )
|
|
||||||
print( 'pcall(tonumber,"1a1",0)', pcall(tonumber,"1a1", 0) )
|
|
||||||
print( 'pcall(tonumber,"1a1",-1)', pcall(tonumber,"1a1", -1) )
|
|
||||||
print( 'pcall(tonumber,"1a1","32")', pcall(tonumber,"1a1", "32") )
|
|
||||||
print( 'pcall(tonumber,"123","456")', pcall(tonumber,"123","456") )
|
|
||||||
print( 'pcall(tonumber,"1a1",10)', pcall(tonumber,"1a1", 10) )
|
|
||||||
print( 'pcall(tonumber,"151",4)', pcall(tonumber,"151", 4) )
|
|
||||||
print( 'pcall(tonumber,"151",3)', pcall(tonumber,"151", 3) )
|
|
||||||
print( 'pcall(tonumber,"151",2)', pcall(tonumber,"151", 2) )
|
|
||||||
print( 'pcall(tonumber,"123",8,8)', pcall(tonumber,"123", 8, 8) )
|
|
||||||
print( 'pcall(tonumber,123)', pcall(tonumber,123) )
|
|
||||||
print( 'pcall(tonumber,true)', pcall(tonumber,true) )
|
|
||||||
print( 'pcall(tonumber,false)', pcall(tonumber,false) )
|
|
||||||
print( 'pcall(tonumber,tonumber)', pcall(tonumber,tonumber) )
|
|
||||||
print( 'pcall(tonumber,function() end)', pcall(tonumber,function() end) )
|
|
||||||
print( 'pcall(tonumber,{"one","two",a="aa",b="bb"})', pcall(tonumber,{"one","two",a="aa",b="bb"}) )
|
|
||||||
print( 'pcall(tonumber,"123.456")', pcall(tonumber,"123.456") )
|
|
||||||
print( 'pcall(tonumber," 123.456")', pcall(tonumber," 123.456") )
|
|
||||||
print( 'pcall(tonumber," 234qwer")', pcall(tonumber," 234qwer") )
|
|
||||||
print( 'pcall(tonumber,"0x20")', pcall(tonumber,"0x20") )
|
|
||||||
print( 'pcall(tonumber," 0x20")', pcall(tonumber," 0x20") )
|
|
||||||
print( 'pcall(tonumber,"0x20 ")', pcall(tonumber,"0x20 ") )
|
|
||||||
print( 'pcall(tonumber," 0x20 ")', pcall(tonumber," 0x20 ") )
|
|
||||||
print( 'pcall(tonumber,"0X20")', pcall(tonumber,"0X20") )
|
|
||||||
print( 'pcall(tonumber," 0X20")', pcall(tonumber," 0X20") )
|
|
||||||
print( 'pcall(tonumber,"0X20 ")', pcall(tonumber,"0X20 ") )
|
|
||||||
print( 'pcall(tonumber," 0X20 ")', pcall(tonumber," 0X20 ") )
|
|
||||||
print( 'pcall(tonumber,"0x20",10)', pcall(tonumber,"0x20",10) )
|
|
||||||
print( 'pcall(tonumber,"0x20",16)', pcall(tonumber,"0x20",16) )
|
|
||||||
print( 'pcall(tonumber,"0x20",8)', pcall(tonumber,"0x20",8) )
|
|
||||||
|
|
||||||
-- tostring
|
|
||||||
print( 'pcall(tostring)', pcall(tostring) )
|
|
||||||
print( 'pcall(tostring,nil)', pcall(tostring,nil) )
|
|
||||||
print( 'pcall(tostring,"abc")', pcall(tostring,"abc") )
|
|
||||||
print( 'pcall(tostring,"abc","def")', pcall(tostring,"abc","def") )
|
|
||||||
print( 'pcall(tostring,123)', pcall(tostring,123) )
|
|
||||||
print( 'pcall(tostring,true)', pcall(tostring,true) )
|
|
||||||
print( 'pcall(tostring,false)', pcall(tostring,false) )
|
|
||||||
print( 'tostring(tostring)', type(tostring(tostring)) )
|
|
||||||
print( 'tostring(function() end)', type(tostring(function() end)) )
|
|
||||||
print( 'tostring({"one","two",a="aa",b="bb"})', type(tostring({"one","two",a="aa",b="bb"})) )
|
|
||||||
|
|
||||||
-- _VERSION
|
|
||||||
print( '_VERSION', type(_VERSION) )
|
|
||||||
|
|
||||||
-- xpcall
|
|
||||||
local errfunc = function( detail )
|
|
||||||
print( ' in errfunc', type(detail) )
|
|
||||||
return 'response-from-xpcall'
|
|
||||||
end
|
|
||||||
local badfunc = function() error( 'error-from-badfunc' ) end
|
|
||||||
local wrappedbad = function() pcall( badfunc ) end
|
|
||||||
print( 'pcall(badfunc)', pcall(badfunc) )
|
|
||||||
print( 'pcall(badfunc,errfunc)', pcall(badfunc,errfunc) )
|
|
||||||
print( 'pcall(badfunc,badfunc)', pcall(badfunc,badfunc) )
|
|
||||||
print( 'pcall(wrappedbad)', pcall(wrappedbad) )
|
|
||||||
print( 'pcall(wrappedbad,errfunc)', pcall(wrappedbad,errfunc) )
|
|
||||||
print( 'pcall(xpcall(badfunc))', pcall(xpcall,badfunc) )
|
|
||||||
print( 'pcall(xpcall(badfunc,errfunc))', pcall(xpcall,badfunc,errfunc) )
|
|
||||||
print( 'pcall(xpcall(badfunc,badfunc))', pcall(xpcall,badfunc,badfunc) )
|
|
||||||
print( 'pcall(xpcall(wrappedbad))', pcall(xpcall,wrappedbad) )
|
|
||||||
-- FIXME Shouldnt print errfunc
|
|
||||||
-- print( 'xpcall(wrappedbad,errfunc)', xpcall(wrappedbad,errfunc) )
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
for l in *.lua
|
|
||||||
do
|
|
||||||
echo $l
|
|
||||||
result=${l/\.lua/\.out}
|
|
||||||
lua $l > jse/$result
|
|
||||||
lua $l 'JME' > jme/$result
|
|
||||||
luajit $l > luajit/$result
|
|
||||||
done
|
|
||||||
|
|
||||||
# TODO Test is currently disabled
|
|
||||||
rm luajit/debuglib.out
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
local platform = ...
|
|
||||||
--print( 'platform', platform )
|
|
||||||
|
|
||||||
-- simple io-library tests
|
|
||||||
--
|
|
||||||
-- C version on Windows will add change \n into \r\n for text files at least
|
|
||||||
--
|
|
||||||
local tostr,files,nfiles = tostring,{},0
|
|
||||||
tostring = function(x)
|
|
||||||
local s = tostr(x)
|
|
||||||
if s:sub(1,4) ~= 'file' then return s end
|
|
||||||
if files[s] then return files[s] end
|
|
||||||
files[s] = 'file.'..nfiles
|
|
||||||
nfiles = nfiles + 1
|
|
||||||
return files[s]
|
|
||||||
end
|
|
||||||
print( io ~= nil )
|
|
||||||
print( io.open ~= nil )
|
|
||||||
print( io.stdin ~= nil )
|
|
||||||
print( io.stdout ~= nil )
|
|
||||||
print( io.stderr ~= nil )
|
|
||||||
print( 'write', io.write() )
|
|
||||||
print( 'write', io.write("This") )
|
|
||||||
print( 'write', io.write(" is a pen.") )
|
|
||||||
print( 'flush', io.flush() )
|
|
||||||
|
|
||||||
local f = io.open("abc.txt","w")
|
|
||||||
print( 'f', type(f) )
|
|
||||||
print( io.type(f) )
|
|
||||||
print( 'write', f:write("abcdef 12345 \t\t 678910 more\aaaaaaa\bbbbthe rest") )
|
|
||||||
print( 'type(f)', io.type(f) )
|
|
||||||
print( 'close', f:close() )
|
|
||||||
print( 'type(f)', io.type(f) )
|
|
||||||
print( 'type("f")', io.type("f") )
|
|
||||||
|
|
||||||
local g = io.open("abc.txt","r")
|
|
||||||
local t = { g:read(3, 3, "*n", "*n", "*l", "*l", "*a") }
|
|
||||||
for i,v in ipairs(t) do
|
|
||||||
print( string.format("%q",tostring(v)), type(v))
|
|
||||||
print( '----- ', i )
|
|
||||||
end
|
|
||||||
|
|
||||||
local h,s = io.open("abc.txt", "a")
|
|
||||||
print( 'h', io.type(h), string.sub(tostring(h),1,6), s )
|
|
||||||
print( 'write', h:write('and more and more and more text.') )
|
|
||||||
print( 'close', h:close() )
|
|
||||||
|
|
||||||
if platform ~= 'JME' then
|
|
||||||
local j = io.open( "abc.txt", "r" )
|
|
||||||
print( 'j', io.type(j) )
|
|
||||||
print( 'seek', j:seek("set", 3) )
|
|
||||||
print( 'read', j:read(4), j:read(3) )
|
|
||||||
print( 'seek', j:seek("set", 2) )
|
|
||||||
print( 'read', j:read(4), j:read(3) )
|
|
||||||
print( 'seek', j:seek("cur", -8 ) )
|
|
||||||
print( 'read', j:read(4), j:read(3) )
|
|
||||||
print( 'seek(cur,0)', j:seek("cur",0) )
|
|
||||||
print( 'seek(cur,20)', j:seek("cur",20) )
|
|
||||||
print( 'seek(end,-5)', j:seek("end", -5) )
|
|
||||||
print( 'read(4)', string.format("%q", tostring(j:read(4))) )
|
|
||||||
print( 'read(4)', string.format("%q", tostring(j:read(4))) )
|
|
||||||
print( 'read(4)', string.format("%q", tostring(j:read(4))) )
|
|
||||||
print( 'close', j:close() )
|
|
||||||
end
|
|
||||||
|
|
||||||
-- write a few lines, including a non-terminating one
|
|
||||||
files = {}
|
|
||||||
f = io.open("abc.txt","w")
|
|
||||||
print( 'f.type', io.type(f) )
|
|
||||||
print( 'f', f )
|
|
||||||
print( 'write', f:write("line one\nline two\n\nafter blank line\nunterminated line") )
|
|
||||||
print( 'type(f)', io.type(f) )
|
|
||||||
print( 'close', f:close() )
|
|
||||||
files = {}
|
|
||||||
|
|
||||||
-- read using io.lines()
|
|
||||||
for l in io.lines("abc.txt") do
|
|
||||||
print( string.format('%q',l) )
|
|
||||||
end
|
|
||||||
io.input("abc.txt")
|
|
||||||
for l in io.lines() do
|
|
||||||
print( string.format('%q',l) )
|
|
||||||
end
|
|
||||||
io.input(io.open("abc.txt","r"))
|
|
||||||
for l in io.lines() do
|
|
||||||
print( string.format('%q',l) )
|
|
||||||
end
|
|
||||||
io.input("abc.txt")
|
|
||||||
io.input(io.input())
|
|
||||||
for l in io.lines() do
|
|
||||||
print( string.format('%q',l) )
|
|
||||||
end
|
|
||||||
|
|
||||||
local count = 0
|
|
||||||
io.tmpfile = function()
|
|
||||||
count = count + 1
|
|
||||||
return io.open("tmp"..count..".out","w")
|
|
||||||
end
|
|
||||||
|
|
||||||
local a = io.tmpfile()
|
|
||||||
local b = io.tmpfile()
|
|
||||||
print( io.type(a) )
|
|
||||||
print( io.type(b) )
|
|
||||||
print( "a:write", a:write('aaaaaaa') )
|
|
||||||
print( "b:write", b:write('bbbbbbb') )
|
|
||||||
print( "a:setvbuf", a:setvbuf("no") )
|
|
||||||
print( "a:setvbuf", a:setvbuf("full",1024) )
|
|
||||||
print( "a:setvbuf", a:setvbuf("line") )
|
|
||||||
print( "a:write", a:write('ccccc') )
|
|
||||||
print( "b:write", b:write('ddddd') )
|
|
||||||
print( "a:flush", a:flush() )
|
|
||||||
print( "b:flush", b:flush() )
|
|
||||||
|
|
||||||
--[[
|
|
||||||
print( "a:read", a:read(7) )
|
|
||||||
print( "b:read", b:read(7) )
|
|
||||||
print( "a:seek", a:seek("cur",-4) )
|
|
||||||
print( "b:seek", b:seek("cur",-4) )
|
|
||||||
print( "a:read", ( a:read(7) ) )
|
|
||||||
print( "b:read", ( b:read(7) ) )
|
|
||||||
print( "a:seek", a:seek("cur",-8) )
|
|
||||||
print( "b:seek", b:seek("cur",-8) )
|
|
||||||
print( "a:read", ( a:read(7) ) )
|
|
||||||
print( "b:read", ( b:read(7) ) )
|
|
||||||
--]]
|
|
||||||
|
|
||||||
local pcall = function(...)
|
|
||||||
local s,e = pcall(...)
|
|
||||||
if s then return s end
|
|
||||||
return s,e:match("closed")
|
|
||||||
end
|
|
||||||
|
|
||||||
b:close()
|
|
||||||
print( 'a:close', pcall( a.close, a ) )
|
|
||||||
print( 'a:write', pcall( a.write, a, 'eee') )
|
|
||||||
print( 'a:flush', pcall( a.flush, a) )
|
|
||||||
print( 'a:read', pcall( a.read, a, 5) )
|
|
||||||
print( 'a:lines', pcall( a.lines, a) )
|
|
||||||
print( 'a:seek', pcall( a.seek, a, "cur", -2) )
|
|
||||||
print( 'a:setvbuf', pcall( a.setvbuf, a, "no") )
|
|
||||||
print( 'a:close', pcall( a.close, a ) )
|
|
||||||
print( 'io.type(a)', pcall( io.type, a ) )
|
|
||||||
|
|
||||||
print( 'io.close()', pcall( io.close ) )
|
|
||||||
print( 'io.close(io.output())', pcall( io.close, io.output() ) )
|
|
||||||
|
|
||||||
io.output('abc.txt')
|
|
||||||
print( 'io.close()', pcall( io.close ) )
|
|
||||||
print( 'io.write', pcall( io.write, 'eee') )
|
|
||||||
print( 'io.flush', pcall( io.flush) )
|
|
||||||
-- FIXME closing a closed file leads to a segfault in luajit
|
|
||||||
-- print( 'io.close', pcall( io.close ) )
|
|
||||||
io.input('abc.txt'):close()
|
|
||||||
print( 'io.read', pcall( io.read, 5) )
|
|
||||||
print( 'io.lines', pcall( io.lines) )
|
|
||||||
|
|
||||||
os.remove('abc.txt')
|
|
||||||
for i=1,count do
|
|
||||||
os.remove('tmp'..i..'.out')
|
|
||||||
end
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
|
|
||||||
11
|
|
||||||
abc 123 nil pqr
|
|
||||||
F
|
|
||||||
F
|
|
||||||
T
|
|
||||||
assert(true) true
|
|
||||||
pcall(assert,true) true
|
|
||||||
pcall(assert,false) false string
|
|
||||||
pcall(assert,nil) false string
|
|
||||||
pcall(assert,true,"msg") true
|
|
||||||
pcall(assert,false,"msg") false string
|
|
||||||
pcall(assert,nil,"msg") false string
|
|
||||||
pcall(assert,false,"msg","msg2") false string
|
|
||||||
collectgarbage("count") number
|
|
||||||
collectgarbage("collect") number
|
|
||||||
collectgarbage("count") number
|
|
||||||
pcall(ipairs) false string
|
|
||||||
pcall(ipairs,nil) false string
|
|
||||||
pcall(ipairs,"a") false string
|
|
||||||
pcall(ipairs,1) false string
|
|
||||||
ipairs2 1 one
|
|
||||||
ipairs2 2 two
|
|
||||||
ipairs4 1 one
|
|
||||||
ipairs4 2 two
|
|
||||||
load("print(3+4); return 8") func.1 nil
|
|
||||||
7
|
|
||||||
load("print(3+4); return 8")() 8
|
|
||||||
pcall(pairs) false string
|
|
||||||
pcall(pairs,nil) false string
|
|
||||||
pcall(pairs,"a") false string
|
|
||||||
pcall(pairs,1) false string
|
|
||||||
pairs2 1 one
|
|
||||||
pairs2 2 two
|
|
||||||
pairs3 aa aaa
|
|
||||||
pairs4 1 one
|
|
||||||
pairs4 2 two
|
|
||||||
pairs4 aa aaa
|
|
||||||
pairs5 20 30
|
|
||||||
pairs5 30 20
|
|
||||||
_G["abc"] (before) nil
|
|
||||||
_G["abc"] (after) def
|
|
||||||
type(nil) nil
|
|
||||||
type("a") string
|
|
||||||
type(1) number
|
|
||||||
type(1.5) number
|
|
||||||
type(function() end) function
|
|
||||||
type({}) table
|
|
||||||
type(true) boolean
|
|
||||||
type(false) boolean
|
|
||||||
pcall(type,type) function
|
|
||||||
pcall(type) false string
|
|
||||||
(function() return pcall(type) end)() false string
|
|
||||||
la() false string
|
|
||||||
ga() false string
|
|
||||||
getmetatable(ta) nil
|
|
||||||
getmetatable(tb) nil
|
|
||||||
setmetatable(ta),{cc1="ccc1"} table
|
|
||||||
setmetatable(tb),{dd1="ddd1"} table
|
|
||||||
getmetatable(ta)["cc1"] ccc1
|
|
||||||
getmetatable(tb)["dd1"] ddd1
|
|
||||||
getmetatable(1) nil
|
|
||||||
pcall(setmetatable,1) false string
|
|
||||||
pcall(setmetatable,nil) false string
|
|
||||||
pcall(setmetatable,"ABC") false string
|
|
||||||
pcall(setmetatable,function() end) false string
|
|
||||||
pcall(rawget) false string
|
|
||||||
pcall(rawget,"a") false string
|
|
||||||
pcall(rawget,s) false string
|
|
||||||
pcall(rawget,t) false string
|
|
||||||
s nil nil ccc ddd nil nil nil
|
|
||||||
s nil nil ccc ddd nil nil nil
|
|
||||||
t aaa bbb ccc ddd nil nil nil
|
|
||||||
t nil nil ccc ddd nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
pcall(rawset,s,"aa","www") tbl.2
|
|
||||||
s www nil ccc ddd nil nil nil
|
|
||||||
s www nil ccc ddd nil nil nil
|
|
||||||
t aaa bbb ccc ddd nil nil nil
|
|
||||||
t nil nil ccc ddd nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
pcall(rawset,s,"cc","xxx") tbl.2
|
|
||||||
s www nil xxx ddd nil nil nil
|
|
||||||
s www nil xxx ddd nil nil nil
|
|
||||||
t aaa bbb ccc ddd nil nil nil
|
|
||||||
t nil nil ccc ddd nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
pcall(rawset,t,"aa","yyy") tbl.3
|
|
||||||
s www nil xxx ddd nil nil nil
|
|
||||||
s www nil xxx ddd nil nil nil
|
|
||||||
t yyy bbb ccc ddd nil nil nil
|
|
||||||
t yyy nil ccc ddd nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
pcall(rawset,t,"dd","zzz") tbl.3
|
|
||||||
s www nil xxx ddd nil nil nil
|
|
||||||
s www nil xxx ddd nil nil nil
|
|
||||||
t yyy bbb ccc zzz nil nil nil
|
|
||||||
t yyy nil ccc zzz nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
pcall(rawlen, {}) 0
|
|
||||||
pcall(rawlen, {"a"}) 1
|
|
||||||
pcall(rawlen, {"a","b"}) 2
|
|
||||||
pcall(rawlen, "") 0
|
|
||||||
pcall(rawlen, "a") 1
|
|
||||||
pcall(rawlen, "ab") 2
|
|
||||||
pcall(rawlen, 1) false string
|
|
||||||
pcall(rawlen, nil) false string
|
|
||||||
pcall(rawlen) false string
|
|
||||||
s www nil xxx ddd nil nil nil
|
|
||||||
s www nil xxx ddd nil nil nil
|
|
||||||
t yyy bbb ccc zzz nil nil nil
|
|
||||||
t yyy nil ccc zzz nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
s["ee"]="ppp"
|
|
||||||
s www nil xxx ddd ppp nil nil
|
|
||||||
s www nil xxx ddd ppp nil nil
|
|
||||||
t yyy bbb ccc zzz nil nil nil
|
|
||||||
t yyy nil ccc zzz nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
s["cc"]="qqq"
|
|
||||||
s www nil qqq ddd ppp nil nil
|
|
||||||
s www nil qqq ddd ppp nil nil
|
|
||||||
t yyy bbb ccc zzz nil nil nil
|
|
||||||
t yyy nil ccc zzz nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
mt aaa bbb nil nil nil nil nil
|
|
||||||
t["ff"]="rrr"
|
|
||||||
s www nil qqq ddd ppp nil nil
|
|
||||||
s www nil qqq ddd ppp nil nil
|
|
||||||
t yyy bbb ccc zzz nil rrr nil
|
|
||||||
t yyy nil ccc zzz nil nil nil
|
|
||||||
mt aaa bbb nil nil nil rrr nil
|
|
||||||
mt aaa bbb nil nil nil rrr nil
|
|
||||||
t["dd"]="sss"
|
|
||||||
s www nil qqq ddd ppp nil nil
|
|
||||||
s www nil qqq ddd ppp nil nil
|
|
||||||
t yyy bbb ccc sss nil rrr nil
|
|
||||||
t yyy nil ccc sss nil nil nil
|
|
||||||
mt aaa bbb nil nil nil rrr nil
|
|
||||||
mt aaa bbb nil nil nil rrr nil
|
|
||||||
mt["gg"]="ttt"
|
|
||||||
s www nil qqq ddd ppp nil nil
|
|
||||||
s www nil qqq ddd ppp nil nil
|
|
||||||
t yyy bbb ccc sss nil rrr ttt
|
|
||||||
t yyy nil ccc sss nil nil nil
|
|
||||||
mt aaa bbb nil nil nil rrr ttt
|
|
||||||
mt aaa bbb nil nil nil rrr ttt
|
|
||||||
pcall(select) false string
|
|
||||||
select(1,11,22,33,44,55) 11 22 33 44 55
|
|
||||||
select(2,11,22,33,44,55) 22 33 44 55
|
|
||||||
select(3,11,22,33,44,55) 33 44 55
|
|
||||||
select(4,11,22,33,44,55) 44 55
|
|
||||||
pcall(select,5,11,22,33,44,55) 55
|
|
||||||
pcall(select,6,11,22,33,44,55) nil
|
|
||||||
pcall(select,7,11,22,33,44,55) nil
|
|
||||||
pcall(select,0,11,22,33,44,55) false string
|
|
||||||
pcall(select,-1,11,22,33,44,55) 55
|
|
||||||
pcall(select,-2,11,22,33,44,55) 44
|
|
||||||
pcall(select,-4,11,22,33,44,55) 22
|
|
||||||
pcall(select,-5,11,22,33,44,55) 11
|
|
||||||
pcall(select,-6,11,22,33,44,55) false string
|
|
||||||
pcall(select,1) nil
|
|
||||||
pcall(select,select) false string
|
|
||||||
pcall(select,{}) false string
|
|
||||||
pcall(select,"2",11,22,33) 22
|
|
||||||
pcall(select,"abc",11,22,33) false string
|
|
||||||
pcall(tonumber) nil
|
|
||||||
pcall(tonumber,nil) nil
|
|
||||||
pcall(tonumber,"abc") nil
|
|
||||||
pcall(tonumber,"123") 123
|
|
||||||
pcall(tonumber,"123",10) 123
|
|
||||||
pcall(tonumber,"123",8) 83
|
|
||||||
pcall(tonumber,"123",6) 51
|
|
||||||
pcall(tonumber,"10101",4) 273
|
|
||||||
pcall(tonumber,"10101",3) 91
|
|
||||||
pcall(tonumber,"10101",2) 21
|
|
||||||
pcall(tonumber,"1a1",16) 417
|
|
||||||
pcall(tonumber,"1a1",32) 1345
|
|
||||||
pcall(tonumber,"1a1",54) false string
|
|
||||||
pcall(tonumber,"1a1",1) false string
|
|
||||||
pcall(tonumber,"1a1",0) false string
|
|
||||||
pcall(tonumber,"1a1",-1) false string
|
|
||||||
pcall(tonumber,"1a1","32") 1345
|
|
||||||
pcall(tonumber,"123","456") false string
|
|
||||||
pcall(tonumber,"1a1",10) nil
|
|
||||||
pcall(tonumber,"151",4) nil
|
|
||||||
pcall(tonumber,"151",3) nil
|
|
||||||
pcall(tonumber,"151",2) nil
|
|
||||||
pcall(tonumber,"123",8,8) 83
|
|
||||||
pcall(tonumber,123) 123
|
|
||||||
pcall(tonumber,true) nil
|
|
||||||
pcall(tonumber,false) nil
|
|
||||||
pcall(tonumber,tonumber) nil
|
|
||||||
pcall(tonumber,function() end) nil
|
|
||||||
pcall(tonumber,{"one","two",a="aa",b="bb"}) nil
|
|
||||||
pcall(tonumber,"123.456") 123.456
|
|
||||||
pcall(tonumber," 123.456") 123.456
|
|
||||||
pcall(tonumber," 234qwer") nil
|
|
||||||
pcall(tonumber,"0x20") 32
|
|
||||||
pcall(tonumber," 0x20") 32
|
|
||||||
pcall(tonumber,"0x20 ") 32
|
|
||||||
pcall(tonumber," 0x20 ") 32
|
|
||||||
pcall(tonumber,"0X20") 32
|
|
||||||
pcall(tonumber," 0X20") 32
|
|
||||||
pcall(tonumber,"0X20 ") 32
|
|
||||||
pcall(tonumber," 0X20 ") 32
|
|
||||||
pcall(tonumber,"0x20",10) nil
|
|
||||||
pcall(tonumber,"0x20",16) nil
|
|
||||||
pcall(tonumber,"0x20",8) nil
|
|
||||||
pcall(tostring) nil
|
|
||||||
pcall(tostring,nil) nil
|
|
||||||
pcall(tostring,"abc") abc
|
|
||||||
pcall(tostring,"abc","def") abc
|
|
||||||
pcall(tostring,123) 123
|
|
||||||
pcall(tostring,true) true
|
|
||||||
pcall(tostring,false) false
|
|
||||||
tostring(tostring) string
|
|
||||||
tostring(function() end) string
|
|
||||||
tostring({"one","two",a="aa",b="bb"}) string
|
|
||||||
_VERSION string
|
|
||||||
pcall(badfunc) false string
|
|
||||||
pcall(badfunc,errfunc) false string
|
|
||||||
pcall(badfunc,badfunc) false string
|
|
||||||
pcall(wrappedbad) nil
|
|
||||||
pcall(wrappedbad,errfunc) nil
|
|
||||||
pcall(xpcall(badfunc)) false string
|
|
||||||
in errfunc string
|
|
||||||
pcall(xpcall(badfunc,errfunc)) false
|
|
||||||
pcall(xpcall(badfunc,badfunc)) false
|
|
||||||
pcall(xpcall(wrappedbad)) false string
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
running is not nil
|
|
||||||
co.status suspended
|
|
||||||
co-body 1 10
|
|
||||||
foo 2
|
|
||||||
main true 4
|
|
||||||
co.status suspended
|
|
||||||
co-body r
|
|
||||||
main true 11 -9
|
|
||||||
co.status suspended
|
|
||||||
co-body x y
|
|
||||||
running is not nil
|
|
||||||
co.status.inside running
|
|
||||||
co.status.inside running
|
|
||||||
co.status.inside2 normal
|
|
||||||
main true 10 end
|
|
||||||
co.status dead
|
|
||||||
main false cannot resume dead coroutine
|
|
||||||
co.status dead
|
|
||||||
running is not nil
|
|
||||||
co.status suspended
|
|
||||||
co-body 1 10
|
|
||||||
foo 2
|
|
||||||
main true 4
|
|
||||||
co.status suspended
|
|
||||||
co-body nil nil
|
|
||||||
main true 11 -9
|
|
||||||
co.status suspended
|
|
||||||
co-body x y
|
|
||||||
main true 10 end
|
|
||||||
co.status dead
|
|
||||||
main false cannot resume dead coroutine
|
|
||||||
co.status dead
|
|
||||||
co-body 1 10
|
|
||||||
foo 2
|
|
||||||
g 4
|
|
||||||
co-body r
|
|
||||||
g 11 -9
|
|
||||||
co-body x y
|
|
||||||
g 10 end
|
|
||||||
g cannot resume dead coroutine
|
|
||||||
(main) sending args 111 222 333
|
|
||||||
(echocr) first args 111 222 333
|
|
||||||
(main) resume returns true 111 222 333
|
|
||||||
(main) sending args
|
|
||||||
(echoch) yield returns
|
|
||||||
(main) resume returns true
|
|
||||||
(main) sending args 111
|
|
||||||
(echoch) yield returns 111
|
|
||||||
(main) resume returns true 111
|
|
||||||
(main) sending args 111 222 333
|
|
||||||
(echoch) yield returns 111 222 333
|
|
||||||
(main) resume returns true 111 222 333
|
|
||||||
main-b suspended
|
|
||||||
main-c suspended
|
|
||||||
b-resumed main-arg-for-b true
|
|
||||||
b-b running
|
|
||||||
b-c suspended
|
|
||||||
b-resume-b false cannot resume non-suspended coroutine
|
|
||||||
c-resumed b-arg-for-c true
|
|
||||||
c-b normal
|
|
||||||
c-c running
|
|
||||||
c-resume-b false cannot resume non-suspended coroutine
|
|
||||||
c-resume-c false cannot resume non-suspended coroutine
|
|
||||||
b-resume-c true c-rslt
|
|
||||||
main-resume-b true b-rslt
|
|
||||||
c-resumed main-arg-for-c true
|
|
||||||
c-b suspended
|
|
||||||
c-c running
|
|
||||||
b-resumed b-arg-for-b true
|
|
||||||
b-b running
|
|
||||||
b-c normal
|
|
||||||
b-resume-b false cannot resume non-suspended coroutine
|
|
||||||
b-resume-c false cannot resume non-suspended coroutine
|
|
||||||
c-resume-b true b-rslt
|
|
||||||
c-resume-c false cannot resume non-suspended coroutine
|
|
||||||
main-resume-c true c-rslt
|
|
||||||
main-b suspended
|
|
||||||
main-c suspended
|
|
||||||
b-resumed main-arg-for-b true
|
|
||||||
b-b running
|
|
||||||
b-c suspended
|
|
||||||
b-resume-b false cannot resume non-suspended coroutine
|
|
||||||
c-resumed b-arg-for-c true
|
|
||||||
c-b normal
|
|
||||||
c-c running
|
|
||||||
c-resume-b false cannot resume non-suspended coroutine
|
|
||||||
c-resume-c false cannot resume non-suspended coroutine
|
|
||||||
b-resume-c true c-rslt
|
|
||||||
main-resume-b true b-rslt
|
|
||||||
main-resume-c true
|
|
||||||
main-b suspended
|
|
||||||
main-c dead
|
|
||||||
b-resumed main-arg-for-b true
|
|
||||||
b-b running
|
|
||||||
b-c dead
|
|
||||||
b-resume-b false cannot resume non-suspended coroutine
|
|
||||||
b-resume-c false cannot resume dead coroutine
|
|
||||||
main-resume-b true b-rslt
|
|
||||||
main-resume-c false cannot resume dead coroutine
|
|
||||||
@@ -1,329 +0,0 @@
|
|||||||
has debug true
|
|
||||||
----- debug.getlocal, debug.setlocal
|
|
||||||
true h-3-0 -> 3-0 get=nil,nil set=nil,nil get=nil,nil g locals=7,8,9 tbl={3,0,#} f locals=,3,0,#,4,5,6
|
|
||||||
true h-3-1 -> 3-1 get=a,3 set=a,nil get=a,# g locals=7,8,9 tbl={3,1,#} f locals=,#,1,#,4,5,6
|
|
||||||
true h-3-2 -> 3-2 get=b,2 set=b,nil get=b,# g locals=7,8,9 tbl={3,2,#} f locals=,3,#,#,4,5,6
|
|
||||||
true h-3-3 -> 3-3 get=c,# set=c,nil get=c,# g locals=7,8,9 tbl={3,3,#} f locals=,3,3,#,4,5,6
|
|
||||||
true h-3-4 -> 3-4 get=d,4 set=d,nil get=d,# g locals=7,8,9 tbl={3,4,#} f locals=,3,4,#,#,5,6
|
|
||||||
true h-3-5 -> 3-5 get=e,5 set=e,nil get=e,# g locals=7,8,9 tbl={3,5,#} f locals=,3,5,#,4,#,6
|
|
||||||
true h-3-6 -> 3-6 get=f,6 set=f,nil get=f,# g locals=7,8,9 tbl={3,6,#} f locals=,3,6,#,4,5,#
|
|
||||||
true h-3-7 -> 3-7 get=nil,nil set=nil,nil get=nil,nil g locals=7,8,9 tbl={3,7,#} f locals=,3,7,#,4,5,6
|
|
||||||
true h-2-0 -> 2-0 get=nil,nil set=nil,nil get=nil,nil g locals=7,8,9 tbl={2,0,#} f locals=,2,0,#,4,5,6
|
|
||||||
true h-2-1 -> 2-1 get=p,7 set=p,nil get=p,# g locals=#,8,9 tbl={2,1,#} f locals=,2,1,#,4,5,6
|
|
||||||
true h-2-2 -> 2-2 get=q,8 set=q,nil get=q,# g locals=7,#,9 tbl={2,2,#} f locals=,2,2,#,4,5,6
|
|
||||||
true h-2-3 -> 2-3 get=r,9 set=r,nil get=r,# g locals=7,8,# tbl={2,3,#} f locals=,2,3,#,4,5,6
|
|
||||||
true h-2-4 -> 2-4 get=nil,nil set=nil,nil get=nil,nil g locals=7,8,9 tbl={2,4,#} f locals=,2,4,#,4,5,6
|
|
||||||
true h-2-5 -> 2-5 get=nil,nil set=nil,nil get=nil,nil g locals=7,8,9 tbl={2,5,#} f locals=,2,5,#,4,5,6
|
|
||||||
true h-2-6 -> 2-6 get=nil,nil set=nil,nil get=nil,nil g locals=7,8,9 tbl={2,6,#} f locals=,2,6,#,4,5,6
|
|
||||||
true h-2-7 -> 2-7 get=nil,nil set=nil,nil get=nil,nil g locals=7,8,9 tbl={2,7,#} f locals=,2,7,#,4,5,6
|
|
||||||
true h-1-3 -> 1-3 get=n,# set=n,nil get=n,# g locals=7,8,9 tbl={1,3,#} f locals=,1,3,#,4,5,6
|
|
||||||
true h-1-4 -> 1-4 get=#,nil set=x1,nil get=x1,# g locals=7,8,9 tbl={1,4,#} f locals=,1,4,#,4,5,6
|
|
||||||
true h-1-5 -> 1-5 get=nil,# set=y1,nil get=y1,# g locals=7,8,9 tbl={1,5,#} f locals=,1,5,#,4,5,6
|
|
||||||
true h-1-6 -> 1-6 get=nil,nil set=nil,nil get=x2,nil g locals=7,8,9 tbl={1,6,#} f locals=,1,6,#,4,5,6
|
|
||||||
true h-1-7 -> 1-7 get=nil,nil set=nil,nil get=y2,nil g locals=7,8,9 tbl={1,7,#} f locals=,1,7,#,4,5,6
|
|
||||||
----- debug.getupvalue, debug.setupvalue
|
|
||||||
h 101 102 103 104 105 106 107 108 109
|
|
||||||
f -> 1-0 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,101,102,103,104,105,106,107,108,109
|
|
||||||
f -> 1-1 get=true,m,101 set=true,m,nil get=true,m,777001 tbl=true,777001,102,103,104,105,106,107,108,109
|
|
||||||
f -> 1-2 get=true,n,102 set=true,n,nil get=true,n,777002 tbl=true,777001,777002,103,104,105,106,107,108,109
|
|
||||||
f -> 1-3 get=true,o,103 set=true,o,nil get=true,o,777003 tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
f -> 1-4 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
f -> 1-5 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
f -> 1-6 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
f -> 1-7 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
f -> 1-8 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
f -> 1-9 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
f -> 1-10 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
g -> 2-0 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,777001,777002,777003,104,105,106,107,108,109
|
|
||||||
g -> 2-1 get=true,m,777001 set=true,m,nil get=true,m,888001 tbl=true,888001,777002,777003,104,105,106,107,108,109
|
|
||||||
g -> 2-2 get=true,n,777002 set=true,n,nil get=true,n,888002 tbl=true,888001,888002,777003,104,105,106,107,108,109
|
|
||||||
g -> 2-3 get=true,o,777003 set=true,o,nil get=true,o,888003 tbl=true,888001,888002,888003,104,105,106,107,108,109
|
|
||||||
g -> 2-4 get=true,p,104 set=true,p,nil get=true,p,888004 tbl=true,888001,888002,888003,888004,105,106,107,108,109
|
|
||||||
g -> 2-5 get=true,q,105 set=true,q,nil get=true,q,888005 tbl=true,888001,888002,888003,888004,888005,106,107,108,109
|
|
||||||
g -> 2-6 get=true,r,106 set=true,r,nil get=true,r,888006 tbl=true,888001,888002,888003,888004,888005,888006,107,108,109
|
|
||||||
g -> 2-7 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,888001,888002,888003,888004,888005,888006,107,108,109
|
|
||||||
g -> 2-8 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,888001,888002,888003,888004,888005,888006,107,108,109
|
|
||||||
g -> 2-9 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,888001,888002,888003,888004,888005,888006,107,108,109
|
|
||||||
g -> 2-10 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,888001,888002,888003,888004,888005,888006,107,108,109
|
|
||||||
h -> 3-0 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,888001,888002,888003,888004,888005,888006,107,108,109
|
|
||||||
h -> 3-1 get=true,m,888001 set=true,m,nil get=true,m,999001 tbl=true,999001,888002,888003,888004,888005,888006,107,108,109
|
|
||||||
h -> 3-2 get=true,n,888002 set=true,n,nil get=true,n,999002 tbl=true,999001,999002,888003,888004,888005,888006,107,108,109
|
|
||||||
h -> 3-3 get=true,o,888003 set=true,o,nil get=true,o,999003 tbl=true,999001,999002,999003,888004,888005,888006,107,108,109
|
|
||||||
h -> 3-4 get=true,p,888004 set=true,p,nil get=true,p,999004 tbl=true,999001,999002,999003,999004,888005,888006,107,108,109
|
|
||||||
h -> 3-5 get=true,q,888005 set=true,q,nil get=true,q,999005 tbl=true,999001,999002,999003,999004,999005,888006,107,108,109
|
|
||||||
h -> 3-6 get=true,r,888006 set=true,r,nil get=true,r,999006 tbl=true,999001,999002,999003,999004,999005,999006,107,108,109
|
|
||||||
h -> 3-7 get=true,v,107 set=true,v,nil get=true,v,999007 tbl=true,999001,999002,999003,999004,999005,999006,999007,108,109
|
|
||||||
h -> 3-8 get=true,w,108 set=true,w,nil get=true,w,999008 tbl=true,999001,999002,999003,999004,999005,999006,999007,999008,109
|
|
||||||
h -> 3-9 get=true,x,109 set=true,x,nil get=true,x,999009 tbl=true,999001,999002,999003,999004,999005,999006,999007,999008,999009
|
|
||||||
h -> 3-10 get=true,nil,nil set=true,nil,nil get=true,nil,nil tbl=true,999001,999002,999003,999004,999005,999006,999007,999008,999009
|
|
||||||
----- debug.setmetatable, debug.getmetatable
|
|
||||||
a.a=bbb a.b=nil b.a=nil b.b=nil
|
|
||||||
a.a=bbb a.b=ccc b.a=nil b.b=nil
|
|
||||||
boolean table nil table
|
|
||||||
boolean nil nil nil
|
|
||||||
boolean table nil nil
|
|
||||||
a.a=bbb a.b=nil b.a=nil b.b=nil
|
|
||||||
boolean nil nil nil
|
|
||||||
get=true,true,nil
|
|
||||||
set=true,true,nil
|
|
||||||
get=true,true,nil
|
|
||||||
get=true,true,nil
|
|
||||||
set=true,true,nil
|
|
||||||
get=true,true,nil
|
|
||||||
true nil
|
|
||||||
true 1
|
|
||||||
true 1
|
|
||||||
----- debug.getinfo
|
|
||||||
6
|
|
||||||
---
|
|
||||||
debug.getinfo(1)
|
|
||||||
source: @debuglib.lua
|
|
||||||
short_src: debuglib.lua
|
|
||||||
what: Lua
|
|
||||||
currentline: 144
|
|
||||||
linedefined: 141
|
|
||||||
lastlinedefined: 155
|
|
||||||
nups: 5
|
|
||||||
func: function
|
|
||||||
debug.getinfo(1,"")
|
|
||||||
debug.getinfo(1,"l")
|
|
||||||
currentline: 146
|
|
||||||
debug.getinfo(1,"fL")
|
|
||||||
func: function
|
|
||||||
activelines: {}
|
|
||||||
debug.getinfo(2)
|
|
||||||
source: @debuglib.lua
|
|
||||||
short_src: debuglib.lua
|
|
||||||
what: Lua
|
|
||||||
currentline: 157
|
|
||||||
linedefined: 135
|
|
||||||
lastlinedefined: 159
|
|
||||||
nups: 6
|
|
||||||
func: function
|
|
||||||
debug.getinfo(2,"l")
|
|
||||||
currentline: 157
|
|
||||||
debug.getinfo(2,"fL")
|
|
||||||
func: function
|
|
||||||
activelines: {}
|
|
||||||
debug.getinfo(10,"")
|
|
||||||
true
|
|
||||||
debug.getinfo(-10,"")
|
|
||||||
true
|
|
||||||
---
|
|
||||||
5
|
|
||||||
e,f,g true function function
|
|
||||||
debug.getinfo(f)
|
|
||||||
true
|
|
||||||
source: @debuglib.lua
|
|
||||||
short_src: debuglib.lua
|
|
||||||
what: Lua
|
|
||||||
currentline: -1
|
|
||||||
linedefined: 137
|
|
||||||
lastlinedefined: 140
|
|
||||||
nups: 1
|
|
||||||
func: function
|
|
||||||
debug.getinfo(f,"nSlufL")
|
|
||||||
true
|
|
||||||
source: @debuglib.lua
|
|
||||||
short_src: debuglib.lua
|
|
||||||
what: Lua
|
|
||||||
currentline: -1
|
|
||||||
linedefined: 137
|
|
||||||
lastlinedefined: 140
|
|
||||||
nups: 1
|
|
||||||
func: function
|
|
||||||
activelines: {}
|
|
||||||
debug.getinfo(f,"n")
|
|
||||||
true
|
|
||||||
debug.getinfo(f,"S")
|
|
||||||
true
|
|
||||||
source: @debuglib.lua
|
|
||||||
short_src: debuglib.lua
|
|
||||||
what: Lua
|
|
||||||
linedefined: 137
|
|
||||||
lastlinedefined: 140
|
|
||||||
debug.getinfo(f,"l")
|
|
||||||
true
|
|
||||||
currentline: -1
|
|
||||||
debug.getinfo(f,"u")
|
|
||||||
true
|
|
||||||
nups: 1
|
|
||||||
debug.getinfo(f,"f")
|
|
||||||
true
|
|
||||||
func: function
|
|
||||||
debug.getinfo(f,"L")
|
|
||||||
true
|
|
||||||
activelines: {}
|
|
||||||
debug.getinfo(g)
|
|
||||||
true
|
|
||||||
source: @debuglib.lua
|
|
||||||
short_src: debuglib.lua
|
|
||||||
what: Lua
|
|
||||||
currentline: -1
|
|
||||||
linedefined: 141
|
|
||||||
lastlinedefined: 155
|
|
||||||
nups: 5
|
|
||||||
func: function
|
|
||||||
debug.getinfo(test)
|
|
||||||
true
|
|
||||||
source: @debuglib.lua
|
|
||||||
short_src: debuglib.lua
|
|
||||||
what: Lua
|
|
||||||
currentline: -1
|
|
||||||
linedefined: 135
|
|
||||||
lastlinedefined: 159
|
|
||||||
nups: 6
|
|
||||||
func: function
|
|
||||||
----- debug.sethook, debug.gethook
|
|
||||||
... in hook call nil
|
|
||||||
info[2]=debuglib.lua,177
|
|
||||||
... in hook call nil
|
|
||||||
info[2]=debuglib.lua,176
|
|
||||||
... in hook call nil
|
|
||||||
info[2]=[C],-1
|
|
||||||
... in hook call nil
|
|
||||||
info[2]=[C],-1
|
|
||||||
hook = c -> result=true,nil,nil,nil,false,false,nil
|
|
||||||
... in hook return nil
|
|
||||||
info[2]=[C],-1
|
|
||||||
... in hook return nil
|
|
||||||
info[2]=[C],-1
|
|
||||||
hook = r -> result=true,nil,nil,nil,false,false,nil
|
|
||||||
... in hook line 192
|
|
||||||
info[2]=debuglib.lua,192
|
|
||||||
... in hook line 177
|
|
||||||
info[2]=debuglib.lua,177
|
|
||||||
... in hook line 178
|
|
||||||
info[2]=debuglib.lua,178
|
|
||||||
... in hook line 176
|
|
||||||
info[2]=debuglib.lua,176
|
|
||||||
... in hook line 195
|
|
||||||
info[2]=debuglib.lua,195
|
|
||||||
hook = l -> result=true,nil,nil,nil,false,false,nil
|
|
||||||
... in hook return nil
|
|
||||||
info[2]=[C],-1
|
|
||||||
... in hook line 192
|
|
||||||
info[2]=debuglib.lua,192
|
|
||||||
... in hook call nil
|
|
||||||
info[2]=debuglib.lua,177
|
|
||||||
... in hook line 177
|
|
||||||
info[2]=debuglib.lua,177
|
|
||||||
... in hook line 178
|
|
||||||
info[2]=debuglib.lua,178
|
|
||||||
... in hook call nil
|
|
||||||
info[2]=debuglib.lua,176
|
|
||||||
... in hook line 176
|
|
||||||
info[2]=debuglib.lua,176
|
|
||||||
... in hook call nil
|
|
||||||
info[2]=[C],-1
|
|
||||||
... in hook return nil
|
|
||||||
info[2]=[C],-1
|
|
||||||
... in hook line 195
|
|
||||||
info[2]=debuglib.lua,195
|
|
||||||
... in hook call nil
|
|
||||||
info[2]=[C],-1
|
|
||||||
hook = crl -> result=true,nil,nil,nil,false,false,nil
|
|
||||||
----- debug.traceback
|
|
||||||
hi
|
|
||||||
stack traceback:
|
|
||||||
debuglib.lua:216: in function <debuglib.lua:215>
|
|
||||||
[C]: in function 'pcall'
|
|
||||||
debuglib.lua:219: in function 'b'
|
|
||||||
debuglib.lua:222: in function 'c'
|
|
||||||
debuglib.lua:225: in function '__index'
|
|
||||||
debuglib.lua:227: in function 'e'
|
|
||||||
debuglib.lua:231: in function 'g'
|
|
||||||
debuglib.lua:235: in function 'i'
|
|
||||||
debuglib.lua:238: in function <debuglib.lua:214>
|
|
||||||
[C]: in function 'pcall'
|
|
||||||
debuglib.lua:240: in main chunk
|
|
||||||
[C]: in ?
|
|
||||||
----- debug.upvalueid
|
|
||||||
debug.getupvalue(a1,1) x 100
|
|
||||||
debug.getupvalue(a1,2) y 200
|
|
||||||
debug.getupvalue(a2,1) x 100
|
|
||||||
debug.getupvalue(a2,2) y 200
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a1,1) true
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a2,1) true
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a1,2) false
|
|
||||||
----- debug.upvaluejoin
|
|
||||||
a1 101 201 301 401
|
|
||||||
a2 102 202 501 601
|
|
||||||
debug.upvaluejoin(a1,1,a2,2)
|
|
||||||
debug.upvaluejoin(a1,3,a2,4)
|
|
||||||
a1 203 203 602 402
|
|
||||||
a2 103 204 502 603
|
|
||||||
a1 205 205 604 403
|
|
||||||
a2 104 206 503 605
|
|
||||||
debug.getupvalue(a1,1) x 206
|
|
||||||
debug.getupvalue(a2,1) x 104
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a1,1) true
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a2,1) false
|
|
||||||
debug.upvalueid(a2,1) == debug.upvalueid(a1,1) false
|
|
||||||
debug.upvalueid(a2,1) == debug.upvalueid(a2,1) true
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a1,2) true
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a2,2) true
|
|
||||||
debug.upvalueid(a2,1) == debug.upvalueid(a1,2) false
|
|
||||||
debug.upvalueid(a2,1) == debug.upvalueid(a2,2) false
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a1,3) false
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a2,3) false
|
|
||||||
debug.upvalueid(a2,1) == debug.upvalueid(a1,3) false
|
|
||||||
debug.upvalueid(a2,1) == debug.upvalueid(a2,3) false
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a1,4) false
|
|
||||||
debug.upvalueid(a1,1) == debug.upvalueid(a2,4) false
|
|
||||||
debug.upvalueid(a2,1) == debug.upvalueid(a1,4) false
|
|
||||||
debug.upvalueid(a2,1) == debug.upvalueid(a2,4) false
|
|
||||||
debug.getupvalue(a1,2) y 206
|
|
||||||
debug.getupvalue(a2,2) y 206
|
|
||||||
debug.upvalueid(a1,2) == debug.upvalueid(a1,1) true
|
|
||||||
debug.upvalueid(a1,2) == debug.upvalueid(a2,1) false
|
|
||||||
debug.upvalueid(a2,2) == debug.upvalueid(a1,1) true
|
|
||||||
debug.upvalueid(a2,2) == debug.upvalueid(a2,1) false
|
|
||||||
debug.upvalueid(a1,2) == debug.upvalueid(a1,2) true
|
|
||||||
debug.upvalueid(a1,2) == debug.upvalueid(a2,2) true
|
|
||||||
debug.upvalueid(a2,2) == debug.upvalueid(a1,2) true
|
|
||||||
debug.upvalueid(a2,2) == debug.upvalueid(a2,2) true
|
|
||||||
debug.upvalueid(a1,2) == debug.upvalueid(a1,3) false
|
|
||||||
debug.upvalueid(a1,2) == debug.upvalueid(a2,3) false
|
|
||||||
debug.upvalueid(a2,2) == debug.upvalueid(a1,3) false
|
|
||||||
debug.upvalueid(a2,2) == debug.upvalueid(a2,3) false
|
|
||||||
debug.upvalueid(a1,2) == debug.upvalueid(a1,4) false
|
|
||||||
debug.upvalueid(a1,2) == debug.upvalueid(a2,4) false
|
|
||||||
debug.upvalueid(a2,2) == debug.upvalueid(a1,4) false
|
|
||||||
debug.upvalueid(a2,2) == debug.upvalueid(a2,4) false
|
|
||||||
debug.getupvalue(a1,3) z 605
|
|
||||||
debug.getupvalue(a2,3) z 503
|
|
||||||
debug.upvalueid(a1,3) == debug.upvalueid(a1,1) false
|
|
||||||
debug.upvalueid(a1,3) == debug.upvalueid(a2,1) false
|
|
||||||
debug.upvalueid(a2,3) == debug.upvalueid(a1,1) false
|
|
||||||
debug.upvalueid(a2,3) == debug.upvalueid(a2,1) false
|
|
||||||
debug.upvalueid(a1,3) == debug.upvalueid(a1,2) false
|
|
||||||
debug.upvalueid(a1,3) == debug.upvalueid(a2,2) false
|
|
||||||
debug.upvalueid(a2,3) == debug.upvalueid(a1,2) false
|
|
||||||
debug.upvalueid(a2,3) == debug.upvalueid(a2,2) false
|
|
||||||
debug.upvalueid(a1,3) == debug.upvalueid(a1,3) true
|
|
||||||
debug.upvalueid(a1,3) == debug.upvalueid(a2,3) false
|
|
||||||
debug.upvalueid(a2,3) == debug.upvalueid(a1,3) false
|
|
||||||
debug.upvalueid(a2,3) == debug.upvalueid(a2,3) true
|
|
||||||
debug.upvalueid(a1,3) == debug.upvalueid(a1,4) false
|
|
||||||
debug.upvalueid(a1,3) == debug.upvalueid(a2,4) true
|
|
||||||
debug.upvalueid(a2,3) == debug.upvalueid(a1,4) false
|
|
||||||
debug.upvalueid(a2,3) == debug.upvalueid(a2,4) false
|
|
||||||
debug.getupvalue(a1,4) w 403
|
|
||||||
debug.getupvalue(a2,4) w 605
|
|
||||||
debug.upvalueid(a1,4) == debug.upvalueid(a1,1) false
|
|
||||||
debug.upvalueid(a1,4) == debug.upvalueid(a2,1) false
|
|
||||||
debug.upvalueid(a2,4) == debug.upvalueid(a1,1) false
|
|
||||||
debug.upvalueid(a2,4) == debug.upvalueid(a2,1) false
|
|
||||||
debug.upvalueid(a1,4) == debug.upvalueid(a1,2) false
|
|
||||||
debug.upvalueid(a1,4) == debug.upvalueid(a2,2) false
|
|
||||||
debug.upvalueid(a2,4) == debug.upvalueid(a1,2) false
|
|
||||||
debug.upvalueid(a2,4) == debug.upvalueid(a2,2) false
|
|
||||||
debug.upvalueid(a1,4) == debug.upvalueid(a1,3) false
|
|
||||||
debug.upvalueid(a1,4) == debug.upvalueid(a2,3) false
|
|
||||||
debug.upvalueid(a2,4) == debug.upvalueid(a1,3) true
|
|
||||||
debug.upvalueid(a2,4) == debug.upvalueid(a2,3) false
|
|
||||||
debug.upvalueid(a1,4) == debug.upvalueid(a1,4) true
|
|
||||||
debug.upvalueid(a1,4) == debug.upvalueid(a2,4) false
|
|
||||||
debug.upvalueid(a2,4) == debug.upvalueid(a1,4) false
|
|
||||||
debug.upvalueid(a2,4) == debug.upvalueid(a2,4) true
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
a(error) false nil
|
|
||||||
a(error,"msg") false string
|
|
||||||
a(error,"msg",0) false string
|
|
||||||
a(error,"msg",1) false string
|
|
||||||
a(error,"msg",2) false string
|
|
||||||
a(error,"msg",3) false string
|
|
||||||
a(error,"msg",4) false string
|
|
||||||
a(error,"msg",5) false string
|
|
||||||
a(error,"msg",6) false string
|
|
||||||
a(nil()) false string
|
|
||||||
a(t()) false string
|
|
||||||
a(s()) false string
|
|
||||||
a(true()) false string
|
|
||||||
a(nil+1) false string
|
|
||||||
a(a+1) false string
|
|
||||||
a(s+1) false string
|
|
||||||
a(true+1) false string
|
|
||||||
a(nil.x) false string
|
|
||||||
a(a.x) false string
|
|
||||||
a(s.x) true nil
|
|
||||||
a(true.x) false string
|
|
||||||
a(nil.x=5) false string
|
|
||||||
a(a.x=5) false string
|
|
||||||
a(s.x=5) false string
|
|
||||||
a(true.x=5) false string
|
|
||||||
a(#nil) false string
|
|
||||||
a(#t) true 0
|
|
||||||
a(#s) true 11
|
|
||||||
a(#a) false string
|
|
||||||
a(#true) false string
|
|
||||||
a(nil>1) false string
|
|
||||||
a(a>1) false string
|
|
||||||
a(s>1) false string
|
|
||||||
a(true>1) false string
|
|
||||||
a(-nil) false string
|
|
||||||
a(-a) false string
|
|
||||||
a(-s) false string
|
|
||||||
a(-true) false string
|
|
||||||
-------- string concatenation
|
|
||||||
"a".."b" true
|
|
||||||
"a"..nil false
|
|
||||||
nil.."b" false
|
|
||||||
"a"..{} false
|
|
||||||
{}.."b" false
|
|
||||||
"a"..2 true
|
|
||||||
2.."b" true
|
|
||||||
"a"..print false
|
|
||||||
print.."b" false
|
|
||||||
"a"..true false
|
|
||||||
true.."b" false
|
|
||||||
nil..true false
|
|
||||||
"a"..3.5 true
|
|
||||||
3.5.."b" true
|
|
||||||
-------- table concatenation
|
|
||||||
"a".."b" true
|
|
||||||
"a"..nil false
|
|
||||||
nil.."b" false
|
|
||||||
"a"..{} false
|
|
||||||
{}.."b" false
|
|
||||||
"a"..2 true
|
|
||||||
2.."b" true
|
|
||||||
"a"..print false
|
|
||||||
print.."b" false
|
|
||||||
"a"..true false
|
|
||||||
true.."b" false
|
|
||||||
nil..true false
|
|
||||||
"a"..3.5 true
|
|
||||||
3.5.."b" true
|
|
||||||
-------- pairs tests
|
|
||||||
a(pairs(nil)) false string
|
|
||||||
a(pairs(a)) false string
|
|
||||||
a(pairs(s)) false string
|
|
||||||
a(pairs(t)) true func.1
|
|
||||||
a(pairs(true)) false string
|
|
||||||
-------- setmetatable tests
|
|
||||||
a(setmetatable(nil)) false string
|
|
||||||
a(setmetatable(a)) false string
|
|
||||||
a(setmetatable(s)) false string
|
|
||||||
a(setmetatable(true)) false string
|
|
||||||
a(setmetatable(t)) true tbl.2
|
|
||||||
a(getmetatable(t)) true tbl.3
|
|
||||||
a(setmetatable(t*)) true tbl.2
|
|
||||||
a(getmetatable(t)) true tbl.4
|
|
||||||
a(setmetatable(t)) false string
|
|
||||||
a(getmetatable(t)) true tbl.4
|
|
||||||
a(setmetatable(t)) true tbl.5
|
|
||||||
a(getmetatable(t)) true tbl.6
|
|
||||||
a(setmetatable(t*)) true tbl.5
|
|
||||||
a(getmetatable(t)) true some string
|
|
||||||
a(setmetatable(t)) false string
|
|
||||||
a(getmetatable(t)) true some string
|
|
||||||
a(setmetatable(t,nil)) false string
|
|
||||||
a(setmetatable(t)) false string
|
|
||||||
a(setmetatable({},"abc")) false string
|
|
||||||
error("msg","arg") false string
|
|
||||||
loadfile("bogus.txt") true nil
|
|
||||||
dofile("bogus.txt") false string
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
f0:
|
|
||||||
f0:
|
|
||||||
f0:
|
|
||||||
f0:
|
|
||||||
f0:
|
|
||||||
f1: nil
|
|
||||||
f1: a1/1
|
|
||||||
f1: a1/2
|
|
||||||
f1: a1/3
|
|
||||||
f1: a1/4
|
|
||||||
f2: nil nil
|
|
||||||
f2: a1/1 nil
|
|
||||||
f2: a1/2 a2/2
|
|
||||||
f2: a1/3 a2/3
|
|
||||||
f2: a1/4 a2/4
|
|
||||||
f3: nil nil nil
|
|
||||||
f3: a1/1 nil nil
|
|
||||||
f3: a1/2 a2/2 nil
|
|
||||||
f3: a1/3 a2/3 a3/3
|
|
||||||
f3: a1/4 a2/4 a3/4
|
|
||||||
f4: nil nil nil nil
|
|
||||||
f4: a1/1 nil nil nil
|
|
||||||
f4: a1/2 a2/2 nil nil
|
|
||||||
f4: a1/3 a2/3 a3/3 nil
|
|
||||||
f4: a1/4 a2/4 a3/4 a4/4
|
|
||||||
z0: nil
|
|
||||||
z2: c2.3/4
|
|
||||||
z4: c4.1/4
|
|
||||||
g0: nil nil nil nil (eol)
|
|
||||||
g2: b2.3/4 b2.4/4 nil nil (eol)
|
|
||||||
g4: b4.1/4 b4.2/4 b4.3/4 b4.4/4 (eol)
|
|
||||||
11 12 13
|
|
||||||
23 22 21
|
|
||||||
32 45 58
|
|
||||||
a nil
|
|
||||||
...
|
|
||||||
...,a nil nil
|
|
||||||
a,... nil
|
|
||||||
a q
|
|
||||||
...
|
|
||||||
...,a nil q
|
|
||||||
a,... q
|
|
||||||
a q
|
|
||||||
... r
|
|
||||||
...,a r q
|
|
||||||
a,... q r
|
|
||||||
a q
|
|
||||||
... r s
|
|
||||||
...,a r q
|
|
||||||
a,... q r s
|
|
||||||
third abc nil | nil nil nil
|
|
||||||
third def nil | nil nil nil
|
|
||||||
third def nil | nil nil nil
|
|
||||||
third abc p | p nil nil
|
|
||||||
third def nil | p nil nil
|
|
||||||
third def nil | p nil nil
|
|
||||||
third abc p | p q nil
|
|
||||||
third def q | p q nil
|
|
||||||
third def q | p q nil
|
|
||||||
third abc p | p q r
|
|
||||||
third def q | p q r
|
|
||||||
third def q | p q r
|
|
||||||
third abc p | p q r
|
|
||||||
third def q | p q r
|
|
||||||
third def q | p q r
|
|
||||||
third abc nil | nil nil nil
|
|
||||||
third def nil | nil nil nil
|
|
||||||
third def nil | nil nil nil
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
write file.0
|
|
||||||
Thiswrite file.0
|
|
||||||
is a pen.write file.0
|
|
||||||
flush true
|
|
||||||
f userdata
|
|
||||||
file.1
|
|
||||||
write file.2
|
|
||||||
type(f) file.1
|
|
||||||
close true
|
|
||||||
type(f) closed file
|
|
||||||
type("f") nil
|
|
||||||
"abc" string
|
|
||||||
----- 1
|
|
||||||
"def" string
|
|
||||||
----- 2
|
|
||||||
"12345" number
|
|
||||||
----- 3
|
|
||||||
"678910" number
|
|
||||||
----- 4
|
|
||||||
" more\7aaaaaa\8bbbthe rest" string
|
|
||||||
----- 5
|
|
||||||
h file.1 file.4 nil
|
|
||||||
write file.3
|
|
||||||
close true
|
|
||||||
f.type file.5
|
|
||||||
f file.6
|
|
||||||
write file.6
|
|
||||||
type(f) file.5
|
|
||||||
close true
|
|
||||||
"line one"
|
|
||||||
"line two"
|
|
||||||
""
|
|
||||||
"after blank line"
|
|
||||||
"unterminated line"
|
|
||||||
"line one"
|
|
||||||
"line two"
|
|
||||||
""
|
|
||||||
"after blank line"
|
|
||||||
"unterminated line"
|
|
||||||
"line one"
|
|
||||||
"line two"
|
|
||||||
""
|
|
||||||
"after blank line"
|
|
||||||
"unterminated line"
|
|
||||||
"line one"
|
|
||||||
"line two"
|
|
||||||
""
|
|
||||||
"after blank line"
|
|
||||||
"unterminated line"
|
|
||||||
file.7
|
|
||||||
file.7
|
|
||||||
a:write file.8
|
|
||||||
b:write file.9
|
|
||||||
a:setvbuf true
|
|
||||||
a:setvbuf true
|
|
||||||
a:setvbuf true
|
|
||||||
a:write file.8
|
|
||||||
b:write file.9
|
|
||||||
a:flush true
|
|
||||||
b:flush true
|
|
||||||
a:close true
|
|
||||||
a:write false closed
|
|
||||||
a:flush false closed
|
|
||||||
a:read false closed
|
|
||||||
a:lines false closed
|
|
||||||
a:seek false closed
|
|
||||||
a:setvbuf false closed
|
|
||||||
a:close false closed
|
|
||||||
io.type(a) true
|
|
||||||
io.close() true
|
|
||||||
io.close(io.output()) true
|
|
||||||
io.close() true
|
|
||||||
io.write false closed
|
|
||||||
io.flush false closed
|
|
||||||
io.read false closed
|
|
||||||
io.lines false closed
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,729 +0,0 @@
|
|||||||
---------- miscellaneous tests ----------
|
|
||||||
math.sin( 0.0 ) true <zero>
|
|
||||||
math.cos( math.pi ) true -1
|
|
||||||
math.sqrt( 9.0 ) true 3
|
|
||||||
math.modf( 5.25 ) true 5 0.25
|
|
||||||
math.frexp(0.00625) true 0.8 -7
|
|
||||||
-5 ^ 2 true -25
|
|
||||||
-5 / 2 true -2.5
|
|
||||||
-5 % 2 true 1
|
|
||||||
---------- constants ----------
|
|
||||||
math.huge true <pos-inf>
|
|
||||||
math.pi true 3.1415
|
|
||||||
---------- unary operator - ----------
|
|
||||||
--2.5 true
|
|
||||||
--2 true
|
|
||||||
-0 true <zero>
|
|
||||||
-2 true -2
|
|
||||||
-2.5 true -2.5
|
|
||||||
-'-2.5' true 2.5
|
|
||||||
-'-2' true 2
|
|
||||||
-'0' true <zero>
|
|
||||||
-'2' true -2
|
|
||||||
-'2.5' true -2.5
|
|
||||||
---------- unary operator not ----------
|
|
||||||
not -2.5 true false
|
|
||||||
not -2 true false
|
|
||||||
not 0 true false
|
|
||||||
not 2 true false
|
|
||||||
not 2.5 true false
|
|
||||||
not '-2.5' true false
|
|
||||||
not '-2' true false
|
|
||||||
not '0' true false
|
|
||||||
not '2' true false
|
|
||||||
not '2.5' true false
|
|
||||||
---------- binary operator + ----------
|
|
||||||
2+0 true 2
|
|
||||||
-2.5+0 true -2.5
|
|
||||||
2+1 true 3
|
|
||||||
5+2 true 7
|
|
||||||
-5+2 true -3
|
|
||||||
16+2 true 18
|
|
||||||
-16+-2 true -18
|
|
||||||
0.5+0 true 0.5
|
|
||||||
0.5+1 true 1.5
|
|
||||||
0.5+2 true 2.5
|
|
||||||
0.5+-1 true -0.5
|
|
||||||
0.5+2 true 2.5
|
|
||||||
2.25+0 true 2.25
|
|
||||||
2.25+2 true 4.25
|
|
||||||
-2+0 true -2
|
|
||||||
3+3 true 6
|
|
||||||
'2'+'0' true 2
|
|
||||||
'2.5'+'3' true 5.5
|
|
||||||
'-2'+'1.5' true -0.5
|
|
||||||
'-2.5'+'-1.5' true -4
|
|
||||||
'3.0'+'3.0' true 6
|
|
||||||
2.75+2.75 true 5.5
|
|
||||||
'2.75'+'2.75' true 5.5
|
|
||||||
3+'3' true 6
|
|
||||||
'3'+3 true 6
|
|
||||||
2.75+'2.75' true 5.5
|
|
||||||
'2.75'+2.75 true 5.5
|
|
||||||
-3+'-4' true -7
|
|
||||||
'-3'+4 true 1
|
|
||||||
-3+'4' true 1
|
|
||||||
'-3'+-4 true -7
|
|
||||||
-4.75+'2.75' true -2
|
|
||||||
'-2.75'+1.75 true -1
|
|
||||||
4.75+'-2.75' true 2
|
|
||||||
'2.75'+-1.75 true 1
|
|
||||||
---------- binary operator - ----------
|
|
||||||
2-0 true 2
|
|
||||||
-2.5-0 true -2.5
|
|
||||||
2-1 true 1
|
|
||||||
5-2 true 3
|
|
||||||
-5-2 true -7
|
|
||||||
16-2 true 14
|
|
||||||
-16--2 true -14
|
|
||||||
0.5-0 true 0.5
|
|
||||||
0.5-1 true -0.5
|
|
||||||
0.5-2 true -1.5
|
|
||||||
0.5--1 true 1.5
|
|
||||||
0.5-2 true -1.5
|
|
||||||
2.25-0 true 2.25
|
|
||||||
2.25-2 true 0.25
|
|
||||||
-2-0 true -2
|
|
||||||
3-3 true <zero>
|
|
||||||
'2'-'0' true 2
|
|
||||||
'2.5'-'3' true -0.5
|
|
||||||
'-2'-'1.5' true -3.5
|
|
||||||
'-2.5'-'-1.5' true -1
|
|
||||||
'3.0'-'3.0' true <zero>
|
|
||||||
2.75-2.75 true <zero>
|
|
||||||
'2.75'-'2.75' true <zero>
|
|
||||||
3-'3' true <zero>
|
|
||||||
'3'-3 true <zero>
|
|
||||||
2.75-'2.75' true <zero>
|
|
||||||
'2.75'-2.75 true <zero>
|
|
||||||
-3-'-4' true 1
|
|
||||||
'-3'-4 true -7
|
|
||||||
-3-'4' true -7
|
|
||||||
'-3'--4 true 1
|
|
||||||
-4.75-'2.75' true -7.5
|
|
||||||
'-2.75'-1.75 true -4.5
|
|
||||||
4.75-'-2.75' true 7.5
|
|
||||||
'2.75'--1.75 true 4.5
|
|
||||||
---------- binary operator * ----------
|
|
||||||
2*0 true <zero>
|
|
||||||
-2.5*0 true <zero>
|
|
||||||
2*1 true 2
|
|
||||||
5*2 true 10
|
|
||||||
-5*2 true -10
|
|
||||||
16*2 true 32
|
|
||||||
-16*-2 true 32
|
|
||||||
0.5*0 true <zero>
|
|
||||||
0.5*1 true 0.5
|
|
||||||
0.5*2 true 1
|
|
||||||
0.5*-1 true -0.5
|
|
||||||
0.5*2 true 1
|
|
||||||
2.25*0 true <zero>
|
|
||||||
2.25*2 true 4.5
|
|
||||||
-2*0 true <zero>
|
|
||||||
3*3 true 9
|
|
||||||
'2'*'0' true <zero>
|
|
||||||
'2.5'*'3' true 7.5
|
|
||||||
'-2'*'1.5' true -3
|
|
||||||
'-2.5'*'-1.5' true 3.75
|
|
||||||
'3.0'*'3.0' true 9
|
|
||||||
2.75*2.75 true 7.5625
|
|
||||||
'2.75'*'2.75' true 7.5625
|
|
||||||
3*'3' true 9
|
|
||||||
'3'*3 true 9
|
|
||||||
2.75*'2.75' true 7.5625
|
|
||||||
'2.75'*2.75 true 7.5625
|
|
||||||
-3*'-4' true 12
|
|
||||||
'-3'*4 true -12
|
|
||||||
-3*'4' true -12
|
|
||||||
'-3'*-4 true 12
|
|
||||||
-4.75*'2.75' true -13.06
|
|
||||||
'-2.75'*1.75 true -4.812
|
|
||||||
4.75*'-2.75' true -13.06
|
|
||||||
'2.75'*-1.75 true -4.812
|
|
||||||
---------- binary operator ^ ----------
|
|
||||||
2^0 true 1
|
|
||||||
-2.5^0 true 1
|
|
||||||
2^1 true 2
|
|
||||||
5^2 true 25
|
|
||||||
-5^2 true 25
|
|
||||||
16^2 true 256
|
|
||||||
-16^-2 true 0.0039
|
|
||||||
0.5^0 true 1
|
|
||||||
0.5^1 true 0.5
|
|
||||||
0.5^2 true 0.25
|
|
||||||
0.5^-1 true 2
|
|
||||||
0.5^2 true 0.25
|
|
||||||
2.25^0 true 1
|
|
||||||
2.25^2 true 5.0625
|
|
||||||
-2^0 true 1
|
|
||||||
3^3 true 27
|
|
||||||
'2'^'0' true 1
|
|
||||||
'2.5'^'3' true 15.625
|
|
||||||
'-2'^'1.5' true <nan>
|
|
||||||
'-2.5'^'-1.5' true <nan>
|
|
||||||
'3.0'^'3.0' true 27
|
|
||||||
2.75^2.75 true 16.149
|
|
||||||
'2.75'^'2.75' true 16.149
|
|
||||||
3^'3' true 27
|
|
||||||
'3'^3 true 27
|
|
||||||
2.75^'2.75' true 16.149
|
|
||||||
'2.75'^2.75 true 16.149
|
|
||||||
-3^'-4' true 0.0123
|
|
||||||
'-3'^4 true 81
|
|
||||||
-3^'4' true 81
|
|
||||||
'-3'^-4 true 0.0123
|
|
||||||
-4.75^'2.75' true <nan>
|
|
||||||
'-2.75'^1.75 true <nan>
|
|
||||||
4.75^'-2.75' true 0.0137
|
|
||||||
'2.75'^-1.75 true 0.1702
|
|
||||||
---------- binary operator / ----------
|
|
||||||
2/0 true <pos-inf>
|
|
||||||
-2.5/0 true <neg-inf>
|
|
||||||
2/1 true 2
|
|
||||||
5/2 true 2.5
|
|
||||||
-5/2 true -2.5
|
|
||||||
16/2 true 8
|
|
||||||
-16/-2 true 8
|
|
||||||
0.5/0 true <pos-inf>
|
|
||||||
0.5/1 true 0.5
|
|
||||||
0.5/2 true 0.25
|
|
||||||
0.5/-1 true -0.5
|
|
||||||
0.5/2 true 0.25
|
|
||||||
2.25/0 true <pos-inf>
|
|
||||||
2.25/2 true 1.125
|
|
||||||
-2/0 true <neg-inf>
|
|
||||||
3/3 true 1
|
|
||||||
'2'/'0' true <pos-inf>
|
|
||||||
'2.5'/'3' true 0.8333
|
|
||||||
'-2'/'1.5' true -1.333
|
|
||||||
'-2.5'/'-1.5' true 1.6666
|
|
||||||
'3.0'/'3.0' true 1
|
|
||||||
2.75/2.75 true 1
|
|
||||||
'2.75'/'2.75' true 1
|
|
||||||
3/'3' true 1
|
|
||||||
'3'/3 true 1
|
|
||||||
2.75/'2.75' true 1
|
|
||||||
'2.75'/2.75 true 1
|
|
||||||
-3/'-4' true 0.75
|
|
||||||
'-3'/4 true -0.75
|
|
||||||
-3/'4' true -0.75
|
|
||||||
'-3'/-4 true 0.75
|
|
||||||
-4.75/'2.75' true -1.727
|
|
||||||
'-2.75'/1.75 true -1.571
|
|
||||||
4.75/'-2.75' true -1.727
|
|
||||||
'2.75'/-1.75 true -1.571
|
|
||||||
---------- binary operator % ----------
|
|
||||||
2%0 true <nan>
|
|
||||||
-2.5%0 true <nan>
|
|
||||||
2%1 true <zero>
|
|
||||||
5%2 true 1
|
|
||||||
-5%2 true 1
|
|
||||||
16%2 true <zero>
|
|
||||||
-16%-2 true <zero>
|
|
||||||
0.5%0 true <nan>
|
|
||||||
0.5%1 true 0.5
|
|
||||||
0.5%2 true 0.5
|
|
||||||
0.5%-1 true -0.5
|
|
||||||
0.5%2 true 0.5
|
|
||||||
2.25%0 true <nan>
|
|
||||||
2.25%2 true 0.25
|
|
||||||
-2%0 true <nan>
|
|
||||||
3%3 true <zero>
|
|
||||||
'2'%'0' true <nan>
|
|
||||||
'2.5'%'3' true 2.5
|
|
||||||
'-2'%'1.5' true 1
|
|
||||||
'-2.5'%'-1.5' true -1
|
|
||||||
'3.0'%'3.0' true <zero>
|
|
||||||
2.75%2.75 true <zero>
|
|
||||||
'2.75'%'2.75' true <zero>
|
|
||||||
3%'3' true <zero>
|
|
||||||
'3'%3 true <zero>
|
|
||||||
2.75%'2.75' true <zero>
|
|
||||||
'2.75'%2.75 true <zero>
|
|
||||||
-3%'-4' true -3
|
|
||||||
'-3'%4 true 1
|
|
||||||
-3%'4' true 1
|
|
||||||
'-3'%-4 true -3
|
|
||||||
-4.75%'2.75' true 0.75
|
|
||||||
'-2.75'%1.75 true 0.75
|
|
||||||
4.75%'-2.75' true -0.75
|
|
||||||
'2.75'%-1.75 true -0.75
|
|
||||||
---------- binary operator == ----------
|
|
||||||
2==0 true false
|
|
||||||
-2.5==0 true false
|
|
||||||
2==1 true false
|
|
||||||
5==2 true false
|
|
||||||
-5==2 true false
|
|
||||||
16==2 true false
|
|
||||||
-16==-2 true false
|
|
||||||
0.5==0 true false
|
|
||||||
0.5==1 true false
|
|
||||||
0.5==2 true false
|
|
||||||
0.5==-1 true false
|
|
||||||
0.5==2 true false
|
|
||||||
2.25==0 true false
|
|
||||||
2.25==2 true false
|
|
||||||
-2==0 true false
|
|
||||||
3==3 true true
|
|
||||||
'2'=='0' true false
|
|
||||||
'2.5'=='3' true false
|
|
||||||
'-2'=='1.5' true false
|
|
||||||
'-2.5'=='-1.5' true false
|
|
||||||
'3.0'=='3.0' true true
|
|
||||||
2.75==2.75 true true
|
|
||||||
'2.75'=='2.75' true true
|
|
||||||
---------- binary operator ~= ----------
|
|
||||||
2~=0 true true
|
|
||||||
-2.5~=0 true true
|
|
||||||
2~=1 true true
|
|
||||||
5~=2 true true
|
|
||||||
-5~=2 true true
|
|
||||||
16~=2 true true
|
|
||||||
-16~=-2 true true
|
|
||||||
0.5~=0 true true
|
|
||||||
0.5~=1 true true
|
|
||||||
0.5~=2 true true
|
|
||||||
0.5~=-1 true true
|
|
||||||
0.5~=2 true true
|
|
||||||
2.25~=0 true true
|
|
||||||
2.25~=2 true true
|
|
||||||
-2~=0 true true
|
|
||||||
3~=3 true false
|
|
||||||
'2'~='0' true true
|
|
||||||
'2.5'~='3' true true
|
|
||||||
'-2'~='1.5' true true
|
|
||||||
'-2.5'~='-1.5' true true
|
|
||||||
'3.0'~='3.0' true false
|
|
||||||
2.75~=2.75 true false
|
|
||||||
'2.75'~='2.75' true false
|
|
||||||
---------- binary operator > ----------
|
|
||||||
2>0 true true
|
|
||||||
-2.5>0 true false
|
|
||||||
2>1 true true
|
|
||||||
5>2 true true
|
|
||||||
-5>2 true false
|
|
||||||
16>2 true true
|
|
||||||
-16>-2 true false
|
|
||||||
0.5>0 true true
|
|
||||||
0.5>1 true false
|
|
||||||
0.5>2 true false
|
|
||||||
0.5>-1 true true
|
|
||||||
0.5>2 true false
|
|
||||||
2.25>0 true true
|
|
||||||
2.25>2 true true
|
|
||||||
-2>0 true false
|
|
||||||
3>3 true false
|
|
||||||
'2'>'0' true true
|
|
||||||
'2.5'>'3' true false
|
|
||||||
'-2'>'1.5' true false
|
|
||||||
'-2.5'>'-1.5' true true
|
|
||||||
'3.0'>'3.0' true false
|
|
||||||
2.75>2.75 true false
|
|
||||||
'2.75'>'2.75' true false
|
|
||||||
---------- binary operator < ----------
|
|
||||||
2<0 true false
|
|
||||||
-2.5<0 true true
|
|
||||||
2<1 true false
|
|
||||||
5<2 true false
|
|
||||||
-5<2 true true
|
|
||||||
16<2 true false
|
|
||||||
-16<-2 true true
|
|
||||||
0.5<0 true false
|
|
||||||
0.5<1 true true
|
|
||||||
0.5<2 true true
|
|
||||||
0.5<-1 true false
|
|
||||||
0.5<2 true true
|
|
||||||
2.25<0 true false
|
|
||||||
2.25<2 true false
|
|
||||||
-2<0 true true
|
|
||||||
3<3 true false
|
|
||||||
'2'<'0' true false
|
|
||||||
'2.5'<'3' true true
|
|
||||||
'-2'<'1.5' true true
|
|
||||||
'-2.5'<'-1.5' true false
|
|
||||||
'3.0'<'3.0' true false
|
|
||||||
2.75<2.75 true false
|
|
||||||
'2.75'<'2.75' true false
|
|
||||||
---------- binary operator >= ----------
|
|
||||||
2>=0 true true
|
|
||||||
-2.5>=0 true false
|
|
||||||
2>=1 true true
|
|
||||||
5>=2 true true
|
|
||||||
-5>=2 true false
|
|
||||||
16>=2 true true
|
|
||||||
-16>=-2 true false
|
|
||||||
0.5>=0 true true
|
|
||||||
0.5>=1 true false
|
|
||||||
0.5>=2 true false
|
|
||||||
0.5>=-1 true true
|
|
||||||
0.5>=2 true false
|
|
||||||
2.25>=0 true true
|
|
||||||
2.25>=2 true true
|
|
||||||
-2>=0 true false
|
|
||||||
3>=3 true true
|
|
||||||
'2'>='0' true true
|
|
||||||
'2.5'>='3' true false
|
|
||||||
'-2'>='1.5' true false
|
|
||||||
'-2.5'>='-1.5' true true
|
|
||||||
'3.0'>='3.0' true true
|
|
||||||
2.75>=2.75 true true
|
|
||||||
'2.75'>='2.75' true true
|
|
||||||
---------- binary operator <= ----------
|
|
||||||
2<=0 true false
|
|
||||||
-2.5<=0 true true
|
|
||||||
2<=1 true false
|
|
||||||
5<=2 true false
|
|
||||||
-5<=2 true true
|
|
||||||
16<=2 true false
|
|
||||||
-16<=-2 true true
|
|
||||||
0.5<=0 true false
|
|
||||||
0.5<=1 true true
|
|
||||||
0.5<=2 true true
|
|
||||||
0.5<=-1 true false
|
|
||||||
0.5<=2 true true
|
|
||||||
2.25<=0 true false
|
|
||||||
2.25<=2 true false
|
|
||||||
-2<=0 true true
|
|
||||||
3<=3 true true
|
|
||||||
'2'<='0' true false
|
|
||||||
'2.5'<='3' true true
|
|
||||||
'-2'<='1.5' true true
|
|
||||||
'-2.5'<='-1.5' true false
|
|
||||||
'3.0'<='3.0' true true
|
|
||||||
2.75<=2.75 true true
|
|
||||||
'2.75'<='2.75' true true
|
|
||||||
---------- math.abs ----------
|
|
||||||
math.abs(-2.5) true 2.5
|
|
||||||
math.abs(-2) true 2
|
|
||||||
math.abs(0) true <zero>
|
|
||||||
math.abs(2) true 2
|
|
||||||
math.abs(2.5) true 2.5
|
|
||||||
math.abs('-2.5') true 2.5
|
|
||||||
math.abs('-2') true 2
|
|
||||||
math.abs('0') true <zero>
|
|
||||||
math.abs('2') true 2
|
|
||||||
math.abs('2.5') true 2.5
|
|
||||||
---------- math.ceil ----------
|
|
||||||
math.ceil(-2.5) true -2
|
|
||||||
math.ceil(-2) true -2
|
|
||||||
math.ceil(0) true <zero>
|
|
||||||
math.ceil(2) true 2
|
|
||||||
math.ceil(2.5) true 3
|
|
||||||
math.ceil('-2.5') true -2
|
|
||||||
math.ceil('-2') true -2
|
|
||||||
math.ceil('0') true <zero>
|
|
||||||
math.ceil('2') true 2
|
|
||||||
math.ceil('2.5') true 3
|
|
||||||
---------- math.cos ----------
|
|
||||||
math.cos(-2.5) true -0.801
|
|
||||||
math.cos(-2) true -0.416
|
|
||||||
math.cos(0) true 1
|
|
||||||
math.cos(2) true -0.416
|
|
||||||
math.cos(2.5) true -0.801
|
|
||||||
math.cos('-2.5') true -0.801
|
|
||||||
math.cos('-2') true -0.416
|
|
||||||
math.cos('0') true 1
|
|
||||||
math.cos('2') true -0.416
|
|
||||||
math.cos('2.5') true -0.801
|
|
||||||
---------- math.deg ----------
|
|
||||||
math.deg(-2.5) true -143.2
|
|
||||||
math.deg(-2) true -114.5
|
|
||||||
math.deg(0) true <zero>
|
|
||||||
math.deg(2) true 114.59
|
|
||||||
math.deg(2.5) true 143.23
|
|
||||||
math.deg('-2.5') true -143.2
|
|
||||||
math.deg('-2') true -114.5
|
|
||||||
math.deg('0') true <zero>
|
|
||||||
math.deg('2') true 114.59
|
|
||||||
math.deg('2.5') true 143.23
|
|
||||||
---------- math.exp ----------
|
|
||||||
math.exp(-2.5) true 0.0820
|
|
||||||
math.exp(-2) true 0.1353
|
|
||||||
math.exp(0) true 1
|
|
||||||
math.exp(2) true 7.3890
|
|
||||||
math.exp(2.5) true 12.182
|
|
||||||
math.exp('-2.5') true 0.0820
|
|
||||||
math.exp('-2') true 0.1353
|
|
||||||
math.exp('0') true 1
|
|
||||||
math.exp('2') true 7.3890
|
|
||||||
math.exp('2.5') true 12.182
|
|
||||||
---------- math.floor ----------
|
|
||||||
math.floor(-2.5) true -3
|
|
||||||
math.floor(-2) true -2
|
|
||||||
math.floor(0) true <zero>
|
|
||||||
math.floor(2) true 2
|
|
||||||
math.floor(2.5) true 2
|
|
||||||
math.floor('-2.5') true -3
|
|
||||||
math.floor('-2') true -2
|
|
||||||
math.floor('0') true <zero>
|
|
||||||
math.floor('2') true 2
|
|
||||||
math.floor('2.5') true 2
|
|
||||||
---------- math.frexp ----------
|
|
||||||
math.frexp(-2.5) true -0.625 2
|
|
||||||
math.frexp(-2) true -0.5 2
|
|
||||||
math.frexp(0) true <zero> <zero>
|
|
||||||
math.frexp(2) true 0.5 2
|
|
||||||
math.frexp(2.5) true 0.625 2
|
|
||||||
math.frexp('-2.5') true -0.625 2
|
|
||||||
math.frexp('-2') true -0.5 2
|
|
||||||
math.frexp('0') true <zero> <zero>
|
|
||||||
math.frexp('2') true 0.5 2
|
|
||||||
math.frexp('2.5') true 0.625 2
|
|
||||||
---------- math.modf ----------
|
|
||||||
math.modf(-2.5) true -2 -0.5
|
|
||||||
math.modf(-2) true -2 <zero>
|
|
||||||
math.modf(0) true <zero> <zero>
|
|
||||||
math.modf(2) true 2 <zero>
|
|
||||||
math.modf(2.5) true 2 0.5
|
|
||||||
math.modf('-2.5') true -2 -0.5
|
|
||||||
math.modf('-2') true -2 <zero>
|
|
||||||
math.modf('0') true <zero> <zero>
|
|
||||||
math.modf('2') true 2 <zero>
|
|
||||||
math.modf('2.5') true 2 0.5
|
|
||||||
---------- math.rad ----------
|
|
||||||
math.rad(-2.5) true -0.043
|
|
||||||
math.rad(-2) true -0.034
|
|
||||||
math.rad(0) true <zero>
|
|
||||||
math.rad(2) true 0.0349
|
|
||||||
math.rad(2.5) true 0.0436
|
|
||||||
math.rad('-2.5') true -0.043
|
|
||||||
math.rad('-2') true -0.034
|
|
||||||
math.rad('0') true <zero>
|
|
||||||
math.rad('2') true 0.0349
|
|
||||||
math.rad('2.5') true 0.0436
|
|
||||||
---------- math.sin ----------
|
|
||||||
math.sin(-2.5) true -0.598
|
|
||||||
math.sin(-2) true -0.909
|
|
||||||
math.sin(0) true <zero>
|
|
||||||
math.sin(2) true 0.9092
|
|
||||||
math.sin(2.5) true 0.5984
|
|
||||||
math.sin('-2.5') true -0.598
|
|
||||||
math.sin('-2') true -0.909
|
|
||||||
math.sin('0') true <zero>
|
|
||||||
math.sin('2') true 0.9092
|
|
||||||
math.sin('2.5') true 0.5984
|
|
||||||
---------- math.sqrt ----------
|
|
||||||
math.sqrt(-2.5) true <nan>
|
|
||||||
math.sqrt(-2) true <nan>
|
|
||||||
math.sqrt(0) true <zero>
|
|
||||||
math.sqrt(2) true 1.4142
|
|
||||||
math.sqrt(2.5) true 1.5811
|
|
||||||
math.sqrt('-2.5') true <nan>
|
|
||||||
math.sqrt('-2') true <nan>
|
|
||||||
math.sqrt('0') true <zero>
|
|
||||||
math.sqrt('2') true 1.4142
|
|
||||||
math.sqrt('2.5') true 1.5811
|
|
||||||
---------- math.tan ----------
|
|
||||||
math.tan(-2.5) true 0.7470
|
|
||||||
math.tan(-2) true 2.1850
|
|
||||||
math.tan(0) true <zero>
|
|
||||||
math.tan(2) true -2.185
|
|
||||||
math.tan(2.5) true -0.747
|
|
||||||
math.tan('-2.5') true 0.7470
|
|
||||||
math.tan('-2') true 2.1850
|
|
||||||
math.tan('0') true <zero>
|
|
||||||
math.tan('2') true -2.185
|
|
||||||
math.tan('2.5') true -0.747
|
|
||||||
---------- math.fmod ----------
|
|
||||||
math.fmod(2,0) true <nan>
|
|
||||||
math.fmod(-2.5,0) true <nan>
|
|
||||||
math.fmod(2,1) true <zero>
|
|
||||||
math.fmod(5,2) true 1
|
|
||||||
math.fmod(-5,2) true -1
|
|
||||||
math.fmod(16,2) true <zero>
|
|
||||||
math.fmod(-16,-2) true <zero>
|
|
||||||
math.fmod(0.5,0) true <nan>
|
|
||||||
math.fmod(0.5,1) true 0.5
|
|
||||||
math.fmod(0.5,2) true 0.5
|
|
||||||
math.fmod(0.5,-1) true 0.5
|
|
||||||
math.fmod(0.5,2) true 0.5
|
|
||||||
math.fmod(2.25,0) true <nan>
|
|
||||||
math.fmod(2.25,2) true 0.25
|
|
||||||
math.fmod(-2,0) true <nan>
|
|
||||||
math.fmod(3,3) true <zero>
|
|
||||||
math.fmod('2','0') true <nan>
|
|
||||||
math.fmod('2.5','3') true 2.5
|
|
||||||
math.fmod('-2','1.5') true -0.5
|
|
||||||
math.fmod('-2.5','-1.5') true -1
|
|
||||||
math.fmod('3.0','3.0') true <zero>
|
|
||||||
math.fmod(2.75,2.75) true <zero>
|
|
||||||
math.fmod('2.75','2.75') true <zero>
|
|
||||||
math.fmod(3,'3') true <zero>
|
|
||||||
math.fmod('3',3) true <zero>
|
|
||||||
math.fmod(2.75,'2.75') true <zero>
|
|
||||||
math.fmod('2.75',2.75) true <zero>
|
|
||||||
math.fmod(-3,'-4') true -3
|
|
||||||
math.fmod('-3',4) true -3
|
|
||||||
math.fmod(-3,'4') true -3
|
|
||||||
math.fmod('-3',-4) true -3
|
|
||||||
math.fmod(-4.75,'2.75') true -2
|
|
||||||
math.fmod('-2.75',1.75) true -1
|
|
||||||
math.fmod(4.75,'-2.75') true 2
|
|
||||||
math.fmod('2.75',-1.75) true 1
|
|
||||||
---------- math.ldexp ----------
|
|
||||||
math.ldexp(2,0) true 2
|
|
||||||
math.ldexp(-2.5,0) true -2.5
|
|
||||||
math.ldexp(2,1) true 4
|
|
||||||
math.ldexp(5,2) true 20
|
|
||||||
math.ldexp(-5,2) true -20
|
|
||||||
math.ldexp(16,2) true 64
|
|
||||||
math.ldexp(-16,-2) true -4
|
|
||||||
math.ldexp(0.5,0) true 0.5
|
|
||||||
math.ldexp(0.5,1) true 1
|
|
||||||
math.ldexp(0.5,2) true 2
|
|
||||||
math.ldexp(0.5,-1) true 0.25
|
|
||||||
math.ldexp(0.5,2) true 2
|
|
||||||
math.ldexp(2.25,0) true 2.25
|
|
||||||
math.ldexp(2.25,2) true 9
|
|
||||||
math.ldexp(-2,0) true -2
|
|
||||||
math.ldexp(3,3) true 24
|
|
||||||
math.ldexp('2','0') true 2
|
|
||||||
math.ldexp('2.5','3') true 20
|
|
||||||
math.ldexp('-2','1.5') true -4
|
|
||||||
math.ldexp('-2.5','-1.5') true -1.25
|
|
||||||
math.ldexp('3.0','3.0') true 24
|
|
||||||
math.ldexp(2.75,2.75) true 11
|
|
||||||
math.ldexp('2.75','2.75') true 11
|
|
||||||
math.ldexp(3,'3') true 24
|
|
||||||
math.ldexp('3',3) true 24
|
|
||||||
math.ldexp(2.75,'2.75') true 11
|
|
||||||
math.ldexp('2.75',2.75) true 11
|
|
||||||
math.ldexp(-3,'-4') true -0.187
|
|
||||||
math.ldexp('-3',4) true -48
|
|
||||||
math.ldexp(-3,'4') true -48
|
|
||||||
math.ldexp('-3',-4) true -0.187
|
|
||||||
math.ldexp(-4.75,'2.75') true -19
|
|
||||||
math.ldexp('-2.75',1.75) true -5.5
|
|
||||||
math.ldexp(4.75,'-2.75') true 1.1875
|
|
||||||
math.ldexp('2.75',-1.75) true 1.375
|
|
||||||
---------- math.pow ----------
|
|
||||||
math.pow(2,0) true 1
|
|
||||||
math.pow(-2.5,0) true 1
|
|
||||||
math.pow(2,1) true 2
|
|
||||||
math.pow(5,2) true 25
|
|
||||||
math.pow(-5,2) true 25
|
|
||||||
math.pow(16,2) true 256
|
|
||||||
math.pow(-16,-2) true 0.0039
|
|
||||||
math.pow(0.5,0) true 1
|
|
||||||
math.pow(0.5,1) true 0.5
|
|
||||||
math.pow(0.5,2) true 0.25
|
|
||||||
math.pow(0.5,-1) true 2
|
|
||||||
math.pow(0.5,2) true 0.25
|
|
||||||
math.pow(2.25,0) true 1
|
|
||||||
math.pow(2.25,2) true 5.0625
|
|
||||||
math.pow(-2,0) true 1
|
|
||||||
math.pow(3,3) true 27
|
|
||||||
math.pow('2','0') true 1
|
|
||||||
math.pow('2.5','3') true 15.625
|
|
||||||
math.pow('-2','1.5') true <nan>
|
|
||||||
math.pow('-2.5','-1.5') true <nan>
|
|
||||||
math.pow('3.0','3.0') true 27
|
|
||||||
math.pow(2.75,2.75) true 16.149
|
|
||||||
math.pow('2.75','2.75') true 16.149
|
|
||||||
math.pow(3,'3') true 27
|
|
||||||
math.pow('3',3) true 27
|
|
||||||
math.pow(2.75,'2.75') true 16.149
|
|
||||||
math.pow('2.75',2.75) true 16.149
|
|
||||||
math.pow(-3,'-4') true 0.0123
|
|
||||||
math.pow('-3',4) true 81
|
|
||||||
math.pow(-3,'4') true 81
|
|
||||||
math.pow('-3',-4) true 0.0123
|
|
||||||
math.pow(-4.75,'2.75') true <nan>
|
|
||||||
math.pow('-2.75',1.75) true <nan>
|
|
||||||
math.pow(4.75,'-2.75') true 0.0137
|
|
||||||
math.pow('2.75',-1.75) true 0.1702
|
|
||||||
---------- math.max ----------
|
|
||||||
math.max(4) true 4
|
|
||||||
math.max(-4.5) true -4.5
|
|
||||||
math.max('5.5') true 5.5
|
|
||||||
math.max('-5') true -5
|
|
||||||
math.max(4,'8') true 8
|
|
||||||
math.max(-4.5,'-8') true -4.5
|
|
||||||
math.max('5.5',2.2) true 5.5
|
|
||||||
math.max('-5',-2.2) true -2.2
|
|
||||||
math.max(111,222,333) true 333
|
|
||||||
math.max(-222,-333,-111) true -111
|
|
||||||
math.max(444,-111,-222) true 444
|
|
||||||
---------- math.min ----------
|
|
||||||
math.min(4) true 4
|
|
||||||
math.min(-4.5) true -4.5
|
|
||||||
math.min('5.5') true 5.5
|
|
||||||
math.min('-5') true -5
|
|
||||||
math.min(4,'8') true 4
|
|
||||||
math.min(-4.5,'-8') true -8
|
|
||||||
math.min('5.5',2.2) true 2.2
|
|
||||||
math.min('-5',-2.2) true -5
|
|
||||||
math.min(111,222,333) true 111
|
|
||||||
math.min(-222,-333,-111) true -333
|
|
||||||
math.min(444,-111,-222) true -222
|
|
||||||
----------- Random number tests
|
|
||||||
math.random() number true
|
|
||||||
math.random() number true
|
|
||||||
math.random() number true
|
|
||||||
math.random() number true
|
|
||||||
math.random() number true
|
|
||||||
math.random(5,10) number true
|
|
||||||
math.random(5,10) number true
|
|
||||||
math.random(5,10) number true
|
|
||||||
math.random(5,10) number true
|
|
||||||
math.random(5,10) number true
|
|
||||||
math.random(30) number true
|
|
||||||
math.random(30) number true
|
|
||||||
math.random(30) number true
|
|
||||||
math.random(30) number true
|
|
||||||
math.random(30) number true
|
|
||||||
math.random(-4,-2) number true
|
|
||||||
math.random(-4,-2) number true
|
|
||||||
math.random(-4,-2) number true
|
|
||||||
math.random(-4,-2) number true
|
|
||||||
math.random(-4,-2) number true
|
|
||||||
|
|
||||||
-- comparing new numbers
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
false false
|
|
||||||
-- resetting seed
|
|
||||||
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
----------- Tests involving -0 and NaN
|
|
||||||
0 == -0 true
|
|
||||||
t[-0] == t[0] true
|
|
||||||
mz, z <zero> <zero>
|
|
||||||
mz == z true
|
|
||||||
a[z] == 1 and a[mz] == 1 true
|
|
||||||
@@ -1,649 +0,0 @@
|
|||||||
---- __eq same types
|
|
||||||
nil nil before true true
|
|
||||||
nil nil before true false
|
|
||||||
nil
|
|
||||||
nil
|
|
||||||
nil nil after true true
|
|
||||||
nil nil after true false
|
|
||||||
nil
|
|
||||||
nil
|
|
||||||
boolean boolean before true false
|
|
||||||
boolean boolean before true true
|
|
||||||
true
|
|
||||||
false
|
|
||||||
boolean boolean after true false
|
|
||||||
boolean boolean after true true
|
|
||||||
true
|
|
||||||
false
|
|
||||||
number number before true false
|
|
||||||
number number before true true
|
|
||||||
123
|
|
||||||
456
|
|
||||||
number number after true false
|
|
||||||
number number after true true
|
|
||||||
123
|
|
||||||
456
|
|
||||||
number number before true false
|
|
||||||
number number before true true
|
|
||||||
11
|
|
||||||
5.5
|
|
||||||
number number after true false
|
|
||||||
number number after true true
|
|
||||||
11
|
|
||||||
5.5
|
|
||||||
function function before true false
|
|
||||||
function function before true true
|
|
||||||
function.1
|
|
||||||
function.2
|
|
||||||
function function after true false
|
|
||||||
function function after true true
|
|
||||||
function.1
|
|
||||||
function.2
|
|
||||||
thread nil before true false
|
|
||||||
thread nil before true true
|
|
||||||
thread.3
|
|
||||||
nil
|
|
||||||
thread nil after true false
|
|
||||||
thread nil after true true
|
|
||||||
thread.3
|
|
||||||
nil
|
|
||||||
string string before true false
|
|
||||||
string string before true true
|
|
||||||
abc
|
|
||||||
def
|
|
||||||
string string after true false
|
|
||||||
string string after true true
|
|
||||||
abc
|
|
||||||
def
|
|
||||||
number string before true false
|
|
||||||
number string before true true
|
|
||||||
111
|
|
||||||
111
|
|
||||||
number string after true false
|
|
||||||
number string after true true
|
|
||||||
111
|
|
||||||
111
|
|
||||||
---- __eq, tables - should invoke metatag comparison
|
|
||||||
table table before true false
|
|
||||||
table table before true true
|
|
||||||
table.4
|
|
||||||
table.5
|
|
||||||
mt.__eq() table.4 table.5
|
|
||||||
table table after-a true true
|
|
||||||
mt.__eq() table.4 table.5
|
|
||||||
table table after-a true false
|
|
||||||
table.4
|
|
||||||
table.5
|
|
||||||
nilmt nil
|
|
||||||
boolmt nil
|
|
||||||
number nil
|
|
||||||
function nil
|
|
||||||
thread nil
|
|
||||||
---- __call
|
|
||||||
number before false attempt to call
|
|
||||||
111
|
|
||||||
mt.__call() 111 nil
|
|
||||||
number after true __call-result
|
|
||||||
mt.__call() 111 a
|
|
||||||
number after true __call-result
|
|
||||||
mt.__call() 111 a
|
|
||||||
number after true __call-result
|
|
||||||
mt.__call() 111 a
|
|
||||||
number after true __call-result
|
|
||||||
mt.__call() 111 a
|
|
||||||
number after true __call-result
|
|
||||||
111
|
|
||||||
boolean before false attempt to call
|
|
||||||
false
|
|
||||||
mt.__call() false nil
|
|
||||||
boolean after true __call-result
|
|
||||||
mt.__call() false a
|
|
||||||
boolean after true __call-result
|
|
||||||
mt.__call() false a
|
|
||||||
boolean after true __call-result
|
|
||||||
mt.__call() false a
|
|
||||||
boolean after true __call-result
|
|
||||||
mt.__call() false a
|
|
||||||
boolean after true __call-result
|
|
||||||
false
|
|
||||||
function before true nil
|
|
||||||
function.1
|
|
||||||
function after true
|
|
||||||
function after true
|
|
||||||
function after true
|
|
||||||
function after true
|
|
||||||
function after true
|
|
||||||
function.1
|
|
||||||
thread before false attempt to call
|
|
||||||
thread.3
|
|
||||||
mt.__call() thread.3 nil
|
|
||||||
thread after true __call-result
|
|
||||||
mt.__call() thread.3 a
|
|
||||||
thread after true __call-result
|
|
||||||
mt.__call() thread.3 a
|
|
||||||
thread after true __call-result
|
|
||||||
mt.__call() thread.3 a
|
|
||||||
thread after true __call-result
|
|
||||||
mt.__call() thread.3 a
|
|
||||||
thread after true __call-result
|
|
||||||
thread.3
|
|
||||||
table before false attempt to call
|
|
||||||
table.4
|
|
||||||
mt.__call() table.4 nil
|
|
||||||
table after true __call-result
|
|
||||||
mt.__call() table.4 a
|
|
||||||
table after true __call-result
|
|
||||||
mt.__call() table.4 a
|
|
||||||
table after true __call-result
|
|
||||||
mt.__call() table.4 a
|
|
||||||
table after true __call-result
|
|
||||||
mt.__call() table.4 a
|
|
||||||
table after true __call-result
|
|
||||||
table.4
|
|
||||||
---- __add, __sub, __mul, __div, __pow, __mod
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
boolean boolean before false attempt to perform arithmetic
|
|
||||||
false
|
|
||||||
mt.__add() false false
|
|
||||||
boolean boolean after true __add-result
|
|
||||||
mt.__add() false false
|
|
||||||
boolean boolean after true __add-result
|
|
||||||
mt.__sub() false false
|
|
||||||
boolean boolean after true __sub-result
|
|
||||||
mt.__sub() false false
|
|
||||||
boolean boolean after true __sub-result
|
|
||||||
mt.__mul() false false
|
|
||||||
boolean boolean after true __mul-result
|
|
||||||
mt.__mul() false false
|
|
||||||
boolean boolean after true __mul-result
|
|
||||||
mt.__pow() false false
|
|
||||||
boolean boolean after true __pow-result
|
|
||||||
mt.__pow() false false
|
|
||||||
boolean boolean after true __pow-result
|
|
||||||
mt.__mod() false false
|
|
||||||
boolean boolean after true __mod-result
|
|
||||||
mt.__mod() false false
|
|
||||||
boolean boolean after true __mod-result
|
|
||||||
false
|
|
||||||
false
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
boolean thread before false attempt to perform arithmetic
|
|
||||||
false
|
|
||||||
mt.__add() false thread.3
|
|
||||||
boolean thread after true __add-result
|
|
||||||
mt.__add() thread.3 false
|
|
||||||
boolean thread after true __add-result
|
|
||||||
mt.__sub() false thread.3
|
|
||||||
boolean thread after true __sub-result
|
|
||||||
mt.__sub() thread.3 false
|
|
||||||
boolean thread after true __sub-result
|
|
||||||
mt.__mul() false thread.3
|
|
||||||
boolean thread after true __mul-result
|
|
||||||
mt.__mul() thread.3 false
|
|
||||||
boolean thread after true __mul-result
|
|
||||||
mt.__pow() false thread.3
|
|
||||||
boolean thread after true __pow-result
|
|
||||||
mt.__pow() thread.3 false
|
|
||||||
boolean thread after true __pow-result
|
|
||||||
mt.__mod() false thread.3
|
|
||||||
boolean thread after true __mod-result
|
|
||||||
mt.__mod() thread.3 false
|
|
||||||
boolean thread after true __mod-result
|
|
||||||
false
|
|
||||||
thread.3
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
boolean function before false attempt to perform arithmetic
|
|
||||||
false
|
|
||||||
mt.__add() false function.1
|
|
||||||
boolean function after true __add-result
|
|
||||||
mt.__add() function.1 false
|
|
||||||
boolean function after true __add-result
|
|
||||||
mt.__sub() false function.1
|
|
||||||
boolean function after true __sub-result
|
|
||||||
mt.__sub() function.1 false
|
|
||||||
boolean function after true __sub-result
|
|
||||||
mt.__mul() false function.1
|
|
||||||
boolean function after true __mul-result
|
|
||||||
mt.__mul() function.1 false
|
|
||||||
boolean function after true __mul-result
|
|
||||||
mt.__pow() false function.1
|
|
||||||
boolean function after true __pow-result
|
|
||||||
mt.__pow() function.1 false
|
|
||||||
boolean function after true __pow-result
|
|
||||||
mt.__mod() false function.1
|
|
||||||
boolean function after true __mod-result
|
|
||||||
mt.__mod() function.1 false
|
|
||||||
boolean function after true __mod-result
|
|
||||||
false
|
|
||||||
function.1
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
boolean string before false attempt to perform arithmetic
|
|
||||||
false
|
|
||||||
mt.__add() false abc
|
|
||||||
boolean string after true __add-result
|
|
||||||
mt.__add() abc false
|
|
||||||
boolean string after true __add-result
|
|
||||||
mt.__sub() false abc
|
|
||||||
boolean string after true __sub-result
|
|
||||||
mt.__sub() abc false
|
|
||||||
boolean string after true __sub-result
|
|
||||||
mt.__mul() false abc
|
|
||||||
boolean string after true __mul-result
|
|
||||||
mt.__mul() abc false
|
|
||||||
boolean string after true __mul-result
|
|
||||||
mt.__pow() false abc
|
|
||||||
boolean string after true __pow-result
|
|
||||||
mt.__pow() abc false
|
|
||||||
boolean string after true __pow-result
|
|
||||||
mt.__mod() false abc
|
|
||||||
boolean string after true __mod-result
|
|
||||||
mt.__mod() abc false
|
|
||||||
boolean string after true __mod-result
|
|
||||||
false
|
|
||||||
abc
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
boolean table before false attempt to perform arithmetic
|
|
||||||
false
|
|
||||||
mt.__add() false table.4
|
|
||||||
boolean table after true __add-result
|
|
||||||
mt.__add() table.4 false
|
|
||||||
boolean table after true __add-result
|
|
||||||
mt.__sub() false table.4
|
|
||||||
boolean table after true __sub-result
|
|
||||||
mt.__sub() table.4 false
|
|
||||||
boolean table after true __sub-result
|
|
||||||
mt.__mul() false table.4
|
|
||||||
boolean table after true __mul-result
|
|
||||||
mt.__mul() table.4 false
|
|
||||||
boolean table after true __mul-result
|
|
||||||
mt.__pow() false table.4
|
|
||||||
boolean table after true __pow-result
|
|
||||||
mt.__pow() table.4 false
|
|
||||||
boolean table after true __pow-result
|
|
||||||
mt.__mod() false table.4
|
|
||||||
boolean table after true __mod-result
|
|
||||||
mt.__mod() table.4 false
|
|
||||||
boolean table after true __mod-result
|
|
||||||
false
|
|
||||||
table.4
|
|
||||||
---- __len
|
|
||||||
boolean before false attempt to get length of
|
|
||||||
false
|
|
||||||
mt.__len() false
|
|
||||||
boolean after true __len-result
|
|
||||||
false
|
|
||||||
function before false attempt to get length of
|
|
||||||
function.1
|
|
||||||
mt.__len() function.1
|
|
||||||
function after true __len-result
|
|
||||||
function.1
|
|
||||||
thread before false attempt to get length of
|
|
||||||
thread.3
|
|
||||||
mt.__len() thread.3
|
|
||||||
thread after true __len-result
|
|
||||||
thread.3
|
|
||||||
number before false attempt to get length of
|
|
||||||
111
|
|
||||||
mt.__len() 111
|
|
||||||
number after true __len-result
|
|
||||||
111
|
|
||||||
---- __neg
|
|
||||||
nil before false attempt to perform arithmetic
|
|
||||||
false
|
|
||||||
mt.__unm() false
|
|
||||||
nil after true __unm-result
|
|
||||||
false
|
|
||||||
nil before false attempt to perform arithmetic
|
|
||||||
function.1
|
|
||||||
mt.__unm() function.1
|
|
||||||
nil after true __unm-result
|
|
||||||
function.1
|
|
||||||
nil before false attempt to perform arithmetic
|
|
||||||
thread.3
|
|
||||||
mt.__unm() thread.3
|
|
||||||
nil after true __unm-result
|
|
||||||
thread.3
|
|
||||||
nil before false attempt to perform arithmetic
|
|
||||||
abcd
|
|
||||||
mt.__unm() abcd
|
|
||||||
nil after true __unm-result
|
|
||||||
abcd
|
|
||||||
nil before false attempt to perform arithmetic
|
|
||||||
table.4
|
|
||||||
mt.__unm() table.4
|
|
||||||
nil after true __unm-result
|
|
||||||
table.4
|
|
||||||
nil before true -111
|
|
||||||
111
|
|
||||||
nil after true -111
|
|
||||||
111
|
|
||||||
---- __lt, __le, same types
|
|
||||||
boolean boolean before false attempt to compare
|
|
||||||
boolean boolean before false attempt to compare
|
|
||||||
boolean boolean before false attempt to compare
|
|
||||||
boolean boolean before false attempt to compare
|
|
||||||
true
|
|
||||||
true
|
|
||||||
mt.__lt() true true
|
|
||||||
boolean boolean after true true
|
|
||||||
mt.__le() true true
|
|
||||||
boolean boolean after true true
|
|
||||||
mt.__lt() true true
|
|
||||||
boolean boolean after true true
|
|
||||||
mt.__le() true true
|
|
||||||
boolean boolean after true true
|
|
||||||
true
|
|
||||||
true
|
|
||||||
boolean boolean before false attempt to compare
|
|
||||||
boolean boolean before false attempt to compare
|
|
||||||
boolean boolean before false attempt to compare
|
|
||||||
boolean boolean before false attempt to compare
|
|
||||||
true
|
|
||||||
false
|
|
||||||
mt.__lt() true false
|
|
||||||
boolean boolean after true true
|
|
||||||
mt.__le() true false
|
|
||||||
boolean boolean after true true
|
|
||||||
mt.__lt() false true
|
|
||||||
boolean boolean after true true
|
|
||||||
mt.__le() false true
|
|
||||||
boolean boolean after true true
|
|
||||||
true
|
|
||||||
false
|
|
||||||
function function before false attempt to compare
|
|
||||||
function function before false attempt to compare
|
|
||||||
function function before false attempt to compare
|
|
||||||
function function before false attempt to compare
|
|
||||||
function.1
|
|
||||||
function.6
|
|
||||||
mt.__lt() function.1 function.6
|
|
||||||
function function after true true
|
|
||||||
mt.__le() function.1 function.6
|
|
||||||
function function after true true
|
|
||||||
mt.__lt() function.6 function.1
|
|
||||||
function function after true true
|
|
||||||
mt.__le() function.6 function.1
|
|
||||||
function function after true true
|
|
||||||
function.1
|
|
||||||
function.6
|
|
||||||
thread thread before false attempt to compare
|
|
||||||
thread thread before false attempt to compare
|
|
||||||
thread thread before false attempt to compare
|
|
||||||
thread thread before false attempt to compare
|
|
||||||
thread.3
|
|
||||||
thread.7
|
|
||||||
mt.__lt() thread.3 thread.7
|
|
||||||
thread thread after true true
|
|
||||||
mt.__le() thread.3 thread.7
|
|
||||||
thread thread after true true
|
|
||||||
mt.__lt() thread.7 thread.3
|
|
||||||
thread thread after true true
|
|
||||||
mt.__le() thread.7 thread.3
|
|
||||||
thread thread after true true
|
|
||||||
thread.3
|
|
||||||
thread.7
|
|
||||||
table table before false attempt to compare
|
|
||||||
table table before false attempt to compare
|
|
||||||
table table before false attempt to compare
|
|
||||||
table table before false attempt to compare
|
|
||||||
table.4
|
|
||||||
table.4
|
|
||||||
mt.__lt() table.4 table.4
|
|
||||||
table table after true true
|
|
||||||
mt.__le() table.4 table.4
|
|
||||||
table table after true true
|
|
||||||
mt.__lt() table.4 table.4
|
|
||||||
table table after true true
|
|
||||||
mt.__le() table.4 table.4
|
|
||||||
table table after true true
|
|
||||||
table.4
|
|
||||||
table.4
|
|
||||||
table table before false attempt to compare
|
|
||||||
table table before false attempt to compare
|
|
||||||
table table before false attempt to compare
|
|
||||||
table table before false attempt to compare
|
|
||||||
table.4
|
|
||||||
table.8
|
|
||||||
mt.__lt() table.4 table.8
|
|
||||||
table table after true true
|
|
||||||
mt.__le() table.4 table.8
|
|
||||||
table table after true true
|
|
||||||
mt.__lt() table.8 table.4
|
|
||||||
table table after true true
|
|
||||||
mt.__le() table.8 table.4
|
|
||||||
table table after true true
|
|
||||||
table.4
|
|
||||||
table.8
|
|
||||||
---- __lt, __le, different types
|
|
||||||
boolean thread before false attempt to compare
|
|
||||||
boolean thread before false attempt to compare
|
|
||||||
boolean thread before false attempt to compare
|
|
||||||
boolean thread before false attempt to compare
|
|
||||||
false
|
|
||||||
thread.3
|
|
||||||
mt.__lt() false thread.3
|
|
||||||
boolean thread after-a true true
|
|
||||||
mt.__le() false thread.3
|
|
||||||
boolean thread after-a true true
|
|
||||||
mt.__lt() thread.3 false
|
|
||||||
boolean thread after-a true true
|
|
||||||
mt.__le() thread.3 false
|
|
||||||
boolean thread after-a true true
|
|
||||||
false
|
|
||||||
thread.3
|
|
||||||
---- __tostring
|
|
||||||
mt.__tostring(boolean)
|
|
||||||
boolean after mt.__tostring(boolean) mt.__tostring(boolean)
|
|
||||||
false
|
|
||||||
function.1
|
|
||||||
function after true mt.__tostring(function)
|
|
||||||
function.1
|
|
||||||
thread.3
|
|
||||||
thread after true mt.__tostring(thread)
|
|
||||||
thread.3
|
|
||||||
table.4
|
|
||||||
table after true mt.__tostring(table)
|
|
||||||
table.4
|
|
||||||
mt.__tostring(string)
|
|
||||||
mt.__tostring(string) mt.__tostring(string) true mt.__tostring(string)
|
|
||||||
abc
|
|
||||||
---- __index, __newindex
|
|
||||||
boolean before false attempt to index
|
|
||||||
boolean before false attempt to index
|
|
||||||
boolean before false index
|
|
||||||
boolean before false index
|
|
||||||
boolean before false attempt to index
|
|
||||||
false
|
|
||||||
mt.__index() false foo
|
|
||||||
boolean after true __index-result
|
|
||||||
mt.__index() false 123
|
|
||||||
boolean after true __index-result
|
|
||||||
mt.__newindex() false foo bar
|
|
||||||
boolean after true
|
|
||||||
mt.__newindex() false 123 bar
|
|
||||||
boolean after true
|
|
||||||
mt.__index() false foo
|
|
||||||
boolean after false attempt to call
|
|
||||||
false
|
|
||||||
number before false attempt to index
|
|
||||||
number before false attempt to index
|
|
||||||
number before false index
|
|
||||||
number before false index
|
|
||||||
number before false attempt to index
|
|
||||||
111
|
|
||||||
mt.__index() 111 foo
|
|
||||||
number after true __index-result
|
|
||||||
mt.__index() 111 123
|
|
||||||
number after true __index-result
|
|
||||||
mt.__newindex() 111 foo bar
|
|
||||||
number after true
|
|
||||||
mt.__newindex() 111 123 bar
|
|
||||||
number after true
|
|
||||||
mt.__index() 111 foo
|
|
||||||
number after false attempt to call
|
|
||||||
111
|
|
||||||
function before false attempt to index
|
|
||||||
function before false attempt to index
|
|
||||||
function before false index
|
|
||||||
function before false index
|
|
||||||
function before false attempt to index
|
|
||||||
function.1
|
|
||||||
mt.__index() function.1 foo
|
|
||||||
function after true __index-result
|
|
||||||
mt.__index() function.1 123
|
|
||||||
function after true __index-result
|
|
||||||
mt.__newindex() function.1 foo bar
|
|
||||||
function after true
|
|
||||||
mt.__newindex() function.1 123 bar
|
|
||||||
function after true
|
|
||||||
mt.__index() function.1 foo
|
|
||||||
function after false attempt to call
|
|
||||||
function.1
|
|
||||||
thread before false attempt to index
|
|
||||||
thread before false attempt to index
|
|
||||||
thread before false index
|
|
||||||
thread before false index
|
|
||||||
thread before false attempt to index
|
|
||||||
thread.3
|
|
||||||
mt.__index() thread.3 foo
|
|
||||||
thread after true __index-result
|
|
||||||
mt.__index() thread.3 123
|
|
||||||
thread after true __index-result
|
|
||||||
mt.__newindex() thread.3 foo bar
|
|
||||||
thread after true
|
|
||||||
mt.__newindex() thread.3 123 bar
|
|
||||||
thread after true
|
|
||||||
mt.__index() thread.3 foo
|
|
||||||
thread after false attempt to call
|
|
||||||
thread.3
|
|
||||||
---- __concat
|
|
||||||
table function before false attempt to concatenate
|
|
||||||
table function before false attempt to concatenate
|
|
||||||
table string number before false attempt to concatenate
|
|
||||||
string table number before false attempt to concatenate
|
|
||||||
string number table before false attempt to concatenate
|
|
||||||
table.4
|
|
||||||
mt.__concat(table,function) table.4 function.1
|
|
||||||
table function after true table.9
|
|
||||||
mt.__concat(function,table) function.1 table.4
|
|
||||||
table function after true table.9
|
|
||||||
mt.__concat(table,string) table.4 sss777
|
|
||||||
table string number before true table.9
|
|
||||||
mt.__concat(table,number) table.4 777
|
|
||||||
string table number before false attempt to concatenate
|
|
||||||
mt.__concat(number,table) 777 table.4
|
|
||||||
string number table before false attempt to concatenate
|
|
||||||
table.4
|
|
||||||
function.1
|
|
||||||
function table before false attempt to concatenate
|
|
||||||
function table before false attempt to concatenate
|
|
||||||
function string number before false attempt to concatenate
|
|
||||||
string function number before false attempt to concatenate
|
|
||||||
string number function before false attempt to concatenate
|
|
||||||
function.1
|
|
||||||
mt.__concat(function,table) function.1 table.4
|
|
||||||
function table after true table.9
|
|
||||||
mt.__concat(table,function) table.4 function.1
|
|
||||||
function table after true table.9
|
|
||||||
mt.__concat(function,string) function.1 sss777
|
|
||||||
function string number before true table.9
|
|
||||||
mt.__concat(function,number) function.1 777
|
|
||||||
string function number before false attempt to concatenate
|
|
||||||
mt.__concat(number,function) 777 function.1
|
|
||||||
string number function before false attempt to concatenate
|
|
||||||
function.1
|
|
||||||
table.4
|
|
||||||
number nil before false attempt to concatenate
|
|
||||||
number nil before false attempt to concatenate
|
|
||||||
number string number before true 123sss777
|
|
||||||
string number number before true sss123777
|
|
||||||
string number number before true sss777123
|
|
||||||
123
|
|
||||||
mt.__concat(number,nil) 123 nil
|
|
||||||
number nil after true table.9
|
|
||||||
mt.__concat(nil,number) nil 123
|
|
||||||
number nil after true table.9
|
|
||||||
number string number before true 123sss777
|
|
||||||
string number number before true sss123777
|
|
||||||
string number number before true sss777123
|
|
||||||
123
|
|
||||||
nil
|
|
||||||
nil number before false attempt to concatenate
|
|
||||||
nil number before false attempt to concatenate
|
|
||||||
nil string number before false attempt to concatenate
|
|
||||||
string nil number before false attempt to concatenate
|
|
||||||
string number nil before false attempt to concatenate
|
|
||||||
nil
|
|
||||||
mt.__concat(nil,number) nil 123
|
|
||||||
nil number after true table.9
|
|
||||||
mt.__concat(number,nil) 123 nil
|
|
||||||
nil number after true table.9
|
|
||||||
mt.__concat(nil,string) nil sss777
|
|
||||||
nil string number before true table.9
|
|
||||||
mt.__concat(nil,number) nil 777
|
|
||||||
string nil number before false attempt to concatenate
|
|
||||||
mt.__concat(number,nil) 777 nil
|
|
||||||
string number nil before false attempt to concatenate
|
|
||||||
nil
|
|
||||||
123
|
|
||||||
---- __metatable
|
|
||||||
boolean before true nil nil
|
|
||||||
false
|
|
||||||
boolean after true table.10 table.11
|
|
||||||
false
|
|
||||||
function before true nil nil
|
|
||||||
function.1
|
|
||||||
function after true table.10 table.11
|
|
||||||
function.1
|
|
||||||
thread before true nil nil
|
|
||||||
thread.3
|
|
||||||
thread after true table.10 table.11
|
|
||||||
thread.3
|
|
||||||
table before true nil nil
|
|
||||||
table.4
|
|
||||||
table after true table.10 table.11
|
|
||||||
table.4
|
|
||||||
string before true table.12 table.12
|
|
||||||
abc
|
|
||||||
string after true table.10 table.11
|
|
||||||
abc
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
os table
|
|
||||||
os.clock() true number nil
|
|
||||||
os.date() true string nil
|
|
||||||
os.difftime(123000, 21500) true number nil
|
|
||||||
os.getenv() false string nil
|
|
||||||
os.getenv("bogus.key") true nil nil
|
|
||||||
os.tmpname() true string
|
|
||||||
os.tmpname() true string
|
|
||||||
io.open true userdata
|
|
||||||
write false string nil
|
|
||||||
close false string nil
|
|
||||||
os.rename(p,q) true boolean nil
|
|
||||||
os.remove(q) true boolean nil
|
|
||||||
os.remove(q) true nil string
|
|
||||||
os.setlocale("C") true string nil
|
|
||||||
os.exit function
|
|
||||||
os.date('%a', 1281364496) true string nil
|
|
||||||
os.date('%A', 1281364496) true string nil
|
|
||||||
os.date('%b', 1281364496) true string nil
|
|
||||||
os.date('%B', 1281364496) true string nil
|
|
||||||
os.date('%c', 1281364496) true string nil
|
|
||||||
os.date('%C', 1281364496) true string nil
|
|
||||||
os.date('%d', 1281364496) true string nil
|
|
||||||
os.date('%D', 1281364496) true string nil
|
|
||||||
os.date('%e', 1281364496) true string nil
|
|
||||||
os.date('%F', 1281364496) true string nil
|
|
||||||
os.date('%g', 1281364496) true string nil
|
|
||||||
os.date('%G', 1281364496) true string nil
|
|
||||||
os.date('%h', 1281364496) true string nil
|
|
||||||
os.date('%H', 1281364496) true string nil
|
|
||||||
os.date('%I', 1281364496) true string nil
|
|
||||||
os.date('%j', 1281364496) true string nil
|
|
||||||
os.date('%m', 1281364496) true string nil
|
|
||||||
os.date('%M', 1281364496) true string nil
|
|
||||||
os.date('%n', 1281364496) true string nil
|
|
||||||
os.date('%p', 1281364496) true string nil
|
|
||||||
os.date('%r', 1281364496) true string nil
|
|
||||||
os.date('%R', 1281364496) true string nil
|
|
||||||
os.date('%S', 1281364496) true string nil
|
|
||||||
os.date('%t', 1281364496) true string nil
|
|
||||||
os.date('%T', 1281364496) true string nil
|
|
||||||
os.date('%u', 1281364496) true string nil
|
|
||||||
os.date('%U', 1281364496) true string nil
|
|
||||||
os.date('%V', 1281364496) true string nil
|
|
||||||
os.date('%w', 1281364496) true string nil
|
|
||||||
os.date('%W', 1281364496) true string nil
|
|
||||||
os.date('%x', 1281364496) true string nil
|
|
||||||
os.date('%X', 1281364496) true string nil
|
|
||||||
os.date('%y', 1281364496) true string nil
|
|
||||||
os.date('%Y', 1281364496) true string nil
|
|
||||||
os.date('%z', 1281364496) true string nil
|
|
||||||
os.date('%Z', 1281364496) true string nil
|
|
||||||
k string year v number 2010
|
|
||||||
k string month v number 8
|
|
||||||
k string day v number 9
|
|
||||||
k string hour v number 16
|
|
||||||
k string min v number 34
|
|
||||||
k string sec v number 56
|
|
||||||
k string wday v number 2
|
|
||||||
k string yday v number 221
|
|
||||||
k string isdst v boolean true
|
|
||||||
type(os.time()) number
|
|
||||||
os.time({year=1971, month=2, day=25}) 36327600
|
|
||||||
os.time({year=1971, month=2, day=25, hour=11, min=22, sec=33}) 36325353
|
|
||||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user