From 089e0cf20857c811a77abcf668b81eb8aaa58c8c Mon Sep 17 00:00:00 2001 From: decatur Date: Tue, 4 Oct 2011 22:27:20 +0200 Subject: [PATCH] first commit --- .classpath | 12 + .gitignore | 7 + .project | 17 + .settings/org.eclipse.jdt.core.prefs | 271 ++ .settings/org.eclipse.jdt.ui.prefs | 6 + .settings/org.eclipse.wst.validation.prefs | 6 + LICENSE | 21 + README.md | 3 + libs/bcel-5.1.jar | Bin 0 -> 515920 bytes libs/commons-io-1.4.jar | Bin 0 -> 109043 bytes src/main/java/Checker.java | 40 + src/main/java/Enhancer.java | 67 + src/main/java/com/j2js/ASTNodeStack.java | 62 + .../java/com/j2js/AnnotationAttribute.java | 28 + src/main/java/com/j2js/AnnotationReader.java | 58 + src/main/java/com/j2js/Assembly.java | 435 +++ src/main/java/com/j2js/Const.java | 2480 +++++++++++++++++ src/main/java/com/j2js/ConstGenerator.java | 29 + src/main/java/com/j2js/Diff.java | 105 + src/main/java/com/j2js/ExceptionHandler.java | 53 + src/main/java/com/j2js/ExceptionHandlers.java | 32 + src/main/java/com/j2js/FileManager.java | 76 + src/main/java/com/j2js/FileObject.java | 54 + src/main/java/com/j2js/Form.java | 109 + src/main/java/com/j2js/InstructionType.java | 59 + src/main/java/com/j2js/J2JSCompiler.java | 357 +++ src/main/java/com/j2js/LineNumberCursor.java | 76 + src/main/java/com/j2js/Log.java | 132 + src/main/java/com/j2js/OperandState.java | 38 + src/main/java/com/j2js/Optimizer.java | 324 +++ src/main/java/com/j2js/ParseException.java | 25 + src/main/java/com/j2js/Parser.java | 204 ++ src/main/java/com/j2js/Pass1.java | 2233 +++++++++++++++ src/main/java/com/j2js/Utils.java | 160 ++ .../java/com/j2js/assembly/ClassUnit.java | 288 ++ .../com/j2js/assembly/ConstructorUnit.java | 14 + .../java/com/j2js/assembly/FieldUnit.java | 21 + .../j2js/assembly/JavaScriptCompressor.java | 69 + .../java/com/j2js/assembly/JunkWriter.java | 81 + .../java/com/j2js/assembly/MemberUnit.java | 32 + .../java/com/j2js/assembly/MethodUnit.java | 14 + .../java/com/j2js/assembly/ProcedureUnit.java | 51 + src/main/java/com/j2js/assembly/Project.java | 330 +++ .../java/com/j2js/assembly/Serializer.java | 153 + .../java/com/j2js/assembly/Signature.java | 106 + .../java/com/j2js/assembly/TypeCollector.java | 13 + .../java/com/j2js/assembly/TypeResolver.java | 77 + .../java/com/j2js/assembly/TypeVisitor.java | 5 + src/main/java/com/j2js/assembly/Unit.java | 62 + .../java/com/j2js/builder/Configuration.java | 84 + .../java/com/j2js/cfg/ConditionalEdge.java | 29 + .../java/com/j2js/cfg/ControlFlowGraph.java | 387 +++ src/main/java/com/j2js/cfg/DominatorTree.java | 233 ++ src/main/java/com/j2js/cfg/Edge.java | 78 + .../java/com/j2js/cfg/EdgeCollections.java | 17 + src/main/java/com/j2js/cfg/EdgeType.java | 17 + src/main/java/com/j2js/cfg/Graph.java | 286 ++ src/main/java/com/j2js/cfg/Node.java | 334 +++ src/main/java/com/j2js/cfg/SwitchEdge.java | 14 + src/main/java/com/j2js/cfg/TryHeaderNode.java | 74 + src/main/java/com/j2js/cfg/WrapperNode.java | 11 + .../com/j2js/cfg/transformation/Loop.java | 47 + .../com/j2js/cfg/transformation/Merge.java | 77 + .../com/j2js/cfg/transformation/Switch.java | 83 + .../cfg/transformation/Transformation.java | 116 + .../java/com/j2js/cfg/transformation/Try.java | 77 + src/main/java/com/j2js/dom/ASTNode.java | 200 ++ src/main/java/com/j2js/dom/ArrayAccess.java | 54 + src/main/java/com/j2js/dom/ArrayCreation.java | 50 + .../java/com/j2js/dom/ArrayInitializer.java | 24 + src/main/java/com/j2js/dom/Assignable.java | 17 + src/main/java/com/j2js/dom/Assignment.java | 96 + src/main/java/com/j2js/dom/Block.java | 356 +++ .../java/com/j2js/dom/BooleanExpression.java | 15 + .../java/com/j2js/dom/BooleanLiteral.java | 36 + src/main/java/com/j2js/dom/Branch.java | 67 + .../java/com/j2js/dom/BreakStatement.java | 19 + .../java/com/j2js/dom/CastExpression.java | 31 + src/main/java/com/j2js/dom/CatchClause.java | 45 + .../com/j2js/dom/ClassInstanceCreation.java | 24 + src/main/java/com/j2js/dom/ClassLiteral.java | 22 + .../java/com/j2js/dom/ConditionalBranch.java | 41 + .../com/j2js/dom/ConditionalExpression.java | 61 + .../java/com/j2js/dom/ContinueStatement.java | 16 + src/main/java/com/j2js/dom/DoStatement.java | 32 + src/main/java/com/j2js/dom/Expression.java | 52 + src/main/java/com/j2js/dom/FieldAccess.java | 85 + src/main/java/com/j2js/dom/FieldRead.java | 14 + src/main/java/com/j2js/dom/FieldWrite.java | 14 + src/main/java/com/j2js/dom/Goto.java | 13 + src/main/java/com/j2js/dom/IfStatement.java | 46 + .../java/com/j2js/dom/InfixExpression.java | 111 + .../com/j2js/dom/InstanceofExpression.java | 31 + src/main/java/com/j2js/dom/Jump.java | 20 + .../java/com/j2js/dom/JumpSubRoutine.java | 12 + src/main/java/com/j2js/dom/LabeledJump.java | 20 + src/main/java/com/j2js/dom/LoopStatement.java | 44 + src/main/java/com/j2js/dom/MethodBinding.java | 120 + .../java/com/j2js/dom/MethodDeclaration.java | 134 + .../java/com/j2js/dom/MethodInvocation.java | 118 + src/main/java/com/j2js/dom/Name.java | 39 + src/main/java/com/j2js/dom/NoOperation.java | 11 + src/main/java/com/j2js/dom/NullLiteral.java | 13 + src/main/java/com/j2js/dom/NumberLiteral.java | 91 + .../java/com/j2js/dom/PStarExpression.java | 71 + src/main/java/com/j2js/dom/Pop.java | 15 + .../java/com/j2js/dom/PostfixExpression.java | 18 + .../java/com/j2js/dom/PrefixExpression.java | 25 + src/main/java/com/j2js/dom/PrimitiveCast.java | 25 + src/main/java/com/j2js/dom/Push.java | 16 + .../java/com/j2js/dom/ReturnStatement.java | 44 + src/main/java/com/j2js/dom/StringLiteral.java | 37 + src/main/java/com/j2js/dom/SwitchCase.java | 38 + .../java/com/j2js/dom/SwitchStatement.java | 40 + .../java/com/j2js/dom/SynchronizedBlock.java | 18 + .../java/com/j2js/dom/ThisExpression.java | 27 + .../java/com/j2js/dom/ThrowStatement.java | 27 + src/main/java/com/j2js/dom/TryStatement.java | 68 + .../java/com/j2js/dom/TypeDeclaration.java | 121 + .../java/com/j2js/dom/VariableBinding.java | 83 + .../com/j2js/dom/VariableDeclaration.java | 111 + .../java/com/j2js/dom/WhileStatement.java | 33 + src/main/java/com/j2js/package.html | 251 ++ src/main/java/com/j2js/util/BuilderUtils.java | 89 + .../java/com/j2js/util/XmlBeanMapper.java | 1001 +++++++ .../com/j2js/visitors/AbstractVisitor.java | 206 ++ .../java/com/j2js/visitors/Generator.java | 80 + .../java/com/j2js/visitors/JavaGenerator.java | 105 + .../j2js/visitors/JavaScriptGenerator.java | 969 +++++++ .../com/j2js/visitors/SimpleGenerator.java | 45 + src/main/java/org/json/JSONArray.java | 889 ++++++ src/main/java/org/json/JSONException.java | 28 + src/main/java/org/json/JSONObject.java | 1327 +++++++++ src/main/java/org/json/JSONString.java | 19 + src/main/java/org/json/JSONStringer.java | 79 + src/main/java/org/json/JSONTokener.java | 462 +++ src/main/java/org/json/JSONWriter.java | 319 +++ src/main/java/scratch.jpage | 16 + src/main/resources/devmode.html | 21 + src/main/resources/instructions.xml | 1920 +++++++++++++ src/main/resources/instructions.xsl | 50 + src/main/resources/j2js.properties | 25 + src/main/resources/notfound.html | 9 + src/main/resources/smalllogo.gif | Bin 0 -> 883 bytes 144 files changed, 21780 insertions(+) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .project create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.jdt.ui.prefs create mode 100644 .settings/org.eclipse.wst.validation.prefs create mode 100644 LICENSE create mode 100644 README.md create mode 100644 libs/bcel-5.1.jar create mode 100644 libs/commons-io-1.4.jar create mode 100644 src/main/java/Checker.java create mode 100644 src/main/java/Enhancer.java create mode 100644 src/main/java/com/j2js/ASTNodeStack.java create mode 100644 src/main/java/com/j2js/AnnotationAttribute.java create mode 100644 src/main/java/com/j2js/AnnotationReader.java create mode 100644 src/main/java/com/j2js/Assembly.java create mode 100644 src/main/java/com/j2js/Const.java create mode 100644 src/main/java/com/j2js/ConstGenerator.java create mode 100644 src/main/java/com/j2js/Diff.java create mode 100644 src/main/java/com/j2js/ExceptionHandler.java create mode 100644 src/main/java/com/j2js/ExceptionHandlers.java create mode 100644 src/main/java/com/j2js/FileManager.java create mode 100644 src/main/java/com/j2js/FileObject.java create mode 100644 src/main/java/com/j2js/Form.java create mode 100644 src/main/java/com/j2js/InstructionType.java create mode 100644 src/main/java/com/j2js/J2JSCompiler.java create mode 100644 src/main/java/com/j2js/LineNumberCursor.java create mode 100644 src/main/java/com/j2js/Log.java create mode 100644 src/main/java/com/j2js/OperandState.java create mode 100644 src/main/java/com/j2js/Optimizer.java create mode 100644 src/main/java/com/j2js/ParseException.java create mode 100644 src/main/java/com/j2js/Parser.java create mode 100644 src/main/java/com/j2js/Pass1.java create mode 100644 src/main/java/com/j2js/Utils.java create mode 100644 src/main/java/com/j2js/assembly/ClassUnit.java create mode 100644 src/main/java/com/j2js/assembly/ConstructorUnit.java create mode 100644 src/main/java/com/j2js/assembly/FieldUnit.java create mode 100644 src/main/java/com/j2js/assembly/JavaScriptCompressor.java create mode 100644 src/main/java/com/j2js/assembly/JunkWriter.java create mode 100644 src/main/java/com/j2js/assembly/MemberUnit.java create mode 100644 src/main/java/com/j2js/assembly/MethodUnit.java create mode 100644 src/main/java/com/j2js/assembly/ProcedureUnit.java create mode 100644 src/main/java/com/j2js/assembly/Project.java create mode 100644 src/main/java/com/j2js/assembly/Serializer.java create mode 100644 src/main/java/com/j2js/assembly/Signature.java create mode 100644 src/main/java/com/j2js/assembly/TypeCollector.java create mode 100644 src/main/java/com/j2js/assembly/TypeResolver.java create mode 100644 src/main/java/com/j2js/assembly/TypeVisitor.java create mode 100644 src/main/java/com/j2js/assembly/Unit.java create mode 100644 src/main/java/com/j2js/builder/Configuration.java create mode 100644 src/main/java/com/j2js/cfg/ConditionalEdge.java create mode 100644 src/main/java/com/j2js/cfg/ControlFlowGraph.java create mode 100644 src/main/java/com/j2js/cfg/DominatorTree.java create mode 100644 src/main/java/com/j2js/cfg/Edge.java create mode 100644 src/main/java/com/j2js/cfg/EdgeCollections.java create mode 100644 src/main/java/com/j2js/cfg/EdgeType.java create mode 100644 src/main/java/com/j2js/cfg/Graph.java create mode 100644 src/main/java/com/j2js/cfg/Node.java create mode 100644 src/main/java/com/j2js/cfg/SwitchEdge.java create mode 100644 src/main/java/com/j2js/cfg/TryHeaderNode.java create mode 100644 src/main/java/com/j2js/cfg/WrapperNode.java create mode 100644 src/main/java/com/j2js/cfg/transformation/Loop.java create mode 100644 src/main/java/com/j2js/cfg/transformation/Merge.java create mode 100644 src/main/java/com/j2js/cfg/transformation/Switch.java create mode 100644 src/main/java/com/j2js/cfg/transformation/Transformation.java create mode 100644 src/main/java/com/j2js/cfg/transformation/Try.java create mode 100644 src/main/java/com/j2js/dom/ASTNode.java create mode 100644 src/main/java/com/j2js/dom/ArrayAccess.java create mode 100644 src/main/java/com/j2js/dom/ArrayCreation.java create mode 100644 src/main/java/com/j2js/dom/ArrayInitializer.java create mode 100644 src/main/java/com/j2js/dom/Assignable.java create mode 100644 src/main/java/com/j2js/dom/Assignment.java create mode 100644 src/main/java/com/j2js/dom/Block.java create mode 100644 src/main/java/com/j2js/dom/BooleanExpression.java create mode 100644 src/main/java/com/j2js/dom/BooleanLiteral.java create mode 100644 src/main/java/com/j2js/dom/Branch.java create mode 100644 src/main/java/com/j2js/dom/BreakStatement.java create mode 100644 src/main/java/com/j2js/dom/CastExpression.java create mode 100644 src/main/java/com/j2js/dom/CatchClause.java create mode 100644 src/main/java/com/j2js/dom/ClassInstanceCreation.java create mode 100644 src/main/java/com/j2js/dom/ClassLiteral.java create mode 100644 src/main/java/com/j2js/dom/ConditionalBranch.java create mode 100644 src/main/java/com/j2js/dom/ConditionalExpression.java create mode 100644 src/main/java/com/j2js/dom/ContinueStatement.java create mode 100644 src/main/java/com/j2js/dom/DoStatement.java create mode 100644 src/main/java/com/j2js/dom/Expression.java create mode 100644 src/main/java/com/j2js/dom/FieldAccess.java create mode 100644 src/main/java/com/j2js/dom/FieldRead.java create mode 100644 src/main/java/com/j2js/dom/FieldWrite.java create mode 100644 src/main/java/com/j2js/dom/Goto.java create mode 100644 src/main/java/com/j2js/dom/IfStatement.java create mode 100644 src/main/java/com/j2js/dom/InfixExpression.java create mode 100644 src/main/java/com/j2js/dom/InstanceofExpression.java create mode 100644 src/main/java/com/j2js/dom/Jump.java create mode 100644 src/main/java/com/j2js/dom/JumpSubRoutine.java create mode 100644 src/main/java/com/j2js/dom/LabeledJump.java create mode 100644 src/main/java/com/j2js/dom/LoopStatement.java create mode 100644 src/main/java/com/j2js/dom/MethodBinding.java create mode 100644 src/main/java/com/j2js/dom/MethodDeclaration.java create mode 100644 src/main/java/com/j2js/dom/MethodInvocation.java create mode 100644 src/main/java/com/j2js/dom/Name.java create mode 100644 src/main/java/com/j2js/dom/NoOperation.java create mode 100644 src/main/java/com/j2js/dom/NullLiteral.java create mode 100644 src/main/java/com/j2js/dom/NumberLiteral.java create mode 100644 src/main/java/com/j2js/dom/PStarExpression.java create mode 100644 src/main/java/com/j2js/dom/Pop.java create mode 100644 src/main/java/com/j2js/dom/PostfixExpression.java create mode 100644 src/main/java/com/j2js/dom/PrefixExpression.java create mode 100644 src/main/java/com/j2js/dom/PrimitiveCast.java create mode 100644 src/main/java/com/j2js/dom/Push.java create mode 100644 src/main/java/com/j2js/dom/ReturnStatement.java create mode 100644 src/main/java/com/j2js/dom/StringLiteral.java create mode 100644 src/main/java/com/j2js/dom/SwitchCase.java create mode 100644 src/main/java/com/j2js/dom/SwitchStatement.java create mode 100644 src/main/java/com/j2js/dom/SynchronizedBlock.java create mode 100644 src/main/java/com/j2js/dom/ThisExpression.java create mode 100644 src/main/java/com/j2js/dom/ThrowStatement.java create mode 100644 src/main/java/com/j2js/dom/TryStatement.java create mode 100644 src/main/java/com/j2js/dom/TypeDeclaration.java create mode 100644 src/main/java/com/j2js/dom/VariableBinding.java create mode 100644 src/main/java/com/j2js/dom/VariableDeclaration.java create mode 100644 src/main/java/com/j2js/dom/WhileStatement.java create mode 100644 src/main/java/com/j2js/package.html create mode 100644 src/main/java/com/j2js/util/BuilderUtils.java create mode 100644 src/main/java/com/j2js/util/XmlBeanMapper.java create mode 100644 src/main/java/com/j2js/visitors/AbstractVisitor.java create mode 100644 src/main/java/com/j2js/visitors/Generator.java create mode 100644 src/main/java/com/j2js/visitors/JavaGenerator.java create mode 100644 src/main/java/com/j2js/visitors/JavaScriptGenerator.java create mode 100644 src/main/java/com/j2js/visitors/SimpleGenerator.java create mode 100644 src/main/java/org/json/JSONArray.java create mode 100644 src/main/java/org/json/JSONException.java create mode 100644 src/main/java/org/json/JSONObject.java create mode 100644 src/main/java/org/json/JSONString.java create mode 100644 src/main/java/org/json/JSONStringer.java create mode 100644 src/main/java/org/json/JSONTokener.java create mode 100644 src/main/java/org/json/JSONWriter.java create mode 100644 src/main/java/scratch.jpage create mode 100644 src/main/resources/devmode.html create mode 100644 src/main/resources/instructions.xml create mode 100644 src/main/resources/instructions.xsl create mode 100644 src/main/resources/j2js.properties create mode 100644 src/main/resources/notfound.html create mode 100644 src/main/resources/smalllogo.gif diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..b8f9892 --- /dev/null +++ b/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b510112 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +git.txt +pom.xml +src/main/resources/META-INF/* +src/site/**/* +src/test/**/* +launchConfig/**/* +target/**/* \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..6e60f53 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + j2js-compiler + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..d253ed8 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,271 @@ +#Wed Sep 03 00:07:36 CEST 2008 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=0 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=1 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=false +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=true +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=80 +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=80 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +org.eclipse.jdt.core.formatter.tabulation.char=space +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000..b1ff5e6 --- /dev/null +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,6 @@ +#Wed Sep 03 00:07:35 CEST 2008 +eclipse.preferences.version=1 +formatter_profile=_MyProfile +formatter_settings_version=11 +internal.default.compliance=default +org.eclipse.jdt.ui.text.custom_code_templates= diff --git a/.settings/org.eclipse.wst.validation.prefs b/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..40588f9 --- /dev/null +++ b/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,6 @@ +#Wed Oct 24 00:47:12 CEST 2007 +DELEGATES_PREFERENCE=delegateValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator\=org.eclipse.wst.wsdl.validation.internal.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator\=org.eclipse.wst.xsd.core.internal.validation.eclipse.Validator; +USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator; +USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator; +USER_PREFERENCE=overrideGlobalPreferencesfalse +eclipse.preferences.version=1 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..662b4d3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +A FreeBSD Licence + +Copyright(c) 2011, the j2js Project. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided +that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and + the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD +PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..72b09d4 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +#j2js-compiler + +A Java Bytecode to JavaScript Cross-Compiler. diff --git a/libs/bcel-5.1.jar b/libs/bcel-5.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..524e375cf370591dda3d1e2806e4a2ae8e02ac6f GIT binary patch literal 515920 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%0D}9m$pCdTK+>sb+s`Vokzz3jak? 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%0ADhdJkbMlc$v!QI%nLo5Yima` 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%0A!a3o#t*4J>~Y%_)tvuTuQyup@f>h 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

r}KkySWS7u=FWX}?!U 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 OKnU!J{D3_>*#80Lb|t_7 literal 0 HcmV?d00001 diff --git a/src/main/java/Checker.java b/src/main/java/Checker.java new file mode 100644 index 0000000..d35b3d4 --- /dev/null +++ b/src/main/java/Checker.java @@ -0,0 +1,40 @@ +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.HashSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.j2js.Const; + +/** + * Copyright by Wolfgang Kuehn 2005 + * Created on Feb 27, 2005 + */ +public class Checker { + public static void main(String argv[]) throws Exception { + BufferedReader reader = new BufferedReader(new FileReader(new File("src/com/j2js/Pass1.java"))); + Pattern p = Pattern.compile(".*case\\s+Const\\.(\\w*)\\s*:.*"); + HashSet set = new HashSet(); + + String line; + while ((line=reader.readLine())!=null) { + Matcher m = p.matcher(line); + if (m.matches()) { + String name = m.group(1); + //System.out.println("Adding " + name); + set.add(name); + } + } + + int missingCount = 0; + for (int i=0; i 1) { + head += " (" + i + ")"; + } + line += head + " Format: " + it.getName(); + for (int j=0; j { + + public ASTNodeStack() { + super(); + } + + public ASTNodeStack(ASTNodeStack other) { + super(other); + } + + public ASTNodeStack(Expression expression) { + super(); + push(expression); + } + + public Expression pop() { + if (size() == 0) throw new RuntimeException("Cannot pop empty stack"); + return (Expression) remove(size() - 1); + } + + public void push(ASTNode node) { + add(node); + } + + public void rotate(int offset) { + if (offset == 0) return; + if (offset > size()) throw new IndexOutOfBoundsException(); + ASTNode node = pop(); + add(size()-offset, node); + } + + public Expression peek() { + return peek(0); + } + + private static Object safeCast(Object object, Class clazz) { + if (!clazz.isInstance(object)) { + throw new RuntimeException("Expected " + clazz + ", but was " + object); + } + return object; + } + + public Expression peek(int offset) { + if (size()-1 < offset) return null; + return (Expression) ASTNodeStack.safeCast(get(size()-1-offset), Expression.class); + } +} diff --git a/src/main/java/com/j2js/AnnotationAttribute.java b/src/main/java/com/j2js/AnnotationAttribute.java new file mode 100644 index 0000000..19493b7 --- /dev/null +++ b/src/main/java/com/j2js/AnnotationAttribute.java @@ -0,0 +1,28 @@ +package com.j2js; + +import java.util.Map; + +import org.apache.bcel.classfile.Attribute; +import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.classfile.Visitor; + +public class AnnotationAttribute extends Attribute { + + Map[] annotations; + + protected AnnotationAttribute(byte tag, int nameIndex, int length, ConstantPool constantPool) { + super(tag, nameIndex, length, constantPool); + } + + @Override + public void accept(Visitor arg0) { + // TODO Auto-generated method stub + + } + + @Override + public Attribute copy(ConstantPool arg0) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/src/main/java/com/j2js/AnnotationReader.java b/src/main/java/com/j2js/AnnotationReader.java new file mode 100644 index 0000000..9f7d8c5 --- /dev/null +++ b/src/main/java/com/j2js/AnnotationReader.java @@ -0,0 +1,58 @@ +package com.j2js; + +import java.io.DataInputStream; +import java.util.HashMap; +import java.util.Map; + +import org.apache.bcel.classfile.Attribute; +import org.apache.bcel.classfile.AttributeReader; +import org.apache.bcel.classfile.Constant; +import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.classfile.ConstantUtf8; + +import com.j2js.assembly.ClassUnit; +import com.j2js.assembly.Project; +import com.j2js.assembly.Signature; + +public class AnnotationReader implements AttributeReader{ + + private ClassUnit classUnit; + + public AnnotationReader(ClassUnit theClassUnit) { + classUnit = theClassUnit; + } + + public Attribute createAttribute(int name_index, int length, DataInputStream file, ConstantPool constantPool) { + Map[] annotations = null; + // TODO: Annotation + try { + int attCount = file.readUnsignedShort(); + annotations = new HashMap[attCount]; + for (int j=0; j map = new HashMap(); + annotations[j] = map; + int nameIndex = file.readUnsignedShort(); + Constant constant = constantPool.getConstant(nameIndex); + Signature signature = Project.getSingleton().getSignature(((ConstantUtf8) constant).getBytes()); + map.put("$signature", signature.toString()); + int fieldCount = file.readUnsignedShort(); + for (int i=0; i entryPoints = new ArrayList(); + + private final static String DECLARECLASS = "dcC"; + + private transient Log logger; + + private transient String entryPointClassName; + + private Project project; + private Set taintedSignatures = new HashSet(); + private Set unprocessedTaintedSignatures = new HashSet(); + String[] patterns; + private Collection resolvedTypes = new ArrayList(); + private transient File targetLocation; + + public Assembly() { + patterns = Utils.getProperty("j2js.taintIfInstantiated").split(";"); + for (int i=0; i 0) { + processSingle(popSignature()); + if (unprocessedTaintedSignatures.size() == 0) { + processOverWrittenMembers(); + } + } + } + + public void processSingle(Signature signature) { + ClassUnit clazz = resolve(signature.className()); + String methodPart = signature.relativeSignature(); + boolean found = false; + for (MemberUnit member : clazz.getMembers(methodPart)) { + taint(member); + found = true; + } + + if (!found) { + //logger.severe("No such method: " + signature); + throw new RuntimeException("No such method: " + signature); + } + +// MemberUnit member = clazz.getMember(methodPart); +// if (member != null) { +// taint(member); +// } else { +// logger.severe("No such method: " + signature); +// } + } + + private ClassUnit resolve(String className) { + ClassUnit clazz = project.getOrCreateClassUnit(className); + + if (className.startsWith("[")) { + project.resolve(clazz); + } else { + project.resolve(clazz); + taint(className + "#()void"); + } + + resolvedTypes.add(clazz); + + return clazz; + } + + /** + * Taint the signatures of methods matching a pattern. + */ + private void taintImplicitelyAccessedMembers(ClassUnit clazz) { + // TODO: This method is called multiple times for each clazz. This + // should not be the case! +// System.out.println(clazz.toString()); + for (MemberUnit member : clazz.getDeclaredMembers()) { + for (int i=0; i classIterator = resolvedTypes.iterator(); + while (classIterator.hasNext()) { + ClassUnit clazz = classIterator.next(); + if (clazz.isConstructorTainted) taintIfSuperTainted(clazz);; + } + } + + public void taint(String signature) { + signature = signature.replaceAll("\\s", ""); +// if (signature.indexOf('*') != -1) { +// if (!signature.endsWith(".*")) { +// throw new RuntimeException("Package signature must end with '.*'"); +// } +// signature = signature.substring(0, signature.length()-2); +// File[] files = Utils.resolvePackage(J2JSCompiler.compiler.getClassPath(), signature); +// for (int i=0; i iter = unprocessedTaintedSignatures.iterator(); + Signature signature = iter.next(); + iter.remove(); + return signature; + } + + public void taint(Signature signature) { + if (!signature.toString().contains("#")) { + throw new IllegalArgumentException("Signature must be field or method: " + signature); + } + + if (taintedSignatures.contains(signature)) return; + + taintedSignatures.add(signature); + unprocessedTaintedSignatures.add(signature); + } + + public void taint(MemberUnit member) { + member.setTainted(); + // TODO: Tainting super types in neccesary for generating only? + member.getDeclaringClass().setSuperTainted(); + if (member instanceof ProcedureUnit) { + taintTargetSignatures((ProcedureUnit) member); + if (member instanceof ConstructorUnit) { + member.getDeclaringClass().isConstructorTainted = true; + taintImplicitelyAccessedMembers(member.getDeclaringClass()); + } + } + } + + /** + * @see #getProject() + */ + public void setProject(Project project) { + this.project = project; + } + + public Project getProject() { + return project; + } + + /** + * @return Returns the entryPointClassName. + */ + public String getEntryPointClassName() { + return entryPointClassName; + } + + /** + *

+ * The static main(String[])void method of the specified class is executed + * after the assembly is loaded by the script engine. + *

+ *

+ * In web mode, the values of the URL query string are passed to this method. + *

+ * + * @param entryPointClassName (required) the class signature + */ + public Assembly setEntryPointClassName(String entryPointClassName) { + this.entryPointClassName = entryPointClassName; + return this; + } + + /** + * @return Returns the targetLocation. + */ + public File getTargetLocation() { + return targetLocation; + } + + /** + * The assembly is written to the specified directory + * + * @param targetLocation (required) the directory the assembly is written to + */ + public void setTargetLocation(File targetLocation) { + this.targetLocation = targetLocation; + } + + /** + * Signature of a field or method to include in the assembly. + *

+ * Note: Normally you will only add those entrypoints which + * the static code analyser cannot detect, for example methods called through + * reflection. + *

+ * + * @param memberSignature the member to include + */ + public void addEntryPoint(String memberSignature) { + entryPoints.add(memberSignature); + } + +} diff --git a/src/main/java/com/j2js/Const.java b/src/main/java/com/j2js/Const.java new file mode 100644 index 0000000..194edb8 --- /dev/null +++ b/src/main/java/com/j2js/Const.java @@ -0,0 +1,2480 @@ + + package com.j2js; + public class Const { + + public static InstructionType[] instructionTypes = new InstructionType[202]; + + public static final int AALOAD = 50; + + public static final int AASTORE = 83; + + public static final int ACONST_NULL = 1; + + public static final int ALOAD = 25; + + public static final int ALOAD_0 = 42; + + public static final int ALOAD_1 = 43; + + public static final int ALOAD_2 = 44; + + public static final int ALOAD_3 = 45; + + public static final int ANEWARRAY = 189; + + public static final int ARETURN = 176; + + public static final int ARRAYLENGTH = 190; + + public static final int ASTORE = 58; + + public static final int ASTORE_0 = 75; + + public static final int ASTORE_1 = 76; + + public static final int ASTORE_2 = 77; + + public static final int ASTORE_3 = 78; + + public static final int ATHROW = 191; + + public static final int BALOAD = 51; + + public static final int BASTORE = 84; + + public static final int BIPUSH = 16; + + public static final int NEW = 187; + + public static final int NEWARRAY = 188; + + public static final int NOP = 0; + + public static final int POP = 87; + + public static final int POP2 = 88; + + public static final int PUTFIELD = 181; + + public static final int PUTSTATIC = 179; + + public static final int RET = 169; + + public static final int RETURN = 177; + + public static final int SALOAD = 53; + + public static final int SASTORE = 86; + + public static final int SIPUSH = 17; + + public static final int SWAP = 95; + + public static final int TABLESWITCH = 170; + + public static final int WIDE = 196; + + public static final int CALOAD = 52; + + public static final int CASTORE = 85; + + public static final int CHECKCAST = 192; + + public static final int D2F = 144; + + public static final int D2I = 142; + + public static final int D2L = 143; + + public static final int DADD = 99; + + public static final int DALOAD = 49; + + public static final int DASTORE = 82; + + public static final int DCMPL = 151; + + public static final int DCMPG = 152; + + public static final int DCONST_0 = 14; + + public static final int DCONST_1 = 15; + + public static final int DDIV = 111; + + public static final int DLOAD = 24; + + public static final int DLOAD_0 = 38; + + public static final int DLOAD_1 = 39; + + public static final int DLOAD_2 = 40; + + public static final int DLOAD_3 = 41; + + public static final int DMUL = 107; + + public static final int DNEG = 119; + + public static final int DREM = 115; + + public static final int DRETURN = 175; + + public static final int DSTORE = 57; + + public static final int DSTORE_0 = 71; + + public static final int DSTORE_1 = 72; + + public static final int DSTORE_2 = 73; + + public static final int DSTORE_3 = 74; + + public static final int DSUB = 103; + + public static final int DUP = 89; + + public static final int DUP_X1 = 90; + + public static final int DUP_X2 = 91; + + public static final int DUP2 = 92; + + public static final int DUP2_X1 = 93; + + public static final int DUP2_X2 = 94; + + public static final int F2D = 141; + + public static final int F2I = 139; + + public static final int F2L = 140; + + public static final int FADD = 98; + + public static final int FALOAD = 48; + + public static final int FASTORE = 81; + + public static final int FCMPL = 149; + + public static final int FCMPG = 150; + + public static final int FCONST_0 = 11; + + public static final int FCONST_1 = 12; + + public static final int FCONST_2 = 13; + + public static final int FDIV = 110; + + public static final int FLOAD = 23; + + public static final int FLOAD_0 = 34; + + public static final int FLOAD_1 = 35; + + public static final int FLOAD_2 = 36; + + public static final int FLOAD_3 = 37; + + public static final int FMUL = 106; + + public static final int FNEG = 118; + + public static final int FREM = 114; + + public static final int FRETURN = 174; + + public static final int FSTORE = 56; + + public static final int FSTORE_0 = 67; + + public static final int FSTORE_1 = 68; + + public static final int FSTORE_2 = 69; + + public static final int FSTORE_3 = 70; + + public static final int FSUB = 102; + + public static final int GETFIELD = 180; + + public static final int GETSTATIC = 178; + + public static final int GOTO = 167; + + public static final int GOTO_W = 200; + + public static final int I2B = 145; + + public static final int I2C = 146; + + public static final int I2D = 135; + + public static final int I2F = 134; + + public static final int I2L = 133; + + public static final int I2S = 147; + + public static final int IADD = 96; + + public static final int IALOAD = 46; + + public static final int IAND = 126; + + public static final int IASTORE = 79; + + public static final int ICONST_M1 = 2; + + public static final int ICONST_0 = 3; + + public static final int ICONST_1 = 4; + + public static final int ICONST_2 = 5; + + public static final int ICONST_3 = 6; + + public static final int ICONST_4 = 7; + + public static final int ICONST_5 = 8; + + public static final int IDIV = 108; + + public static final int IF_ACMPEQ = 165; + + public static final int IF_ACMPNE = 166; + + public static final int IF_ICMPEQ = 159; + + public static final int IF_ICMPNE = 160; + + public static final int IF_ICMPLT = 161; + + public static final int IF_ICMPGE = 162; + + public static final int IF_ICMPGT = 163; + + public static final int IF_ICMPLE = 164; + + public static final int IFEQ = 153; + + public static final int IFNE = 154; + + public static final int IFLT = 155; + + public static final int IFGE = 156; + + public static final int IFGT = 157; + + public static final int IFLE = 158; + + public static final int IFNONNULL = 199; + + public static final int IFNULL = 198; + + public static final int IINC = 132; + + public static final int ILOAD = 21; + + public static final int ILOAD_0 = 26; + + public static final int ILOAD_1 = 27; + + public static final int ILOAD_2 = 28; + + public static final int ILOAD_3 = 29; + + public static final int IMUL = 104; + + public static final int INEG = 116; + + public static final int INSTANCEOF = 193; + + public static final int INVOKEINTERFACE = 185; + + public static final int INVOKESPECIAL = 183; + + public static final int INVOKESTATIC = 184; + + public static final int INVOKEVIRTUAL = 182; + + public static final int IOR = 128; + + public static final int IREM = 112; + + public static final int IRETURN = 172; + + public static final int ISHL = 120; + + public static final int ISHR = 122; + + public static final int ISTORE = 54; + + public static final int ISTORE_0 = 59; + + public static final int ISTORE_1 = 60; + + public static final int ISTORE_2 = 61; + + public static final int ISTORE_3 = 62; + + public static final int ISUB = 100; + + public static final int IUSHR = 124; + + public static final int IXOR = 130; + + public static final int JSR = 168; + + public static final int JSR_W = 201; + + public static final int L2D = 138; + + public static final int L2F = 137; + + public static final int L2I = 136; + + public static final int LADD = 97; + + public static final int LALOAD = 47; + + public static final int LAND = 127; + + public static final int LASTORE = 80; + + public static final int LCMP = 148; + + public static final int LCONST_0 = 9; + + public static final int LCONST_1 = 10; + + public static final int LDC = 18; + + public static final int LDC_W = 19; + + public static final int LDC2_W = 20; + + public static final int LDIV = 109; + + public static final int LLOAD = 22; + + public static final int LLOAD_0 = 30; + + public static final int LLOAD_1 = 31; + + public static final int LLOAD_2 = 32; + + public static final int LLOAD_3 = 33; + + public static final int LMUL = 105; + + public static final int LNEG = 117; + + public static final int LOOKUPSWITCH = 171; + + public static final int LOR = 129; + + public static final int LREM = 113; + + public static final int LRETURN = 173; + + public static final int LSHL = 121; + + public static final int LSHR = 123; + + public static final int LSTORE = 55; + + public static final int LSTORE_0 = 63; + + public static final int LSTORE_1 = 64; + + public static final int LSTORE_2 = 65; + + public static final int LSTORE_3 = 66; + + public static final int LSUB = 101; + + public static final int LUSHR = 125; + + public static final int LXOR = 131; + + public static final int MONITORENTER = 194; + + public static final int MONITOREXIT = 195; + + public static final int MULTIANEWARRAY = 197; + + public static final int XXXUNUSEDXXX = 186; + + + static { + InstructionType i; + Form f; + + i = new InstructionType((short)0, "nop", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[0] = i; + + i = new InstructionType((short)1, "aconst_null", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("object","null"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[1] = i; + + i = new InstructionType((short)2, "iconst_m1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","i"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[2] = i; + + i = new InstructionType((short)3, "iconst_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","i"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[3] = i; + + i = new InstructionType((short)4, "iconst_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","i"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[4] = i; + + i = new InstructionType((short)5, "iconst_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","i"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[5] = i; + + i = new InstructionType((short)6, "iconst_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","i"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[6] = i; + + i = new InstructionType((short)7, "iconst_4", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","i"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[7] = i; + + i = new InstructionType((short)8, "iconst_5", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","i"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[8] = i; + + i = new InstructionType((short)9, "lconst_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("long","l"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[9] = i; + + i = new InstructionType((short)10, "lconst_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("long","l"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[10] = i; + + i = new InstructionType((short)11, "fconst_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("float","f"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[11] = i; + + i = new InstructionType((short)12, "fconst_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("float","f"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[12] = i; + + i = new InstructionType((short)13, "fconst_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("float","f"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[13] = i; + + i = new InstructionType((short)14, "dconst_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("double","d"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[14] = i; + + i = new InstructionType((short)15, "dconst_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("double","d"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[15] = i; + + i = new InstructionType((short)16, "bipush", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{new Form.Value("byte","byte"), }); + i.setForm(f, 0); + + instructionTypes[16] = i; + + i = new InstructionType((short)17, "sipush", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("short","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[17] = i; + + i = new InstructionType((short)18, "ldc", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value"), }); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[18] = i; + + i = new InstructionType((short)19, "ldc_w", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[19] = i; + + i = new InstructionType((short)20, "ldc2_w", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[20] = i; + + i = new InstructionType((short)21, "iload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[21] = i; + + i = new InstructionType((short)22, "lload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("long","value"), }); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[22] = i; + + i = new InstructionType((short)23, "fload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("float","value"), }); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[23] = i; + + i = new InstructionType((short)24, "dload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("double","value"), }); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[24] = i; + + i = new InstructionType((short)25, "aload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[25] = i; + + i = new InstructionType((short)26, "iload_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[26] = i; + + i = new InstructionType((short)27, "iload_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[27] = i; + + i = new InstructionType((short)28, "iload_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[28] = i; + + i = new InstructionType((short)29, "iload_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[29] = i; + + i = new InstructionType((short)30, "lload_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("long","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[30] = i; + + i = new InstructionType((short)31, "lload_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("long","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[31] = i; + + i = new InstructionType((short)32, "lload_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("long","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[32] = i; + + i = new InstructionType((short)33, "lload_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("long","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[33] = i; + + i = new InstructionType((short)34, "fload_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("float","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[34] = i; + + i = new InstructionType((short)35, "fload_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("float","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[35] = i; + + i = new InstructionType((short)36, "fload_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("float","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[36] = i; + + i = new InstructionType((short)37, "fload_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("float","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[37] = i; + + i = new InstructionType((short)38, "dload_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("double","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[38] = i; + + i = new InstructionType((short)39, "dload_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("double","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[39] = i; + + i = new InstructionType((short)40, "dload_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("double","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[40] = i; + + i = new InstructionType((short)41, "dload_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("double","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[41] = i; + + i = new InstructionType((short)42, "aload_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[42] = i; + + i = new InstructionType((short)43, "aload_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[43] = i; + + i = new InstructionType((short)44, "aload_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[44] = i; + + i = new InstructionType((short)45, "aload_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[45] = i; + + i = new InstructionType((short)46, "iaload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[46] = i; + + i = new InstructionType((short)47, "laload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[47] = i; + + i = new InstructionType((short)48, "faload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[48] = i; + + i = new InstructionType((short)49, "daload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[49] = i; + + i = new InstructionType((short)50, "aaload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), }); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[50] = i; + + i = new InstructionType((short)51, "baload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[51] = i; + + i = new InstructionType((short)52, "caload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[52] = i; + + i = new InstructionType((short)53, "saload", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), }); + f.setOuts(new Form.Value[]{new Form.Value("short","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[53] = i; + + i = new InstructionType((short)54, "istore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[54] = i; + + i = new InstructionType((short)55, "lstore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[55] = i; + + i = new InstructionType((short)56, "fstore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[56] = i; + + i = new InstructionType((short)57, "dstore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("double","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[57] = i; + + i = new InstructionType((short)58, "astore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[58] = i; + + i = new InstructionType((short)59, "istore_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[59] = i; + + i = new InstructionType((short)60, "istore_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[60] = i; + + i = new InstructionType((short)61, "istore_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[61] = i; + + i = new InstructionType((short)62, "istore_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[62] = i; + + i = new InstructionType((short)63, "lstore_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[63] = i; + + i = new InstructionType((short)64, "lstore_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[64] = i; + + i = new InstructionType((short)65, "lstore_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[65] = i; + + i = new InstructionType((short)66, "lstore_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[66] = i; + + i = new InstructionType((short)67, "fstore_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("float","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[67] = i; + + i = new InstructionType((short)68, "fstore_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("float","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[68] = i; + + i = new InstructionType((short)69, "fstore_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("float","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[69] = i; + + i = new InstructionType((short)70, "fstore_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("float","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[70] = i; + + i = new InstructionType((short)71, "dstore_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("double","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[71] = i; + + i = new InstructionType((short)72, "dstore_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("double","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[72] = i; + + i = new InstructionType((short)73, "dstore_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("double","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[73] = i; + + i = new InstructionType((short)74, "dstore_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("double","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[74] = i; + + i = new InstructionType((short)75, "astore_0", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[75] = i; + + i = new InstructionType((short)76, "astore_1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[76] = i; + + i = new InstructionType((short)77, "astore_2", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[77] = i; + + i = new InstructionType((short)78, "astore_3", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[78] = i; + + i = new InstructionType((short)79, "iastore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[79] = i; + + i = new InstructionType((short)80, "lastore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[80] = i; + + i = new InstructionType((short)81, "fastore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[81] = i; + + i = new InstructionType((short)82, "dastore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[82] = i; + + i = new InstructionType((short)83, "aastore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[83] = i; + + i = new InstructionType((short)84, "bastore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[84] = i; + + i = new InstructionType((short)85, "castore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), new Form.Value("","index"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[85] = i; + + i = new InstructionType((short)86, "sastore", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","array"), new Form.Value("","index"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[86] = i; + + i = new InstructionType((short)87, "pop", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[87] = i; + + i = new InstructionType((short)88, "pop2", 2); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat2","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 1); + + instructionTypes[88] = i; + + i = new InstructionType((short)89, "dup", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value"), new Form.Value("cat1","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[89] = i; + + i = new InstructionType((short)90, "dup_x1", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value1"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[90] = i; + + i = new InstructionType((short)91, "dup_x2", 2); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value3"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value1"), new Form.Value("cat1","value3"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat2","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value1"), new Form.Value("cat2","value2"), new Form.Value("cat1","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 1); + + instructionTypes[91] = i; + + i = new InstructionType((short)92, "dup2", 2); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat2","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat2","value"), new Form.Value("cat2","value"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 1); + + instructionTypes[92] = i; + + i = new InstructionType((short)93, "dup2_x1", 2); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value3"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), new Form.Value("cat1","value3"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat2","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat2","value1"), new Form.Value("cat1","value2"), new Form.Value("cat2","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 1); + + instructionTypes[93] = i; + + i = new InstructionType((short)94, "dup2_x2", 4); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value4"), new Form.Value("cat1","value3"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), new Form.Value("cat1","value4"), new Form.Value("cat1","value3"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value3"), new Form.Value("cat1","value2"), new Form.Value("cat2","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat2","value1"), new Form.Value("cat1","value3"), new Form.Value("cat1","value2"), new Form.Value("cat2","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat2","value3"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), new Form.Value("cat2","value3"), new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 2); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat2","value2"), new Form.Value("cat2","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat2","value1"), new Form.Value("cat2","value2"), new Form.Value("cat2","value1"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 3); + + instructionTypes[94] = i; + + i = new InstructionType((short)95, "swap", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("cat1","value2"), new Form.Value("cat1","value1"), }); + f.setOuts(new Form.Value[]{new Form.Value("cat1","value1"), new Form.Value("cat1","value2"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[95] = i; + + i = new InstructionType((short)96, "iadd", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[96] = i; + + i = new InstructionType((short)97, "ladd", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[97] = i; + + i = new InstructionType((short)98, "fadd", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[98] = i; + + i = new InstructionType((short)99, "dadd", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("double","value1"), new Form.Value("double","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[99] = i; + + i = new InstructionType((short)100, "isub", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[100] = i; + + i = new InstructionType((short)101, "lsub", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[101] = i; + + i = new InstructionType((short)102, "fsub", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[102] = i; + + i = new InstructionType((short)103, "dsub", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("double","value1"), new Form.Value("double","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[103] = i; + + i = new InstructionType((short)104, "imul", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[104] = i; + + i = new InstructionType((short)105, "lmul", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[105] = i; + + i = new InstructionType((short)106, "fmul", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[106] = i; + + i = new InstructionType((short)107, "dmul", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[107] = i; + + i = new InstructionType((short)108, "idiv", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[108] = i; + + i = new InstructionType((short)109, "ldiv", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[109] = i; + + i = new InstructionType((short)110, "fdiv", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[110] = i; + + i = new InstructionType((short)111, "ddiv", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[111] = i; + + i = new InstructionType((short)112, "irem", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[112] = i; + + i = new InstructionType((short)113, "lrem", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[113] = i; + + i = new InstructionType((short)114, "frem", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[114] = i; + + i = new InstructionType((short)115, "drem", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[115] = i; + + i = new InstructionType((short)116, "ineg", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[116] = i; + + i = new InstructionType((short)117, "lneg", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[117] = i; + + i = new InstructionType((short)118, "fneg", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[118] = i; + + i = new InstructionType((short)119, "dneg", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[119] = i; + + i = new InstructionType((short)120, "ishl", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[120] = i; + + i = new InstructionType((short)121, "lshl", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[121] = i; + + i = new InstructionType((short)122, "ishr", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[122] = i; + + i = new InstructionType((short)123, "lshr", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[123] = i; + + i = new InstructionType((short)124, "iushr", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[124] = i; + + i = new InstructionType((short)125, "lushr", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[125] = i; + + i = new InstructionType((short)126, "iand", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[126] = i; + + i = new InstructionType((short)127, "land", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[127] = i; + + i = new InstructionType((short)128, "ior", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[128] = i; + + i = new InstructionType((short)129, "lor", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[129] = i; + + i = new InstructionType((short)130, "ixor", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[130] = i; + + i = new InstructionType((short)131, "lxor", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[131] = i; + + i = new InstructionType((short)132, "iinc", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), new Form.Value("int","const"), }); + i.setForm(f, 0); + + instructionTypes[132] = i; + + i = new InstructionType((short)133, "i2l", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[133] = i; + + i = new InstructionType((short)134, "i2f", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[134] = i; + + i = new InstructionType((short)135, "i2d", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[135] = i; + + i = new InstructionType((short)136, "l2i", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[136] = i; + + i = new InstructionType((short)137, "l2f", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[137] = i; + + i = new InstructionType((short)138, "l2d", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[138] = i; + + i = new InstructionType((short)139, "f2i", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("float","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[139] = i; + + i = new InstructionType((short)140, "f2l", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[140] = i; + + i = new InstructionType((short)141, "f2d", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("double","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[141] = i; + + i = new InstructionType((short)142, "d2i", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[142] = i; + + i = new InstructionType((short)143, "d2l", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("long","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[143] = i; + + i = new InstructionType((short)144, "d2f", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("float","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[144] = i; + + i = new InstructionType((short)145, "i2b", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("byte","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[145] = i; + + i = new InstructionType((short)146, "i2c", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("byte","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[146] = i; + + i = new InstructionType((short)147, "i2s", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{new Form.Value("short","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[147] = i; + + i = new InstructionType((short)148, "lcmp", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[148] = i; + + i = new InstructionType((short)149, "fcmpl", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[149] = i; + + i = new InstructionType((short)150, "fcmpg", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[150] = i; + + i = new InstructionType((short)151, "dcmpl", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[151] = i; + + i = new InstructionType((short)152, "dcmpg", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[152] = i; + + i = new InstructionType((short)153, "ifeq", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[153] = i; + + i = new InstructionType((short)154, "ifne", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[154] = i; + + i = new InstructionType((short)155, "iflt", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[155] = i; + + i = new InstructionType((short)156, "ifge", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[156] = i; + + i = new InstructionType((short)157, "ifgt", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[157] = i; + + i = new InstructionType((short)158, "ifle", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[158] = i; + + i = new InstructionType((short)159, "if_icmpeq", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[159] = i; + + i = new InstructionType((short)160, "if_icmpne", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[160] = i; + + i = new InstructionType((short)161, "if_icmplt", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[161] = i; + + i = new InstructionType((short)162, "if_icmpge", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[162] = i; + + i = new InstructionType((short)163, "if_icmpgt", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[163] = i; + + i = new InstructionType((short)164, "if_icmple", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[164] = i; + + i = new InstructionType((short)165, "if_acmpeq", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[165] = i; + + i = new InstructionType((short)166, "if_acmpne", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value1"), new Form.Value("","value2"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[166] = i; + + i = new InstructionType((short)167, "goto", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[167] = i; + + i = new InstructionType((short)168, "jsr", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("returnAddress","address"), }); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[168] = i; + + i = new InstructionType((short)169, "ret", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","index"), }); + i.setForm(f, 0); + + instructionTypes[169] = i; + + i = new InstructionType((short)170, "tableswitch", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("int","index"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","padding"), new Form.Value("byte","padding"), new Form.Value("byte","padding"), new Form.Value("int","default"), new Form.Value("int","low"), new Form.Value("int","high"), }); + i.setForm(f, 0); + + instructionTypes[170] = i; + + i = new InstructionType((short)171, "lookupswitch", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","key"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("byte","padding"), new Form.Value("byte","padding"), new Form.Value("byte","padding"), new Form.Value("int","default"), new Form.Value("int","npairs"), }); + i.setForm(f, 0); + + instructionTypes[171] = i; + + i = new InstructionType((short)172, "ireturn", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[172] = i; + + i = new InstructionType((short)173, "lreturn", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[173] = i; + + i = new InstructionType((short)174, "freturn", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[174] = i; + + i = new InstructionType((short)175, "dreturn", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("double","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[175] = i; + + i = new InstructionType((short)176, "areturn", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[176] = i; + + i = new InstructionType((short)177, "return", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[177] = i; + + i = new InstructionType((short)178, "getstatic", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("","value"), }); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[178] = i; + + i = new InstructionType((short)179, "putstatic", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[179] = i; + + i = new InstructionType((short)180, "getfield", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{new Form.Value("","value"), }); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[180] = i; + + i = new InstructionType((short)181, "putfield", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[181] = i; + + i = new InstructionType((short)182, "invokevirtual", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), new Form.Value("","arg1"), new Form.Value("","..."), new Form.Value("","argN"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[182] = i; + + i = new InstructionType((short)183, "invokespecial", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), new Form.Value("","arg1"), new Form.Value("","..."), new Form.Value("","argN"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[183] = i; + + i = new InstructionType((short)184, "invokestatic", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arg1"), new Form.Value("","..."), new Form.Value("","argN"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[184] = i; + + i = new InstructionType((short)185, "invokeinterface", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), new Form.Value("","arg1"), new Form.Value("","..."), new Form.Value("","argN"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), new Form.Value("byte","count"), new Form.Value("byte","0"), }); + i.setForm(f, 0); + + instructionTypes[185] = i; + + i = new InstructionType((short)186, "xxxunusedxxx", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[186] = i; + + i = new InstructionType((short)187, "new", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[187] = i; + + i = new InstructionType((short)188, "newarray", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("int","count"), }); + f.setOuts(new Form.Value[]{new Form.Value("object","arrayref"), }); + f.setOperands(new Form.Value[]{new Form.Value("byte","atype"), }); + i.setForm(f, 0); + + instructionTypes[188] = i; + + i = new InstructionType((short)189, "anewarray", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("int","count"), }); + f.setOuts(new Form.Value[]{new Form.Value("object","arrayref"), }); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[189] = i; + + i = new InstructionType((short)190, "arraylength", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","arrayref"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","length"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[190] = i; + + i = new InstructionType((short)191, "athrow", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[191] = i; + + i = new InstructionType((short)192, "checkcast", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{new Form.Value("object","objectref"), }); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[192] = i; + + i = new InstructionType((short)193, "instanceof", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{new Form.Value("int","result"), }); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), }); + i.setForm(f, 0); + + instructionTypes[193] = i; + + i = new InstructionType((short)194, "monitorenter", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[194] = i; + + i = new InstructionType((short)195, "monitorexit", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","objectref"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[195] = i; + + i = new InstructionType((short)196, "wide", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, 0); + + instructionTypes[196] = i; + + i = new InstructionType((short)197, "multianewarray", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","count1"), new Form.Value("","..."), new Form.Value("","countN"), }); + f.setOuts(new Form.Value[]{new Form.Value("object","arrayref"), }); + f.setOperands(new Form.Value[]{new Form.Value("short","index"), new Form.Value("byte","dimension N"), }); + i.setForm(f, 0); + + instructionTypes[197] = i; + + i = new InstructionType((short)198, "ifnull", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[198] = i; + + i = new InstructionType((short)199, "ifnonnull", 1); + + f = new Form(); + f.setIns(new Form.Value[]{new Form.Value("","value"), }); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("short","branch"), }); + i.setForm(f, 0); + + instructionTypes[199] = i; + + i = new InstructionType((short)200, "goto_w", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{new Form.Value("int","branch"), }); + i.setForm(f, 0); + + instructionTypes[200] = i; + + i = new InstructionType((short)201, "jsr_w", 1); + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{new Form.Value("returnAddress","address"), }); + f.setOperands(new Form.Value[]{new Form.Value("int","branch"), }); + i.setForm(f, 0); + + instructionTypes[201] = i; + + } + } + \ No newline at end of file diff --git a/src/main/java/com/j2js/ConstGenerator.java b/src/main/java/com/j2js/ConstGenerator.java new file mode 100644 index 0000000..0b1a496 --- /dev/null +++ b/src/main/java/com/j2js/ConstGenerator.java @@ -0,0 +1,29 @@ +/* + * Created on 26.12.2005 + * Copyright Wolfgang Kuehn 2005 + */ +package com.j2js; + +import java.io.File; + +import javax.xml.transform.Result; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; + +/** + * @author kuehn + */ +public class ConstGenerator { + + public static void main(String[] args) throws Exception { + TransformerFactory factory = TransformerFactory.newInstance(); + StreamSource xslSource = new StreamSource(new File("src/com/j2js/instructions.xsl")); + Transformer xltTransformer = factory.newTransformer(xslSource); + + StreamSource xmlSource = new StreamSource(new File("src/com/j2js/instructions.xml")); + Result result = new StreamResult(new File("src/com/j2js/Const.java")); + xltTransformer.transform(xmlSource, result); + } +} diff --git a/src/main/java/com/j2js/Diff.java b/src/main/java/com/j2js/Diff.java new file mode 100644 index 0000000..9f03483 --- /dev/null +++ b/src/main/java/com/j2js/Diff.java @@ -0,0 +1,105 @@ +package com.j2js; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.io.Reader; + +/** + * Copyright by Wolfgang Kuehn 2005 + * Created on Feb 26, 2005 + */ +public class Diff { + + private int lookAheadLines = 5; + private LineNumberReader in1; + private LineNumberReader in2; + private int skipLineCount = 0; + + public Diff(Reader r1, Reader r2) { + in1 = new LineNumberReader(r1); + in2 = new LineNumberReader(r2); + } + + public Diff(File f1, File f2) throws FileNotFoundException { + this(new FileReader(f1), new FileReader(f2)); + } + + public boolean apply() throws IOException { + boolean equal = true; + int lineCount = 0; + + while (true) { + lineCount++; + String l1 = in1.readLine(); + String l2 = in2.readLine(); + if (l1==null || l2==null) { + break; + } else if (l1==null && l2!=null) { + equal = false; + System.out.println("File 2 extends File 1 at line " + in2.getLineNumber()); + break; + } else if (l1!=null && l2==null) { + equal = false; + System.out.println("File 1 extends File 2 at line " + in1.getLineNumber()); + break; + } + + if (lineCount > skipLineCount && !l1.equals(l2)) { + equal = false; + System.out.println("Mismatch"); + System.out.println("File 1 Line " + in1.getLineNumber() + ": " + l1); + System.out.println("File 2 Line " + in2.getLineNumber() + ": " + l2); + + if (!sync()) { + break; + } + } + } + + in1.close(); + in2.close(); + + return equal; + } + + private boolean sync() throws IOException { + int maxCharactersInLine = 200; + int readAheadLimit = lookAheadLines * maxCharactersInLine; + + in2.mark(readAheadLimit); + in1.mark(readAheadLimit); + + for (int i=0; i { + + public ExceptionHandlers(Code code) { + + // Join all contiguous CodeExceptions with equal handler PC. + // This is to eliminate multi-entrant execption handlers. + CodeException previousCodeException = null; + for (CodeException codeException : code.getExceptionTable()) { + if (previousCodeException != null && + previousCodeException.getHandlerPC() == codeException.getHandlerPC()) { + previousCodeException.setEndPC(codeException.getEndPC()); + } else { + add(new ExceptionHandler(codeException)); + } + previousCodeException = codeException; + } + } +} diff --git a/src/main/java/com/j2js/FileManager.java b/src/main/java/com/j2js/FileManager.java new file mode 100644 index 0000000..60bb0da --- /dev/null +++ b/src/main/java/com/j2js/FileManager.java @@ -0,0 +1,76 @@ +package com.j2js; + +import com.j2js.J2JSCompiler; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * A FileManager can resolve relative file names against a class path. + *

+ * The file names "java/lang.package-info", "java/lang/package-info" and + * "java.lang.package-info" are valid and equivalent. + *

+ * + * @author wolle + */ +public class FileManager { + + private List path = new ArrayList(); + + /** + * Create a new FileManager. + * + * @param classPath list of file system directories or jar files. + */ + public FileManager(List classPath) { + Log.getLogger().info("Resolving class path " + classPath); + + // Replace all jar files on classPath by instances of JarFile. + // Non-existing files are sorted out. + for (File file : classPath) { + if (!file.exists()) { + J2JSCompiler.errorCount++; + Log.getLogger().error("Cannot find resource on class path: " + file.getAbsolutePath()); + continue; + } + + if (file.getName().endsWith(".jar")) { + try { + path.add(new JarFile(file)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + path.add(file); + } + } + } + + /** + * Resolves a file given by name along the class path. + */ + public FileObject getFileForInput(String relativeName) { + for (Object o : path) { + if (o instanceof JarFile) { + JarFile jarFile = (JarFile) o; + JarEntry entry = jarFile.getJarEntry(relativeName); + if (entry != null) { + return new FileObject(jarFile, entry); + } + } else { + File file = new File(((File) o), relativeName); + if (file.exists()) { + return new FileObject(file); + } + } + } + + throw new RuntimeException("Could not find " + relativeName + " on class path"); + } + +} diff --git a/src/main/java/com/j2js/FileObject.java b/src/main/java/com/j2js/FileObject.java new file mode 100644 index 0000000..3807271 --- /dev/null +++ b/src/main/java/com/j2js/FileObject.java @@ -0,0 +1,54 @@ +package com.j2js; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +/** + * File abstraction for tools. In this context, file means an abstraction of regular + * files and other sources of data. + * + * @author wolle + */ +public class FileObject { + + private long lastModified; + private InputStream in; + + FileObject(JarFile jarFile, JarEntry entry) { + try { + in = jarFile.getInputStream(entry); + } catch (IOException e) { + throw new RuntimeException(e); + } + lastModified = entry.getTime(); + } + + FileObject(File file) { + try { + in = new FileInputStream(file); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + lastModified = file.lastModified(); + } + + /** + * Gets an InputStream for this file object. + */ + public InputStream openInputStream() throws IOException { + return in; + } + + /** + * @return Returns the lastModified. + */ + public long getLastModified() { + return lastModified; + } + +} diff --git a/src/main/java/com/j2js/Form.java b/src/main/java/com/j2js/Form.java new file mode 100644 index 0000000..7b93814 --- /dev/null +++ b/src/main/java/com/j2js/Form.java @@ -0,0 +1,109 @@ +package com.j2js; + +import org.apache.bcel.generic.Type; + +/** + * @author wolfgang + */ +public class Form { + + public static int CATEGORY1 = 1; + public static int CATEGORY2 = 2; + + public static class Value { + public String type; + public String name; + + public Value(String theType, String theName) { + type = theType; + name = theName; + } + + public int getCategory() { + return type.equals("cat2") || type.equals("long") || type.equals("double")?CATEGORY2:CATEGORY1; + } + } + + private int index; + private Form.Value[] ins; + private Form.Value[] outs; + private Form.Value[] operands; + private Type type; + + /** + * @return Returns the ins. + */ + public Form.Value[] getIns() { + return ins; + } + + /** + * @param theIns The ins to set. + */ + public void setIns(Form.Value[] theIns) { + ins = theIns; + } + + /** + * @return Returns the operands. + */ + public Form.Value[] getOperands() { + return operands; + } + + /** + * @param theOperands The operands to set. + */ + public void setOperands(Form.Value[] theOperands) { + operands = theOperands; + } + + /** + * @return Returns the outs. + */ + public Form.Value[] getOuts() { + return outs; + } + + /** + * @param theOuts The outs to set. + */ + public void setOuts(Form.Value[] theOuts) { + outs = theOuts; + + if (theOuts.length != 1) return; + + String s = theOuts[0].type; + if (s.equals("object")) type = Type.OBJECT; + else if (s.equals("int")) type = Type.INT; + else if (s.equals("short")) type = Type.SHORT; + else if (s.equals("byte")) type = Type.SHORT; + else if (s.equals("long")) type = Type.LONG; + else if (s.equals("float")) type = Type.FLOAT; + else if (s.equals("double")) type = Type.DOUBLE; + else if (!s.equals("cat1") && !s.equals("returnAddress") && !s.equals("")) + throw new RuntimeException("Unhandled type: " + s); + } + + public int getOpStackDelta() { + return getOuts().length - getIns().length; + } + + public Type getResultType() { + if (type == null) throw new RuntimeException("Result type is not available for " + this); + + return type; + } + /** + * @return Returns the index. + */ + public int getIndex() { + return index; + } + /** + * @param theIndex The index to set. + */ + public void setIndex(int theIndex) { + index = theIndex; + } +} diff --git a/src/main/java/com/j2js/InstructionType.java b/src/main/java/com/j2js/InstructionType.java new file mode 100644 index 0000000..ecc2d3e --- /dev/null +++ b/src/main/java/com/j2js/InstructionType.java @@ -0,0 +1,59 @@ +package com.j2js; + +/** + * @author wolfgang + */ +public class InstructionType { + + private short code; + private String name; + private Form[] forms; + + public InstructionType(short theCode, String theName, int formCount) { + code = theCode; + name = theName; + forms = new Form[formCount]; + } + + public int getFormCount() { + return forms.length; + } + + public void setForm(Form form, int index) { + forms[index] = form; + form.setIndex(index); + } + + public Form getForm(int index) { + return forms[index]; + } + + /** + * @return Returns the name. + */ + public String getName() { + return name; + } + + /** + * @param theName The name to set. + */ + public void setName(String theName) { + name = theName; + } + + /** + * @return Returns the code. + */ + public short getCode() { + return code; + } + + /** + * @param theCode The code to set. + */ + public void setCode(short theCode) { + code = theCode; + } + +} diff --git a/src/main/java/com/j2js/J2JSCompiler.java b/src/main/java/com/j2js/J2JSCompiler.java new file mode 100644 index 0000000..3c6ba65 --- /dev/null +++ b/src/main/java/com/j2js/J2JSCompiler.java @@ -0,0 +1,357 @@ +// Copyright 2011 The j2js Authors. All Rights Reserved. +// +// This file is part of j2js. +// +// j2js is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// j2js is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with j2js. If not, see . + +package com.j2js; + +import java.io.File; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.List; + +import com.j2js.FileManager; +import com.j2js.Log; +import com.j2js.Utils; +import com.j2js.assembly.Project; +import com.j2js.visitors.JavaScriptGenerator; + +/** + * The cross-compiler translates Java class files into JavaScript code and assembles all reachable code + * into assemblies. + *

+ * For details please refer to the plugin description. + * + * @author Wolfgang Kuehn + */ +public class J2JSCompiler { + + public static J2JSCompiler compiler; + + public static int errorCount = 0; + + private File basedir; + private File cacheFile; + + List assemblies = new ArrayList(); + + private List classpath = new ArrayList(); + + public FileManager fileManager; + + public boolean optimize = true; + public boolean failOnError = true; + private boolean compression = true; + + private String singleEntryPoint; + private String targetPlatform; + public int reductionLevel = 5; + + private int junkSizeInKiloBytes = Integer.MAX_VALUE; + + private boolean generateLineNumbers = false; + + public int compileCount = 0; + public JavaScriptGenerator generator; + + private Log logger; + + // Begin main + public static void main(String argv[]) throws Exception { + if ( argv == null || argv.length != 4 ) { + StringBuffer sb = new StringBuffer(); + sb.append("Usage: java "); + sb.append(J2JSCompiler.class.getName()); + sb.append(" "); + System.out.print(sb.toString()); + return; + } + + File basedir = new File(argv[0]); + String classpathElements = argv[1]; + String entryPointClassName = argv[2]; + + Assembly assembly = new Assembly(); + assembly.setEntryPointClassName(entryPointClassName); + + assembly.setTargetLocation(new File(basedir, argv[3])); + + J2JSCompiler compiler = new J2JSCompiler(); + compiler.setBasedir(basedir); + compiler.addClasspathElements(classpathElements); + compiler.addAssembly(assembly); + compiler.setGenerateLineNumbers(true); + compiler.execute(); + } + // End main + + /** + * Create new compiler with the current directory as basedir. + */ + public J2JSCompiler() { + setBasedir(new File(System.getProperty("user.dir"))); + setTargetPlatform("web"); + } + + public void execute() throws Exception { + if (logger == null) { + setLogger(new Log()); + } + + for (Assembly assembly : assemblies) { + execute(assembly); + } + } + + private boolean isMavenExecution() { + return System.getProperty("localRepository") != null; + } + + public void execute(Assembly assembly) throws Exception { + J2JSCompiler.compiler = this; + + logger.info("Entry point is " + assembly.getEntryPointClassName() + "#main(java.lang.String[])void"); + + if (classpath == null) { + throw new RuntimeException("Field classPath must be set"); + } + + if (assembly.getEntryPointClassName() == null) { + throw new RuntimeException("Field assembly.entryPointClassName must be set"); + } + + if (cacheFile == null) { + setCacheFile(new File(basedir, "target/j2js.cache")); + } + + if (assembly.getTargetLocation() == null) { + throw new RuntimeException("Field assembly.targetLocation must be set"); + //assembly.setTargetLocation(new File(basedir, "target/classes/assemblies/" + assembly.getEntryPointClassName().replaceAll("\\.", "/"))); + } + + logger.info("Creating assembly " + assembly.getTargetLocation()); + + fileManager = new FileManager(classpath); + Project project = Project.createSingleton(getCacheFile()); + assembly.setProject(project); + generator = new JavaScriptGenerator(project); + + errorCount = 0; + + assembly.addEntryPoint(assembly.getEntryPointClassName() + "#main(java.lang.String[])void"); + + for (String memberSignature : assembly.entryPoints) { + assembly.taint(memberSignature); + } + + long startTime = System.currentTimeMillis(); + + // Used by the JavaScript JVM. The static code analyser would miss these. + + String[] signatures = Utils.getProperty("j2js.preTaintedSignatures").split(";"); + for (int i=0; i 0) { + logger.error("There " + timesName("was|were", errorCount, "error|errors") + "."); + } + } + + private String timesName(String verb, int count, String noun) { + String[] verbs = verb.split("\\|"); + String[] nouns = noun.split("\\|"); + int index = (count==1?0:1); + return verbs[index] + " " + count + " " + nouns[index]; + } + + public void setCompression(boolean isCompression) { + this.compression = isCompression; + } + + public boolean isCompression() { + return compression; + } + + + /** + * For debugging. Internal use only. + */ + public void setSingleEntryPoint(String signature) { + singleEntryPoint = signature; + } + + /** + * @see #setSingleEntryPoint(String) + */ + public String getSingleEntryPoint() { + return singleEntryPoint; + } + + /** + * Sets one of the target platforms "web" or "javascript". + * + * @param targetPlatform optional; default is "web" + */ + public void setTargetPlatform(String targetPlatform) { + targetPlatform = targetPlatform.toLowerCase(); + if ("web".equals(targetPlatform) || "javascript".equals(targetPlatform)) { + this.targetPlatform = targetPlatform; + } else { + throw new IllegalArgumentException("Target platform must be web or javascript"); + } + } + + /** + * @see #setTargetPlatform(String) + */ + public String getTargetPlatform() { + return targetPlatform; + } + + public List getClasspath() { + return classpath; + } + + /** + * @param classpathElements (optional) additional class path elements + */ + public void addClasspathElements(List classpathElements) { + classpath.addAll(classpathElements); + } + + /** + * @param classpathElement (optional) additional class path element + */ + public void addClasspathElement(File classpathElement) { + classpath.add(classpathElement); + } + + /** + * Semicolon- or whitespace-separated list of class path elements. + * + * @param classPathElements (optional) additional class path elements + * @see #setClasspathElements(List) + */ + public void addClasspathElements(String classPathElements) { + String[] array = classPathElements.split("(;|,)"); + for (String path : array) { + path = path.trim(); + if (path.length() > 0) { + addClasspathElement(Utils.resolve(basedir, path)); + } + } + } + + public void setClasspathElements(List classpathElements) { + for (Object part : classpathElements) { + addClasspathElements((String) part); + } + } + + public void setFailOnError(boolean flag) { + failOnError = flag; + } + + public boolean isFailOnError() { + return failOnError; + } + + public File getCacheFile() { + return cacheFile; + } + + public void setCacheFile(File theCacheFile) { + cacheFile = theCacheFile; + } + + public List getAssemblies() { + return assemblies; + } + + public void setAssemlies(List assemblies) { + this.assemblies = assemblies; + } + + public void setGenerateLineNumbers(boolean theGenerateLineNumbers) { + generateLineNumbers = theGenerateLineNumbers; + } + + public boolean isGenerateLineNumbers() { + return generateLineNumbers; + } + + public void setJunkSizeInKiloBytes(int junkSizeInKiloBytes) { + if (junkSizeInKiloBytes < 1) { + throw new RuntimeException("Junk size must be greater than zero."); + } + this.junkSizeInKiloBytes = junkSizeInKiloBytes; + } + + public int getJunkSizeInKiloBytes() { + return junkSizeInKiloBytes; + } + + /** + * @return Returns the logger. + */ + public Log getLogger() { + return logger; + } + + /** + * Sets the logger. + */ + public void setLogger(Log logger) { + this.logger = logger; + Log.logger = logger; + } + + public void setBasedir(File basedir) { + this.basedir = basedir; + } + + public File getBasedir() { + return basedir; + } + + public void addAssembly(Assembly assembly) { + assemblies.add(assembly); + } + +} diff --git a/src/main/java/com/j2js/LineNumberCursor.java b/src/main/java/com/j2js/LineNumberCursor.java new file mode 100644 index 0000000..465736a --- /dev/null +++ b/src/main/java/com/j2js/LineNumberCursor.java @@ -0,0 +1,76 @@ +package com.j2js; + +import java.util.Arrays; +import java.util.Comparator; + +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.LineNumber; +import org.apache.bcel.classfile.LineNumberTable; + +import com.j2js.dom.ASTNode; + +public class LineNumberCursor { + + private class LineNumberComparator implements Comparator { + + public int compare(LineNumber arg0, LineNumber arg1) { + return arg0.getStartPC() - arg1.getStartPC(); + } + + } + + private LineNumber[] lineNumbers = null; + private int index = 0; + private int markedLineNumber = -1; + private int length; + + public LineNumberCursor(Code code) { + if (code == null) return; + LineNumberTable table = code.getLineNumberTable(); + if (table == null) return; + lineNumbers = table.getLineNumberTable(); + length = lineNumbers.length; + // TODO: Is table already ordered? + Arrays.sort(lineNumbers, new LineNumberComparator()); + } + + public boolean hasLineNumbers() { + return lineNumbers != null; + } + + public int getLineNumber(ASTNode node) { + if (!hasLineNumbers()) return -1; + + while (node.getBeginIndex() == Integer.MAX_VALUE && node.getPreviousSibling() != null) { + node = node.getPreviousSibling(); + } + + int pc = node.getBeginIndex(); + L: if (pc > lineNumbers[index].getStartPC()) { + do { + if (index+1 == length) break L; + index ++; + } while (pc >= lineNumbers[index].getStartPC()); + index --; + } else if (pc < lineNumbers[index].getStartPC()) { + do { + if (index == 0) break L; + index --; + } while (pc <= lineNumbers[index].getStartPC()); + index ++; + } + + return lineNumbers[index].getLineNumber(); + } + + public int getAndMarkLineNumber(ASTNode node) { + if (!hasLineNumbers()) return -1; + + int lineNumber = getLineNumber(node); + if (lineNumber == markedLineNumber) return -1; + + markedLineNumber = lineNumber; + return lineNumber; + } + +} diff --git a/src/main/java/com/j2js/Log.java b/src/main/java/com/j2js/Log.java new file mode 100644 index 0000000..4d54886 --- /dev/null +++ b/src/main/java/com/j2js/Log.java @@ -0,0 +1,132 @@ +/* + * Copyright 2005 by Wolfgang Kuehn + * Created on 04.10.2005 + */ +package com.j2js; + + +/** + * @author wolfgang + */ +public class Log { + + public static Log logger; + + public static Log getLogger() { + return logger; + } + + private int state = INFO; + + /** + * @return Returns the state. + */ + public int getState() { + return state; + } + + /** + * @param state The state to set. + */ + public void setState(int state) { + this.state = state; + } + + public static final int DEBUG = 3; + public static final int INFO = 2; + public static final int WARN = 1; + public static final int ERROR = 0; + + public void debug(CharSequence arg0, Throwable arg1) { + if (isDebugEnabled()) { + System.out.println("[DEBUG] " + arg0); + arg1.printStackTrace(); + } + } + + public void debug(CharSequence arg0) { + if (isDebugEnabled()) { + System.out.println("[DEBUG] " + arg0); + } + } + + public void debug(Throwable arg0) { + if (isDebugEnabled()) { + arg0.printStackTrace(); + } + } + + public void error(CharSequence arg0, Throwable arg1) { + if (isErrorEnabled()) { + System.out.println("[ERROR] " + arg0); + arg1.printStackTrace(); + } + } + + public void error(CharSequence arg0) { + if (isErrorEnabled()) { + System.out.println("[ERROR] " + arg0); + } + } + + public void error(Throwable arg0) { + if (isErrorEnabled()) { + arg0.printStackTrace(); + } + } + + public void info(CharSequence arg0, Throwable arg1) { + if (isInfoEnabled()) { + System.out.println("[INFO] " + arg0); + arg1.printStackTrace(); + } + } + + public void info(CharSequence arg0) { + if (isInfoEnabled()) { + System.out.println("[INFO] " + arg0); + } + } + + public void info(Throwable arg0) { + if (isInfoEnabled()) { + arg0.printStackTrace(); + } + } + + public boolean isDebugEnabled() { + return state >= DEBUG; + } + + public boolean isErrorEnabled() { + return state >= ERROR; + } + + public boolean isInfoEnabled() { + return state >= INFO; + } + + public boolean isWarnEnabled() { + return state >= WARN; + } + + public void warn(CharSequence arg0, Throwable arg1) { + if (isWarnEnabled()) { + System.out.println("[WARNING] " + arg0); + arg1.printStackTrace(); + } + } + + public void warn(CharSequence arg0) { + if (isWarnEnabled()) { + System.out.println("[WARNING] " + arg0); + } + } + + public void warn(Throwable arg0) { + if (isWarnEnabled()) { + arg0.printStackTrace(); + } + } + +} diff --git a/src/main/java/com/j2js/OperandState.java b/src/main/java/com/j2js/OperandState.java new file mode 100644 index 0000000..8e248ed --- /dev/null +++ b/src/main/java/com/j2js/OperandState.java @@ -0,0 +1,38 @@ +/* + * Created on 20.10.2004 + * + * To change the template for this generated file go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +package com.j2js; + +import com.j2js.dom.ASTNode; + +/** + * @author kuehn + * + * To change the template for this generated type comment go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +public class OperandState { + + int code; + int beginIndex; + int endIndex; + + ASTNode stmt; + + OperandState(int theCode) { + code = theCode; + } + + OperandState(int theCode, int theBeginIndex, ASTNode theStmt) { + code = theCode; + beginIndex = theBeginIndex; + stmt = theStmt; + } + + public String toString() { + return "State: " + code + " " + stmt; + } +} diff --git a/src/main/java/com/j2js/Optimizer.java b/src/main/java/com/j2js/Optimizer.java new file mode 100644 index 0000000..b34ec3e --- /dev/null +++ b/src/main/java/com/j2js/Optimizer.java @@ -0,0 +1,324 @@ +package com.j2js; + +import java.util.Iterator; +import java.util.List; + +import org.apache.bcel.generic.Type; + +import com.j2js.dom.ASTNode; +import com.j2js.dom.Assignable; +import com.j2js.dom.Assignment; +import com.j2js.dom.Block; +import com.j2js.dom.Expression; +import com.j2js.dom.FieldAccess; +import com.j2js.dom.InfixExpression; +import com.j2js.dom.MethodDeclaration; +import com.j2js.dom.NumberLiteral; +import com.j2js.dom.PStarExpression; +import com.j2js.dom.PostfixExpression; +import com.j2js.dom.PrefixExpression; +import com.j2js.dom.VariableBinding; +import com.j2js.dom.VariableDeclaration; + +public class Optimizer { + + private MethodDeclaration methodDecl; + private List tempDecls; + + public Optimizer(MethodDeclaration theMethodDecl, List theTempDecls) { + methodDecl = theMethodDecl; + tempDecls = theTempDecls; + } + + public static Expression negate(Expression expr) { + PrefixExpression pe = new PrefixExpression(); + pe.setOperator(PrefixExpression.NOT); + pe.setOperand(expr); + return pe; + } + + /** + * Simplifies the (possibly negated) expression. + */ + public static Expression simplifyBooleanExpression(Expression expr, boolean negate) { + if (expr instanceof PrefixExpression) { + PrefixExpression pe = (PrefixExpression) expr; + if (pe.getOperator() != PrefixExpression.NOT) return expr; + return simplifyBooleanExpression((Expression) pe.getOperand(), !negate); + } + + if (expr instanceof InfixExpression && expr.getTypeBinding() == Type.BOOLEAN) { + InfixExpression in = (InfixExpression) expr; + InfixExpression.Operator op = in.getOperator(); + if (negate) { + op = op.getComplement(); + if (op != InfixExpression.Operator.CONDITIONAL_AND && op != InfixExpression.Operator.CONDITIONAL_OR) + negate = false; + } + InfixExpression out = new InfixExpression(op); + out.widen(in); + out.setOperands(simplifyBooleanExpression(in.getLeftOperand(), negate), simplifyBooleanExpression(in.getRightOperand(), negate)); + return out; + } + + if (negate) { + PrefixExpression pe = new PrefixExpression(); + pe.setOperator(PrefixExpression.NOT); + pe.setOperand(expr); + return pe; + } + + return expr; + } + + private boolean representSameAssignables(Assignable a, Assignable b) { + if (!(a instanceof FieldAccess && b instanceof FieldAccess)) return false; + FieldAccess faa = (FieldAccess) a; + FieldAccess fab = (FieldAccess) b; + if (!faa.getName().equals(fab.getName())) return false; + if (faa.getExpression() instanceof VariableBinding && fab.getExpression() instanceof VariableBinding ) { + VariableBinding vba = (VariableBinding) faa.getExpression(); + VariableBinding vbb = (VariableBinding) fab.getExpression(); + return vba.getVariableDeclaration() == vbb.getVariableDeclaration(); + } + return false; + } + + /** + * Reduces occurences of + * temp = x; + * y = temp; + * to + * y = x; + */ +// private ASTNode bar1(ASTNode child, ASTNode next) { +// if (child instanceof Assignment && next instanceof Assignment) { +// Assignment a1 = (Assignment) child; +// Assignment a2 = (Assignment) next; +// if (a1.getLeftHandSide().equals(a2.getRightHandSide())) { +// a2.setRightHandSide(a1.getRightHandSide()); +// child.getParentBlock().removeChild(child); +// return next; +// } +// } +// return child; +// } + + private VariableBinding fetchVariableBinding(Expression expr, VariableDeclaration decl) { + ASTNode child = expr.getFirstChild(); + while (child != null) { + if (child instanceof VariableBinding && ((VariableBinding) child).getVariableDeclaration() == decl) + return (VariableBinding) child; + VariableBinding vb = fetchVariableBinding((Expression) child, decl); + if (vb != null) return vb; + child = child.getNextSibling(); + } + return null; + } + + /** + * If the specified expression corresponds to + * xy + 1 or xy - (-1), + * returns the INCREMENT operator. If the specified expression corresponds to + * xy - 1 or xy + (-1), + * returns the DECREMENT operator. Otherwise, null is returned. + * @param expr + * @return + */ + private PStarExpression.Operator getOp(InfixExpression expr) { + NumberLiteral nl; + if (expr.getRightOperand() instanceof NumberLiteral) { + nl = (NumberLiteral) expr.getRightOperand(); + } else return null; + + PStarExpression.Operator op; + if (expr.getOperator() == InfixExpression.Operator.PLUS) { + op = PStarExpression.INCREMENT; + } else if (expr.getOperator() == InfixExpression.Operator.MINUS) { + op = PStarExpression.DECREMENT; + } else { + return null; + } + + if (NumberLiteral.isOne(nl)) { + // We are ok. + } else if (NumberLiteral.isMinusOne(nl)) { + op = op.complement(); + } else { + return null; + } + return op; + } + + /** + * Reduces + * vb = x.y; (1) + * x.y = vb + 1; (2) + * ... + * expr(vb); + * to incremental form + * expr(x.y++); + * Likewise decrement. + */ + private boolean reduceXCrement(VariableDeclaration decl) { + Assignment a1 = null; + Assignment a2 = null; + VariableBinding vb1 = null; + VariableBinding vb2 = null; + + Assignable fa1 = null; + Assignable fa2 = null; + + InfixExpression sum = null; + + + Iterator iter = decl.vbs.iterator(); + + while (iter.hasNext()) { + VariableBinding vb = (VariableBinding) iter.next(); + + if (vb.getParentNode() instanceof Assignment) { + Assignment a = (Assignment) vb.getParentNode(); + if (a.getLeftHandSide() == vb && a.getRightHandSide() instanceof Assignable) { + vb1 = vb; + a1 = a; + fa1 = (Assignable) a.getRightHandSide(); + continue; + } + } + + if (vb.getParentNode() instanceof InfixExpression) { + InfixExpression infix = (InfixExpression) vb.getParentNode(); + if (infix.getParentNode() instanceof Assignment) { + Assignment a = (Assignment) infix.getParentNode(); + if (a.getLeftHandSide() instanceof Assignable) { + vb2 = vb; + fa2 = (Assignable) a.getLeftHandSide(); + a2 = a; + sum = infix; + continue; + } + } + } + } + + if (a1 == null || a2 == null) return false; + if (!fa1.isSame(fa2)) return false; + + PStarExpression.Operator operator = getOp(sum); + if (operator == null) return false; + + PStarExpression p = new PostfixExpression(); + p.setOperand((Expression) fa1); + p.setOperator(operator); + + decl.vbs.remove(vb1); + decl.vbs.remove(vb2); + VariableBinding vb = decl.vbs.get(0); + vb.getParentBlock().replaceChild(p, vb); + + Block b = a1.getParentBlock(); + b.removeChild(a1); + b.removeChild(a2); + return true; + } + + /** + * Reduces + * vb = x.y op z; (3) + * x.y = vb; (4) + * ... + * expr(vb); + * to incremental form + * expr(x.y op= z) or expr(++x.y); + * Likewise decrement. + */ + private boolean reduceYCrement(VariableDeclaration decl) { + Assignment a1 = null; + Assignment a2 = null; + VariableBinding vb1 = null; + VariableBinding vb2 = null; + + Assignable fa1 = null; + Assignable fa2 = null; + + InfixExpression infixExpr = null; + + Iterator iter = decl.vbs.iterator(); + + while (iter.hasNext()) { + VariableBinding vb = (VariableBinding) iter.next(); + + if (!(vb.getParentNode() instanceof Assignment)) continue; + + Assignment a = (Assignment) vb.getParentNode(); + if (a.getRightHandSide() == vb && a.getLeftHandSide() instanceof Assignable) { + vb2 = vb; + a2 = a; + fa2 = (Assignable) a.getLeftHandSide(); + continue; + } + + if (a.getLeftHandSide() == vb && a.getRightHandSide() instanceof InfixExpression) { + InfixExpression infix = (InfixExpression) a.getRightHandSide(); + if (!(infix.getLeftOperand() instanceof Assignable)) continue; + vb1 = vb; + a1 = a; + fa1 = (Assignable) infix.getLeftOperand(); + infixExpr = infix; + continue; + } + } + + if (a1 == null || a2 == null) return false; + if (!fa1.isSame(fa2)) return false; + + decl.vbs.remove(vb1); + decl.vbs.remove(vb2); + VariableBinding vb = decl.vbs.get(0); + Expression replacement = null; + + PStarExpression.Operator operator = getOp(infixExpr); + if (operator != null) { + PrefixExpression p = new PrefixExpression(); + p.setOperand((Expression) fa1); + p.setOperator(operator); + replacement = p; + } else { + InfixExpression.Operator op = infixExpr.getOperator(); + Assignment.Operator opp = Assignment.Operator.lookup(op.toString() + '='); + Assignment a = new Assignment(opp); + a.setLeftHandSide((Expression) fa2); + a.setRightHandSide(infixExpr.getRightOperand()); + replacement = a; + } + + vb.getParentBlock().replaceChild(replacement, vb); + + Block b = a1.getParentBlock(); + b.removeChild(a1); + b.removeChild(a2); + return true; + } + + public void optimize() { + if (false) return; + // Review this code. For example j2js.fa(obj, name)++ is illegal! + + Iterator iter = tempDecls.iterator(); + while (iter.hasNext()) { + VariableDeclaration decl = (VariableDeclaration) iter.next(); + int count = decl.vbs.size(); + if (count == 3) { + if (reduceXCrement(decl)) { + iter.remove(); + methodDecl.removeLocalVariable(decl.getName()); + } else if (reduceYCrement(decl)) { + iter.remove(); + methodDecl.removeLocalVariable(decl.getName()); + } + } + } + } + +} diff --git a/src/main/java/com/j2js/ParseException.java b/src/main/java/com/j2js/ParseException.java new file mode 100644 index 0000000..e039d00 --- /dev/null +++ b/src/main/java/com/j2js/ParseException.java @@ -0,0 +1,25 @@ +package com.j2js; + +import com.j2js.dom.ASTNode; + +/** + * @author kuehn + */ +public class ParseException extends RuntimeException { + + private ASTNode astNode; + + public ParseException(String msg, ASTNode node) { + super(msg); + astNode = node; + } + + public ParseException(Throwable cause, ASTNode node) { + super(cause); + astNode = node; + } + + public ASTNode getAstNode() { + return astNode; + } +} diff --git a/src/main/java/com/j2js/Parser.java b/src/main/java/com/j2js/Parser.java new file mode 100644 index 0000000..7f2e6b4 --- /dev/null +++ b/src/main/java/com/j2js/Parser.java @@ -0,0 +1,204 @@ +package com.j2js; + +import com.j2js.J2JSCompiler; + +import java.io.IOException; +import java.lang.reflect.Modifier; + +import com.j2js.Pass1; +import com.j2js.ParseException; + +import org.apache.bcel.classfile.Attribute; +import org.apache.bcel.classfile.AttributeReader; +import org.apache.bcel.classfile.ClassParser; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.classfile.Method; +import org.apache.bcel.classfile.Field; +import org.apache.bcel.generic.ObjectType; +import org.apache.bcel.generic.Type; + +import com.j2js.assembly.ClassUnit; +import com.j2js.assembly.Project; +import com.j2js.assembly.Signature; +import com.j2js.dom.*; + +/** + * @author wolfgang + */ +public class Parser { + + public static String getResourcePath(String name) { + name = name.replace('.', '/') + ".class"; + java.net.URL url = Parser.class.getClassLoader().getResource(name); + if (url == null) throw new RuntimeException("Resource not found: " + name); + return url.getPath(); + } + + private JavaClass jc; + private ClassUnit fileUnit; + + public Parser(ClassUnit theFileUnit) { + fileUnit = theFileUnit; + fileUnit.annotations = null; + + AttributeReader r = new AnnotationReader(fileUnit); + Attribute.addAttributeReader("RuntimeVisibleAnnotations", r); + + try { + ClassParser cp = new ClassParser(fileUnit.getClassFile().openInputStream(), fileUnit.getName()); + jc = cp.parse(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public TypeDeclaration parse() { + +// Attribute[] attributes = jc.getAttributes(); +// for (int i=0; i", "(java/lang/String)V;"); + ClassInstanceCreation cic = new ClassInstanceCreation(methodDecl, binding); + cic.addArgument(new StringLiteral("Unresolved decompilation problem")); + throwStmt.setExpression(cic); + body.appendChild(throwStmt); + methodDecl.setBody(body); + + } + + // Remove from body last expressionless return statement. + if (J2JSCompiler.compiler.optimize && methodDecl.getBody().getLastChild() instanceof ReturnStatement) { + ReturnStatement ret = (ReturnStatement) methodDecl.getBody().getLastChild(); + if (ret.getExpression() == null) { + methodDecl.getBody().removeChild(ret); + } + } + + Pass1.dump(methodDecl.getBody(), "Body of " + methodDecl.toString()); + +// if (typeDecl.getClassName().equals("java.lang.String")) { +// if (methodDecl.isInstanceConstructor()) { +// +// } +// } + + return; + } + + public ConstantPool getConstantPool() { + return jc.getConstantPool(); + } + + public String toString() { + return jc.getClassName(); + } + +} diff --git a/src/main/java/com/j2js/Pass1.java b/src/main/java/com/j2js/Pass1.java new file mode 100644 index 0000000..d658164 --- /dev/null +++ b/src/main/java/com/j2js/Pass1.java @@ -0,0 +1,2233 @@ +package com.j2js; + +import org.apache.bcel.Constants; +//import org.apache.bcel.classfile.*; +import org.apache.bcel.classfile.ClassFormatException; +import org.apache.bcel.classfile.CodeException; +import org.apache.bcel.classfile.Constant; +import org.apache.bcel.classfile.ConstantClass; +import org.apache.bcel.classfile.ConstantCP; +import org.apache.bcel.classfile.ConstantDouble; +import org.apache.bcel.classfile.ConstantFieldref; +import org.apache.bcel.classfile.ConstantInteger; +import org.apache.bcel.classfile.ConstantFloat; +import org.apache.bcel.classfile.ConstantLong; +import org.apache.bcel.classfile.ConstantNameAndType; +import org.apache.bcel.classfile.ConstantString; +import org.apache.bcel.classfile.ConstantUtf8; +import org.apache.bcel.classfile.JavaClass; +import org.apache.bcel.classfile.Code; +import org.apache.bcel.classfile.Method; +import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.classfile.Utility; + +import org.apache.bcel.generic.BasicType; +import org.apache.bcel.generic.InstructionHandle; +import org.apache.bcel.generic.InstructionTargeter; +import org.apache.bcel.generic.ObjectType; +import org.apache.bcel.generic.Type; +import org.apache.bcel.util.ByteSequence; + +import com.j2js.cfg.ControlFlowGraph; +import com.j2js.cfg.Node; +import com.j2js.cfg.SwitchEdge; +import com.j2js.cfg.TryHeaderNode; +import com.j2js.dom.*; +import com.j2js.visitors.SimpleGenerator; +import com.j2js.assembly.Project; +import com.j2js.assembly.Signature; + +import org.apache.bcel.generic.InstructionList; + +import com.j2js.J2JSCompiler; + +import java.io.*; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +public class Pass1 { + + private ConstantPool constantPool; + + private ByteSequence bytes; + private static ASTNode currentNode; + + private ASTNodeStack stack; + + private Code code; + private MethodDeclaration methodDecl; + // The currently parsed method. + private Method method; + + private List tryStatements = new ArrayList(); + private ControlFlowGraph graph = new ControlFlowGraph(tryStatements); + + // Not used anymore. + private int depth; + + private static Log logger = Log.getLogger(); + + + /* + * The `WIDE' instruction is used in the byte code to allow 16-bit wide + * indices for local variables. This opcode may precede one of + * iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, ret or iinc. + * The opcode immediately following takes an extra byte which is combined with + * the following byte to form a 16-bit value. + * In case of iinc, the default two 8 bit operants are widened to two 16 bit aperants accordingly. + */ + private boolean wide = false; + + public static ASTNode getCurrentNode() { + return currentNode; + } + + public Pass1(JavaClass jc) { + constantPool = jc.getConstantPool(); + } + + private CatchClause createCatchClause(TryStatement tryStmt, ExceptionHandler handle) { + CatchClause cStmt = new CatchClause(handle.getHandlerPC()); + VariableDeclaration decl = new VariableDeclaration(VariableDeclaration.LOCAL_PARAMETER); + decl.setName("_EX_"); + decl.setType(handle.getCatchType(constantPool)); + cStmt.setException(decl); + tryStmt.addCatchStatement(cStmt); + return cStmt; + } + + private void makeTryFrames() { + for (int i=0; i handleIterator = handlers.iterator(); + + ExceptionHandler handle = handleIterator.hasNext()?handleIterator.next():null; + while (handle != null) { + boolean hasFinally = false; + int start = handle.getStartPC(); + int end = handle.getEndPC(); + + TryStatement tryStmt = new TryStatement(); + tryStmt.header = (TryHeaderNode) graph.createNode(TryHeaderNode.class); + tryStmt.header.tryStmt = tryStmt; + + Block tryBlock = new Block(start, end); + tryStmt.setTryBlock(tryBlock); + + //tryStmt.setBeginIndex(start); + + tryStatements.add(tryStmt); + + CatchClause cStmt = null; + + // Collect all non-default handlers. The range of each handler is from the 'store'-instruction to the beginning of the next handler. + while (handle != null && !handle.isDefault() && handle.getStartPC()==start && handle.getEndPC()==end) { + if (cStmt!=null) { + cStmt.setEndIndex(handle.getHandlerPC()-1); + } + cStmt = createCatchClause(tryStmt, handle); + handle = handleIterator.hasNext()?handleIterator.next():null; + } + + int foo = -1; + if (handle != null && handle.isDefault() && handle.getStartPC()==start) { + // Collect first default handler. + hasFinally = true; + if (cStmt!=null) { + cStmt.setEndIndex(handle.getHandlerPC()-1); + tryStmt.setEndIndex(handle.getHandlerPC()-1); + // Warning: We only set a lower bound for the end index. The correct index is set later + // when the finally statement is analysed. + } + cStmt = createCatchClause(tryStmt, handle); + foo = handle.getHandlerPC(); + handle = handleIterator.hasNext()?handleIterator.next():null; + } + + // Last catch stmt has no endIndex, yet! + + while (handle != null && handle.isDefault() && (handle.getHandlerPC()==foo)) { + // Skip all remaining default handlers. + throw new RuntimeException("remaining default handlers"); + //handle = handleIterator.hasNext()?handleIterator.next():null; + } + + Block catches = tryStmt.getCatchStatements(); + if (catches.getChildCount() == 0) { + throw new ParseException("A try clause must have at least one (possibly default) catch clause", tryStmt); + } + cStmt = (CatchClause) catches.getChildAt(0); + tryBlock.setEndIndex(cStmt.getBeginIndex()-1); + cStmt = (CatchClause) catches.getLastChild(); + if (cStmt.getEndIndex() == Integer.MIN_VALUE) { + cStmt.setEndIndex(cStmt.getBeginIndex()+1); + } + tryStmt.setEndIndex(cStmt.getEndIndex()); + + if (hasFinally) { + // Can't say yet where finally block is located. + } + + if (logger.isDebugEnabled()) { + dump(tryStmt, "Try"); + } + } + } + + /** + * Dumps instructions and exeption table. + */ + private void dumpCode() { + InstructionList il = new InstructionList(code.getCode()); + InstructionHandle[] handles = il.getInstructionHandles(); + + for (InstructionHandle handle : handles) { + System.out.println(handle.toString(true)); + InstructionTargeter[] targeters = handle.getTargeters(); + if (targeters != null) { + for (InstructionTargeter targeter : handle.getTargeters()) { + System.out.println(" Targeter: " + targeter.toString() + " " + targeter.getClass()); + } + } + } + + for (CodeException ce : code.getExceptionTable()) { + String exceptionType; + if (ce.getCatchType() > 0) { + Constant constant = constantPool.getConstant(ce.getCatchType()); + exceptionType = Pass1.constantToString(constant, constantPool); + } else { + exceptionType = "Default"; + } + System.out.println(ce.toString() + " " + exceptionType); + } + } + + public void parse(Method theMethod, MethodDeclaration theMethodDecl) throws IOException { + method = theMethod; + methodDecl = theMethodDecl; + + code = method.getCode(); + + if (logger.isDebugEnabled()) { + dumpCode(); + } + + Block.TAG = 0; + + compileCodeException(); + + bytes = new ByteSequence(code.getCode()); + + graph.createNode(0); + + makeTryFrames(); + + parseStatement(); + + try { + Optimizer optimizer = new Optimizer(methodDecl, tempDecls); + optimizer.optimize(); + } catch (Error e) { + J2JSCompiler.errorCount++; + if (logger.isDebugEnabled()) { + logger.debug("In Expression Optimizer:\n" + e + "\n" + Utils.stackTraceToString(e)); + } else { + logger.error("In Expression Optimizer:\n " + e); + } + } + + Block block; + if (J2JSCompiler.compiler.reductionLevel == 0) { + block = graph.reduceDumb(); + } else { + block = graph.reduce(); + } + + methodDecl.setBody(block); + + } + + private boolean isProcedure(ASTNode stmt) { + if (stmt instanceof MethodInvocation) { + MethodInvocation mi = (MethodInvocation) stmt; + return mi.getTypeBinding().equals(Type.VOID); + } + return false; + } + + Node cNode; + Node lastCurrentNode; + + private void setCurrentNode(Node theNode) { + if (cNode == theNode) return; + cNode = theNode; + if (cNode != null && cNode != lastCurrentNode) { + logger.debug("Switched to " + cNode); + lastCurrentNode = cNode; + } + } + + private void joinNodes(Node node) { + Collection nodes = node.preds(); + Iterator iter = nodes.iterator(); + while (iter.hasNext()) { + Node n = (Node) iter.next(); + if (n.stack.size() == 0) iter.remove(); + } + if (nodes.size() > 0) { + mergeStacks(nodes, node.stack); + } + } + + /** + * Selects a single node as currently active node. + */ + private void selectActiveNode(int pc) { + // Find all nodes currently active at pc. + List activeNodes = new ArrayList(); + for (Node node : graph.getNodes()) { + if (node.getCurrentPc() == pc) { + activeNodes.add(node); + } + } + + if (activeNodes.size() == 0) { + // No active node: Create one. + Node node = graph.createNode(pc); + setCurrentNode(node); + return; + } + + if (activeNodes.size() == 1) { + // Return single active node. + Node node = activeNodes.get(0); + setCurrentNode(node); + return; + } + + // Multiple nodes. Select the one starting at pc. + + Node node = graph.getNode(pc); + if (node == null) throw new RuntimeException("No node found at " + pc); + + setCurrentNode(node); + + // Add edges from all other active nodes to the selected node. + activeNodes.remove(node); + for (Node n : activeNodes) { + graph.addEdge(n, node); + } + } + + /** + * If the stack of the specified node is [s0, s1, ..., sn], then [t1=s1; ... tn=sn} is + * appended to its block, and the stack is replaced by [t1, t2, ..., tn]. + */ + private void expressionsToVariables(Node node, boolean clone) { + if (node.stack.size() == 0) return; + + logger.debug("expressionsToVariables ..."); + + for (int i=0; i 0) { + + int pc = bytes.getIndex(); + //Logger.getLogger().finer("@" + pc); + + if (cNode != null) { + cNode.setCurrentPc(pc); + } + + selectActiveNode(pc); + + if (cNode.getInitialPc() == pc) { + joinNodes(cNode); + } + + stack = cNode.stack; + + ASTNode stmt = parseInstruction(); + //InstructionHandle handle = il.findHandle(stmt.getBeginIndex()); + //System.out.println(">>>" + handle); + + if (stmt instanceof NoOperation) continue; + + depth += stmt.getStackDelta(); + + if (stmt instanceof VariableBinding) { + depth = depth; + } + + logger.debug(" -> " + stmt + " @ " + + methodDecl.getLineNumberCursor().getLineNumber(stmt) + + ", depth:" + depth + ", delta:" + stmt.getStackDelta()); + + if (stmt instanceof JumpSubRoutine) { + JumpSubRoutine jsr = (JumpSubRoutine) stmt; + cNode.block.setEndIndex(jsr.getEndIndex()); + + Node finallyNode = graph.getNode(jsr.getTargetIndex()); + + if (finallyNode == null) { + // Found finally clause. + finallyNode = graph.createNode(jsr.getTargetIndex()); + // Generate dummy expression for the astore instruction of the finally block. + finallyNode.stack = new ASTNodeStack(new Expression()); + + //finallyNode.jsrCallers.add(cNode); + } + finallyNode.jsrCallers.add(cNode); + if (cNode.preds().size() == 1 && finallyNode.preds().size() == 0 && cNode.getPred() instanceof TryHeaderNode) { + // Current node must be the default handler. + // TODO: This only works if default handler is a single node!! + TryHeaderNode tryHeaderNode = (TryHeaderNode) cNode.getPred(); + // Attach finally to its try header node. + tryHeaderNode.setFinallyNode(finallyNode); + } + + } else if (stmt instanceof ConditionalBranch) { + ConditionalBranch cond = (ConditionalBranch) stmt; + + if (bytes.getIndex() == cond.getTargetIndex()) { + // This is a conditional branch with an empty body, i.e. not a branch at all. We ignore it. + } else { + Node elseNode = graph.getOrCreateNode(bytes.getIndex()); + + Node ifNode; + if (cond.getTargetIndex() <= pc) { + Node[] nodes = graph.getOrSplitNodeAt(cNode, cond.getTargetIndex()); + cNode = nodes[0]; + ifNode = nodes[1]; + } else { + ifNode = graph.getOrCreateNode(cond.getTargetIndex()); + } + + BooleanExpression be = new BooleanExpression(cond.getExpression()); + + graph.addIfElseEdge(cNode, ifNode, elseNode, be); + expressionsToVariables(cNode, false); + cNode = null; + } + } else if (stmt instanceof Jump) { + int targetPc = ((Jump) stmt).getTargetIndex(); + Node targetNode; + + if (targetPc <= pc) { + // Backward jump. + Node[] nodes = graph.getOrSplitNodeAt(cNode, targetPc); + cNode = nodes[0]; + targetNode = nodes[1]; + } else { + targetNode = graph.getOrCreateNode(targetPc); + } + graph.addEdge(cNode, targetNode); + cNode = null; + } else if (stmt instanceof SynchronizedBlock || isProcedure(stmt)) { + cNode.block.appendChild(stmt); + } else if (stmt instanceof Assignment) { + expressionsToVariables(cNode, true); + cNode.block.appendChild(stmt); + } else if (stmt instanceof ThrowStatement || stmt instanceof ReturnStatement) { + cNode.block.appendChild(stmt); + cNode.close(); + cNode = null; + } else { + stack.push(stmt); + } + } + + } + + + void dump(Collection nodes) { + if (!logger.isDebugEnabled()) return; + + Iterator iter = nodes.iterator(); + while (iter.hasNext()) { + Node node = (Node) iter.next(); + dump(node.stack, node.toString()); + } + } + + public static void dump(ASTNode node, String msg) { + if (!logger.isDebugEnabled()) return; + + ByteArrayOutputStream ba = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(ba); + out.println(msg); + SimpleGenerator generator = new SimpleGenerator(out); + generator.visit(node); + out.close(); + try { + ba.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + logger.debug(ba.toString()); + } + + static void dump(List list, String msg) { + if (!logger.isDebugEnabled()) return; + + StringBuffer sb = new StringBuffer(); + sb.append("Begin dumping " + msg + "...\n"); + for (int i=0; i tempDecls = new ArrayList(); + + private Expression[] duplicate(Expression e) { + if (e instanceof NumberLiteral || e instanceof ThisExpression || e instanceof StringLiteral) { + // Refered values will never change nor will they have side effects, + // so we do not need to create an intermediate variable. + return new Expression[] {e, (Expression) e.clone()}; + } + + if (e instanceof VariableBinding && ((VariableBinding) e).isTemporary()) { + VariableBinding vb1 = (VariableBinding) e; + VariableBinding vb2 = (VariableBinding) vb1.clone(); + return new VariableBinding[] {vb1, vb2}; + } + + Assignment a = new Assignment(Assignment.Operator.ASSIGN); + a.setRange(bytes.getIndex(), bytes.getIndex()); + VariableBinding vb1 = methodDecl.createAnonymousVariableBinding(e.getTypeBinding(), true); + VariableBinding vb2 = (VariableBinding) vb1.clone(); + VariableBinding vb3 = (VariableBinding) vb1.clone(); + tempDecls.add(vb1.getVariableDeclaration()); + vb1.getVariableDeclaration().setParentNode(methodDecl); + a.setLeftHandSide(vb1); + a.setRightHandSide(e); + cNode.block.appendChild(a); + return new VariableBinding[] {vb2, vb3}; + } + + /** + * Creates a new case group at the specified pc if it does not yet exist. + * + * @param header the switch header + * @param switchEdges all currently existing switch edges + * @param startPc the pc at which the case group starts + * @return the switch edge to the case group. + */ + private SwitchEdge getOrCreateCaseGroup(Node header, Map switchEdges, int startPc) { + SwitchEdge switchEdge = switchEdges.get(startPc); + if (switchEdge == null) { + Node caseGroupNode = graph.createNode(startPc); + switchEdge = (SwitchEdge) graph.addEdge(header, caseGroupNode, SwitchEdge.class); + switchEdges.put(startPc, switchEdge); + } + + return switchEdge; + } + + private int readUnsigned() throws IOException { + int index; + if (wide) { + index = bytes.readUnsignedShort(); + wide = false; // Clear flag + } else { + index = bytes.readUnsignedByte(); + } + return index; + } + + private int readSigned() throws IOException { + int index; + if (wide) { + index = bytes.readShort(); + wide = false; // Clear flag + } else { + index = bytes.readByte(); + } + return index; + } + + private void dup1() { + Expression[] value1 = duplicate(stack.pop()); + stack.push(value1[0]); + stack.push(value1[1]); + } + + private void dup2() { + Expression[] value1 = duplicate(stack.pop()); + Expression[] value2 = duplicate(stack.pop()); + stack.push(value2[0]); + stack.push(value1[0]); + stack.push(value2[1]); + stack.push(value1[1]); + } + + private ASTNode parseInstruction() throws IOException { + int currentIndex = bytes.getIndex(); + short opcode = (short) bytes.readUnsignedByte(); + + InstructionType instructionType = Const.instructionTypes[opcode]; + + Form form = selectForm(instructionType); + + int opStackDelta = form.getOpStackDelta(); + + ASTNode instruction = null; + + logger.debug(currentIndex + " " + instructionType.getName() + "[" + opcode + "] "); + + switch (opcode) { + /* + * Switches have variable length arguments. + */ + case Const.TABLESWITCH : + // Format: tableswitch, padding(byte), padding(byte), padding(byte), default(int), low(int), high(int) + // Operand stack: ..., index(int) -> ... + case Const.LOOKUPSWITCH : { + // Format: lookupswitch, padding(byte), padding(byte), padding(byte), default(int), npairs(int) + // Operand stack: ..., key() -> ... + Node switchNode = graph.createNode(currentIndex); + switchNode.isSwitchHeader = true; + graph.addEdge(cNode, switchNode); + cNode = null; + + int defaultOffset; + int npairs; + int offset; + int remainder = bytes.getIndex() % 4; + int noPadBytes = (remainder == 0) ? 0 : 4 - remainder; + + // Skip (0-3) padding bytes, i.e., the following bytes are 4-byte-aligned. + for (int i = 0; i < noPadBytes; i++) { + byte b; + + if ((b = bytes.readByte()) != 0) { + logger.warn("Padding byte != 0 in " + instructionType.getName() + ":" + b); + } + } + + defaultOffset = bytes.readInt(); + + int low = 0; + if (opcode==Const.LOOKUPSWITCH) { + npairs = bytes.readInt(); + offset = bytes.getIndex() - 8 - noPadBytes - 1; + } else { + low = bytes.readInt(); + int high = bytes.readInt(); + npairs = high - low + 1; + offset = bytes.getIndex() - 12 - noPadBytes - 1; + } + + defaultOffset += offset; + + switchNode.switchExpression = stack.pop(); + + TreeMap caseGroups = new TreeMap(); + + // Add all cases. + for (int i = 0; i < npairs; i++) { + int key; + if (opcode==Const.LOOKUPSWITCH) { + key = bytes.readInt(); + } else { + key = low + i; + } + + SwitchEdge switchEdge = getOrCreateCaseGroup(switchNode, caseGroups, offset + bytes.readInt()); + switchEdge.expressions.add(NumberLiteral.create(new Integer(key))); + } + + Node defaultNode = graph.createNode(defaultOffset); + graph.addEdge(switchNode, defaultNode); + //getOrCreateCaseGroup(switchNode, caseGroups, defaultOffset); + + instruction = new NoOperation(); + break; + } + + case Const.CHECKCAST : { + // Format: checkcast, index(short) + // Operand stack: ..., objectref() -> ..., objectref(object) + CastExpression cast = new CastExpression(); + int index = bytes.readUnsignedShort(); + ConstantClass c = (ConstantClass) constantPool.getConstant(index); + ObjectType type = new ObjectType(c.getBytes(constantPool).replace('/', '.')); + cast.setTypeBinding(type); + cast.setExpression(stack.pop()); + instruction = cast; + break; + } + + + case Const.INSTANCEOF : { + // Format: instanceof, index(short) + // Operand stack: ..., objectref() -> ..., result(int) + int index = bytes.readUnsignedShort(); + InstanceofExpression ex = new InstanceofExpression(); + Expression objectref = stack.pop(); + ex.setLeftOperand(objectref); + ConstantClass c = (ConstantClass) constantPool.getConstant(index); + ObjectType type = new ObjectType(c.getBytes(constantPool).replace('/', '.')); + ex.setRightOperand(type); + ex.widen(objectref); + instruction = ex; + break; + } + + + case Const.ACONST_NULL : + // Format: aconst_null + // Operand stack: ... -> ..., null(object) + instruction = new NullLiteral(); + break; + + case Const.JSR : { + // Format: jsr, branch(short) + // Operand stack: ... -> ..., address(returnAddress) + instruction = new JumpSubRoutine(currentIndex + bytes.readShort()); + opStackDelta = 0; + break; + } + + case Const.JSR_W : { + // Format: jsr_w, branch(int) + // Operand stack: ... -> ..., address() + instruction = new JumpSubRoutine(currentIndex + bytes.readInt()); + break; + } + + case Const.IFEQ : + // Format: ifeq, branch(short) + // Operand stack: ..., value() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.EQUALS, NumberLiteral.create(0)); + break; + case Const.IFNE : + // Format: ifne, branch(short) + // Operand stack: ..., value() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.NOT_EQUALS, NumberLiteral.create(0)); + break; + case Const.IFGE : + // Format: ifge, branch(short) + // Operand stack: ..., value() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.GREATER_EQUALS, NumberLiteral.create(0)); + break; + case Const.IFGT : + // Format: ifgt, branch(short) + // Operand stack: ..., value() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.GREATER, NumberLiteral.create(0)); + break; + case Const.IFLE : + // Format: ifle, branch(short) + // Operand stack: ..., value() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.LESS_EQUALS, NumberLiteral.create(0)); + break; + case Const.IFLT : + // Format: iflt, branch(short) + // Operand stack: ..., value() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.LESS, NumberLiteral.create(0)); + break; + case Const.IFNONNULL : + // Format: ifnonnull, branch(short) + // Operand stack: ..., value() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.NOT_EQUALS, new NullLiteral()); + break; + case Const.IFNULL : + // Format: ifnull, branch(short) + // Operand stack: ..., value() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.EQUALS, new NullLiteral()); + break; + + case Const.IF_ACMPEQ : + // Format: if_acmpeq, branch(short) + // Operand stack: ..., value1(), value2() -> ... + case Const.IF_ICMPEQ : + // Format: if_icmpeq, branch(short) + // Operand stack: ..., value1(), value2() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.EQUALS); + break; + case Const.IF_ACMPNE : + // Format: if_acmpne, branch(short) + // Operand stack: ..., value1(), value2() -> ... + case Const.IF_ICMPNE : + // Format: if_icmpne, branch(short) + // Operand stack: ..., value1(), value2() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.NOT_EQUALS); + break; + case Const.IF_ICMPGE : + // Format: if_icmpge, branch(short) + // Operand stack: ..., value1(), value2() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.GREATER_EQUALS); + break; + case Const.IF_ICMPGT : + // Format: if_icmpgt, branch(short) + // Operand stack: ..., value1(), value2() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.GREATER); + break; + case Const.IF_ICMPLE : + // Format: if_icmple, branch(short) + // Operand stack: ..., value1(), value2() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.LESS_EQUALS); + break; + case Const.IF_ICMPLT : + // Format: if_icmplt, branch(short) + // Operand stack: ..., value1(), value2() -> ... + instruction = createConditional(currentIndex, InfixExpression.Operator.LESS); + break; + + case Const.LCMP : + // Format: lcmp + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.FCMPL : + // Format: fcmpl + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.FCMPG : + // Format: fcmpg + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.DCMPL : + // Format: dcmpl + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.DCMPG : { + // Format: dcmpg + // Operand stack: ..., value1(), value2() -> ..., result(int) + MethodBinding binding = MethodBinding.lookup("javascript.Utils", "cmp", "(DDI)I"); + MethodInvocation mi = new MethodInvocation(methodDecl, binding); + + Expression value2 = stack.pop(); + mi.addArgument(stack.pop()); + mi.addArgument(value2); + + int gORl = 0; + if (instructionType.getName().endsWith("g")) gORl = 1; + else if (instructionType.getName().endsWith("l")) gORl = -1; + mi.addArgument(NumberLiteral.create(gORl)); + + instruction = mi; + + break; + } + + case Const.GOTO : { + // Format: goto, branch(short) + // Operand stack: ... -> ... + instruction = new Jump(currentIndex + bytes.readShort()); + break; + } + + case Const.GOTO_W : { + // Format: goto_w, branch(int) + // Operand stack: ... -> ... + instruction = new Jump(currentIndex + bytes.readInt()); + break; + } + + case Const.NEW: { + // Format: new, index(short) + // Operand stack: ... -> ..., objectref(object) + ConstantClass c = (ConstantClass) constantPool.getConstant(bytes.readUnsignedShort()); + ObjectType type = new ObjectType(c.getBytes(constantPool).replace('/', '.')); + + instruction = new ClassInstanceCreation(type); + } + break; + + /** + * Create new array with component type being primitiv. + */ + case Const.NEWARRAY: { + // Format: newarray, atype(byte) + // Operand stack: ..., count(int) -> ..., arrayref(object) + + String componentSignature = BasicType.getType(bytes.readByte()).getSignature(); + + // Create a new array with components of type componentType. + List dimensions = new ArrayList(); + dimensions.add(stack.pop()); + ArrayCreation ac = new ArrayCreation(methodDecl, new ObjectType("[" + componentSignature), dimensions); + instruction = ac; + break; + } + + /* + * Create new array of reference of non-primitiv type. + */ + case Const.ANEWARRAY: { + // Format: anewarray, index(short) + // Operand stack: ..., count(int) -> ..., arrayref(object) + + ConstantClass c = (ConstantClass) constantPool.getConstant(bytes.readUnsignedShort()); + String componentSignature = c.getBytes(constantPool).replace('/', '.'); + Type arrayType; + if (componentSignature.startsWith("[")) { + arrayType = new ObjectType("[" + componentSignature); + } else { + arrayType = new ObjectType("[L" + componentSignature + ";"); + } + + // Create a new array with components of type componentType. + List dimensions = new ArrayList(); + dimensions.add(stack.pop()); + ArrayCreation ac = new ArrayCreation(methodDecl, arrayType, dimensions); + instruction = ac; + break; + } + + /* + * Multidimensional array of references. + */ + case Const.MULTIANEWARRAY : { + // Format: multianewarray, index(short), dimension N(byte) + // Operand stack: ..., count1(), ...(), countN() -> ..., arrayref(object) + + ConstantClass c = (ConstantClass) constantPool.getConstant(bytes.readUnsignedShort()); + ObjectType arrayType = new ObjectType(c.getBytes(constantPool).replace('/', '.')); + + // Create a new multidimensional array of the array type arrayType. + // The array type must be an array class type of dimensionality greater than or equal to dimensions. + + int dimCount = bytes.readUnsignedByte(); + opStackDelta = 1 - dimCount; + List dimensions = new ArrayList(); + for (int i=0; i ... + case Const.PUTFIELD : { + // Format: putfield, index(short) + // Operand stack: ..., objectref(), value() -> ... + Assignment a = new Assignment(Assignment.Operator.ASSIGN); + Expression rhs = stack.pop(); + + int index = bytes.readUnsignedShort(); + ConstantFieldref fieldRef = (ConstantFieldref) constantPool.getConstant(index, Constants.CONSTANT_Fieldref); + + FieldAccess fa = new FieldWrite(); + fa.setName(getFieldName(fieldRef)); + fa.setType(new ObjectType(fieldRef.getClass(constantPool))); + fa.initialize(methodDecl); + + if (opcode==Const.PUTFIELD) { + fa.setExpression(stack.pop()); + } + + a.setLeftHandSide(fa); + a.setRightHandSide(rhs); + + instruction = a; + break; + } + + case Const.GETFIELD : { + // Format: getfield, index(short) + // Operand stack: ..., objectref() -> ..., value() + int index = bytes.readUnsignedShort(); + ConstantFieldref fieldRef = (ConstantFieldref) constantPool.getConstant(index, Constants.CONSTANT_Fieldref); + + Expression ex = stack.pop(); + FieldAccess fa = new FieldRead(); + fa.setType(new ObjectType(fieldRef.getClass(constantPool))); + fa.setName(getFieldName(fieldRef)); + fa.setExpression(ex); + fa.initialize(methodDecl); + instruction = fa; + break; + } + + case Const.GETSTATIC : { + // Format: getstatic, index(short) + // Operand stack: ... -> ..., value() + int index = bytes.readUnsignedShort(); + ConstantFieldref fieldRef = (ConstantFieldref) constantPool.getConstant(index, Constants.CONSTANT_Fieldref); + + FieldAccess fa = new FieldRead(); + fa.setType(new ObjectType(fieldRef.getClass(constantPool))); + fa.setName(getFieldName(fieldRef)); + fa.initialize(methodDecl); + //Name e = new Name(fieldRef.getClass(constantPool)); + //fa.setExpression(e); + instruction = fa; + break; + } + + case Const.DUP : { + // Format: dup + // Operand stack: ..., value(cat1) -> ..., value(cat1), value(cat1) + dup1(); + instruction = stack.pop(); + break; + } + + case Const.DUP2 : + // (0) Format: dup2 + // (0) Operand stack: ..., value2(cat1), value1(cat1) -> ..., value2(cat1), value1(cat1), value2(cat1), value1(cat1) + // (1) Format: dup2 + // (1) Operand stack: ..., value(cat2) -> ..., value(cat2), value(cat2) + if (form.getIndex() == 0) { + dup2(); + instruction = stack.pop(); + } else { + dup1(); + instruction = stack.pop(); + } + break; + + case Const.DUP_X1 : { + // Format: dup_x1 + // Operand stack: ..., value2(cat1), value1(cat1) -> ..., value1(cat1), value2(cat1), value1(cat1) + dup1(); + stack.rotate(2); + instruction = stack.pop(); + break; + } + + case Const.DUP_X2 : { + // (0) Format: dup_x2 + // (0) Operand stack: ..., value3(cat1), value2(cat1), value1(cat1) -> ..., value1(cat1), value3(cat1), value2(cat1), value1(cat1) + // (1) Format: dup_x2 + // (1) Operand stack: ..., value2(cat2), value1(cat1) -> ..., value1(cat1), value2(cat2), value1(cat1) + if (form.getIndex()==0) { + dup1(); + stack.rotate(3); + } else { + dup1(); + stack.rotate(2); + } + instruction = stack.pop(); + break; + } + + case Const.DUP2_X1 : + // (0) Format: dup2_x1 + // (0) Operand stack: ..., value3(cat1), value2(cat1), value1(cat1) -> ..., value2(cat1), value1(cat1), value3(cat1), value2(cat1), value1(cat1) + // (1) Format: dup2_x1 + // (1) Operand stack: ..., value2(cat1), value1(cat2) -> ..., value1(cat2), value2(cat1), value1(cat2) + if (form.getIndex()==0) { + dup2(); + stack.rotate(4); + stack.rotate(4); + } else { + dup1(); + stack.rotate(2); + } + instruction = stack.pop(); + break; + + case Const.DUP2_X2 : + // (0) Format: dup2_x2 + // (0) Operand stack: ..., value4(cat1), value3(cat1), value2(cat1), value1(cat1) -> ..., value2(cat1), value1(cat1), value4(cat1), value3(cat1), value2(cat1), value1(cat1) + // (1) Format: dup2_x2 + // (1) Operand stack: ..., value3(cat1), value2(cat1), value1(cat2) -> ..., value1(cat2), value3(cat1), value2(cat1), value1(cat2) + // (2) Format: dup2_x2 + // (2) Operand stack: ..., value3(cat2), value2(cat1), value1(cat1) -> ..., value2(cat1), value1(cat1), value3(cat2), value2(cat1), value1(cat1) + // (3) Format: dup2_x2 + // (3) Operand stack: ..., value2(cat2), value1(cat2) -> ..., value1(cat2), value2(cat2), value1(cat2) + if (form.getIndex()==0) { + dup2(); + stack.rotate(5); + stack.rotate(5); + } else if (form.getIndex()==1) { + dup1(); + stack.rotate(3); + } else if (form.getIndex()==2) { + dup2(); + stack.rotate(4); + stack.rotate(4); + } else { + dup1(); + stack.rotate(2); + } + + instruction = stack.pop(); + break; + + case Const.SWAP : { + // Format: swap + // Operand stack: ..., value2(cat1), value1(cat1) -> ..., value1(cat1), value2(cat1) + stack.rotate(1); + instruction = new NoOperation(); + break; + } + + case Const.I2S : + // Format: i2s + // Operand stack: ..., value() -> ..., result(short) + case Const.I2F : + // Format: i2f + // Operand stack: ..., value() -> ..., result(float) + case Const.L2I : + // Format: l2i + // Operand stack: ..., value() -> ..., result(int) + case Const.F2I : + // Format: f2i + // Operand stack: ..., value(float) -> ..., result(int) + case Const.F2L : + // Format: f2l + // Operand stack: ..., value() -> ..., result(long) + case Const.L2F : + // Format: l2f + // Operand stack: ..., value() -> ..., result(float) + case Const.L2D : + // Format: l2d + // Operand stack: ..., value() -> ..., result(double) + case Const.D2I : + // Format: d2i + // Operand stack: ..., value() -> ..., result(int) + case Const.D2L : + // Format: d2l + // Operand stack: ..., value() -> ..., result(long) + case Const.D2F : + // Format: d2f + // Operand stack: ..., value() -> ..., result(float) + case Const.I2B : + // Format: i2b + // Operand stack: ..., value() -> ..., result(byte) + case Const.I2C : + // Format: i2c + // Operand stack: ..., value() -> ..., result(byte) + // Operation i2f may result in a loss of precision because values of type float have only 24 significand bits. + // Operation l2d may lose precision because values of type double have only 53 significand bits + instruction = new PrimitiveCast(opcode, stack.pop(), form.getResultType()); + break; + + case Const.I2L : + // Format: i2l + // Operand stack: ..., value() -> ..., result(long) + stack.peek().setTypeBinding(Type.LONG); + instruction = new NoOperation(); + break; + case Const.I2D : + // Format: i2d + // Operand stack: ..., value() -> ..., result(double) + case Const.F2D : + // Format: f2d + // Operand stack: ..., value() -> ..., result(double) + // Widening preserves the numeric value exactly, see VM Spec2, Section 2.6.2. + // For operation f2d there may be a rounding related to value set conversion. + stack.peek().setTypeBinding(Type.DOUBLE); + instruction = new NoOperation(); + break; + + case Const.INEG: + // Format: ineg + // Operand stack: ..., value() -> ..., result(int) + case Const.LNEG: + // Format: lneg + // Operand stack: ..., value() -> ..., result(long) + case Const.FNEG: + // Format: fneg + // Operand stack: ..., value() -> ..., result(float) + case Const.DNEG: + // Format: dneg + // Operand stack: ..., value() -> ..., result(double) + instruction = createPrefix(PrefixExpression.MINUS, stack.pop(), form.getResultType()); + break; + + case Const.ISHR : + // Format: ishr + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LSHR : + // Format: lshr + // Operand stack: ..., value1(), value2() -> ..., result(long) + instruction = createInfixRightLeft(InfixExpression.Operator.RIGHT_SHIFT_SIGNED, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.ISHL : + // Format: ishl + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LSHL : + // Format: lshl + // Operand stack: ..., value1(), value2() -> ..., result(long) + instruction = createInfixRightLeft(InfixExpression.Operator.LEFT_SHIFT, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IUSHR : + // Format: iushr + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LUSHR : + // Format: lushr + // Operand stack: ..., value1(), value2() -> ..., result(long) + instruction = createInfixRightLeft(InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IADD : + // Format: iadd + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LADD : + // Format: ladd + // Operand stack: ..., value1(), value2() -> ..., result(long) + case Const.FADD : + // Format: fadd + // Operand stack: ..., value1(), value2() -> ..., result(float) + case Const.DADD : + // Format: dadd + // Operand stack: ..., value1(double), value2(double) -> ..., result(double) + instruction = createInfixRightLeft(InfixExpression.Operator.PLUS, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.ISUB : + // Format: isub + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LSUB : + // Format: lsub + // Operand stack: ..., value1(), value2() -> ..., result(long) + case Const.FSUB : + // Format: fsub + // Operand stack: ..., value1(), value2() -> ..., result(float) + case Const.DSUB : + // Format: dsub + // Operand stack: ..., value1(double), value2(double) -> ..., result(double) + instruction = createInfixRightLeft(InfixExpression.Operator.MINUS, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IMUL : + // Format: imul + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LMUL : + // Format: lmul + // Operand stack: ..., value1(), value2() -> ..., result(long) + case Const.FMUL : + // Format: fmul + // Operand stack: ..., value1(), value2() -> ..., result(float) + case Const.DMUL : + // Format: dmul + // Operand stack: ..., value1(), value2() -> ..., result(double) + instruction = createInfixRightLeft(InfixExpression.Operator.TIMES, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IDIV : + // Format: idiv + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LDIV : + // Format: ldiv + // Operand stack: ..., value1(), value2() -> ..., result(long) + case Const.FDIV : + // Format: fdiv + // Operand stack: ..., value1(), value2() -> ..., result(float) + case Const.DDIV : + // Format: ddiv + // Operand stack: ..., value1(), value2() -> ..., result(double) + instruction = createInfixRightLeft(InfixExpression.Operator.DIVIDE, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IREM : + // Format: irem + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LREM : + // Format: lrem + // Operand stack: ..., value1(), value2() -> ..., result(long) + case Const.FREM : + // Format: frem + // Operand stack: ..., value1(), value2() -> ..., result(float) + case Const.DREM : + // Format: drem + // Operand stack: ..., value1(), value2() -> ..., result(double) + instruction = createInfixRightLeft(InfixExpression.Operator.REMAINDER, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IXOR : + // Format: ixor + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LXOR : + // Format: lxor + // Operand stack: ..., value1(), value2() -> ..., result(long) + instruction = createInfixRightLeft(InfixExpression.Operator.XOR, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IAND : + // Format: iand + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LAND : + // Format: land + // Operand stack: ..., value1(), value2() -> ..., result(long) + instruction = createInfixRightLeft(InfixExpression.Operator.AND, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IOR : + // Format: ior + // Operand stack: ..., value1(), value2() -> ..., result(int) + case Const.LOR : + // Format: lor + // Operand stack: ..., value1(), value2() -> ..., result(long) + instruction = createInfixRightLeft(InfixExpression.Operator.OR, stack.pop(), stack.pop(), form.getResultType()); + break; + + case Const.IINC : { + // Format: iinc, index(byte), const(int) + // Operand stack: ... -> ... + boolean isWide = wide; + int index = readUnsigned(); + // Reset wide flag. + wide = isWide; + int constByte = readSigned(); + + VariableBinding reference = createVariableBinding(index, Type.INT, true); + reference.setField(false); + +// if (stack.peek() instanceof VariableBinding) { +// if (reference.isSame(reference) && Math.abs(constByte) == 1) { +// stack.pop(); +// PostfixExpression pe = new PostfixExpression(); +// pe.setOperator(constByte==1?PStarExpression.INCREMENT:PStarExpression.DECREMENT); +// pe.setOperand(reference); +// instruction = pe; +// break; +// } +// } + + Assignment assign = new Assignment(Assignment.Operator.PLUS_ASSIGN); + assign.setLeftHandSide(reference); + assign.setRightHandSide(NumberLiteral.create(new Integer(constByte))); + instruction = assign; + break; + } + + case Const.ARRAYLENGTH : { + // Format: arraylength + // Operand stack: ..., arrayref() -> ..., length(int) + Expression arrayRef = stack.pop(); + FieldAccess access = new FieldRead(); + access.setExpression(arrayRef); + access.setName("length"); + //access.initialize(methodDecl); + instruction = access; + break; + } + + /* + * Remember wide byte which is used to form a 16-bit address in + * the following instruction. Relies on that the method is + * called again with the following opcode. + */ + case Const.WIDE : + // Format: wide + // Operand stack: ... -> ... + wide = true; + return new NoOperation(); + + case Const.ILOAD_0 : + // Format: iload_0 + // Operand stack: ... -> ..., value(int) + case Const.ILOAD_1 : + // Format: iload_1 + // Operand stack: ... -> ..., value(int) + case Const.ILOAD_2 : + // Format: iload_2 + // Operand stack: ... -> ..., value(int) + case Const.ILOAD_3 : { + // Format: iload_3 + // Operand stack: ... -> ..., value(int) + VariableBinding reference = createVariableBinding(opcode - Const.ILOAD_0, Type.INT, false); + reference.setField(false); + instruction = reference; + break; + } + + case Const.LLOAD_0 : + // Format: lload_0 + // Operand stack: ... -> ..., value(long) + case Const.LLOAD_1 : + // Format: lload_1 + // Operand stack: ... -> ..., value(long) + case Const.LLOAD_2 : + // Format: lload_2 + // Operand stack: ... -> ..., value(long) + case Const.LLOAD_3 : { + // Format: lload_3 + // Operand stack: ... -> ..., value(long) + VariableBinding reference = createVariableBinding(opcode - Const.LLOAD_0, Type.LONG, false); + reference.setField(false); + instruction = reference; + break; + } + + case Const.FLOAD_0 : + // Format: fload_0 + // Operand stack: ... -> ..., value(float) + case Const.FLOAD_1 : + // Format: fload_1 + // Operand stack: ... -> ..., value(float) + case Const.FLOAD_2 : + // Format: fload_2 + // Operand stack: ... -> ..., value(float) + case Const.FLOAD_3 : { + // Format: fload_3 + // Operand stack: ... -> ..., value(float) + VariableBinding reference = createVariableBinding(opcode - Const.FLOAD_0, Type.FLOAT, false); + reference.setField(false); + instruction = reference; + break; + } + + case Const.DLOAD_0 : + // Format: dload_0 + // Operand stack: ... -> ..., value(double) + case Const.DLOAD_1 : + // Format: dload_1 + // Operand stack: ... -> ..., value(double) + case Const.DLOAD_2 : + // Format: dload_2 + // Operand stack: ... -> ..., value(double) + case Const.DLOAD_3 : { + // Format: dload_3 + // Operand stack: ... -> ..., value(double) + VariableBinding reference = createVariableBinding(opcode - Const.DLOAD_0, Type.DOUBLE, false); + reference.setField(false); + instruction = reference; + break; + } + + case Const.ALOAD_0 : + // Format: aload_0 + // Operand stack: ... -> ..., objectref(object) + case Const.ALOAD_1 : + // Format: aload_1 + // Operand stack: ... -> ..., objectref(object) + case Const.ALOAD_2 : + // Format: aload_2 + // Operand stack: ... -> ..., objectref(object) + case Const.ALOAD_3 : { + // Format: aload_3 + // Operand stack: ... -> ..., objectref(object) + if (opcode == Const.ALOAD_0 && !Modifier.isStatic(methodDecl.getAccess())) { + ThisExpression reference = new ThisExpression(); + instruction = reference; + } else { + VariableBinding reference = createVariableBinding(opcode - Const.ALOAD_0, Type.OBJECT, false); + reference.setField(true); + instruction = reference; + } + break; + } + + case Const.ILOAD : + // Format: iload, index(byte) + // Operand stack: ... -> ..., value(int) + case Const.LLOAD : + // Format: lload, index(byte) + // Operand stack: ... -> ..., value(long) + case Const.FLOAD : + // Format: fload, index(byte) + // Operand stack: ... -> ..., value(float) + case Const.DLOAD : { + // Format: dload, index(byte) + // Operand stack: ... -> ..., value(double) + VariableBinding reference = createVariableBinding(readUnsigned(), form.getResultType(), false); + reference.setField(false); + instruction = reference; + break; + } + + case Const.ALOAD : { + // Format: aload, index(byte) + // Operand stack: ... -> ..., objectref(object) + VariableBinding reference = createVariableBinding(readUnsigned(), Type.OBJECT, false); + reference.setField(true); + instruction = reference; + break; + } + + case Const.BALOAD : + // Format: baload + // Operand stack: ..., arrayref(), index() -> ..., value(int) + case Const.CALOAD : + // Format: caload + // Operand stack: ..., arrayref(), index() -> ..., value(int) + case Const.SALOAD : + // Format: saload + // Operand stack: ..., arrayref(), index() -> ..., value(short) + case Const.IALOAD : + // Format: iaload + // Operand stack: ..., arrayref(), index() -> ..., value(int) + case Const.LALOAD : + // Format: laload + // Operand stack: ..., arrayref(), index() -> ..., value(long) + case Const.FALOAD : + // Format: faload + // Operand stack: ..., arrayref(), index() -> ..., value(float) + case Const.DALOAD : + // Format: daload + // Operand stack: ..., arrayref(), index() -> ..., value(double) + case Const.AALOAD : { + // Format: aaload + // Operand stack: ..., arrayref(), index() -> ..., objectref(object) + Expression index = stack.pop(); + Expression arrayRef = stack.pop(); + ArrayAccess aa; + aa = new ArrayAccess(); + aa.setTypeBinding(form.getResultType()); + aa.setArray(arrayRef); + aa.setIndex(index); + + instruction = aa; + break; + } + + case Const.BASTORE : + // Format: bastore + // Operand stack: ..., arrayref(), index(), value() -> ... + case Const.CASTORE : + // Format: castore + // Operand stack: ..., arrayref(), index(), value() -> ... + case Const.SASTORE : + // Format: sastore + // Operand stack: ..., array(), index(), value() -> ... + case Const.IASTORE : + // Format: iastore + // Operand stack: ..., arrayref(), index(), value() -> ... + case Const.LASTORE : + // Format: lastore + // Operand stack: ..., arrayref(), index(), value() -> ... + case Const.FASTORE : + // Format: fastore + // Operand stack: ..., arrayref(), index(), value() -> ... + case Const.DASTORE : + // Format: dastore + // Operand stack: ..., arrayref(), index(), value() -> ... + case Const.AASTORE : { + // Format: aastore + // Operand stack: ..., arrayref(), index(), value() -> ... + Expression value = stack.pop(); + Expression index = stack.pop(); + Expression arrayRef = stack.pop(); + if (arrayRef instanceof ArrayCreation) { + ArrayCreation ac = (ArrayCreation) arrayRef; + if (ac.getInitializer() == null) { + ac.setInitializer(new ArrayInitializer()); + } + ac.getInitializer().getExpressions().add(value); + instruction = new NoOperation(); + break; + } + Assignment a = new Assignment(Assignment.Operator.ASSIGN); + + ArrayAccess aa; + aa = new ArrayAccess(); + aa.setArray(arrayRef); + aa.setIndex(index); + + a.setLeftHandSide(aa); + a.setRightHandSide(value); + instruction = a; + break; + } + + + case Const.DSTORE : + // Format: dstore, index(byte) + // Operand stack: ..., value(double) -> ... + case Const.DSTORE_0 : + // Format: dstore_0 + // Operand stack: ..., value(double) -> ... + case Const.DSTORE_1 : + // Format: dstore_1 + // Operand stack: ..., value(double) -> ... + case Const.DSTORE_2 : + // Format: dstore_2 + // Operand stack: ..., value(double) -> ... + case Const.DSTORE_3 : { + // Format: dstore_3 + // Operand stack: ..., value(double) -> ... + int index; + if (opcode == Const.DSTORE) { + index = readUnsigned(); + } else { + index = opcode - Const.DSTORE_0; + } + Assignment a = new Assignment(Assignment.Operator.ASSIGN); + VariableBinding reference = createVariableBinding(index, Type.DOUBLE, true); + reference.setField(false); + a.setLeftHandSide(reference); + a.setRightHandSide(stack.pop()); + instruction = a; + break; + } + + case Const.FSTORE : + // Format: fstore, index(byte) + // Operand stack: ..., value() -> ... + case Const.FSTORE_0 : + // Format: fstore_0 + // Operand stack: ..., value(float) -> ... + case Const.FSTORE_1 : + // Format: fstore_1 + // Operand stack: ..., value(float) -> ... + case Const.FSTORE_2 : + // Format: fstore_2 + // Operand stack: ..., value(float) -> ... + case Const.FSTORE_3 : { + // Format: fstore_3 + // Operand stack: ..., value(float) -> ... + int index; + if (opcode == Const.FSTORE) { + index = readUnsigned(); + } else { + index = opcode - Const.FSTORE_0; + } + Assignment a = new Assignment(Assignment.Operator.ASSIGN); + VariableBinding reference = createVariableBinding(index, Type.FLOAT, true); + reference.setField(false); + a.setLeftHandSide(reference); + a.setRightHandSide(stack.pop()); + instruction = a; + break; + } + + case Const.ISTORE : + // Format: istore, index(byte) + // Operand stack: ..., value() -> ... + case Const.ISTORE_0 : + // Format: istore_0 + // Operand stack: ..., value() -> ... + case Const.ISTORE_1 : + // Format: istore_1 + // Operand stack: ..., value() -> ... + case Const.ISTORE_2 : + // Format: istore_2 + // Operand stack: ..., value() -> ... + case Const.ISTORE_3 : { + // Format: istore_3 + // Operand stack: ..., value() -> ... + int index; + if (opcode == Const.ISTORE) { + index = readUnsigned(); + } else { + index = opcode - Const.ISTORE_0; + } + Assignment a = new Assignment(Assignment.Operator.ASSIGN); + VariableBinding reference = createVariableBinding(index, Type.INT, true); + reference.setField(false); + a.setLeftHandSide(reference); + a.setRightHandSide(stack.pop()); + instruction = a; + break; + } + + case Const.LSTORE : + // Format: lstore, index(byte) + // Operand stack: ..., value() -> ... + case Const.LSTORE_0 : + // Format: lstore_0 + // Operand stack: ..., value() -> ... + case Const.LSTORE_1 : + // Format: lstore_1 + // Operand stack: ..., value() -> ... + case Const.LSTORE_2 : + // Format: lstore_2 + // Operand stack: ..., value() -> ... + case Const.LSTORE_3 : { + // Format: lstore_3 + // Operand stack: ..., value() -> ... + int index; + if (opcode == Const.LSTORE) { + index = readUnsigned(); + } else { + index = opcode - Const.LSTORE_0; + } + Assignment a = new Assignment(Assignment.Operator.ASSIGN); + VariableBinding reference = createVariableBinding(index, Type.LONG, true); + reference.setField(false); + a.setLeftHandSide(reference); + a.setRightHandSide(stack.pop()); + instruction = a; + break; + } + + case Const.ASTORE : + // Format: astore, index(byte) + // Operand stack: ..., objectref() -> ... + case Const.ASTORE_0 : + // Format: astore_0 + // Operand stack: ..., objectref() -> ... + case Const.ASTORE_1 : + // Format: astore_1 + // Operand stack: ..., objectref() -> ... + case Const.ASTORE_2 : + // Format: astore_2 + // Operand stack: ..., objectref() -> ... + case Const.ASTORE_3 : { + // Format: astore_3 + // Operand stack: ..., objectref() -> ... + + Assignment a = new Assignment(Assignment.Operator.ASSIGN); + int index; + if (opcode==Const.ASTORE) { + index = readUnsigned(); + } else { + index = (opcode - Const.ASTORE_0); + } + VariableBinding reference = createVariableBinding(index, Type.OBJECT, true); + a.setLeftHandSide(reference); + + // This may be the first instruction of an exception handler. + // It will store the implied exception. This exception is pushed onto the + // stack by makeTryFrames(). However, if the handler is unreachable, the + // Java Compiler may not generate an exception handler, and the stack is therefore + // empty. + // TODO: Refactor this Class by using org.apache.bcel.generic.InstructionList() + // and having two passes, not just one! + if (stack.size() > 0) { + a.setRightHandSide(stack.pop()); + } + instruction = a; + break; + } + + case Const.ATHROW: { + // Format: athrow + // Operand stack: ..., objectref() -> ..., objectref(object) + ThrowStatement throwStmt = new ThrowStatement(); + throwStmt.setExpression(stack.pop()); + instruction = throwStmt; + break; + } + + case Const.ICONST_M1 : + // Format: iconst_m1 + // Operand stack: ... -> ..., i(int) + case Const.ICONST_0 : + // Format: iconst_0 + // Operand stack: ... -> ..., i(int) + case Const.ICONST_1 : + // Format: iconst_1 + // Operand stack: ... -> ..., i(int) + case Const.ICONST_2 : + // Format: iconst_2 + // Operand stack: ... -> ..., i(int) + case Const.ICONST_3 : + // Format: iconst_3 + // Operand stack: ... -> ..., i(int) + case Const.ICONST_4 : + // Format: iconst_4 + // Operand stack: ... -> ..., i(int) + case Const.ICONST_5 : + // Format: iconst_5 + // Operand stack: ... -> ..., i(int) + instruction = NumberLiteral.create(new Integer(-1 + opcode - Const.ICONST_M1)); + break; + + case Const.LCONST_0 : + // Format: lconst_0 + // Operand stack: ... -> ..., l(long) + case Const.LCONST_1 : + // Format: lconst_1 + // Operand stack: ... -> ..., l(long) + // Push the long constant 0 or 1 onto the operand stack. + instruction = NumberLiteral.create(new Long(opcode - Const.LCONST_0)); + break; + + case Const.FCONST_0 : + // Format: fconst_0 + // Operand stack: ... -> ..., f(float) + case Const.FCONST_1 : + // Format: fconst_1 + // Operand stack: ... -> ..., f(float) + case Const.FCONST_2 : + // Format: fconst_2 + // Operand stack: ... -> ..., f(float) + // Push the float constant 0.0, 1.0 or 2.0 onto the operand stack. + instruction = NumberLiteral.create(new Float(opcode - Const.FCONST_0)); + break; + + case Const.DCONST_0 : + // Format: dconst_0 + // Operand stack: ... -> ..., d(double) + case Const.DCONST_1 : + // Format: dconst_1 + // Operand stack: ... -> ..., d(double) + // Push the double constant 0.0 or 1.0 onto the operand stack. + instruction = NumberLiteral.create(new Double(opcode - Const.DCONST_0)); + break; + + case Const.BIPUSH : { + // Format: bipush, byte(byte) + // Operand stack: ... -> ..., value(int) + NumberLiteral literal = NumberLiteral.create(new Byte(bytes.readByte())); + instruction = literal; + break; + } + + case Const.SIPUSH : { + // Format: sipush + // Operand stack: ... -> ..., value(short) + NumberLiteral il = NumberLiteral.create(new Short(bytes.readShort())); + instruction = il; + break; + } + + case Const.LDC : + // Format: ldc, index(byte) + // Operand stack: ... -> ..., value(cat1) + case Const.LDC_W : + // Format: ldc_w + // Operand stack: ... -> ..., value(cat1) + case Const.LDC2_W : { + // Format: ldc2_w + // Operand stack: ... -> ..., value(cat1) + int index; + if (opcode == Const.LDC) { + index = bytes.readUnsignedByte(); + } else { + index = bytes.readUnsignedShort(); + } + Constant constant = constantPool.getConstant(index); + + if (opcode==Const.LDC2_W && (constant.getTag()!=Constants.CONSTANT_Double && constant.getTag()!=Constants.CONSTANT_Long)) + throw new RuntimeException("LDC2_W must load long or double"); + + if (constant.getTag() == Constants.CONSTANT_Integer) { + instruction = NumberLiteral.create(new Integer(((ConstantInteger) constant).getBytes())); + } else if (constant.getTag() == Constants.CONSTANT_Float) { + instruction = NumberLiteral.create(new Float(((ConstantFloat) constant).getBytes())); + } else if (constant.getTag() == Constants.CONSTANT_Long) { + instruction = NumberLiteral.create(new Long(((ConstantLong) constant).getBytes())); + } else if (constant.getTag() == Constants.CONSTANT_Double) { + instruction = NumberLiteral.create(new Double(((ConstantDouble) constant).getBytes())); + } else if (constant.getTag() == Constants.CONSTANT_Utf8) { + instruction = new StringLiteral(((ConstantUtf8) constant).getBytes()); + } else if (constant.getTag() == Constants.CONSTANT_String) { + int k = ((ConstantString) constant).getStringIndex(); + constant = constantPool.getConstant(k, Constants.CONSTANT_Utf8); + instruction = new StringLiteral(((ConstantUtf8) constant).getBytes()); + } else if (constant.getTag() == Constants.CONSTANT_Class) { + Signature signature = Project.getSingleton().getSignature(((ConstantClass) constant).getBytes(constantPool)); + instruction = new ClassLiteral(signature); + } else { + throw new RuntimeException("Cannot handle constant tag: " + constant.getTag()); + } + break; + } + + + case Const.RET: { + // Format: ret, index(byte) + // Operand stack: ... -> ... + int index = readUnsigned(); + ReturnStatement r = new ReturnStatement(currentIndex, currentIndex); + r.setExpression(createVariableBinding(index, Type.INT, false)); + instruction = r; + break; + } + + case Const.RETURN: + // Format: return + // Operand stack: ... -> ... + case Const.IRETURN: + // Format: ireturn + // Operand stack: ..., value() -> ... + case Const.FRETURN: + // Format: freturn + // Operand stack: ..., value() -> ... + case Const.LRETURN: + // Format: lreturn + // Operand stack: ..., value() -> ... + case Const.DRETURN: + // Format: dreturn + // Operand stack: ..., value(double) -> ... + case Const.ARETURN: { + // Format: areturn + // Operand stack: ..., objectref() -> ... + ReturnStatement r = new ReturnStatement(currentIndex, currentIndex); + if (opcode != Const.RETURN) { + r.setExpression(stack.pop()); + } + instruction = r; + break; + } + + case Const.POP : + // Format: pop + // Operand stack: ..., value(cat1) -> ... + case Const.POP2: { + // (0) Format: pop2 + // (0) Operand stack: ..., value(cat2) -> ... + // (1) Format: pop2 + // (1) Operand stack: ..., value2(cat1), value1(cat1) -> ... + + if (opcode == Const.POP2 && form.getIndex() == 1) { + throw new UnsupportedOperationException("InstructionType " + instructionType.getName() + " not supported"); + } + + //instruction = stack.pop(); + // TODO: Which is correct? + // Node is probably an invokation of a method with unused result. + ASTNode a = stack.pop(); + if (!(a instanceof VariableBinding)) { + // Can't have binding on stack! TODO: VariableBinding must not be an ASTNode, + // because it has no location. + cNode.block.appendChild(a); + } + instruction = new NoOperation(); + break; + } + + case Const.NOP : + // Format: nop + // Operand stack: ... -> ... + return new NoOperation(); + + case Const.XXXUNUSEDXXX : + // Format: xxxunusedxxx + // Operand stack: ... -> ... + logger.info("Byte code contains unused operation (Ignored)"); + return new NoOperation(); + + case Const.INVOKEINTERFACE : + // Format: invokeinterface, index(short), count(byte), 0(byte) + // Operand stack: ..., objectref(), arg1(), ...(), argN() -> ... + case Const.INVOKESPECIAL : + // Format: invokespecial + // Operand stack: ..., objectref(), arg1(), ...(), argN() -> ... + case Const.INVOKEVIRTUAL : + // Format: invokevirtual + // Operand stack: ..., objectref(), arg1(), ...(), argN() -> ... + case Const.INVOKESTATIC : { + // Format: invokestatic, index(short) + // Operand stack: ..., arg1(), ...(), argN() -> ... + int index = bytes.readUnsignedShort(); + MethodBinding methodBinding = MethodBinding.lookup(index, constantPool); + MethodInvocation invocation = new MethodInvocation(methodDecl, methodBinding); + + //Processor.getLogger().finer(method.getName() + "->" + invocation.binding); + + int nArgs = methodBinding.getParameterTypes().length; + int kk = stack.size() - nArgs; + for (int i=0; i 0 && stack.peek() instanceof ClassInstanceCreation && methodBinding.getName().equals("")) { +// ClassInstanceCreation cic = (ClassInstanceCreation) stack.pop(); +// List args = invocation.getArguments(); +// for (int i=0; i ... + SynchronizedBlock sb = new SynchronizedBlock(); + sb.monitor = stack.pop(); + sb.widen(sb.monitor); + sb.setEndIndex(currentIndex); + instruction = sb; + break; + } + case Const.MONITOREXIT : + // Format: monitorexit + // Operand stack: ..., objectref() -> ... + instruction = new NoOperation(); + instruction.widen(stack.pop()); + instruction.setEndIndex(currentIndex); + break; + + default : + throw new UnsupportedOperationException("InstructionType " + instructionType.getName() + " not supported"); + //break; + } + + if (opcode!=Const.WIDE && wide) throw new RuntimeException("Expected wide operation"); + + instruction.setStackDelta(opStackDelta); + if (opcode < Const.DUP || opcode > Const.DUP2_X2) { + instruction.leftWiden(currentIndex); + instruction.rightWiden(bytes.getIndex()-1); + } + currentNode = instruction; + return instruction; + } + + ConditionalBranch createConditional(int currentIndex, InfixExpression.Operator operator) throws IOException { + ConditionalBranch c = new ConditionalBranch(currentIndex + bytes.readShort()); + InfixExpression be = new InfixExpression(operator); + Expression rightOperand = stack.pop(); + be.setOperands(stack.pop(),rightOperand); + c.setExpression(be); + return c; + } + + ConditionalBranch createConditional(int currentIndex, InfixExpression.Operator operator, + Expression rightOperand) throws IOException { + ConditionalBranch c = new ConditionalBranch(currentIndex + bytes.readShort()); + Expression leftOperand = stack.pop(); + + if (leftOperand.getTypeBinding()!=null && leftOperand.getTypeBinding()==Type.BOOLEAN) { + if (operator == InfixExpression.Operator.EQUALS && NumberLiteral.isZero(rightOperand)) { + c.setExpression(Optimizer.negate(leftOperand)); + } else { + c.setExpression(leftOperand); + } + } else { + InfixExpression be = new InfixExpression(operator); + be.setOperands(leftOperand, rightOperand); + c.setExpression(be); + } + + return c; + } + + private String getFieldName(ConstantFieldref fieldRef) { + ConstantNameAndType nameAndType = (ConstantNameAndType) constantPool.getConstant(fieldRef.getNameAndTypeIndex()); + return nameAndType.getName(constantPool); + } + + public static String constantToString(Constant c, ConstantPool constantPool) throws ClassFormatException { + String str; + byte tag = c.getTag(); + + switch (tag) { + case Constants.CONSTANT_Class : + str = Utility.compactClassName(((ConstantClass) c).getBytes(constantPool), false); + break; + + case Constants.CONSTANT_String : + str = "\"" + Utils.escape(((ConstantString) c).getBytes(constantPool)) + "\""; + break; + + case Constants.CONSTANT_Utf8 : + str = ((ConstantUtf8) c).getBytes(); + break; + case Constants.CONSTANT_Double : + str = "" + ((ConstantDouble) c).getBytes(); + break; + case Constants.CONSTANT_Float : + str = "" + ((ConstantFloat) c).getBytes(); + break; + case Constants.CONSTANT_Long : + str = "" + ((ConstantLong) c).getBytes(); + break; + case Constants.CONSTANT_Integer : + str = "" + ((ConstantInteger) c).getBytes(); + break; + + case Constants.CONSTANT_NameAndType : + str = ((ConstantNameAndType) c).getName(constantPool); + break; + + case Constants.CONSTANT_InterfaceMethodref : + case Constants.CONSTANT_Methodref : + case Constants.CONSTANT_Fieldref : + str = ((ConstantCP) c).getClass(constantPool); + break; + + default : // Never reached + throw new RuntimeException("Unknown constant type " + tag); + } + + return str; + } + +} diff --git a/src/main/java/com/j2js/Utils.java b/src/main/java/com/j2js/Utils.java new file mode 100644 index 0000000..84f4347 --- /dev/null +++ b/src/main/java/com/j2js/Utils.java @@ -0,0 +1,160 @@ +package com.j2js; + +import com.j2js.J2JSCompiler; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.DateFormat; +import java.util.Date; +import java.util.Properties; + + +import org.apache.bcel.generic.ArrayType; +import org.apache.bcel.generic.BasicType; +import org.apache.bcel.generic.ObjectType; +import org.apache.bcel.generic.Type; + +import com.j2js.dom.ASTNode; +import com.j2js.dom.MethodDeclaration; + +/** + * @author j2js.com + */ +public final class Utils { + + private static final String propertiesFile = "j2js.properties"; + private static final Properties properties; + + static { + properties = new Properties(); + try { + properties.load(Utils.class.getClassLoader().getResourceAsStream(propertiesFile)); + } catch (Exception e) { + J2JSCompiler.errorCount++; + Log.getLogger().error("Could not read from classpath: " + propertiesFile); + throw new RuntimeException(e); + } + } + + private Utils() {} + + public static String generateExceptionMessage(MethodDeclaration methodDecl, ASTNode node) { + String msg = null; + if (node != null) { + int line = methodDecl.getLineNumberCursor().getLineNumber(node); + if (line != -1) { + msg = "Error near line " + line; + } + } + if (msg == null) { + msg = "Error"; + } + + msg += " in " + methodDecl.getMethodBinding(); + + return msg; + } + + public static RuntimeException generateException(Throwable e, MethodDeclaration methodDecl, ASTNode node) { + String msg = generateExceptionMessage(methodDecl, node); + J2JSCompiler.errorCount++; + Log.getLogger().error(msg); + return new RuntimeException(msg, e); + } + + public static String stackTraceToString(Throwable e) { + StringWriter sw = new StringWriter(); + PrintWriter writer = new PrintWriter(sw); + e.printStackTrace(writer); + writer.close(); + return sw.getBuffer().toString(); + } + + public static String currentTimeStamp() { + return DateFormat.getDateTimeInstance().format(new Date()); + } + + public static String getVersion() { + return (String) properties.get("j2js.version"); + } + + public static String getProperty(String key) { + return (String) properties.get(key); + } + + public static String getSignature(Type type) { + String signature; + + if (type instanceof ArrayType) { + ArrayType aType = (ArrayType) type; + signature = getSignature(aType.getBasicType()); + for (int i = 0; i declaredMembers; + + // The super class. + private ClassUnit superUnit; + + // All interfaces implemented by this unit. + private Collection interfaces; + + // All derived classes. + private Collection subUnits; + + public boolean isInterface = false; + + public boolean isConstructorTainted = false; + + public Map[] annotations; + + private Project project; + + // Transient fields start here. + private transient boolean isResolved = false; + + // The class file of this unit. + private transient FileObject classFile; + + public ClassUnit() { + } + + public ClassUnit(Project theProject, Signature theSignature) { + project = theProject; + + interfaces = new HashSet(); + declaredMembers = new HashMap(); + subUnits = new HashSet(); + lastCompiled = -1; + setSignature(theSignature); + } + + /** + * Reset all fields filled by compilation. + */ + void clear() { + // Do not remove registered subunits! + lastCompiled = -1; + removeInterfaces(); + setSuperUnit(null); + declaredMembers.clear(); + } + + /** + * Returns true if this unit is up to date. + */ + public boolean isUpToDate() { + return lastCompiled >= getLastModified(); + } + + public Collection getInterfaces() { + return interfaces; + } + + public void addInterface(ClassUnit interfaceUnit) { + interfaces.add(interfaceUnit); + //interfaceUnit.addSubUnit(this); + } + + private void removeInterfaces() { + Iterator iter = interfaces.iterator(); + while (iter.hasNext()) { + ClassUnit interfaceUnit = (ClassUnit) iter.next(); + interfaceUnit.removeSubUnit(this); + iter.remove(); + } + } + + public void addSubUnit(ClassUnit subUnit) { + if (subUnit == null) throw new NullPointerException(); + subUnits.add(subUnit); + } + + public void removeSubUnit(ClassUnit subUnit) { + if (subUnit == null) throw new NullPointerException(); + subUnits.remove(subUnit); + } + + public Collection getSubUnits() { + return subUnits; + } + + /** + * Returns the declared member with the specified signature. + */ + public MemberUnit getDeclaredMember(String signature) { + if (signature == null) throw new NullPointerException(); + return declaredMembers.get(signature); + } + + /** + * Returns all types to which this class can be converted, i.e., the collection of + * all supertypes and implemented interfaces and the class itself. + */ + public Collection getSupertypes() { + TypeCollector collector = new TypeCollector(); + project.visitSuperTypes(this, collector); + return collector.collectedTypes; + } + + /** + * Returns a member object that reflects the specified public member method of the class + * or interface represented by this Class object. + */ +// public MemberUnit getMember(String signature) { +// if (signature == null) throw new NullPointerException(); +// +// ClassUnit clazz = this; +// do { +// MemberUnit member = clazz.getDeclaredMember(signature); +// if (member != null) return member; +// clazz = clazz.getSuperUnit(); +// } while (clazz != null); +// +// return null; +// } + + public Collection getMembers(String signature) { + if (signature == null) throw new NullPointerException(); + ArrayList list = new ArrayList(); + + for (ClassUnit clazz : getSupertypes()) { + MemberUnit member = clazz.getDeclaredMember(signature); + if (member != null) list.add(member); + } + + return list; + } + + public Collection getDeclaredMembers() { + if (!isResolved) throw new RuntimeException("Class is not yet resolved: " + getName()); + return declaredMembers.values(); + } + + public void addMemberUnit(MemberUnit unit) { + declaredMembers.put(unit.getSignature().toString(), unit); + } + + public ClassUnit getSuperUnit() { + return superUnit; + } + + public void setSuperUnit(ClassUnit theSuperUnit) { + if (superUnit != null) { + superUnit.removeSubUnit(this); + } + superUnit = theSuperUnit; + if (superUnit != null) { + superUnit.addSubUnit(this); + } + } + + public void write(int depth, Writer writer) throws IOException { + if (!isTainted()) return; + + Log.getLogger().debug(getIndent(depth) + this); + + if (getData() != null) { + writer.write(getData()); + } else { + // TODO: Is it correct to return so soon? + return; + } + + if (interfaces.size() > 0) { + //Logger.getLogger().info("Class + " + this.getName() + " has interfaces: "); + + writer.write("_T.interfaces = ["); + int i = 0; + for (ClassUnit interFace : interfaces) { + //Logger.getLogger().info(">>>" + interFace.getName()); + if (i++ > 0) writer.write(", "); + writer.write(String.valueOf(interFace.getSignature().getId())); + } + writer.write("];\n"); + } + + if (annotations != null) { + writer.write("_T.annotations = "); + Serializer serializer = new Serializer(writer); + serializer.serialize(annotations); + writer.write(";\n"); + } + + for (MemberUnit member : getDeclaredMembers()) { + if (member.isTainted()) { + member.write(depth + 1, writer); + if (member instanceof ProcedureUnit) { + project.currentGeneratedMethods++; + writer.flush(); + } + } + } + + for (ClassUnit child : getSubUnits()) { + // TODO Interface: Interfaces must not extend java.lang.Object! + //if (!child.isInterface) { + child.write(depth + 1, writer); + //} + } + } + + void setSignature(Signature theSignature) { + super.setSignature(theSignature); + } + + public FileObject getClassFile() { + if (classFile == null) { + classFile = J2JSCompiler.compiler.fileManager.getFileForInput( + getSignature().toString().replaceAll("\\.", "/") + ".class"); + } + return classFile; + } + + public void setLastCompiled(long theLastCompiled) { + lastCompiled = theLastCompiled; + } + + public boolean isResolved() { + return isResolved; + } + + public void setSuperTainted() { + ClassUnit clazz = this; + do { + clazz.setTainted(); + clazz = clazz.getSuperUnit(); + } while (clazz != null); + + for (ClassUnit i : interfaces) { + i.setSuperTainted(); + } + } + + public void setResolved(boolean theIsResolved) { + isResolved = theIsResolved; + } + public String getName() { + return getSignature().className(); + } + + public Project getProject() { + return project; + } + +} diff --git a/src/main/java/com/j2js/assembly/ConstructorUnit.java b/src/main/java/com/j2js/assembly/ConstructorUnit.java new file mode 100644 index 0000000..4e4a3a5 --- /dev/null +++ b/src/main/java/com/j2js/assembly/ConstructorUnit.java @@ -0,0 +1,14 @@ +package com.j2js.assembly; + +/** + * ConstructorUnit provides information about, and access to, a single constructor for a class. + * + * @author wolle + */ +public class ConstructorUnit extends ProcedureUnit { + + public ConstructorUnit(Signature theSignature, ClassUnit theDeclaringClazz) { + super(theSignature, theDeclaringClazz); + } + +} diff --git a/src/main/java/com/j2js/assembly/FieldUnit.java b/src/main/java/com/j2js/assembly/FieldUnit.java new file mode 100644 index 0000000..5f5f297 --- /dev/null +++ b/src/main/java/com/j2js/assembly/FieldUnit.java @@ -0,0 +1,21 @@ +package com.j2js.assembly; + +import java.io.IOException; +import java.io.Writer; + +/** + * A FieldUnit provides information about, and dynamic access to, a single field of a class or an interface. + * + * @author wolle + */ +public class FieldUnit extends MemberUnit { + + public FieldUnit(Signature theSignature, ClassUnit theDeclaringClazz) { + super(theSignature, theDeclaringClazz); + } + + void write(int depth, Writer writer) throws IOException { + return; + } + +} diff --git a/src/main/java/com/j2js/assembly/JavaScriptCompressor.java b/src/main/java/com/j2js/assembly/JavaScriptCompressor.java new file mode 100644 index 0000000..fbf449e --- /dev/null +++ b/src/main/java/com/j2js/assembly/JavaScriptCompressor.java @@ -0,0 +1,69 @@ +package com.j2js.assembly; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class JavaScriptCompressor { + + private int CODE = 0; + private int LINECOMMENT = 1; + private int MULTILINECOMMENT = 2; + private int STRING = 3; + + public String compress(InputStream input) throws FileNotFoundException, IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(input)); + StringBuffer buffer = new StringBuffer(); + int state = CODE; + char c; + char lastC = 0; + + do { + int i = reader.read(); + if (i == -1) break; + c = (char) i; + + if (state == LINECOMMENT) { + if (c == '\n') { + state = CODE; + buffer.append(c); + } // else ignore character. + } else if (state == MULTILINECOMMENT) { + if (c == '/' && lastC == '*') { + state = CODE; + } // else ignore character. + } else if (state == STRING) { + if (c == '"') { + state = CODE; + } + buffer.append(c); + } else if (c == '/' && lastC == c) { + state = LINECOMMENT; + buffer.deleteCharAt(buffer.length()-1); + } else if (c == '*' && lastC == '/') { + state = MULTILINECOMMENT; + buffer.deleteCharAt(buffer.length()-1); + } else if (c == '"') { + state = STRING; + buffer.append(c); + } else { + int length = buffer.length(); + if (length > 0 && Character.isWhitespace(c) && Character.isWhitespace(buffer.charAt(length-1))) { + + } else { + buffer.append(c); + } + } + lastC = c; + } while (true); + + reader.close(); + + return buffer.toString(); + } + +} diff --git a/src/main/java/com/j2js/assembly/JunkWriter.java b/src/main/java/com/j2js/assembly/JunkWriter.java new file mode 100644 index 0000000..740d590 --- /dev/null +++ b/src/main/java/com/j2js/assembly/JunkWriter.java @@ -0,0 +1,81 @@ +package com.j2js.assembly; + +import com.j2js.J2JSCompiler; + +import java.io.File; +import java.io.FileWriter; +import java.io.FilterWriter; +import java.io.IOException; +import java.io.StringWriter; + +import com.j2js.Log; + +public class JunkWriter extends FilterWriter { + + private File assembly; + private int junkCount = 0; + private int sizeOfCurrentJunk; + private int sizeOfAllJunks = 0; + + public JunkWriter(File assembly) throws IOException { + super(new StringWriter()); + this.assembly = assembly; + startNewJunk(); + } + + private void startNewJunk() throws IOException { + sizeOfAllJunks += sizeOfCurrentJunk; + + if (junkCount > 0) { + write("j2js.loadScript(" + sizeOfAllJunks + ");"); + out.flush(); + out.close(); + } + + Log logger = Log.getLogger(); + String newJunkName = (junkCount + 1) + ".js"; + logger.info("Creating assembly " + newJunkName); + out = new FileWriter(new File(assembly, newJunkName)); + sizeOfCurrentJunk = 0; + junkCount++; + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + super.write(cbuf, off, len); + sizeOfCurrentJunk += len; + } + + @Override + public void write(int c) throws IOException { + super.write(c); + sizeOfCurrentJunk++; + } + + @Override + public void write(String str, int off, int len) throws IOException { + super.write(str, off, len); + sizeOfCurrentJunk += len; + } + + @Override + public void flush() throws IOException { + super.flush(); + if (sizeOfCurrentJunk/1024 > J2JSCompiler.compiler.getJunkSizeInKiloBytes()) { + startNewJunk(); + } + } + + @Override + public void close() throws IOException { + sizeOfAllJunks += sizeOfCurrentJunk; + // Set to 0 in case super.close() calls flush(). + sizeOfCurrentJunk = 0; + super.close(); + } + + public int getSize() { + return sizeOfAllJunks; + } + +} diff --git a/src/main/java/com/j2js/assembly/MemberUnit.java b/src/main/java/com/j2js/assembly/MemberUnit.java new file mode 100644 index 0000000..1bbe86d --- /dev/null +++ b/src/main/java/com/j2js/assembly/MemberUnit.java @@ -0,0 +1,32 @@ +package com.j2js.assembly; + +/** + * The MemberUnit class is the base class for Field, Method and Constructor objects. + * + * @author wolle + */ +public abstract class MemberUnit extends Unit { + + // The class to which this method belongs. + ClassUnit declaringClass; + + MemberUnit(Signature theSignature, ClassUnit theDeclaringClazz) { + setSignature(theSignature); + declaringClass = theDeclaringClazz; + declaringClass.addMemberUnit(this); + } + + public ClassUnit getDeclaringClass() { + return declaringClass; + } + + public Signature getAbsoluteSignature() { + Signature s = Project.getSingleton().getSignature(declaringClass.toString(), getSignature().toString()); + return s; + } + + public String toString() { + return declaringClass.getName() + "#" + super.toString(); + } + +} diff --git a/src/main/java/com/j2js/assembly/MethodUnit.java b/src/main/java/com/j2js/assembly/MethodUnit.java new file mode 100644 index 0000000..6e85ab9 --- /dev/null +++ b/src/main/java/com/j2js/assembly/MethodUnit.java @@ -0,0 +1,14 @@ +package com.j2js.assembly; + +/** + * A MethodUnit provides information about, and access to, a single method on a class or interface. + * + * @author wolle + */ +public class MethodUnit extends ProcedureUnit { + + public MethodUnit(Signature theSignature, ClassUnit theDeclaringClazz) { + super(theSignature, theDeclaringClazz); + } + +} diff --git a/src/main/java/com/j2js/assembly/ProcedureUnit.java b/src/main/java/com/j2js/assembly/ProcedureUnit.java new file mode 100644 index 0000000..c3b01a5 --- /dev/null +++ b/src/main/java/com/j2js/assembly/ProcedureUnit.java @@ -0,0 +1,51 @@ +package com.j2js.assembly; + +import java.io.IOException; +import java.io.Writer; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +import com.j2js.Log; + +public abstract class ProcedureUnit extends MemberUnit { + + // Set of all member signatures targeted by this method. + private Collection targetSignatures = new HashSet(); + + public ProcedureUnit(Signature theSignature, ClassUnit theDeclaringClazz) { + super(theSignature, theDeclaringClazz); + } + + public void addTarget(Signature targetSignature) { + if (!targetSignature.toString().contains("#")) { + throw new IllegalArgumentException("Signature must be field or method: " + targetSignature); + } + //Logger.getLogger().info("Adding " + this + " -> " + targetSignature); + targetSignatures.add(targetSignature); + } + + public void removeTargets() { + Iterator iter = targetSignatures.iterator(); + while (iter.hasNext()) { + iter.next(); + iter.remove(); + } + } + + void write(int depth, Writer writer) throws IOException { + if (getData() == null) return; + Log.getLogger().debug(getIndent(depth) + getSignature()); + writer.write(getData()); + } + + public String getData() { + if (!declaringClass.isResolved()) throw new RuntimeException("Class must be resolved"); + return super.getData(); + } + + public Collection getTargetSignatures() { + return targetSignatures; + } + +} diff --git a/src/main/java/com/j2js/assembly/Project.java b/src/main/java/com/j2js/assembly/Project.java new file mode 100644 index 0000000..2b1a07e --- /dev/null +++ b/src/main/java/com/j2js/assembly/Project.java @@ -0,0 +1,330 @@ +package com.j2js.assembly; + +import com.j2js.J2JSCompiler; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.apache.bcel.generic.ArrayType; +import org.apache.bcel.generic.ObjectType; +import org.apache.bcel.generic.ReferenceType; +import org.apache.bcel.generic.Type; + +import com.j2js.Log; +import com.j2js.Utils; +import com.j2js.dom.ArrayCreation; +import com.j2js.dom.FieldAccess; +import com.j2js.dom.MethodBinding; +import com.j2js.dom.MethodDeclaration; +import com.j2js.dom.MethodInvocation; +import com.j2js.dom.TypeDeclaration; + +public class Project implements Serializable { + + static final long serialVersionUID = 0; + + private static Project singleton; + + // All managed classes mapped by class name. + private Map classesByName; + private ClassUnit javaLangObject; + private boolean compressed; + private boolean generateLineNumbers; + private Map signatures; + + private transient Stack ids; + private transient int currentId; + private transient int currentIndex; + + public transient int currentGeneratedMethods; + + public static Project getSingleton() { + if (singleton == null) throw new NullPointerException(); + return singleton; + } + + public static Project createSingleton(File cacheFile) { + + if (cacheFile != null && cacheFile.exists()) { + Log.getLogger().info("Using cache " + cacheFile); + try { + read(cacheFile); + } catch (Exception e) { + Log.getLogger().warn("Could not read cache:\n" + e.getMessage()); + } + } + + if (singleton == null || + singleton.compressed != J2JSCompiler.compiler.isCompression() || + singleton.generateLineNumbers != J2JSCompiler.compiler.isGenerateLineNumbers()) { + // Cache does not exist, could not be read, or compression does not match. + singleton = new Project(); + singleton.clear(); + } + + return singleton; + } + + private static void read(File file) throws Exception { + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis); + singleton = (Project) ois.readObject(); + ois.close(); + } + + public static void write() throws IOException { + File file = J2JSCompiler.compiler.getCacheFile(); + if (file.exists() && !file.canWrite()) { + throw new IOException("Cannot write " + file); + } + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(singleton); + oos.close(); + } + + public Signature getArraySignature(Type type) { + String signatureString = type.getSignature(); + /* Examples: + * L[java.lang.Integer;; -> [java.lang.Integer; + * L[I; -> [I + */ + if (!signatureString.startsWith("L") || !signatureString.endsWith(";")) { + throw new RuntimeException("Not a class signature: " + signatureString); + } + signatureString = signatureString.substring(1, signatureString.length()-1); + return getSignature(signatureString); + } + + /** + * All request for a signature delegate to this method. + */ + public Signature getSignature(String signatureString) { + if (signatureString.endsWith(";")) { + //throw new RuntimeException("Invalid signature: " + signatureString); + } + signatureString = signatureString.replaceAll("/", "."); + + Signature signature = signatures.get(signatureString); + if (signature == null) { + signature = new Signature(signatureString, getUniqueId()); + signatures.put(signatureString, signature); + } + + return signature; + } + + public Signature getSignature(String className, String relativeSignature) { + return getSignature(className + '#' + relativeSignature); + } + + public Signature getSignature(FieldAccess fa) { + return getSignature(fa.getType().getClassName(), fa.getName()); + } + + private int getUniqueId() { + if (ids == null) { + ids = new Stack(); + for (Signature signature : signatures.values()) { + ids.add(signature.getId()); + } + Collections.sort(ids); + } + + while (currentIndex(); + javaLangObject = null; + + signatures = new HashMap(); + ids = null; + currentId = 0; + currentIndex = 0; + compressed = J2JSCompiler.compiler.isCompression(); + generateLineNumbers = J2JSCompiler.compiler.isGenerateLineNumbers(); + } + + public void remove(ClassUnit clazz) { + classesByName.remove(clazz); + } + + void visitSuperTypes(ClassUnit clazz, TypeVisitor visitor) { + visitor.visit(clazz); + ClassUnit superClass = clazz.getSuperUnit(); + if (superClass != null) { + visitSuperTypes(superClass, visitor); + } + + for (ClassUnit interfaceUnit : clazz.getInterfaces()) { + visitor.visit(interfaceUnit); + visitSuperTypes(interfaceUnit, visitor); + } + } + + public ClassUnit getJavaLangObject() { + return javaLangObject; + } + + public ClassUnit getClassUnit(String className) { + ClassUnit clazz = classesByName.get(className); + if (clazz != null) return clazz; + + throw new RuntimeException("No such unit: " + className); + } + + public ClassUnit getClassUnit(ReferenceType type) { + String signature; + if (type instanceof ArrayType) { + ArrayType aType = (ArrayType) type; + signature = Utils.getSignature(aType.getBasicType()); + for (int i = 0; i getClasses() { + return classesByName.values(); + } + + public void resolve(ClassUnit clazz) { + if (clazz.isResolved()) return; + + if (clazz.getName().startsWith("[")) { + // This is an array type and not a class. + clazz.setSuperUnit(getJavaLangObject()); + //clazz.setTainted(); + clazz.setResolved(true); + // We need a member (and we chose length) in addReference(..) to taint the class. + new FieldUnit(getSignature("length"), clazz); + + TypeDeclaration typeDecl = new TypeDeclaration(new ObjectType(clazz.getName()), 0); + typeDecl.setSuperType(Type.OBJECT); + typeDecl.visit(J2JSCompiler.compiler.generator); + } else { + TypeResolver resolver = new TypeResolver(this, J2JSCompiler.compiler.generator); + visitSuperTypes(clazz, resolver); + } + } + +} diff --git a/src/main/java/com/j2js/assembly/Serializer.java b/src/main/java/com/j2js/assembly/Serializer.java new file mode 100644 index 0000000..2611e8c --- /dev/null +++ b/src/main/java/com/j2js/assembly/Serializer.java @@ -0,0 +1,153 @@ +package com.j2js.assembly; + +import java.util.List; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.Writer; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +public class Serializer { + private Writer writer; + private SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy"); + + /** Creates a new instance of Serializer */ + public Serializer(Writer theWriter) { + writer = theWriter; + } + + public void serialize(Object object) throws NotSerializableException { + try { + this.serializeInternal(object); + } catch (IOException e) { + throw new NotSerializableException(e.getMessage()); + } + } + + private void serializeInternal(Object object) throws IOException { + if (object==null) { + writer.write("null"); + } else if (object instanceof String) { + quote((String)object); + } else if (object instanceof Number) { + numberToString((Number) object); + } else if (object instanceof Map) { + serializeMap((Map) object); + } else if (object instanceof List) { + serializeArray((List) object); + } else if (object.getClass().isArray()) { + serializeArray((Object[]) object);// && object.getClass().getComponentType().equals(Double.TYPE) double[]) object); + } else if (object instanceof Boolean) { + writer.write(((Boolean)object).toString()); + } else if (object instanceof Date) { + quote(dateFormatter.format((Date) object)); + } else { + throw serializeError("Unknown object type " + object.getClass().toString()); + } + } + + private void serializeArray(List list) throws IOException { + String sep = ""; + + writer.write('['); + for (Object o : list) { + writer.write(sep); + sep = ","; + this.serializeInternal(o); + } + writer.write(']'); + } + + private void serializeArray(Object[] array) throws IOException { + String sep = ""; + + writer.write('['); + for (int i=0; i map) throws IOException { + String sep = ""; + + writer.write('{'); + for (String key : map.keySet()) { + writer.write(sep); + sep = ","; + Object value = map.get(key); + if (key.matches("\\w*")) { + writer.write(key); + } else { + writer.write("\"" + key + "\""); + } + + writer.write(':'); + this.serializeInternal(value); + } + writer.write('}'); + } + + /** + * Stream a numeric value. + * @exception NotSerializableException If number is infinite or not a number. + * @param n A Number + * @return A String. + */ + private void numberToString(Number n) throws IOException { + if (n instanceof Double && (((Double) n).isInfinite() || ((Double) n).isNaN())) { + throw serializeError("Can only serialize finite numbers"); + } + if (n instanceof Float && (((Float) n).isInfinite() || ((Float) n).isNaN())) { + throw serializeError("Can only serialize finite numbers"); + } + + writer.write(n.toString().toLowerCase()); + } + + private void numberToString(double n) throws IOException { + writer.write(String.valueOf(n)); + } + + /** + * Stream a string in double quotes " with the following backslash replacements: + * " -> \" + * \ -> \\ + * @param string A String + */ + private void quote(String s) throws IOException { + if (s == null) { + writer.write("null"); + return; + } + writer.write('"'); + int l = s.length(); + for (int i=0; i java.lang.Integer + * L[I; -> [I + */ +// public String getClassName() { +// if (!signatureString.startsWith("L") || !signatureString.endsWith(";")) { +// throw new RuntimeException("Not a class signature: " + signatureString); +// } +// return signatureString.substring(1, signatureString.length()-1); +// } + + public int hashCode() { + return signatureString.hashCode(); + } + + public boolean equals(Object obj) { + if (obj instanceof Signature) { + return signatureString.equals(((Signature) obj).signatureString); + } + return false; + } + + public String toString() { + return signatureString; + } + + public boolean isClass() { + return signatureString.indexOf('#') == -1; + } + + public boolean isArrayType() { + return isClass() && signatureString.startsWith("["); + } + + public boolean isConstructor() { + return signatureString.startsWith(""); + } + + public boolean isMethod() { + return !isConstructor() && signatureString.indexOf('(') != -1; + } + + public boolean isField() { + return !isClass() && signatureString.indexOf('(') == -1; + } + + public String className() { + String array[] = signatureString.split("#"); + //if (array[0].startsWith("[")) array[0] = array[0].substring(1); + return array[0]; + } + + public String relativeSignature() { + String array[] = signatureString.split("#"); + if (array.length != 2) { + throw new RuntimeException("Not a method signature: " + this); + } + return array[1]; + } + + /** + * Returns the relative signature. + */ + public Signature relative() { + return Project.getSingleton().getSignature(relativeSignature()); + } + + public int getId() { + return id; + } + + public String getCommentedId() { + StringBuffer sb = new StringBuffer(); + sb.append(String.valueOf(getId())); + if (!J2JSCompiler.compiler.isCompression()) { + sb.append(" /*"); + sb.append(toString()); + sb.append("*/"); + } + return sb.toString(); + } +} diff --git a/src/main/java/com/j2js/assembly/TypeCollector.java b/src/main/java/com/j2js/assembly/TypeCollector.java new file mode 100644 index 0000000..0b61561 --- /dev/null +++ b/src/main/java/com/j2js/assembly/TypeCollector.java @@ -0,0 +1,13 @@ +package com.j2js.assembly; + +import java.util.Collection; +import java.util.HashSet; + +public class TypeCollector implements TypeVisitor { + + Collection collectedTypes = new HashSet(); + + public void visit(ClassUnit clazz) { + collectedTypes.add(clazz); + } +} diff --git a/src/main/java/com/j2js/assembly/TypeResolver.java b/src/main/java/com/j2js/assembly/TypeResolver.java new file mode 100644 index 0000000..95cdf59 --- /dev/null +++ b/src/main/java/com/j2js/assembly/TypeResolver.java @@ -0,0 +1,77 @@ +package com.j2js.assembly; + +import com.j2js.J2JSCompiler; + +import com.j2js.Log; +import com.j2js.Parser; +import com.j2js.dom.TypeDeclaration; +import com.j2js.visitors.JavaScriptGenerator; + +public class TypeResolver implements TypeVisitor { + + private JavaScriptGenerator generator; + private Project project; + + public TypeResolver(Project theProject, JavaScriptGenerator theGenerator) { + project = theProject; + generator = theGenerator; + } + + public void visit(ClassUnit clazz) { + if (clazz.isResolved()) return; + + Log logger = Log.getLogger(); + + if (clazz.getSignature().toString().startsWith("[")) { + // Class is an array class without class file: Do nothing. + } else if (!clazz.isUpToDate()) { + clazz.clear(); + try { + compile(clazz); + J2JSCompiler.compiler.compileCount++; + } catch (RuntimeException ex) { + J2JSCompiler.errorCount++; + logger.error(ex.toString()); + //ex.printStackTrace(); + if (J2JSCompiler.compiler.failOnError) { + throw ex; + } + } + } else { + logger.debug("Up to date: " + clazz); + } + + clazz.setResolved(true); + } + + /** + * Compiles the unit. + */ + private void compile(ClassUnit classUnit) { + + if (classUnit.getClassFile() == null) { + Log.getLogger().warn("Cannot read " + classUnit.getClassFile()); + return; + } + + Log.getLogger().info("Cross-Compiling " + classUnit); + + TypeDeclaration typeDecl = parse(classUnit); + + // TODO + //if (!Modifier.isInterface(typeDecl.getAccess())) { + typeDecl.visit(generator); + //} + + // Set not current date but date of last modification. This is + // independent of system clock. + classUnit.setLastCompiled(classUnit.getLastModified()); + } + + private TypeDeclaration parse(ClassUnit classUnit) { + Parser parser = new Parser(classUnit); + TypeDeclaration typeDecl = parser.parse(); + + return typeDecl; + } +} diff --git a/src/main/java/com/j2js/assembly/TypeVisitor.java b/src/main/java/com/j2js/assembly/TypeVisitor.java new file mode 100644 index 0000000..f7b7865 --- /dev/null +++ b/src/main/java/com/j2js/assembly/TypeVisitor.java @@ -0,0 +1,5 @@ +package com.j2js.assembly; + +public interface TypeVisitor { + public void visit(ClassUnit clazz); +} diff --git a/src/main/java/com/j2js/assembly/Unit.java b/src/main/java/com/j2js/assembly/Unit.java new file mode 100644 index 0000000..7d406c1 --- /dev/null +++ b/src/main/java/com/j2js/assembly/Unit.java @@ -0,0 +1,62 @@ +package com.j2js.assembly; + +import java.io.IOException; +import java.io.Serializable; +import java.io.Writer; + +import com.j2js.Log; + + +public abstract class Unit implements Serializable { + + private Signature signature; + + private String data; + + private transient boolean isTainted = false; + private static transient String[] indentPerDepth = new String[10]; + + public Unit() { + } + + abstract void write(int depth, Writer writer) throws IOException; + + String getIndent(int depth) { + String indent = indentPerDepth[depth]; + if (indent == null) { + indent = ""; + for (int i=0; i uaArgs = new ArrayList(); + + @XmlElement(name = "devModeWebSocketURL", required = true) + public URI devModeWebSocketURL; + + @XmlElement(name = "devModeHttpURL", required = true) + public URI devModeHttpURL; + + public void write(OutputStream os) { + try { + JAXBContext context = JAXBContext.newInstance(Configuration.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(this, os); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static Configuration read() { + File file = new File(System.getProperty("user.home") + "/.m2/j2js.xml"); + InputStream is = null; + try { + is = new FileInputStream(file); + } catch (FileNotFoundException e) { + throw new RuntimeException("Could not read file " + file); + } + System.out.println("Reading j2js configuration from " + file); + return Configuration.read(is); + } + + public static Configuration read(InputStream inStream) { + JAXBContext context; + try { + context = JAXBContext.newInstance(Configuration.class); + Unmarshaller um = context.createUnmarshaller(); + return (Configuration) um.unmarshal(inStream); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +// public ApplicationConfiguration getApplicationConfiguration(String applicationName) { +// if ( applicationName == null ) { +// throw new NullPointerException("applicationName cannot be null."); +// } +// +// for (ApplicationConfiguration applConfig : applications) { +// if ( applicationName.equals(applConfig.applicationName) ) { +// return applConfig; +// } +// } +// +// return null; +// } +} diff --git a/src/main/java/com/j2js/cfg/ConditionalEdge.java b/src/main/java/com/j2js/cfg/ConditionalEdge.java new file mode 100644 index 0000000..87a2800 --- /dev/null +++ b/src/main/java/com/j2js/cfg/ConditionalEdge.java @@ -0,0 +1,29 @@ +package com.j2js.cfg; + +import com.j2js.dom.BooleanExpression; + +public class ConditionalEdge extends Edge { + + private BooleanExpression expression; + private boolean negate = false; + + ConditionalEdge(Graph graph, Node theSource, Node theTarget) { + super(graph, theSource, theTarget); + } + + public BooleanExpression getBooleanExpression() { + return expression; + } + + public void setBooleanExpression(BooleanExpression expr) { + expression = expr; + } + + public boolean isNegate() { + return negate; + } + + public void setNegate(boolean theNegate) { + negate = theNegate; + } +} diff --git a/src/main/java/com/j2js/cfg/ControlFlowGraph.java b/src/main/java/com/j2js/cfg/ControlFlowGraph.java new file mode 100644 index 0000000..a9fee23 --- /dev/null +++ b/src/main/java/com/j2js/cfg/ControlFlowGraph.java @@ -0,0 +1,387 @@ +package com.j2js.cfg; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +import com.j2js.ASTNodeStack; +import com.j2js.cfg.transformation.Transformation; +import com.j2js.dom.ASTNode; +import com.j2js.dom.Block; +import com.j2js.dom.BooleanExpression; +import com.j2js.dom.InfixExpression; +import com.j2js.dom.TryStatement; + +/** + * Instances of this class represent a Control Flow Graph CFG. + */ +public class ControlFlowGraph extends Graph { + + // Ordering is only used by method getNodeAt(). + private SortedMap nodesByPc = new TreeMap(); + + // The single entry point of control. + private Node sourceNode; + + private List tryStatements; + + public ControlFlowGraph(List theTryStatements) { + tryStatements = theTryStatements; + } + + /** + * Returns the try statement which contains the specified node. + */ + private TryStatement selectTryStatement(Node node) { + int pc = node.getInitialPc(); + for (int i=0; i= block.getBeginIndex() && pc <= block.getEndIndex()) return tryStmt; + } + return null; + } + + + public Node createNode(int pc) { + return createNode(pc, Node.class); + } + + public Node getOrCreateNode(int pc) { + Node node = getNode(pc); + if (node == null) { + node = createNode(pc, Node.class); + } + return node; + } + + public Node createNode(int pc, Class nodeClass) { + if (pc < 0) throw new RuntimeException("Program counter may not be negative"); + + Node node = super.createNode(nodeClass); + node.setInitialPc(pc); + if (nodesByPc.put(node.getInitialPc(), node) != null) { + throw new RuntimeException("Node already exists: " + node); + } + + if (pc == 0) sourceNode = node; + + return node; + } + + /** + * Returns the largest (w.r. to its initial pc) node closest to the specified pc. + */ + public Node getNodeAt(int pc) { + int minPcDelta = Integer.MAX_VALUE; + Node node = null; + for (Node n : getNodes()) { + if (n.getInitialPc() <= pc && pc-n.getInitialPc() < minPcDelta) { + minPcDelta = pc-n.getInitialPc(); + node = n; + if (minPcDelta == 0) return node; + } + } + + if (node == null) { + throw new RuntimeException("No node at pc " + pc); + } + + return node; + } + + /** + * Splits a node at the given pc value into two nodes nodeA and nodeB. + * nodeB will start at pc and will have the outbound edges of the original node, and an + * extra edge is added from nodeA to nodeB. + */ + public Node split(Node node, int pc) { + if (node.block.getBeginIndex() >= pc) throw new RuntimeException("Block must contain program counter"); + + Node nodeB = createNode(pc); + + // Reroot all outbound edges at nodeB. + for (Edge edge : new ArrayList(node.getOutEdges())) { + edge.reroot(nodeB); + } + + addEdge(node, nodeB); + + // Transfer code starting at pc to nodeB. + ASTNode astNode = node.block.getFirstChild(); + while (astNode != null) { + if (astNode.getBeginIndex() >= pc) { + node.setCurrentPc(astNode.getBeginIndex()-1); + nodeB.block.appendChildren(astNode, node.block.getLastChild()); + break; + } + astNode = astNode.getNextSibling(); + } + + // Transfer stack to nodeB. + nodeB.stack = node.stack; + node.stack = new ASTNodeStack(); + + return nodeB; + } + + public Node[] getOrSplitNodeAt(Node currentNode, int pc) { + Node targetNode = getNodeAt(pc); + if (targetNode.getInitialPc() != pc) { + // No node starts at target pc. We have to split the node. + Node nodeB = split(targetNode, pc); + if (targetNode == currentNode) { + currentNode = nodeB; + } + targetNode = nodeB; + } + return new Node[]{currentNode, targetNode}; + } + + /** + * Redirect all incoming edges for try bodys to its try header. + */ + private void processTrys() { + for (int i=0; i(tryNode.getInEdges())) { + int pc = edge.source.getInitialPc(); + if (pc >= stmt.getBeginIndex() && pc <= stmt.getEndIndex()) continue; + if (edge.source == header) continue; + edge.redirect(header); + } + } + } + + /** + * Reroots all local edges exiting a try body at the corresponding try header. + */ + private void processTrys2() { + for (Node node: nodesByPc.values()) { + TryStatement sourceTry = selectTryStatement(node); + if (sourceTry == null) continue; + + for (Edge edge : node.getOutEdges()) { + if (edge.target.getInEdges().size() != 1) { + continue; + } + TryStatement targetTry = selectTryStatement(edge.target); + if (targetTry == null || targetTry != sourceTry) { + edge.reroot(sourceTry.header); + } + } + } + } + + /** + * Reroot the fall through successor directly at the try header. + */ + private void processTrys1() { + for (int i=0; i finallyNode.getInitialPc()) { + removeInEdges(node); + addEdge(header, node); + node.setDomParent(header); + } + } + } + } + + public Node getSource() { + return sourceNode; + } + + public Node getNode(int pc) { + return nodesByPc.get(pc); + } + + /** + * Finds the set of all successors of the specified predecessor which are not dominated by it. + * Each node in this set is then marked as a global target of the predecessor. + * If the predecessor is a branch, then a newly created node will function as the referer. + */ + private void markGlobalTargets(Node predecessor) { + for (Edge edge : predecessor.getOutEdges()) { + Node target = edge.target; + if (target.getDomParent() == predecessor) + continue; + + if (predecessor.isBranch()) { + Node node = createNode(Node.class); + edge.redirect(node); + node.setDomParent(predecessor); + edge = addEdge(node, target); + } + } + } + + /** + * For each node in tree, mark global targets. + */ + void visitToMark(Node node) { + // Be concurrent safe. + for (Node child : new ArrayList(node.getDomChildren())) { + visitToMark(child); + } + + markGlobalTargets(node); + } + + /** + * Recursively (depth first) traverses the dominator tree rooted at the specified node and post-processes + * all possible reductions. + */ + void visit(Node node) { + + // Be concurrent safe. + for (Node child : new ArrayList(node.getDomChildren())) { + visit(child); + } + + do { + Transformation t = Transformation.select(this, node); + if (t == null) break; + node = t.apply(); + dump("After transformation"); + } while (true); + + if (node.getDomChildren().size() > 0) { + throw new RuntimeException("Could not reduce graph at " + node); + } + } + + public void replaceNode(Node node, Node newNode) { + + super.replaceNode(node, newNode); + + if (newNode != null) { + nodesByPc.put(node.getInitialPc(), newNode); + } else { + nodesByPc.remove(node.getInitialPc()); + } + + if (node == sourceNode) { + if (newNode == null) { + throw new RuntimeException("Cannot remove source node " + sourceNode); + } + sourceNode = newNode; + } + } + + public Block reduce() { + processTrys(); + processTrys2(); + + dump("Before Shortcuts"); + processShortcuts(); + + DominatorTree builder = new DominatorTree(this); + builder.build(); + + processTrys1(); + + visitToMark(getSource()); + dump("Begin reduce"); + + visit(getSource()); + + if (size() != 1) { + throw new RuntimeException("Could not reduce graph"); + } + + Block block = new Block(); + + rollOut(getSource(), block); + + return block; + } + + /** + * Performs an OR or AND shortcut on two branches A and B by replacing them with new node A&B or A|B. + */ + boolean performAndOrShortcut(Node a, Node b) { + if (b.getInEdges().size() != 1) return false; + if (b.block.getChildCount() > 0) { + // Node b is not a mere conditional. + return false; + } + + + ConditionalEdge aToC; + ConditionalEdge bToC; + boolean isOR = true; + + while(true) { + aToC = a.getConditionalEdge(isOR); + bToC = b.getConditionalEdge(isOR); + if (bToC.target == aToC.target) break; + if (!isOR) return false; + isOR = false; + } + + if (aToC.target.getInEdges().size() != 2) return false; + + ConditionalEdge bToD = b.getConditionalEdge(!isOR); + ConditionalEdge aToB = a.getConditionalEdge(!isOR); + + aToB.redirect(bToD.target); + removeEdge(bToC); + removeEdge(bToD); + removeNode(b); + + InfixExpression infix = new InfixExpression( + isOR?InfixExpression.Operator.CONDITIONAL_OR:InfixExpression.Operator.CONDITIONAL_AND); + // Note that the order aToC, then bToC is important. + infix.setOperands( + aToC.getBooleanExpression().getExpression(), + bToC.getBooleanExpression().getExpression()); + + BooleanExpression be = new BooleanExpression(infix); + aToC.setBooleanExpression(be); + aToB.setBooleanExpression(be); + + logger.debug("Created shortcut and removed " + b); + + return true; + } + + public void processShortcuts() { + Collection branches = new HashSet(); + for (Node node : getNodes()) { + if (node.isBranch()) branches.add(node); + } + + L: while (true) { + Iterator iter = branches.iterator(); + while (iter.hasNext()) { + Node branch = iter.next(); + for (Node node: branch.succs()) { + if (node.isBranch() && performAndOrShortcut(branch, node)) { + branches.remove(node); + continue L; + } + } + } + break L; + } + + } +} diff --git a/src/main/java/com/j2js/cfg/DominatorTree.java b/src/main/java/com/j2js/cfg/DominatorTree.java new file mode 100644 index 0000000..c1e96d1 --- /dev/null +++ b/src/main/java/com/j2js/cfg/DominatorTree.java @@ -0,0 +1,233 @@ +package com.j2js.cfg; + +import java.util.*; + +import com.j2js.Log; + +/** + * Class to build the dominator tree of a given control flow graph. + * The algorithm is according Purdum-Moore, which isn't as fast as Lengauer-Tarjan, but a lot simpler. + */ +public class DominatorTree { + + private ControlFlowGraph graph; + + public DominatorTree(ControlFlowGraph theGraph) { + graph = theGraph; + } + + /** + * Sets the pre-order index of a node. + */ + private void visit(Node node, Collection visited) { + // Establish preorder index. + node.setPreOrderIndex(visited.size()); + visited.add(node); + + for (Node succ : node.succs()) { + if (! visited.contains(succ)) { + visit(succ, visited); + } + } + + } + + /** + * Builds the dominator tree and store it in the respective nodes. + * It will remove all unreachable nodes on the way! + */ + public void build() { + + // Construct list of nodes in pre-order order. + ArrayList preOrder = new ArrayList(); + + visit(graph.getSource(), preOrder); + + // Remove unreachable nodes. + for (Node node : new ArrayList(graph.getNodes())) { + if (!preOrder.contains(node)) { + Log.getLogger().warn("Unreachable code detected and removed"); + //Logger.getLogger().info("Removed " + node); + graph.removeInEdges(node); + graph.removeOutEdges(node); + graph.removeNode(node); + } else if (node.getPreOrderIndex() == -1) { + throw new RuntimeException("Pre-order not set for " + node); + } + } + + + int size = graph.size(); // The number of vertices in the cfg + + Map snkPreds = new HashMap(); // The predacessor vertices from the sink + + + // Determine the predacessors of the cfg's sink node + //insertEdgesToSink(graph, snkPreds, reverse); + + // Get the index of the root + int rootIndex = graph.getSource().getPreOrderIndex(); + + if (rootIndex < 0 || rootIndex >= size) throw new RuntimeException("Root index out of range"); + + // Bit matrix indicating the dominators of each node. + // If bit j of dom[i] is set, then node j dominates node i. + BitSet[] domMatrix = new BitSet[size]; + + // Initially, all the bits in the dominance matrix are set, except + // for the root node. The root node is initialized to have itself + // as an immediate dominator. + for (int i = 0; i < size; i++) { + BitSet domVector = new BitSet(size); + + if (i == rootIndex) { + // Only root dominates root. + domVector.set(rootIndex); + } + else { + // Assume that all nodes dominate non-root node i. + domVector.set(0, size); + } + + domMatrix[i] = domVector; + } + + // Did the dominator bit vector array change? + boolean changed; + + do { + changed = false; + + // Fetch all nodes in pre-order. + Iterator nodes = preOrder.iterator(); + + // Compute the dominators of each node in the cfg. We iterate + // over every node in the cfg. The dominators of a node N are + // found by taking the intersection of the dominator bit vectors + // of each predacessor of N and unioning that with N. This + // process is repeated until no changes are made to any dominator + // bit vector. + + while (nodes.hasNext()) { + Node node = (Node) nodes.next(); + + int i = node.getPreOrderIndex(); + + if (i < 0 || i >= size) throw new RuntimeException("Unreachable node " + node); + + // We already know the dominators of the root, keep looking + if (i == rootIndex) { + continue; + } + + BitSet oldSet = domMatrix[i]; + + // domVector := intersection of dom(pred) for all pred(node). + BitSet domVector = new BitSet(size); + domVector.or(oldSet); + + + Collection preds = node.preds(); + + Iterator e = preds.iterator(); + + // Find the intersection of the dominators of node's + // predacessors. + while (e.hasNext()) { + Node pred = (Node) e.next(); + + int j = pred.getPreOrderIndex(); + if (j == -1) throw new RuntimeException("Unreachable node " + pred); + + domVector.and(domMatrix[j]); + } + + // Don't forget to account for the sink node if node is a + // leaf node. Appearantly, there are not edges between + // leaf nodes and the sink node! + preds = (Collection) snkPreds.get(node); + + if (preds != null) { + e = preds.iterator(); + + while (e.hasNext()) { + Node pred = (Node) e.next(); + + int j = pred.getPreOrderIndex(); + + domVector.and(domMatrix[j]); + } + } + + // Include yourself in your dominators?! + domVector.set(i); + + // If the set changed, set the changed bit. + if (!domVector.equals(oldSet)) { + changed = true; + domMatrix[i] = domVector; + } + } + } while (changed); + + // Once we have the predacessor bit vectors all squared away, we can + // determine which vertices dominate which vertices. + + // Initialize each node's (post)dominator parent and children + for (Node node : graph.getNodes()) { + node.setDomParent(null); + node.getDomChildren().clear(); + } + + // A node's immediate dominator is its closest dominator. So, we + // start with the dominators, dom(b), of a node, b. To find the + // imediate dominator of b, we remove all nodes from dom(b) that + // dominate any node in dom(b). + + for (Node node : graph.getNodes()) { + int i = node.getPreOrderIndex(); + + if (i < 0 || i >= size) throw new RuntimeException("Unreachable node " + node); + + if (i == rootIndex) { + continue; + } + + // Find the immediate dominator + // idom := dom(node) - dom(dom(node)) - node + BitSet domVector = domMatrix[i]; + + BitSet idom = new BitSet(size); + idom.or(domVector); + idom.clear(i); + + for (int j = 0; j < size; j++) { + if (i != j && domVector.get(j)) { + // idom = idom - (domMatrix[j] - {j}) + BitSet b = new BitSet(size); + // Complement of domMatrix[j]. + b.or(domMatrix[j]); b.flip(0, size); + b.set(j); + idom.and(b); + } + } + + Node parent = null; + + // A node should only have one immediate dominator. + for (int j = 0; j < size; j++) { + if (idom.get(j)) { + Node p = preOrder.get(j); + if (parent != null) + throw new RuntimeException(node + " has more than one immediate dominator: " + parent + " and " + p); + parent = p; + } + } + + if (parent == null) + throw new RuntimeException(node + " has 0 immediate dominators"); + + node.setDomParent(parent); + } + } +} diff --git a/src/main/java/com/j2js/cfg/Edge.java b/src/main/java/com/j2js/cfg/Edge.java new file mode 100644 index 0000000..6c961c3 --- /dev/null +++ b/src/main/java/com/j2js/cfg/Edge.java @@ -0,0 +1,78 @@ +/* + * Copyright 2005 by Wolfgang Kuehn + * Created on 12.11.2005 + */ +package com.j2js.cfg; + +/** + * @author wolfgang + */ +public class Edge { + + private Graph graph; + public Node source; + public Node target; + public EdgeType type; + private Node orgSource; + + Edge(Graph theGraph, Node theSource, Node theTarget) { + graph = theGraph; + source = theSource; + target = theTarget; + } + + public boolean equals(Object other) { + if (other == null || !(other instanceof Edge)) return false; + Edge otherEdge = (Edge) other; + return source.getId().equals(otherEdge.source.getId()) && target.getId().equals(otherEdge.target.getId()); + } + + /** + * Replace the target of this edge. + */ + public void reroot(Node newSource) { + source.outEdges.remove(this); + newSource.outEdges.add(this); + source = newSource; + } + + /** + * Replace the target of this edge. + */ + public void redirect(Node newTarget) { + target.inEdges.remove(this); + newTarget.inEdges.add(this); + target = newTarget; + } + + /** + * Returns true if this edge is a backward (i.e. loop) edge. + */ + public boolean isBackEdge() { + return target.isDomAncestor(source); + } + + public boolean isGlobal() { + return orgSource != null; + } + + public String toString() { + String s = getClass().getName(); + // Extract unqualified class name. + s = s.substring(s.lastIndexOf('.')+1); + return s + " " + source.getId() + " -> " + target.getId(); + } + + public Node getOrgSource() { + if (orgSource == null) { + return source; + } + return orgSource; + } + + public void setOrgSource(Node theOrgSource) { + orgSource = theOrgSource; + } + + +} diff --git a/src/main/java/com/j2js/cfg/EdgeCollections.java b/src/main/java/com/j2js/cfg/EdgeCollections.java new file mode 100644 index 0000000..3849ff8 --- /dev/null +++ b/src/main/java/com/j2js/cfg/EdgeCollections.java @@ -0,0 +1,17 @@ +package com.j2js.cfg; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public class EdgeCollections { + + public static Set getSources(Collection edges) { + HashSet sources = new HashSet(); + for (Edge edge : edges) { + sources.add(edge.source); + } + return sources; + } + +} diff --git a/src/main/java/com/j2js/cfg/EdgeType.java b/src/main/java/com/j2js/cfg/EdgeType.java new file mode 100644 index 0000000..99a7e9c --- /dev/null +++ b/src/main/java/com/j2js/cfg/EdgeType.java @@ -0,0 +1,17 @@ +package com.j2js.cfg; + +public class EdgeType { + public static EdgeType FINALLY = new EdgeType("Finally"); + public static EdgeType CATCH = new EdgeType("Catch"); + public static EdgeType TRYBODY = new EdgeType("TryBody"); + + private String name; + + private EdgeType(String theName) { + name = theName; + } + + public String toString() { + return name; + } +} diff --git a/src/main/java/com/j2js/cfg/Graph.java b/src/main/java/com/j2js/cfg/Graph.java new file mode 100644 index 0000000..e482505 --- /dev/null +++ b/src/main/java/com/j2js/cfg/Graph.java @@ -0,0 +1,286 @@ +package com.j2js.cfg; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.j2js.Log; +import com.j2js.cfg.Node; + +import com.j2js.dom.Block; +import com.j2js.dom.BooleanExpression; +import com.j2js.dom.BreakStatement; +import com.j2js.dom.IfStatement; + +public abstract class Graph { + + private Map nodes = new HashMap(); + + int nodeIdSequence = 0; + + Log logger = Log.getLogger(); + + public Graph() { + } + + public Node getNodeById(String id) { + return nodes.get(id); + } + + public Node createNode(Class nodeClass) { + return createNode(nodeClass, Integer.toString(nodeIdSequence++, 26)); + } + + public Node createNode(Class nodeClass, String id) { + Node node; + try { + Constructor constructor = nodeClass.getConstructor(new Class[]{Graph.class}); + node = (Node) constructor.newInstance(new Object[] {this}); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + node.id = id; + nodes.put(id, node); + return node; + } + + /** + * Returns true if node set A is contained in node set B. + */ + public boolean isContained(Set nodesA, Node[] nodesB) { + Set foo = new HashSet(Arrays.asList(nodesB)); + return foo.containsAll(nodesA); + } + + /** + * Redirects all inbound edges of a node to another node. + */ + public void replaceAsTarget(Node oldTarget, Node newTarget) { + for (Edge edge : new ArrayList(oldTarget.getInEdges())) { + edge.redirect(newTarget); + } + } + + public Edge removeEdge(Node source, Node target) { + Edge edge = getEdge(source, target); + return removeEdge(edge); + } + + public Edge removeEdge(Edge edge) { + edge.source.getOutEdges().remove(edge); + edge.target.getInEdges().remove(edge); + return edge; + } + +// public void replaceNodes(Node header, List nodes, Node newNode) { +// replaceNodes(header, (Node[]) nodes.toArray(new Node[nodes.size()]), newNode); +// } + + public String getEdgeId(Node source, Node target) { + return source.getId() + "->" + target.getId(); + } + + public void addIfElseEdge(Node source, Node ifTarget, Node elseTarget, BooleanExpression be) { + ConditionalEdge ifEdge = (ConditionalEdge) addEdge(source, ifTarget, ConditionalEdge.class); + ifEdge.setBooleanExpression(be); + ConditionalEdge elseEdge = (ConditionalEdge) addEdge(source, elseTarget, ConditionalEdge.class); + elseEdge.setBooleanExpression(be); + elseEdge.setNegate(true); + } + + public Edge addEdge(Node source, Node target) { + return addEdge(source, target, Edge.class); + } + + public Edge addEdge(Node source, Node target, Class clazz) { + Edge edge = getEdge(source, target); + if (edge != null) { + // TODO: Why not allow adding multiple edges? This is possible + // anyway through reroot or redirect! + throw new RuntimeException("Edge already exists"); + } + if (clazz.equals(Edge.class)) { + edge = new Edge(this, source, target); + } else if (clazz.equals(SwitchEdge.class)) { + edge = new SwitchEdge(this, source, target); + } else if (clazz.equals(ConditionalEdge.class)) { + edge = new ConditionalEdge(this, source, target); + } else { + throw new RuntimeException("Illegal edge class " + clazz); + } + source.addEdge(edge); + if (source != target) { + target.addEdge(edge); + } + return edge; + } + + public Edge getEdge(Node source, Node target) { + for (Edge edge : source.getOutEdges()) { + if (edge.target == target) return edge; + } + return null; + } + + public void removeNode(Node node) { + replaceNode(node, null); + } + + public Set removeOutEdges(Node node) { + Set outEdges = new HashSet(node.outEdges); + Iterator iter = outEdges.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + removeEdge(edge); + } + + return outEdges; + } + + /** + * Removes all in-edges to the specified node. + * + * @return the set of removed in-edges + */ + public Set removeInEdges(Node node) { + Set inEdges = new HashSet(node.inEdges); + Iterator iter = inEdges.iterator(); + while (iter.hasNext()) { + Edge edge = iter.next(); + removeEdge(edge); + } + + return inEdges; + } + + public Set removeSelfEdges(Node node) { + Set selfEdges = new HashSet(); + + for (Edge edge: new HashSet(node.outEdges)) { + if (edge.target != node) continue; + removeEdge(edge); + selfEdges.add(edge); + } + + return selfEdges; + } + + public void rerootGlobalOutEdges(Node node, Node newSource) { + Edge[] edges = node.getOutEdgesArray(); + for (int i=0; i(oldNode.getDomChildren())) { + child.setDomParent(newNode); + } + } + + if (oldNode.inEdges.size() > 0 || oldNode.outEdges.size() > 0) + throw new RuntimeException("Cannot replace node with edges"); + + oldNode.setDomParent(null); + } + + public Collection getNodes() { + return nodes.values(); + } + + public int size() { + return getNodes().size(); + } + + public Block reduceDumb() { + Block block = new Block(); + + for (Node node : getNodes()) { + block.appendChild(node.block); + + if (node.isBranch()) { + IfStatement ifStmt = new IfStatement(); + ConditionalEdge cEdge = node.getConditionalEdge(true); + ifStmt.setExpression(cEdge.getBooleanExpression().getExpression()); + ifStmt.setIfBlock(new Block()); + Block targetBlock = cEdge.target.block; + ifStmt.getIfBlock().appendChild(new BreakStatement(targetBlock)); + ifStmt.setElseBlock(new Block()); + targetBlock = node.getConditionalEdge(false).target.block; + ifStmt.getElseBlock().appendChild(new BreakStatement(targetBlock)); + block.appendChild(ifStmt); + } else { + for (Edge e : node.getOutEdges()) { + BreakStatement bStmt = new BreakStatement(e.target.block); + node.block.appendChild(bStmt); + } + } + } + return block; + } + + boolean isTarget(Node n, Set edgeSet) { + Iterator iter = edgeSet.iterator(); + while (iter.hasNext()) { + Edge e = (Edge) iter.next(); + if (n == e.target) return true; + } + return false; + } + + public void rollOut(Node node, Block targetBlock) { + if (node.trans != null) { + node.trans.rollOut(targetBlock); + } else { + targetBlock.appendChildren(node.block); + } + } + + public void dump(String msg) { + StringBuffer sb = new StringBuffer(); + sb.append(msg + " ...\n"); + for (Node node : getNodes()) { + sb.append(node.describe() + "\n"); + //dump(node.block, "Block"); + } + sb.append("... " + msg); + logger.debug(sb.toString()); + } +} diff --git a/src/main/java/com/j2js/cfg/Node.java b/src/main/java/com/j2js/cfg/Node.java new file mode 100644 index 0000000..4ba115e --- /dev/null +++ b/src/main/java/com/j2js/cfg/Node.java @@ -0,0 +1,334 @@ +/* + * Copyright 2005 by Wolfgang Kuehn + * Created on 12.11.2005 + */ +package com.j2js.cfg; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; + +import com.j2js.ASTNodeStack; +import com.j2js.cfg.transformation.Transformation; +import com.j2js.dom.Block; +import com.j2js.dom.Expression; +import com.j2js.dom.IfStatement; + +/** + * @author wolfgang + */ +public class Node { + + public class Reference { + public Node source; + public boolean isBackward = false; + } + + public static int NON_HEADER = 0; + public static int REDUCIBLE = 1; + public static int IRREDUCIBLE = 2; + + String id; + + Set inEdges = new LinkedHashSet(); + Set outEdges = new LinkedHashSet(); + Graph graph; + private int currentPc = -1; + private int initialPc = -1; + public ASTNodeStack stack = new ASTNodeStack(); + public Block block = new Block(); + public boolean closed = false; + + protected int preOrderIndex = -1; + + private Node domParent; // Block that (immediately) dominates this Block + private Set domChildren = new HashSet(); // Blocks that this Block dominates + + IfStatement ifStmt; + public Expression switchExpression; + + public Transformation trans; + public Collection jsrCallers = new HashSet(); + + public boolean isSwitchHeader = false; + + public Node(Graph theGraph, int pc) { + this(theGraph); + setInitialPc(pc); + } + + public Node(Graph theGraph) { + graph = theGraph; + } + + public int getComplexity() { + Node node = this; + int complexity = 0; + while (node.trans != null) { + complexity++; + node = node.trans.header; + } + return complexity; + } + + /** + * @return Returns the pc. + */ + public int getCurrentPc() { + return currentPc; + } + /** + * @param pc The pc to set. + */ + public void setCurrentPc(int pc) { + currentPc = pc; + } + + public void close() { + closed = true; + } + + public void addEdge(Edge e) { + if (e.source == this) { + if (!outEdges.add(e)) { + throw new RuntimeException("\n" + this + "\nalready bound to " + e); + } + } + + if (e.target == this) { + if (!inEdges.add(e)) { + throw new RuntimeException("" + this + " already bound to " + e); + } + } + } + + public String toString() { + String s = getClass().getName(); + // Same as getClass().getSimpleName() in JDK 5.0. + s = s.replaceFirst(".*\\.", ""); + + s += " " + id + "[" + initialPc + ", " + currentPc + "]"; + //if (preOrderIndex >= 0) s += " preIndex=" + preOrderIndex; + if (domParent != null) s += " dominated by " + domParent.id; + if (isLoopHeader()) s += " LH"; + return s; + } + + public String describe() { + String s = toString(); + Iterator iter = outEdges.iterator(); + while (iter.hasNext()) { + Edge e = (Edge) iter.next(); + s += "\n\t" + e; + } + return s; + } + + + /** + * @return Returns the inEdges. + */ + public Set getInEdges() { + return inEdges; + } + + public Edge getSelfEdge() { + Iterator iterator = inEdges.iterator(); + while (iterator.hasNext()) { + Edge edge = (Edge) iterator.next(); + if (edge.source == this) return edge; + } + return null; + } + +// public Set getGlobalInEdges() { +// HashSet set = new HashSet(); +// Iterator iterator = inEdges.iterator(); +// while (iterator.hasNext()) { +// Edge edge = (Edge) iterator.next(); +// if (edge.global) set.add(edge); +// } +// return set; +// } + +// public Set getForewardOutEdges() { +// HashSet set = new HashSet(); +// Iterator iterator = outEdges.iterator(); +// while (iterator.hasNext()) { +// Edge edge = (Edge) iterator.next(); +// if (!edge.isBackEdge()) set.add(edge); +// } +// return set; +// } + + /** + * @return Returns the outEdges. + */ + public Set getOutEdges() { + return outEdges; + } + + public Edge[] getOutEdgesArray() { + return outEdges.toArray(new Edge[outEdges.size()]); + } + + public Edge[] getInEdgesArray() { + return inEdges.toArray(new Edge[inEdges.size()]); + } + + public int getPreOrderIndex() { + return preOrderIndex; + } + + public void setPreOrderIndex(int thePreOrderIndex) { + preOrderIndex = thePreOrderIndex; + } + + public Set succs() { + Set list = new LinkedHashSet(); + Edge[] edges = getOutEdgesArray(); + for (int i=edges.length-1; i>=0; i--) { + list.add(edges[i].target); + } + return list; + } + + public Set preds() { + Set list = new LinkedHashSet(); + Iterator iter = inEdges.iterator(); + while (iter.hasNext()) { + Edge e = (Edge) iter.next(); + list.add(e.source); + } + return list; + } + + public Node getPred() { + int count = inEdges.size(); + if (count != 1) throw new RuntimeException("Requested unique predecessor, found " + count); + return inEdges.iterator().next().source; + } + + public Node getSucc() { + return getOutEdge().target; + } + + public Edge getLocalOutEdgeOrNull() { + Edge outEdge = null; + Iterator iter = outEdges.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + if (outEdge != null) new RuntimeException("Found multiple local out-edges"); + outEdge = edge; + } + return outEdge; + } + + public Edge getOutEdge() { + int count = outEdges.size(); + if (count != 1) throw new RuntimeException("Requested unique successor, found " + count); + return outEdges.iterator().next(); + } + + /** + * Return true if this node is equal to or dominates the specified node. + */ + public boolean isDomAncestor(Node node) { + do { + if (node == null) return false; + if (node == this) return true; + node = node.getDomParent(); + } while (true); + } + + public Set getDomChildren() { + return domChildren; + } + + public Node getDomChild() { + if (domChildren.size() != 1) throw new RuntimeException("Node must have single child"); + return getDomChildren().iterator().next(); + } + + public Node getDomParent() { + return domParent; + } + + public void setDomParent(Node newDomParent) { + // If this Block already had a dominator specified, remove + // it from its dominator's children. + if (domParent != null) { + domParent.domChildren.remove(this); + } + + domParent = newDomParent; + + // Add this Block to its new dominator's children. + if (domParent != null) { + domParent.domChildren.add(this); + } + } + + public boolean isBranch() { + Edge[] edges = getOutEdgesArray(); + if (edges.length != 2) return false; + if (edges[0] instanceof ConditionalEdge && edges[1] instanceof ConditionalEdge) return true; + if ((edges[0] instanceof ConditionalEdge) || (edges[1] instanceof ConditionalEdge)) + throw new RuntimeException("Node must not have mixed edges"); + return false; + } + + /** + * Returns either the true or false edge. + */ + public ConditionalEdge getConditionalEdge(boolean trueFalse) { + if (!isBranch()) throw new RuntimeException("Node must be a branch"); + Iterator iter = outEdges.iterator(); + Edge edge = iter.next(); + if (!trueFalse) edge = iter.next(); + return (ConditionalEdge) edge; + } + + public String getId() { + return id; + } + + public int getInitialPc() { + return initialPc; + } + + public Graph getGraph() { + return graph; + } + + public void setInitialPc(int theInitialPc) { + initialPc = theInitialPc; + currentPc = theInitialPc; + } + + public boolean isLoopHeader() { + Iterator iter = inEdges.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + if (edge.isBackEdge()) return true; + } + return false; + } + + public boolean hasSelfEdges() { + Iterator iter = outEdges.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + if (edge.target == this) return true; + } + return false; + } + +// public void replaceEdge(Edge oldEdge, Edge newEdge) { +// source.outEdges.remove(this); +// newSource.outEdges.add(this); +// source = newSource; +// } +} diff --git a/src/main/java/com/j2js/cfg/SwitchEdge.java b/src/main/java/com/j2js/cfg/SwitchEdge.java new file mode 100644 index 0000000..ce58a82 --- /dev/null +++ b/src/main/java/com/j2js/cfg/SwitchEdge.java @@ -0,0 +1,14 @@ +package com.j2js.cfg; + +import java.util.ArrayList; +import java.util.List; + +import com.j2js.dom.NumberLiteral; + +public class SwitchEdge extends Edge { + public List expressions = new ArrayList(); + + SwitchEdge(Graph graph, Node theSource, Node theTarget) { + super(graph, theSource, theTarget); + } +} diff --git a/src/main/java/com/j2js/cfg/TryHeaderNode.java b/src/main/java/com/j2js/cfg/TryHeaderNode.java new file mode 100644 index 0000000..e1d74d0 --- /dev/null +++ b/src/main/java/com/j2js/cfg/TryHeaderNode.java @@ -0,0 +1,74 @@ +package com.j2js.cfg; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.j2js.dom.TryStatement; + +public class TryHeaderNode extends Node { + + public TryStatement tryStmt; + + public TryHeaderNode(Graph theGraph) { + super(theGraph); + } + + public void setTryBody(Node theTryBody) { + Edge edge = graph.addEdge(this, theTryBody); + edge.type = EdgeType.TRYBODY; + } + + public void setFinallyNode(Node theFinallyNode) { + Edge edge = graph.addEdge(this, theFinallyNode); + edge.type = EdgeType.FINALLY; + //finallyNode = theFinallyNode; + } + + public void addCatchNode(Node node) { + Edge edge = graph.addEdge(this, node); + edge.type = EdgeType.CATCH; + //catchNodes.add(node); + } + + public Node getSuccessor() { + Iterator iter = outEdges.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + if (edge.type == null) return edge.target; + } + return null; + } + + public Node getTryBody() { + Iterator iter = outEdges.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + if (edge.type == EdgeType.TRYBODY) return edge.target; + } + throw new RuntimeException(); + } + + public Node getFinallyNode() { + Iterator iter = outEdges.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + if (edge.type == EdgeType.FINALLY) return edge.target; + } + return null; + } + + public List getCatchNodes() { + List catchNodes = new ArrayList(); + for (Edge edge : outEdges) { + if (edge.type == EdgeType.CATCH) catchNodes.add(edge.target); + } + + return catchNodes; + } + + public TryStatement getTryStatement() { + return tryStmt; + } + +} diff --git a/src/main/java/com/j2js/cfg/WrapperNode.java b/src/main/java/com/j2js/cfg/WrapperNode.java new file mode 100644 index 0000000..90f7ef0 --- /dev/null +++ b/src/main/java/com/j2js/cfg/WrapperNode.java @@ -0,0 +1,11 @@ +package com.j2js.cfg; + +public class WrapperNode extends Node{ + + Node node; + + public WrapperNode(Graph theGraph) { + super(theGraph); + } + +} diff --git a/src/main/java/com/j2js/cfg/transformation/Loop.java b/src/main/java/com/j2js/cfg/transformation/Loop.java new file mode 100644 index 0000000..fa298d3 --- /dev/null +++ b/src/main/java/com/j2js/cfg/transformation/Loop.java @@ -0,0 +1,47 @@ +package com.j2js.cfg.transformation; + +import java.util.Iterator; +import java.util.Set; + +import com.j2js.cfg.Edge; +import com.j2js.dom.Block; +import com.j2js.dom.BooleanLiteral; +import com.j2js.dom.WhileStatement; + + +public class Loop extends Transformation { + + private Set selfEdges; + + public boolean applies_() { + return header.hasSelfEdges(); + } + + public void apply_() { + // Remove self edges. + selfEdges = graph.removeSelfEdges(header); + } + + void rollOut_(Block block) { + WhileStatement loopStmt = new WhileStatement(); + Block loopBody = new Block(); + loopStmt.setBlock(loopBody); + loopStmt.setExpression(new BooleanLiteral(true)); + + block.appendChild(loopStmt); + + Iterator iter = selfEdges.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + if (!edge.isGlobal()) continue; + loopStmt.isLabeled(); + produceJump(edge, loopStmt); + } + + graph.rollOut(header, loopBody); + } + + public String toString() { + return super.toString() + "(" + header + ")"; + } +} diff --git a/src/main/java/com/j2js/cfg/transformation/Merge.java b/src/main/java/com/j2js/cfg/transformation/Merge.java new file mode 100644 index 0000000..27f0068 --- /dev/null +++ b/src/main/java/com/j2js/cfg/transformation/Merge.java @@ -0,0 +1,77 @@ +package com.j2js.cfg.transformation; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import com.j2js.cfg.ControlFlowGraph; +import com.j2js.cfg.Edge; +import com.j2js.cfg.EdgeCollections; +import com.j2js.cfg.Node; +import com.j2js.dom.Block; + +/** + * @author wolfgang + */ +public class Merge extends Transformation { + + private Node tail; + private Set inEdgesForTail; + + public Merge() { + } + + public Merge(ControlFlowGraph theGraph) { + graph = theGraph; + } + + public boolean applies_() { + HashSet headerSet = new HashSet(); + headerSet.add(header); + + for (Node child : header.getDomChildren()) { + if (EdgeCollections.getSources(child.getInEdges()).equals(headerSet)) { + tail = child; + return true; + } + } + + return false; + } + + public void apply_() { + // Remove all in-edges to Tail. + inEdgesForTail = graph.removeInEdges(tail); + + // Reroot all out-edges from Tail. + graph.rerootOutEdges(tail, newNode, false); + + //Remove Tail. + graph.removeNode(tail); + } + + void rollOut_(Block block) { + Block labeledBlock = block; + + Iterator iter = inEdgesForTail.iterator(); + while (iter.hasNext()) { + Edge edge = (Edge) iter.next(); + if (!edge.isGlobal()) continue; + + if (labeledBlock == block) { + labeledBlock = new Block(); + block.appendChild(labeledBlock); + } + + produceJump(edge, labeledBlock); + } + + graph.rollOut(header, labeledBlock); + graph.rollOut(tail, block); + block.appendChildren(newNode.block); + } + + public String toString() { + return super.toString() + "(" + header + ", " + tail + ")"; + } +} diff --git a/src/main/java/com/j2js/cfg/transformation/Switch.java b/src/main/java/com/j2js/cfg/transformation/Switch.java new file mode 100644 index 0000000..d581bd3 --- /dev/null +++ b/src/main/java/com/j2js/cfg/transformation/Switch.java @@ -0,0 +1,83 @@ +package com.j2js.cfg.transformation; + +import java.util.ArrayList; +import java.util.List; + +import com.j2js.cfg.Edge; +import com.j2js.cfg.Node; +import com.j2js.cfg.SwitchEdge; +import com.j2js.dom.Block; +import com.j2js.dom.NumberLiteral; +import com.j2js.dom.SwitchCase; +import com.j2js.dom.SwitchStatement; + +/** + */ +public class Switch extends Transformation { + + private List caseGroups = new ArrayList(); + private List> caseGroupExpressions = new ArrayList>(); + + public boolean applies_() { + return header.isSwitchHeader; + } + + private void removeFallThroughEdgesl() { + Edge prevPotentialFallThroughEdge = null; + + for (Edge e : header.getOutEdges()) { + if (!(e instanceof SwitchEdge)) continue; + + SwitchEdge edge = (SwitchEdge) e; + Node caseGroup = edge.target; + + if (prevPotentialFallThroughEdge != null && prevPotentialFallThroughEdge.target == caseGroup) { + // This is a fall through edge. + graph.removeEdge(prevPotentialFallThroughEdge); + } + + prevPotentialFallThroughEdge = caseGroup.getLocalOutEdgeOrNull(); + } + } + + void apply_() { + removeFallThroughEdgesl(); + + for (Edge e : new ArrayList(header.getOutEdges())) { + if (!(e instanceof SwitchEdge)) continue; + + SwitchEdge edge = (SwitchEdge) e; + Node caseGroup = edge.target; + caseGroups.add(caseGroup); + caseGroupExpressions.add(edge.expressions); + graph.rerootOutEdges(caseGroup, newNode, true); + graph.removeOutEdges(caseGroup); + graph.removeInEdges(caseGroup); + graph.removeNode(caseGroup); + } + } + + void rollOut_(Block block) { + SwitchStatement switchStmt = new SwitchStatement(); + switchStmt.setExpression(header.switchExpression); + + for (int i=0; i " + newNode); + return newNode; + } + + public boolean applies(Node node) { + graph = (ControlFlowGraph) node.getGraph(); + header = node; + return applies_(); + } + + abstract boolean applies_(); + abstract void apply_(); + abstract void rollOut_(Block block); + + public void rollOut(Block block) { + rollOut_(block); + block.appendChildren(newNode.block); + } + + void produceJump(Edge edge, Block labeledBlock) { + Node referer = edge.getOrgSource(); + Block breakBlock; + if (edge instanceof ConditionalEdge) { + ConditionalEdge condEdge = (ConditionalEdge) edge; + BooleanExpression condExpr = condEdge.getBooleanExpression(); + Expression expr = Optimizer.simplifyBooleanExpression(condExpr.getExpression(), condEdge.isNegate()); + IfStatement ifStmt = new IfStatement(); + ifStmt.setExpression(expr); + referer.block.appendChild(ifStmt); + Block ifBlock = new Block(); + ifStmt.setIfBlock(ifBlock); + breakBlock = ifBlock; + } else { + breakBlock = referer.block; + } + + if (edge.isBackEdge()) { + breakBlock.appendChild(new ContinueStatement(labeledBlock)); + } else { + breakBlock.appendChild(new BreakStatement(labeledBlock)); + } + } + + public String toString() { + return getClass().getName(); + } +} diff --git a/src/main/java/com/j2js/cfg/transformation/Try.java b/src/main/java/com/j2js/cfg/transformation/Try.java new file mode 100644 index 0000000..4ad7779 --- /dev/null +++ b/src/main/java/com/j2js/cfg/transformation/Try.java @@ -0,0 +1,77 @@ +package com.j2js.cfg.transformation; + +import java.util.Iterator; +import java.util.List; + +import com.j2js.cfg.Node; +import com.j2js.cfg.TryHeaderNode; +import com.j2js.dom.Block; +import com.j2js.dom.CatchClause; +import com.j2js.dom.TryStatement; + +public class Try extends Transformation { + + private Node tryBodyNode; + private List catchNodes; + private Node finallyNode; + + boolean applies_() { + return header instanceof TryHeaderNode; + } + + void apply_() { + TryHeaderNode head = (TryHeaderNode) header; + catchNodes = head.getCatchNodes(); + + for (Node catchNode : head.getCatchNodes()) { + graph.rerootOutEdges(catchNode, newNode, false); + graph.removeInEdges(catchNode); + graph.removeNode(catchNode); + } + + tryBodyNode = head.getTryBody(); + graph.rerootOutEdges(tryBodyNode, newNode, false); + graph.removeInEdges(tryBodyNode); + graph.removeNode(tryBodyNode); + + finallyNode = head.getFinallyNode(); + if (finallyNode != null) { + Block b = finallyNode.block; + // Remove return address. + b.removeChild(b.getFirstChild()); + // Remove return statement. + b.removeChild(b.getLastChild()); + graph.rerootOutEdges(finallyNode, newNode, false); + graph.removeInEdges(finallyNode); + graph.removeNode(finallyNode); + } + + } + + void rollOut_(Block block) { + TryHeaderNode head = (TryHeaderNode) header; + + TryStatement stmt = head.getTryStatement(); + block.appendChild(stmt); + + graph.rollOut(tryBodyNode, stmt.getTryBlock()); + + if (finallyNode != null) { + stmt.setFinallyBlock(new Block()); + graph.rollOut(finallyNode, stmt.getFinallyBlock()); + } + + CatchClause cc = (CatchClause) stmt.getCatchStatements().getFirstChild(); + Iterator iter = catchNodes.iterator(); + while (iter.hasNext()) { + Node catchNode = (Node) iter.next(); + graph.rollOut(catchNode, cc); + cc = (CatchClause) cc.getNextSibling(); + } + } + + public String toString() { + return super.toString() + "(" + header + ")"; + } + +} diff --git a/src/main/java/com/j2js/dom/ASTNode.java b/src/main/java/com/j2js/dom/ASTNode.java new file mode 100644 index 0000000..630a1b9 --- /dev/null +++ b/src/main/java/com/j2js/dom/ASTNode.java @@ -0,0 +1,200 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/* + * Statement.java + * + * Created on 21. Mai 2004, 11:45 + */ + +/** + * + * @author kuehn + */ +public class ASTNode { + + public static final int BEFORE = 0; + public static final int AFTER = 1; + public static final int SAME = 2; + public static final int CONTAINS = 3; + public static final int ISCONTAINED = 4; + + int beginIndex = Integer.MAX_VALUE; + int endIndex = Integer.MIN_VALUE; + private ASTNode parent = null; + private ASTNode previousSibling = null; + private ASTNode nextSibling = null; + + private int stackDelta = 0; + + public ASTNode() { + super(); + } + + public ASTNode(int theBeginIndex, int theEndIndex) { + setRange(theBeginIndex, theEndIndex); + } + + /** + * @return Returns the stackDelta. + */ + public int getStackDelta() { + return stackDelta; + } + + /** + * @param theStackDelta The stackDelta to set. + */ + public void setStackDelta(int theStackDelta) { + stackDelta = theStackDelta; + } + + public void widen(ASTNode node) { + leftWiden(node.beginIndex); + rightWiden(node.endIndex); + } + + public void leftWiden(int targetBeginIndex) { + if (targetBeginIndex < beginIndex) beginIndex = targetBeginIndex; + } + + public void rightWiden(int targetEndIndex) { + if (targetEndIndex > endIndex) endIndex = targetEndIndex; + } + + public void setRange(int theBeginIndex, int theEndIndex) { + setBeginIndex(theBeginIndex); + setEndIndex(theEndIndex); + } + +// private void checkRange() { +// if (endIndex!=Integer.MIN_VALUE && beginIndex!=Integer.MAX_VALUE && endIndex" + endIndex); +// } +// } + + /** Getter for property beginIndex. + * @return Value of property beginIndex. + */ + public int getBeginIndex() { + return beginIndex; + } + + /** Setter for property beginIndex. + * @param theBeginIndex New value of property beginIndex. + */ + public void setBeginIndex(int theBeginIndex) { + beginIndex = theBeginIndex; + } + + /** Getter for property endIndex. + * @return Value of property endIndex. + */ + public int getEndIndex() { + return endIndex; + } + + /** Setter for property endIndex. + * @param endIndex New value of property endIndex. + */ + public void setEndIndex(int theEndIndex) { + endIndex = theEndIndex; + } + + public boolean isRightSiblingOf(ASTNode leftSibling) { + for (ASTNode node=this; node!=null; node=node.getPreviousSibling()) { + if (node == leftSibling) { + return true; + } + } + return false; + } + + public ASTNode rightMostSibling() { + for (ASTNode node=this;;) { + if (node.getNextSibling() == null) { + return node; + } + node = node.getNextSibling(); + } + } + + public boolean isAncestorOf(ASTNode node) { + do { + node = node.getParentNode(); + if (node == this) { + return true; + } + } while (node != null); + + return false; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + if (getBeginIndex() != Integer.MAX_VALUE) { + sb.append("["); + sb.append(getBeginIndex()); + sb.append(", "); + sb.append(getEndIndex()); + sb.append("]"); + } + return sb.toString(); + } + + /** + * @return Returns the parent. + */ + public ASTNode getParentNode() { + return parent; + } + + public Block getParentBlock() { + return (Block) parent; + } + + public Block getLogicalParentBlock() { + if (parent != null && parent.parent instanceof IfStatement) { + return (Block) parent.parent; + } + return (Block) parent; + } + + /** + * @param theParent The parent to set. + */ + public void setParentNode(ASTNode theParent) { + parent = theParent; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the nextSibling. + */ + public ASTNode getNextSibling() { + return nextSibling; + } + /** + * @param theNextSibling The nextSibling to set. + */ + public void setNextSibling(ASTNode theNextSibling) { + nextSibling = theNextSibling; + } + /** + * @return Returns the previousSibling. + */ + public ASTNode getPreviousSibling() { + return previousSibling; + } + /** + * @param thePreviousSibling The previousSibling to set. + */ + public void setPreviousSibling(ASTNode thePreviousSibling) { + previousSibling = thePreviousSibling; + } +} diff --git a/src/main/java/com/j2js/dom/ArrayAccess.java b/src/main/java/com/j2js/dom/ArrayAccess.java new file mode 100644 index 0000000..8f1aef2 --- /dev/null +++ b/src/main/java/com/j2js/dom/ArrayAccess.java @@ -0,0 +1,54 @@ +/* + * Created on Oct 31, 2004 + */ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class ArrayAccess extends Expression implements Assignable { + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public boolean isSame(Object obj) { + if (!(obj instanceof ArrayAccess)) return false; + ArrayAccess other = (ArrayAccess) obj; + if (getArray() instanceof VariableBinding && other.getArray() instanceof VariableBinding) { + VariableBinding vba = (VariableBinding) getArray(); + VariableBinding vbb = (VariableBinding) other.getArray(); + return vba.getVariableDeclaration() == vbb.getVariableDeclaration(); + } + return false; + } + + /** + * @return Returns the array. + */ + public Expression getArray() { + return (Expression) getChildAt(0); + } + /** + * @param array The array to set. + */ + public void setArray(Expression array) { + widen(array); + setChildAt(0, array); + } + /** + * @return Returns the index. + */ + public Expression getIndex() { + return (Expression) getChildAt(1); + } + /** + * @param index The index to set. + */ + public void setIndex(Expression index) { + widen(index); + setChildAt(1, index); + } +} diff --git a/src/main/java/com/j2js/dom/ArrayCreation.java b/src/main/java/com/j2js/dom/ArrayCreation.java new file mode 100644 index 0000000..35a881d --- /dev/null +++ b/src/main/java/com/j2js/dom/ArrayCreation.java @@ -0,0 +1,50 @@ +package com.j2js.dom; + +import java.util.List; + +import org.apache.bcel.generic.Type; + +import com.j2js.assembly.Project; +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class ArrayCreation extends Expression { + + private List dimensions; + private ArrayInitializer initializer; + + public ArrayCreation(MethodDeclaration methodDecl, Type theType, List theDimensions) { + type = theType; + dimensions = theDimensions; + for (ASTNode dimension : dimensions) { + this.widen(dimension); + } + Project.getSingleton().addReference(methodDecl, this); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the initializer. + */ + public ArrayInitializer getInitializer() { + return initializer; + } + /** + * @param theInitializer The initializer to set. + */ + public void setInitializer(ArrayInitializer theInitializer) { + initializer = theInitializer; + } + /** + * @return Returns the dimensions. + */ + public List getDimensions() { + return dimensions; + } + +} diff --git a/src/main/java/com/j2js/dom/ArrayInitializer.java b/src/main/java/com/j2js/dom/ArrayInitializer.java new file mode 100644 index 0000000..b151a07 --- /dev/null +++ b/src/main/java/com/j2js/dom/ArrayInitializer.java @@ -0,0 +1,24 @@ +package com.j2js.dom; + +import java.util.List; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class ArrayInitializer extends Expression { + + private List expressions = new java.util.ArrayList(); + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the expressions. + */ + public List getExpressions() { + return expressions; + } +} diff --git a/src/main/java/com/j2js/dom/Assignable.java b/src/main/java/com/j2js/dom/Assignable.java new file mode 100644 index 0000000..a60a0ba --- /dev/null +++ b/src/main/java/com/j2js/dom/Assignable.java @@ -0,0 +1,17 @@ +/* + * Copyright 2005 by Wolfgang Kuehn + * Created on 16.10.2005 + */ +package com.j2js.dom; + +/** + * Tagging interface for all node types which are legal assignment targets. + */ +public interface Assignable { + + /** + * Returns true if the specified Assignable corresponds to this Assignable. + */ + public boolean isSame(Object obj); + +} diff --git a/src/main/java/com/j2js/dom/Assignment.java b/src/main/java/com/j2js/dom/Assignment.java new file mode 100644 index 0000000..df54d30 --- /dev/null +++ b/src/main/java/com/j2js/dom/Assignment.java @@ -0,0 +1,96 @@ +package com.j2js.dom; + +import java.util.HashMap; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author kuehn + */ +public class Assignment extends Expression { + + static public class Operator { + + static private HashMap opsByToken = new HashMap(); + + static public Operator lookup(String token) { + return opsByToken.get(token); + } + + static public Operator ASSIGN = new Operator("="); + static public Operator PLUS_ASSIGN = new Operator("+="); + static public Operator MINUS_ASSIGN = new Operator("-="); + static public Operator TIMES_ASSIGN = new Operator("*="); + static public Operator DIVIDE_ASSIGN = new Operator("/="); + static public Operator BIT_AND_ASSIGN = new Operator("&="); + static public Operator BIT_OR_ASSIGN = new Operator("|="); + static public Operator BIT_XOR_ASSIGN = new Operator("^="); + static public Operator REMAINDER_ASSIGN = new Operator("%="); + static public Operator LEFT_SHIFT_ASSIGN = new Operator("<<="); + static public Operator RIGHT_SHIFT_SIGNED_ASSIGN = new Operator(">>="); + static public Operator RIGHT_SHIFT_UNSIGNED_ASSIGN = new Operator(">>>="); + + private String token; + + Operator(String theToken) { + token = theToken; + opsByToken.put(theToken, this); + } + + public String toString() { + return token; + } + } + + private Operator operator; + + public Assignment(Operator theOperator) { + super(); + operator = theOperator; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @param rightHandSide The rightHandSide to set. + */ + public void setRightHandSide(Expression rightHandSide) { + widen(rightHandSide); + setChildAt(1, rightHandSide); + } + + /** + * @return Returns the rightHandSide. + */ + public Expression getRightHandSide() { + return (Expression) getChildAt(1); + } + + /** + * @param leftHandSide The leftHandSide to set. + */ + public void setLeftHandSide(Expression leftHandSide) { + setChildAt(0, leftHandSide); + } + + /** + * @return Returns the leftHandSide. + */ + public Expression getLeftHandSide() { + return (Expression) getChildAt(0); + } + /** + * @return Returns the operator. + */ + public Operator getOperator() { + return operator; + } + /** + * @param theOerator The operator to set. + */ + public void setOperator(Operator theOperator) { + operator = theOperator; + } +} diff --git a/src/main/java/com/j2js/dom/Block.java b/src/main/java/com/j2js/dom/Block.java new file mode 100644 index 0000000..cd68d02 --- /dev/null +++ b/src/main/java/com/j2js/dom/Block.java @@ -0,0 +1,356 @@ +package com.j2js.dom; + +import com.j2js.Log; +import com.j2js.visitors.AbstractVisitor; +import org.w3c.dom.DOMException; + +/* + * Block.java + * + * Created on 21. Mai 2004, 11:38 + */ +public class Block extends ASTNode { + + public static int TAG = 0; + + private String label; + + private ASTNode firstChild = null; + private ASTNode lastChild = null; + private int childCount = 0; + + public Block() { + super(); + } + + public Block(int theBeginIndex) { + setBeginIndex(theBeginIndex); + } + + public Block(int theBeginIndex, int theEndIndex) { + this(theBeginIndex); + setRange(theBeginIndex, theEndIndex); + } + +// public Block getFooBlock() { +// Block block = this; +// while (block!=null) { +// if (!block.getClass().equals(Block.class)) { +// return block; +// } +// block = block.getParentBlock(); +// } +// return this; +// } + + public int getTargetPc() { + if (lastChild instanceof Jump) { + return ((Jump) lastChild).getTargetIndex(); + } + return Integer.MAX_VALUE; + } + + public int getTargetIndex() { + return beginIndex; + } + + public void setBeginIndex(int theBeginIndex) { + super.setBeginIndex(theBeginIndex); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public void appendChildren(ASTNode begin, ASTNode end) { + if (begin == null || end == null) { + throw new RuntimeException("Illegal null parameters"); + } + if (begin.getParentBlock() != null) + (begin.getParentBlock()).removeChildren(begin, end); + + if (firstChild == null) { + setFirstChildInternal(begin); + } else { + ASTNode prev = getLastChild(); + prev.setNextSibling(begin); + begin.setPreviousSibling(prev); + } + setLastChildInternal(end); + + ASTNode node = begin; + while (node != null) { + node.setParentNode(this); + childCount++; + if (node == end) break; + node = node.getNextSibling(); + } + } + + /** + * Appends all children of the specified block to this block. + * @param sourceBlock + */ + public void appendChildren(Block sourceBlock) { + if (sourceBlock.getChildCount() > 0) { + appendChildren(sourceBlock.getFirstChild(), sourceBlock.getLastChild()); + } + } + + /** + * Sets the specified node at the index. Returns the replaced node, or null if the index + * was equal to the cild count. + */ + public ASTNode setChildAt(int index, ASTNode newChild) { + if (index == childCount) { + appendChild(newChild); + return null; + } else if (index < 0 || index > childCount) { + throw new RuntimeException("Index " + index + " out of range [0, " + childCount + "]"); + } + + return replaceChild(newChild, getChildAt(index)); + } + + public ASTNode getChildAt(int index) { + if (childCount == 0) { + throw new RuntimeException("Requested child at index " + index + ", but block has no children"); + } + if (index < 0 || index >= childCount) { + throw new RuntimeException("Index " + index + " out of range [0, " + (childCount-1) + "]"); + } + + if (index == childCount-1) { + return getLastChild(); + } + + ASTNode node = getFirstChild(); + int i = 0; + while (i < index) { + i++; + node = node.getNextSibling(); + } + + return node; + } + + public ASTNode appendChild(ASTNode newChild) { + Log.getLogger().debug("Appending " + newChild + " to " + this); + + unlink(newChild); + + if (firstChild == null) { + newChild.setPreviousSibling(null); + setFirstChildInternal(newChild); + } else { + ASTNode prev = getLastChild(); + prev.setNextSibling(newChild); + newChild.setPreviousSibling(prev); + } + setLastChildInternal(newChild); + newChild.setParentNode(this); + childCount++; + + return newChild; + } + + public ASTNode replaceChild(ASTNode newChild, ASTNode oldChild) { + Log.getLogger().debug("Replacing " + oldChild + " by " + newChild + " in " + this); + if (oldChild.getParentNode() != this) { + throw new DOMException(DOMException.NOT_FOUND_ERR, "Node " + oldChild + " is not a child of " + this); + } + unlink(newChild); + if (oldChild.getPreviousSibling() != null) { + oldChild.getPreviousSibling().setNextSibling(newChild); + } + if (oldChild.getNextSibling() != null) { + oldChild.getNextSibling().setPreviousSibling(newChild); + } + newChild.setPreviousSibling(oldChild.getPreviousSibling()); + newChild.setNextSibling(oldChild.getNextSibling()); + newChild.setParentNode(this); + if (getFirstChild() == oldChild) { + setFirstChildInternal(newChild); + } + if (getLastChild() == oldChild) { + setLastChildInternal(newChild); + } + oldChild.setPreviousSibling(null); + oldChild.setNextSibling(null); + oldChild.setParentNode(null); + return oldChild; + } + + public ASTNode removeChild(ASTNode oldChild) { + Log.getLogger().debug("Removing " + oldChild + " from " + this); + removeChildren(oldChild, oldChild); + + oldChild.setPreviousSibling(null); + oldChild.setNextSibling(null); + return oldChild; + } + + /** + * Removes all children from begin to end inclusively. + */ + private void removeChildren(ASTNode begin, ASTNode end) { + if (begin == null || end == null) throw new RuntimeException("Illegal null parameters"); + ASTNode node = begin; + while (node!= null) { + if (node.getParentNode() != this) { + throw new DOMException(DOMException.NOT_FOUND_ERR, "Node " + node + " is not a child of " + this); + } + node.setParentNode(null); + childCount--; + if (node == end) break; + node = node.getNextSibling(); + } + + + if (node != end) { + throw new RuntimeException("Node " + end + " is not a right-sibling of " + begin); + } + + if (begin.getPreviousSibling() != null) { + begin.getPreviousSibling().setNextSibling(end.getNextSibling()); + } + if (end.getNextSibling() != null) { + end.getNextSibling().setPreviousSibling(begin.getPreviousSibling()); + } + if (getFirstChild() == begin) { + setFirstChildInternal(end.getNextSibling()); + } + if (getLastChild() == end) { + setLastChildInternal(begin.getPreviousSibling()); + } + } + + public void removeChildren() { + if (getFirstChild() != null) { + removeChildren(getFirstChild(), getLastChild()); + } + } + + public int getChildCount() { + return childCount; + } + + /** + * Inserts the node newChild after the existing child node refChild. + * If refChild is null, insert newChild at the beginning of the list of children. + * + * @param newChild The node to insert + * @param refChild The reference node, i.e., the node before which the new node must be inserted + * @return + */ +// public ASTNode insertAfter(ASTNode newChild, ASTNode refChild) { +// if (refChild == null) { +// refChild = getFirstChild(); +// } else { +// refChild = refChild.getNextSibling(); +// } +// return insertBefore(newChild, refChild); +// } + + /** + * Inserts the node newChild before the existing child node refChild. + * If refChild is null, insert newChild at the end of the list of children. + * + * @param newChild The node to insert + * @param refChild The reference node, i.e., the node before which the new node must be inserted + * @return + */ + public ASTNode insertBefore(ASTNode newChild, ASTNode refChild) { + if (refChild == null) { + return appendChild(newChild); + } + + Log.getLogger().debug("Inserting " + newChild + " before " + refChild + " in " + this); + + if (refChild.getParentNode() != this) { + throw new DOMException(DOMException.NOT_FOUND_ERR, "Reference " + refChild + " is not a child of " + this); + } + + unlink(newChild); + + if (refChild.getPreviousSibling() != null) { + refChild.getPreviousSibling().setNextSibling(newChild); + } + newChild.setPreviousSibling(refChild.getPreviousSibling()); + newChild.setNextSibling(refChild); + newChild.setParentNode(this); + childCount++; + + refChild.setPreviousSibling(newChild); + + if (getFirstChild() == refChild) { + setFirstChildInternal(newChild); + } + + return newChild; + } + + public void addStatements(java.util.List statements) { + for (int i=0; i "; + if (target != null) { + Exception e = new Exception(); + if (target == this) { + s += "self"; + } else if (e.getStackTrace().length>20) { + s += "..."; + } else { + s += "" + target.toString(); + } + } else { + s += "null"; + } + return s; + } + /** + * @return Returns the target. + */ + public ASTNode getTarget() { + return target; + } + /** + * @param theTarget The target to set. + */ + public void setTarget(ASTNode theTarget) { + target = theTarget; + if (theTarget != null) targetIndex = theTarget.getBeginIndex(); + } +} diff --git a/src/main/java/com/j2js/dom/BreakStatement.java b/src/main/java/com/j2js/dom/BreakStatement.java new file mode 100644 index 0000000..d9b4c46 --- /dev/null +++ b/src/main/java/com/j2js/dom/BreakStatement.java @@ -0,0 +1,19 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +public class BreakStatement extends LabeledJump { + + public BreakStatement(String theLabel) { + super(theLabel); + } + + public BreakStatement(Block block) { + super(block); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + +} diff --git a/src/main/java/com/j2js/dom/CastExpression.java b/src/main/java/com/j2js/dom/CastExpression.java new file mode 100644 index 0000000..16afe3b --- /dev/null +++ b/src/main/java/com/j2js/dom/CastExpression.java @@ -0,0 +1,31 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author kuehn + */ +public class CastExpression extends Expression { + + private Expression expression; + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @param theExpression The expression to set. + */ + public void setExpression(Expression theExpression) { + widen(theExpression); + expression = theExpression; + } + + /** + * @return Returns the expression. + */ + public Expression getExpression() { + return expression; + } + +} diff --git a/src/main/java/com/j2js/dom/CatchClause.java b/src/main/java/com/j2js/dom/CatchClause.java new file mode 100644 index 0000000..963857d --- /dev/null +++ b/src/main/java/com/j2js/dom/CatchClause.java @@ -0,0 +1,45 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + + +/* + * CatchStatement.java + * + * Created on 22. Mai 2004, 22:49 + */ + +/** + * + * @author kuehn + */ +public class CatchClause extends Block { + + private VariableDeclaration exception; + + /** Creates a new instance of CatchStatement */ + //public CatchStatement() { + //} + + public CatchClause(int theBeginIndex) { + super(theBeginIndex); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the exception. + */ + public VariableDeclaration getException() { + return exception; + } + + /** + * @param theException The exception to set. + */ + public void setException(VariableDeclaration theException) { + exception = theException; + } +} diff --git a/src/main/java/com/j2js/dom/ClassInstanceCreation.java b/src/main/java/com/j2js/dom/ClassInstanceCreation.java new file mode 100644 index 0000000..1529fa4 --- /dev/null +++ b/src/main/java/com/j2js/dom/ClassInstanceCreation.java @@ -0,0 +1,24 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.ObjectType; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class ClassInstanceCreation extends MethodInvocation { + + public ClassInstanceCreation(ObjectType theType) { + type = theType; + } + + public ClassInstanceCreation(MethodDeclaration methodDecl, MethodBinding methodBinding) { + super(methodDecl, methodBinding); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + +} diff --git a/src/main/java/com/j2js/dom/ClassLiteral.java b/src/main/java/com/j2js/dom/ClassLiteral.java new file mode 100644 index 0000000..29221aa --- /dev/null +++ b/src/main/java/com/j2js/dom/ClassLiteral.java @@ -0,0 +1,22 @@ +package com.j2js.dom; + +import com.j2js.assembly.Signature; +import com.j2js.visitors.AbstractVisitor; + +public class ClassLiteral extends Expression { + + private Signature signature; + + public ClassLiteral(Signature theSignature) { + signature = theSignature; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public Signature getSignature() { + return signature; + } + +} diff --git a/src/main/java/com/j2js/dom/ConditionalBranch.java b/src/main/java/com/j2js/dom/ConditionalBranch.java new file mode 100644 index 0000000..b747329 --- /dev/null +++ b/src/main/java/com/j2js/dom/ConditionalBranch.java @@ -0,0 +1,41 @@ +/* + * Created on Feb 13, 2005 + */ +package com.j2js.dom; + +/** + * Copyright by Wolfgang Kuehn 2005 + */ +public class ConditionalBranch extends Branch { + + private Expression expression; + + public ConditionalBranch(int targetIndex) { + super(targetIndex); + } + + /** + * This constructor is for testing purposes only!! + */ + public ConditionalBranch(int theBeginIndex, int theEndIndex, int targetIndex) { + super(targetIndex); + setExpression(new Expression(theBeginIndex, theEndIndex)); + } + + /** + * @return Returns the condition. + */ + public Expression getExpression() { + return expression; + } + + /** + * @param condition The condition to set. + */ + public void setExpression(Expression theExpression) { + expression = theExpression; + widen(theExpression); + appendChild(theExpression); + } + +} diff --git a/src/main/java/com/j2js/dom/ConditionalExpression.java b/src/main/java/com/j2js/dom/ConditionalExpression.java new file mode 100644 index 0000000..175d1c9 --- /dev/null +++ b/src/main/java/com/j2js/dom/ConditionalExpression.java @@ -0,0 +1,61 @@ +/* + * Created on Sep 10, 2005 + */ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class ConditionalExpression extends Expression { + + private Expression conditionExpression = null; + private Expression thenExpression = null; + private Expression elseExpression = null; + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the conditionExpression. + */ + public Expression getConditionExpression() { + return conditionExpression; + } + /** + * @param theConditionExpression The conditionExpression to set. + */ + public void setConditionExpression(Expression theConditionExpression) { + widen(theConditionExpression); + conditionExpression = theConditionExpression; + } + /** + * @return Returns the elseExpression. + */ + public Expression getElseExpression() { + return elseExpression; + } + /** + * @param theElseExpression The elseExpression to set. + */ + public void setElseExpression(Expression theElseExpression) { + widen(theElseExpression); + elseExpression = theElseExpression; + } + /** + * @return Returns the thenExpression. + */ + public Expression getThenExpression() { + return thenExpression; + } + /** + * @param theThenExpression The thenExpression to set. + */ + public void setThenExpression(Expression theThenExpression) { + widen(theThenExpression); + thenExpression = theThenExpression; + } + +} diff --git a/src/main/java/com/j2js/dom/ContinueStatement.java b/src/main/java/com/j2js/dom/ContinueStatement.java new file mode 100644 index 0000000..a28ede9 --- /dev/null +++ b/src/main/java/com/j2js/dom/ContinueStatement.java @@ -0,0 +1,16 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +public class ContinueStatement extends LabeledJump { + + public ContinueStatement(Block block) { + super(block); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + +} + diff --git a/src/main/java/com/j2js/dom/DoStatement.java b/src/main/java/com/j2js/dom/DoStatement.java new file mode 100644 index 0000000..b3bb863 --- /dev/null +++ b/src/main/java/com/j2js/dom/DoStatement.java @@ -0,0 +1,32 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/* + * DoStatement.java + * + * Created on 21. Mai 2004, 17:30 + */ + +/** + * + * @author kuehn + */ +public class DoStatement extends LoopStatement { + + public DoStatement() { + super(); + } + + public DoStatement(int theBeginIndex) { + super(theBeginIndex); + } + + public DoStatement(int theBeginIndex, int theEndIndex) { + super(theBeginIndex, theEndIndex); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/com/j2js/dom/Expression.java b/src/main/java/com/j2js/dom/Expression.java new file mode 100644 index 0000000..032bbf0 --- /dev/null +++ b/src/main/java/com/j2js/dom/Expression.java @@ -0,0 +1,52 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.Type; + +import com.j2js.Form; + +/** + * Copyright by Wolfgang Kuehn 2005 + * Created on Feb 17, 2005 + */ +public class Expression extends Block implements Cloneable { + + Type type = Type.UNKNOWN; + + public Expression() { + super(); + } + + public Expression(int theBeginIndex, int theEndIndex) { + super(theBeginIndex, theEndIndex); + } + + public Object clone() { + if (getChildCount() > 0) throw new RuntimeException("Cannot clone expression with children"); + ASTNode node; + try { + node = (ASTNode) super.clone(); + } catch (CloneNotSupportedException e) { + return null; + } + node.setParentNode(null); + node.setPreviousSibling(null); + node.setNextSibling(null); + return node; + } + + public Type getTypeBinding() { + return type; + } + + public void setTypeBinding(Type theType) { + type = theType; + } + + public int getCategory() { + if (getTypeBinding().getType() == Type.LONG.getType()) return Form.CATEGORY2; + if (getTypeBinding().getType() == Type.DOUBLE.getType()) return Form.CATEGORY2; + return Form.CATEGORY1; + //return getTypeBinding().getType() == Type.LONG.getType() || getTypeBinding().getType() == Type.DOUBLE.getType()?Form.CATEGORY2:Form.CATEGORY1; + } + +} diff --git a/src/main/java/com/j2js/dom/FieldAccess.java b/src/main/java/com/j2js/dom/FieldAccess.java new file mode 100644 index 0000000..08cb5a7 --- /dev/null +++ b/src/main/java/com/j2js/dom/FieldAccess.java @@ -0,0 +1,85 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.ObjectType; + +import com.j2js.assembly.Project; +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public abstract class FieldAccess extends Expression { + + private String name; + private ObjectType type; + //private MethodDeclaration methodDecl; + + public FieldAccess() { + } + + public void initialize(MethodDeclaration methodDecl) { + Project.getSingleton().addReference(methodDecl, this); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + +// if (!faa.getName().equals(fab.getName())) return false; +// + public boolean isSame(Object obj) { + if (!(obj instanceof FieldAccess)) return false; + FieldAccess other = (FieldAccess) obj; + if (!name.equals(other.name)) return false; + if (getExpression() instanceof VariableBinding && other.getExpression() instanceof VariableBinding) { + VariableBinding vba = (VariableBinding) getExpression(); + VariableBinding vbb = (VariableBinding) other.getExpression(); + return vba.getVariableDeclaration() == vbb.getVariableDeclaration(); + } + return false; + } + + /** + * @return Returns the expression. + */ + public Expression getExpression() { + return (Expression) getFirstChild(); + } + + /** + * @param expression The expression to set. + */ + public void setExpression(Expression expression) { + widen(expression); + removeChildren(); + appendChild(expression); + } + + /** + * @return Returns the name. + */ + public String getName() { + return name; + } + + /** + * @param theName The name to set. + */ + public void setName(String theName) { + name = theName; + } + + public String toString() { + return super.toString() + " " + name; + } + + public ObjectType getType() { + return type; + } + + public void setType(ObjectType theType) { + if (type != null) throw new RuntimeException("Type is already set"); + type = theType; + } + +} diff --git a/src/main/java/com/j2js/dom/FieldRead.java b/src/main/java/com/j2js/dom/FieldRead.java new file mode 100644 index 0000000..8e01ed9 --- /dev/null +++ b/src/main/java/com/j2js/dom/FieldRead.java @@ -0,0 +1,14 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +public class FieldRead extends FieldAccess { + + public FieldRead() { + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + +} diff --git a/src/main/java/com/j2js/dom/FieldWrite.java b/src/main/java/com/j2js/dom/FieldWrite.java new file mode 100644 index 0000000..27de586 --- /dev/null +++ b/src/main/java/com/j2js/dom/FieldWrite.java @@ -0,0 +1,14 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +public class FieldWrite extends FieldAccess implements Assignable { + + public FieldWrite() { + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + +} diff --git a/src/main/java/com/j2js/dom/Goto.java b/src/main/java/com/j2js/dom/Goto.java new file mode 100644 index 0000000..0fd9f0e --- /dev/null +++ b/src/main/java/com/j2js/dom/Goto.java @@ -0,0 +1,13 @@ +/* + * Copyright 2005 by Wolfgang Kuehn + * Created on 12.11.2005 + */ +package com.j2js.dom; + +/** + * @author wolfgang + */ +public class Goto extends ASTNode { + + +} diff --git a/src/main/java/com/j2js/dom/IfStatement.java b/src/main/java/com/j2js/dom/IfStatement.java new file mode 100644 index 0000000..3b2f62e --- /dev/null +++ b/src/main/java/com/j2js/dom/IfStatement.java @@ -0,0 +1,46 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author kuehn + */ +public class IfStatement extends Block { + + public IfStatement() { + super(); + } + + public Expression getExpression() { + return (Expression) getChildAt(0); + } + + public void setExpression(Expression expression) { + widen(expression); + setChildAt(0, expression); + } + + public Block getIfBlock() { + return (Block) getChildAt(1); + } + + public void setIfBlock(Block block) { + widen(block); + setChildAt(1, block); + } + + public Block getElseBlock() { + if (getChildCount() < 3) return null; + return (Block) getChildAt(2); + } + + public void setElseBlock(Block block) { + widen(block); + setChildAt(2, block); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + +} diff --git a/src/main/java/com/j2js/dom/InfixExpression.java b/src/main/java/com/j2js/dom/InfixExpression.java new file mode 100644 index 0000000..473097d --- /dev/null +++ b/src/main/java/com/j2js/dom/InfixExpression.java @@ -0,0 +1,111 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author kuehn + */ +public class InfixExpression extends Expression { + + static public class Operator { + static public Operator CONDITIONAL_AND = new Operator("&&"); + static public Operator CONDITIONAL_OR = new Operator("||"); + static public Operator PLUS = new Operator("+"); + static public Operator MINUS = new Operator("-"); + static public Operator TIMES = new Operator("*"); + static public Operator DIVIDE = new Operator("/"); + static public Operator REMAINDER = new Operator("%"); + static public Operator XOR = new Operator("^"); + static public Operator AND = new Operator("&"); + static public Operator OR = new Operator("|"); + static public Operator EQUALS = new Operator("=="); + static public Operator NOT_EQUALS = new Operator("!="); + static public Operator GREATER_EQUALS = new Operator(">="); + static public Operator GREATER = new Operator(">"); + static public Operator LESS_EQUALS = new Operator("<="); + static public Operator LESS = new Operator("<"); + static public Operator RIGHT_SHIFT_SIGNED = new Operator(">>"); + static public Operator LEFT_SHIFT = new Operator("<<"); + static public Operator RIGHT_SHIFT_UNSIGNED = new Operator(">>>"); + + static { + EQUALS.complement = NOT_EQUALS; + NOT_EQUALS.complement = EQUALS; + GREATER_EQUALS.complement = LESS; + GREATER.complement = LESS_EQUALS; + LESS_EQUALS.complement = GREATER; + LESS.complement = GREATER_EQUALS; + CONDITIONAL_AND.complement = CONDITIONAL_OR; + CONDITIONAL_OR.complement = CONDITIONAL_AND; + } + + private String token; + private Operator complement; + + Operator(String theToken) { + token = theToken; + } + + public String toString() { + return token; + } + + /** + * @return Returns the complement. + */ + public Operator getComplement() { + return complement; + } + } + + private Operator operator; + + public InfixExpression(Operator op) { + super(); + operator = op; + if (operator.getComplement() != null) type = org.apache.bcel.generic.Type.BOOLEAN; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the leftOperand. + */ + public Expression getLeftOperand() { + return (Expression) getChildAt(0); + } + + /** + * @param leftOperand The leftOperand to set. + */ + public void setOperands(Expression leftOperand, Expression rightOperand) { + widen(leftOperand); + widen(rightOperand); + removeChildren(); + appendChild(leftOperand); + appendChild(rightOperand); + } + + /** + * @return Returns the rightOperand. + */ + public Expression getRightOperand() { + return (Expression) getChildAt(1); + } + + /** + * @return Returns the operator. + */ + public Operator getOperator() { + return operator; + } + + /** + * @param theOperator The operator to set. + */ + public void setOperator(Operator theOperator) { + operator = theOperator; + } +} diff --git a/src/main/java/com/j2js/dom/InstanceofExpression.java b/src/main/java/com/j2js/dom/InstanceofExpression.java new file mode 100644 index 0000000..777ce1e --- /dev/null +++ b/src/main/java/com/j2js/dom/InstanceofExpression.java @@ -0,0 +1,31 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.Type; + +import com.j2js.visitors.AbstractVisitor; + +/** + * Copyright by Wolfgang Kuehn 2005 + * Created on Feb 27, 2005 + */ +public class InstanceofExpression extends Expression { + private Expression leftOperand; + private Type rightOperand; + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public Expression getLeftOperand() { + return leftOperand; + } + public void setLeftOperand(Expression theLeftOperand) { + leftOperand = theLeftOperand; + } + public Type getRightOperand() { + return rightOperand; + } + public void setRightOperand(Type theRightOperand) { + rightOperand = theRightOperand; + } +} diff --git a/src/main/java/com/j2js/dom/Jump.java b/src/main/java/com/j2js/dom/Jump.java new file mode 100644 index 0000000..35cbaf0 --- /dev/null +++ b/src/main/java/com/j2js/dom/Jump.java @@ -0,0 +1,20 @@ +package com.j2js.dom; + +/** + * @author wolfgang + */ +public class Jump extends Branch { + + public Jump() { + super(); + } + + public Jump(int targetIndex) { + super(targetIndex); + } + +// public Jump(int beginIndex, int endIndex, int targetIndex) { +// this(targetIndex); +// setRange(beginIndex, endIndex); +// } +} diff --git a/src/main/java/com/j2js/dom/JumpSubRoutine.java b/src/main/java/com/j2js/dom/JumpSubRoutine.java new file mode 100644 index 0000000..25c9102 --- /dev/null +++ b/src/main/java/com/j2js/dom/JumpSubRoutine.java @@ -0,0 +1,12 @@ +package com.j2js.dom; + +/** + * @author wolfgang + */ +public class JumpSubRoutine extends Branch { + + public JumpSubRoutine(int targetIndex) { + super(targetIndex); + } + +} diff --git a/src/main/java/com/j2js/dom/LabeledJump.java b/src/main/java/com/j2js/dom/LabeledJump.java new file mode 100644 index 0000000..cb89347 --- /dev/null +++ b/src/main/java/com/j2js/dom/LabeledJump.java @@ -0,0 +1,20 @@ +package com.j2js.dom; + +abstract public class LabeledJump extends Jump { + + String label; + + public LabeledJump(String newLabel) { + super(); + label = newLabel; + } + + public LabeledJump(Block block) { + super(); + label = block.setLabeled(); + } + + public String getLabel() { + return label; + } +} diff --git a/src/main/java/com/j2js/dom/LoopStatement.java b/src/main/java/com/j2js/dom/LoopStatement.java new file mode 100644 index 0000000..548d0be --- /dev/null +++ b/src/main/java/com/j2js/dom/LoopStatement.java @@ -0,0 +1,44 @@ +package com.j2js.dom; + +/* + * LoopStatement.java + * + * Created on 21. Mai 2004, 16:51 + */ + +/** + * + * @author kuehn + */ +public class LoopStatement extends Block { + + public LoopStatement() { + super(); + } + + public LoopStatement(int theBeginIndex) { + super(theBeginIndex); + } + + public LoopStatement(int theBeginIndex, int theEndIndex) { + super(theBeginIndex, theEndIndex); + } + + public Expression getExpression() { + return (Expression) getChildAt(1); + } + + public void setExpression(Expression expression) { + widen(expression); + setChildAt(1, expression); + } + + public Block getBlock() { + return (Block) getChildAt(0); + } + + public void setBlock(Block block) { + widen(block); + setChildAt(0, block); + } +} diff --git a/src/main/java/com/j2js/dom/MethodBinding.java b/src/main/java/com/j2js/dom/MethodBinding.java new file mode 100644 index 0000000..d074c0e --- /dev/null +++ b/src/main/java/com/j2js/dom/MethodBinding.java @@ -0,0 +1,120 @@ +/* + * Created on 29.01.2006 + * Copyright Wolfgang Kuehn 2005 + */ +package com.j2js.dom; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.bcel.Constants; +import org.apache.bcel.classfile.ConstantCP; +import org.apache.bcel.classfile.ConstantNameAndType; +import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.generic.ObjectType; +import org.apache.bcel.generic.Type; + +import com.j2js.Utils; + +/** + * @author kuehn + */ +public class MethodBinding { + + private static Map methodBindingsByKey = new HashMap(); + + public static MethodBinding lookup(int index, ConstantPool constantPool) { + ConstantCP methodRef = (ConstantCP) constantPool.getConstant(index); + ConstantNameAndType nameAndType = (ConstantNameAndType) + constantPool.getConstant(methodRef.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType); + + String name = nameAndType.getName(constantPool); + String signature = nameAndType.getSignature(constantPool); + + return lookup(methodRef.getClass(constantPool), name, signature); + } + + public static MethodBinding lookup(String className, String name, String signature) { + String key = className + "#" + name + signature; + + MethodBinding binding = methodBindingsByKey.get(key); + if (binding != null) return binding; + + binding = new MethodBinding(); + binding.declaringClass = new ObjectType(className); + binding.name = name; + binding.parameterTypes = Type.getArgumentTypes(signature); + binding.returnType = Type.getReturnType(signature); + binding.signature = signature; + + methodBindingsByKey.put(key, binding); + + return binding; + } + + private ObjectType declaringClass; + private String name; + private Type[] parameterTypes; + private Type returnType; + private String signature; + + private MethodBinding() { + } + + /** + * Returns the type binding representing the class or interface that declares this method or constructor. + */ + public ObjectType getDeclaringClass() { + return declaringClass; + } + + /** + * Returns the name of the method declared in this binding. + */ + public String getName() { + return name; + } + + /** + * Returns a list of type bindings representing the formal parameter types, in declaration order, of this method or constructor. + */ + public Type[] getParameterTypes() { + return parameterTypes; + } + + /** + * Returns the binding for the return type of this method. + */ + public Type getReturnType() { + return returnType; + } + + /** + * Returns whether this binding is for a constructor or a method. + */ + public boolean isConstructor() { + return "".equals(name); + } + + public String getSignature() { + return signature; + } + + public String toString() { + return getDeclaringClass().getClassName() + "#" + getRelativeSignature(); + } + + public String getRelativeSignature() { + String signature = getName() + "("; + String sep = ""; + for (int i = 0; i < getParameterTypes().length; i++) { + Type type = getParameterTypes()[i]; + signature += sep + Utils.getSignature(type); + sep = ","; + } + signature += ")"; + signature += Utils.getSignature(returnType); + return signature; + } + +} diff --git a/src/main/java/com/j2js/dom/MethodDeclaration.java b/src/main/java/com/j2js/dom/MethodDeclaration.java new file mode 100644 index 0000000..b79efc3 --- /dev/null +++ b/src/main/java/com/j2js/dom/MethodDeclaration.java @@ -0,0 +1,134 @@ +package com.j2js.dom; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.bcel.classfile.Code; +import org.apache.bcel.generic.Type; + +import com.j2js.LineNumberCursor; +import com.j2js.assembly.Project; +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class MethodDeclaration extends ASTNode { + + private String tempPrefix = "_"; + private Block block; + private Map parameters = new LinkedHashMap(); + private Map localVariables = new HashMap(); + private int accessFlags; + private Code code; + private MethodBinding methodBinding; + private LineNumberCursor lineNumberCursor; + + public MethodDeclaration(MethodBinding theMethodBinding, int theAccessFlags, Code theCode) { + methodBinding = theMethodBinding; + accessFlags = theAccessFlags; + code = theCode; + lineNumberCursor = new LineNumberCursor(code); + Project.getSingleton().getOrCreateProcedureUnit(methodBinding); + } + + public int getAccess() { + return accessFlags; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public boolean isInstanceConstructor() { + return methodBinding.getName().equals(""); + } + + /** + * @return Returns the block. + */ + public Block getBody() { + return block; + } + + /** + * @param theBlock The block to set. + */ + public void setBody(Block theBlock) { + block = theBlock; + theBlock.setParentNode(this); + } + + public VariableBinding createVariableBinding(String name, Type type, boolean isWrite) { + if (type == null) throw new NullPointerException(); + + VariableDeclaration decl = getParameter(name); + if (decl == null) { + decl = getLocalVariable(name); + } + if (decl == null) { + decl = new VariableDeclaration(!isWrite); + decl.setName(name); + decl.setType(type); + addLocalVariable(decl); + } + + VariableBinding binding = new VariableBinding(decl); + + return binding; + } + + private int vbCount = 0; + public VariableBinding createAnonymousVariableBinding(Type type, boolean isWrite) { + String name = tempPrefix + (vbCount++); + VariableBinding vb = createVariableBinding(name, type, isWrite); + vb.setTemporary(true); + return vb; + } + + public void addParameter(VariableDeclaration variableDecl) { + parameters.put(variableDecl.getName(), variableDecl); + } + + public Collection getParameters() { + return parameters.values(); + } + + public VariableDeclaration getParameter(String name) { + return parameters.get(name); + } + + public void addLocalVariable(VariableDeclaration variableDecl) { + localVariables.put(variableDecl.getName(), variableDecl); + } + + public void removeLocalVariable(String name) { + localVariables.remove(name); + } + + public Collection getLocalVariables() { + return localVariables.values(); + } + + public VariableDeclaration getLocalVariable(String name) { + return localVariables.get(name); + } + + public MethodBinding getMethodBinding() { + return methodBinding; + } + + public String toString() { + return methodBinding.toString(); + } + + public Code getCode() { + return code; + } + + public LineNumberCursor getLineNumberCursor() { + return lineNumberCursor; + } +} diff --git a/src/main/java/com/j2js/dom/MethodInvocation.java b/src/main/java/com/j2js/dom/MethodInvocation.java new file mode 100644 index 0000000..d3e8e2e --- /dev/null +++ b/src/main/java/com/j2js/dom/MethodInvocation.java @@ -0,0 +1,118 @@ +package com.j2js.dom; + +import java.util.List; + +import org.apache.bcel.generic.Type; + +import com.j2js.ASTNodeStack; +import com.j2js.assembly.Project; +import com.j2js.visitors.AbstractVisitor; + +/** + * @author kuehn + */ +public class MethodInvocation extends Expression { + + private Expression expression; + private MethodDeclaration methodDecl; + + /** + * Special handling for superclass, private, and instance initialization method invocations. + */ + public boolean isSpecial = false; + private MethodBinding methodBinding; + + public MethodInvocation() { + } + + public MethodInvocation(MethodDeclaration theMethodDecl) { + methodDecl = theMethodDecl; + } + + public MethodInvocation(MethodDeclaration theMethodDecl, MethodBinding theMethodBinding) { + methodDecl = theMethodDecl; + setMethodBinding(theMethodBinding); + } + + public Type getTypeBinding() { + if (methodBinding == null) return super.getTypeBinding(); + return methodBinding.getReturnType(); + } + + /** + * Returns true if this method invocation applies to a super class of the specified class. + */ + public boolean isSuper(String currentClassName) { + if (!isSpecial) return false; + // Use resolved class unless + // 1) the resolved method is not an instance initialization method, + if (methodBinding.isConstructor()) return false; + // 2) and the class of the resolved method is a superclass of the current class and + String name = methodBinding.getDeclaringClass().getClassName(); + if (currentClassName.equals(name)) return false; + + // TODO: The resolved class is different from the current class, but this does not imply that + // the resolved class is a superclass! Problem: How do we get this information without loading + // the class hierarchy? + return true; + } + + /** + * @return Returns the arguments. + */ + public List getArguments() { + ASTNodeStack stack = new ASTNodeStack(); + ASTNode node = getFirstChild(); + if (expression != null) { + node = node.getNextSibling(); + } + + while (node != null) { + stack.add(node); + node = node.getNextSibling(); + } + + return stack; + + } + + /** + * @param arguments The arguments to set. + */ + public void addArgument(Expression argument) { + widen(argument); + appendChild(argument); + } + + /** + * @return Returns the expression. + */ + public Expression getExpression() { + return expression; + } + + /** + * @param expression The expression to set. + */ + public void setExpression(Expression targetExpression) { + if (expression != null) { + throw new RuntimeException("Expression is already set"); + } + expression = targetExpression; + widen(expression); + insertBefore(expression, getFirstChild()); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public MethodBinding getMethodBinding() { + return methodBinding; + } + + public void setMethodBinding(MethodBinding theMethodBinding) { + methodBinding = theMethodBinding; + Project.getSingleton().addReference(methodDecl, this); + } +} diff --git a/src/main/java/com/j2js/dom/Name.java b/src/main/java/com/j2js/dom/Name.java new file mode 100644 index 0000000..87d5911 --- /dev/null +++ b/src/main/java/com/j2js/dom/Name.java @@ -0,0 +1,39 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * Copyright by Wolfgang Kuehn 2005 + * Created on Feb 20, 2005 + */ +public class Name extends Expression { + + private String identifier; + + public Name(String newIdentifier) { + //super(); + identifier = newIdentifier; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public boolean equals(Object obj) { + if (!(obj instanceof Name)) return false; + return identifier.equals(((Name) obj).identifier); + } + + /** + * @return Returns the identifier. + */ + public String getIdentifier() { + return identifier; + } + /** + * @param theIdentifier The identifier to set. + */ + public void setIdentifier(String theIdentifier) { + identifier = theIdentifier; + } +} diff --git a/src/main/java/com/j2js/dom/NoOperation.java b/src/main/java/com/j2js/dom/NoOperation.java new file mode 100644 index 0000000..02a9700 --- /dev/null +++ b/src/main/java/com/j2js/dom/NoOperation.java @@ -0,0 +1,11 @@ +/* + * Created on Oct 31, 2004 + */ +package com.j2js.dom; + +/** + * @author wolfgang + */ +public class NoOperation extends ASTNode { + // Tagging class. +} diff --git a/src/main/java/com/j2js/dom/NullLiteral.java b/src/main/java/com/j2js/dom/NullLiteral.java new file mode 100644 index 0000000..bb27e0d --- /dev/null +++ b/src/main/java/com/j2js/dom/NullLiteral.java @@ -0,0 +1,13 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class NullLiteral extends Expression { + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/com/j2js/dom/NumberLiteral.java b/src/main/java/com/j2js/dom/NumberLiteral.java new file mode 100644 index 0000000..8667c80 --- /dev/null +++ b/src/main/java/com/j2js/dom/NumberLiteral.java @@ -0,0 +1,91 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.Type; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class NumberLiteral extends Expression { + + public static Number ZERO = new Integer(0); + public static Number ONE = new Integer(1); + public static Number MINUS_ONE = new Integer(-1); + + private Number value; + + public static boolean isZero(Expression expr) { + if (expr == null || !(expr instanceof NumberLiteral)) return false; + return ((NumberLiteral) expr).getValue().equals(ZERO); + } + + public static boolean isOne(Expression expr) { + if (expr == null || !(expr instanceof NumberLiteral)) return false; + return ((NumberLiteral) expr).getValue().equals(ONE); + } + + public static boolean isMinusOne(Expression expr) { + if (expr == null || !(expr instanceof NumberLiteral)) return false; + return ((NumberLiteral) expr).getValue().equals(MINUS_ONE); + } + + private NumberLiteral(Number theValue) { + value = theValue; + if (theValue instanceof Integer) { + type = Type.INT; + } else if (theValue instanceof Byte) { + type = Type.BYTE; + } else if (theValue instanceof Float) { + type = Type.FLOAT; + } else if (theValue instanceof Double) { + type = Type.DOUBLE; + } else if (theValue instanceof Long) { + type = Type.LONG; + } else if (theValue instanceof Short) { + type = Type.SHORT; + } else + // TODO: Other types + throw new RuntimeException("Type not supported: " + theValue.getClass()); + } + + public static NumberLiteral create(int i) { + Number value; + if (i == 0) value = ZERO; + else if (i == 1) value = ONE; + else value = new Integer(i); + return new NumberLiteral(value); + } + + public static NumberLiteral create(Number value) { + if (value instanceof Integer) { + Integer i = (Integer) value; + if (i.intValue()==0) value = ZERO; + else if (i.intValue()==1) value = ONE; + } + return new NumberLiteral(value); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the value. + */ + public Number getValue() { + return value; + } + + /** + * @param theValue The value to set. + */ + public void setValue(Number theValue) { + value = theValue; + } + + public String toString() { + return super.toString() + " value " + value; + } + +} diff --git a/src/main/java/com/j2js/dom/PStarExpression.java b/src/main/java/com/j2js/dom/PStarExpression.java new file mode 100644 index 0000000..a773e49 --- /dev/null +++ b/src/main/java/com/j2js/dom/PStarExpression.java @@ -0,0 +1,71 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * Class representing the union of pre- and post-fix expression. + * @author kuehn + */ +public class PStarExpression extends Expression { + + // Operators common to both pre- and post-fix expression. + static public Operator INCREMENT = new Operator("++"); + static public Operator DECREMENT = new Operator("--"); + + static public class Operator { + + private String token; + + Operator(String theToken) { + token = theToken; + } + + public String toString() { + return token; + } + + public Operator complement() { + if (this == PStarExpression.INCREMENT) return PStarExpression.DECREMENT; + else if (this == PStarExpression.DECREMENT) return PStarExpression.INCREMENT; + else throw new RuntimeException("Operation not supported for " + this); + } + + } + + private ASTNode operand; + private Operator operator; + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the operand. + */ + public ASTNode getOperand() { + return operand; + } + + /** + * @param leftOperand The leftOperand to set. + */ + public void setOperand(ASTNode theOperand) { + widen(theOperand); + operand = theOperand; + } + + /** + * @return Returns the operator. + */ + public Operator getOperator() { + return operator; + } + + /** + * @param theOperator The operator to set. + */ + public void setOperator(Operator theOperator) { + operator = theOperator; + } +} + diff --git a/src/main/java/com/j2js/dom/Pop.java b/src/main/java/com/j2js/dom/Pop.java new file mode 100644 index 0000000..fb26f17 --- /dev/null +++ b/src/main/java/com/j2js/dom/Pop.java @@ -0,0 +1,15 @@ +/* + * Copyright 2005 by Wolfgang Kuehn + * Created on 19.10.2005 + */ +package com.j2js.dom; + +/** + * @author wolfgang + */ +public class Pop extends Expression { + + public Pop(Expression e) { + //setRange(-1,-1); + } +} diff --git a/src/main/java/com/j2js/dom/PostfixExpression.java b/src/main/java/com/j2js/dom/PostfixExpression.java new file mode 100644 index 0000000..9a336c3 --- /dev/null +++ b/src/main/java/com/j2js/dom/PostfixExpression.java @@ -0,0 +1,18 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * Tagging class for a postfix expression. + * @author kuehn + */ +public class PostfixExpression extends PStarExpression { + + public PostfixExpression() { + super(); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/com/j2js/dom/PrefixExpression.java b/src/main/java/com/j2js/dom/PrefixExpression.java new file mode 100644 index 0000000..9f59b27 --- /dev/null +++ b/src/main/java/com/j2js/dom/PrefixExpression.java @@ -0,0 +1,25 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * Tagging class for a prefix expression. + * @author kuehn + */ +public class PrefixExpression extends PStarExpression { + + static public Operator NOT = new Operator("!"); +// static public Operator INCREMENT = new Operator("++"); +// static public Operator DECREMENT = new Operator("--"); + static public Operator MINUS = new Operator("-"); + static public Operator PLUS = new Operator("+"); + static public Operator COMPLEMENT = new Operator("~"); + + public PrefixExpression() { + super(); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } +} \ No newline at end of file diff --git a/src/main/java/com/j2js/dom/PrimitiveCast.java b/src/main/java/com/j2js/dom/PrimitiveCast.java new file mode 100644 index 0000000..f7bef0c --- /dev/null +++ b/src/main/java/com/j2js/dom/PrimitiveCast.java @@ -0,0 +1,25 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.Type; + +import com.j2js.visitors.AbstractVisitor; + +public class PrimitiveCast extends Expression { + public int castType = 0; + public Expression expression; + + public PrimitiveCast(int theCastType, Expression expr, Type typeBinding) { + super(); + type = typeBinding; + castType = theCastType; + expression = expr; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public Expression getExpression() { + return expression; + } +} diff --git a/src/main/java/com/j2js/dom/Push.java b/src/main/java/com/j2js/dom/Push.java new file mode 100644 index 0000000..0abf448 --- /dev/null +++ b/src/main/java/com/j2js/dom/Push.java @@ -0,0 +1,16 @@ +/* + * Copyright 2005 by Wolfgang Kuehn + * Created on 19.10.2005 + */ +package com.j2js.dom; + +/** + * @author wolfgang + */ +public class Push extends Expression { + + public Push(Expression e) { + widen(e); + } + +} diff --git a/src/main/java/com/j2js/dom/ReturnStatement.java b/src/main/java/com/j2js/dom/ReturnStatement.java new file mode 100644 index 0000000..a4007af --- /dev/null +++ b/src/main/java/com/j2js/dom/ReturnStatement.java @@ -0,0 +1,44 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/* + * Created on Sep 12, 2004 + * + * To change the template for this generated file go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ + +/** + * @author wolfgang + * + * To change the template for this generated type comment go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +public class ReturnStatement extends ASTNode { + + private Expression expression; + + public ReturnStatement(int theBeginIndex, int theEndIndex) { + setRange(theBeginIndex, theEndIndex); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @param theExpression The expression to set. + */ + public void setExpression(Expression theExpression) { + widen(theExpression); + expression = theExpression; + } + + /** + * @return Returns the expression. + */ + public Expression getExpression() { + return expression; + } +} diff --git a/src/main/java/com/j2js/dom/StringLiteral.java b/src/main/java/com/j2js/dom/StringLiteral.java new file mode 100644 index 0000000..ec41551 --- /dev/null +++ b/src/main/java/com/j2js/dom/StringLiteral.java @@ -0,0 +1,37 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.Type; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class StringLiteral extends Expression { + + private String value; + + public StringLiteral(String theValue) { + value = theValue; + type = Type.STRING; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the value. + */ + public String getValue() { + return value; + } + + /** + * @param theValue The value to set. + */ + public void setValue(String theValue) { + value = theValue; + } + +} diff --git a/src/main/java/com/j2js/dom/SwitchCase.java b/src/main/java/com/j2js/dom/SwitchCase.java new file mode 100644 index 0000000..c0e0528 --- /dev/null +++ b/src/main/java/com/j2js/dom/SwitchCase.java @@ -0,0 +1,38 @@ +/* + * Created on Oct 24, 2004 + */ +package com.j2js.dom; + +import java.util.List; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class SwitchCase extends Block { + + private List expressions; + + public SwitchCase(int theBeginIndex) { + super(theBeginIndex); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the expression. + */ + public List getExpressions() { + return expressions; + } + /** + * @param expression The expression to set. + */ + public void setExpressions(List theExpressions) { + expressions = theExpressions; + } + +} diff --git a/src/main/java/com/j2js/dom/SwitchStatement.java b/src/main/java/com/j2js/dom/SwitchStatement.java new file mode 100644 index 0000000..e49334c --- /dev/null +++ b/src/main/java/com/j2js/dom/SwitchStatement.java @@ -0,0 +1,40 @@ +/* + * Created on Oct 24, 2004 + */ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class SwitchStatement extends Block { + + private Expression expression; + + public SwitchStatement() { + super(); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public SwitchCase getDefault() { + return (SwitchCase) getLastChild(); + } + + /** + * @return Returns the expression. + */ + public Expression getExpression() { + return expression; + } + /** + * @param theExpression The expression to set. + */ + public void setExpression(Expression theExpression) { + widen(theExpression); + expression = theExpression; + } +} diff --git a/src/main/java/com/j2js/dom/SynchronizedBlock.java b/src/main/java/com/j2js/dom/SynchronizedBlock.java new file mode 100644 index 0000000..aeba418 --- /dev/null +++ b/src/main/java/com/j2js/dom/SynchronizedBlock.java @@ -0,0 +1,18 @@ +/* + * Copyright 2005 by Wolfgang Kuehn + * Created on 18.10.2005 + */ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class SynchronizedBlock extends Block { + public Expression monitor; + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/com/j2js/dom/ThisExpression.java b/src/main/java/com/j2js/dom/ThisExpression.java new file mode 100644 index 0000000..05d3e82 --- /dev/null +++ b/src/main/java/com/j2js/dom/ThisExpression.java @@ -0,0 +1,27 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.Type; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author kuehn + */ +public class ThisExpression extends VariableBinding { + + private static VariableDeclaration vd; + + static { + vd = new VariableDeclaration(VariableDeclaration.NON_LOCAL); + vd.setName("this"); + vd.setType(Type.OBJECT); + } + + public ThisExpression() { + super(vd); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } +} diff --git a/src/main/java/com/j2js/dom/ThrowStatement.java b/src/main/java/com/j2js/dom/ThrowStatement.java new file mode 100644 index 0000000..dc179cb --- /dev/null +++ b/src/main/java/com/j2js/dom/ThrowStatement.java @@ -0,0 +1,27 @@ +package com.j2js.dom; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class ThrowStatement extends Block { + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the expression. + */ + public Expression getExpression() { + return (Expression) getFirstChild(); + } + /** + * @param expression The expression to set. + */ + public void setExpression(Expression expression) { + widen(expression); + appendChild(expression); + } +} diff --git a/src/main/java/com/j2js/dom/TryStatement.java b/src/main/java/com/j2js/dom/TryStatement.java new file mode 100644 index 0000000..79b0c47 --- /dev/null +++ b/src/main/java/com/j2js/dom/TryStatement.java @@ -0,0 +1,68 @@ +package com.j2js.dom; + +import com.j2js.cfg.TryHeaderNode; +import com.j2js.visitors.AbstractVisitor; + +/** + * TryStatement.java + * + * Created on 21. Mai 2004, 17:33 + * @author kuehn + */ +public class TryStatement extends Block { + + public TryHeaderNode header; + + /** Creates a new instance of TryStatement */ + public TryStatement() { + super(); + } + + public void addCatchStatement(CatchClause catchStatement) { + if (getChildCount() < 2) throw new RuntimeException("Illegal DOM state"); + ((Block) getChildAt(1)).appendChild(catchStatement); + } + + public Block getCatchStatements() { + return (Block) getChildAt(1); + } + + /** Getter for property finallyBlock. + * @return Value of property finallyBlock. + */ + public Block getFinallyBlock() { + if (getChildCount() < 3) return null; + return (Block) getChildAt(2); + } + + /** Setter for property finallyBlock. + * @param finallyBlock New value of property finallyBlock. + */ + public void setFinallyBlock(Block finallyBlock) { + setChildAt(2, finallyBlock); + } + + /** + * @return Returns the tryBlock. + */ + public Block getTryBlock() { + return (Block) getChildAt(0); + } + + /** + * @param tryBlock The tryBlock to set. + */ + public void setTryBlock(Block tryBlock) { + setChildAt(0, tryBlock); + setChildAt(1, new Block()); + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public String toString() { + return super.toString(); + } + +} diff --git a/src/main/java/com/j2js/dom/TypeDeclaration.java b/src/main/java/com/j2js/dom/TypeDeclaration.java new file mode 100644 index 0000000..823d6f4 --- /dev/null +++ b/src/main/java/com/j2js/dom/TypeDeclaration.java @@ -0,0 +1,121 @@ +/* + * Created on 22.10.2004 + */ +package com.j2js.dom; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.bcel.generic.ObjectType; + +import com.j2js.assembly.Project; +import com.j2js.visitors.AbstractVisitor; + + +/** + * @author kuehn + */ +public class TypeDeclaration extends ASTNode { + + private ObjectType type; + private ObjectType superType; + + private ArrayList methods = new ArrayList(); + //private MethodDeclaration initializer; + private List fields = new ArrayList(); + private int accessFlags; + //private String superClassName; + + public TypeDeclaration(ObjectType theType, int theAccessFlags) { + type = theType; + accessFlags = theAccessFlags; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + /** + * @return Returns the methods. + */ + public MethodDeclaration[] getMethods() { + MethodDeclaration[] a = new MethodDeclaration[methods.size()]; + return methods.toArray(a); + } + + public int getAccess() { + return accessFlags; + } + + /** + * @param methods The methods to set. + */ + public void addMethod(MethodDeclaration method) { + method.setParentNode(this); + methods.add(method); + } + + /** + * @return Returns the name. + */ + public ObjectType getType() { + return type; + } + + /** + * @return Returns the package portion of this types name. + */ + public String getPackageName() { + String name = type.getClassName(); + int index = name.lastIndexOf('.'); + if (index != -1) + return name.substring(0, index); + else + return name; + } + + public String getClassName() { + return type.getClassName(); + } + + public String getUnQualifiedName() { + String name = type.getClassName(); + int index = name.lastIndexOf('.'); + if (index != -1) + return name.substring(index+1); + else + return name; + } + + /** + * @return Returns the fields. + */ + public List getFields() { + return fields; + } + /** + * @param fields The fields to set. + */ + public void addField(VariableDeclaration field) { + fields.add(field); + Project.getSingleton().getOrCreateFieldUnit(type, field.getName()); + } + /** + * @return Returns the superClassName. + */ + public ObjectType getSuperType() { + return superType; + } + + /** + * Sets the super type. + */ + public void setSuperType(ObjectType newSuperType) { + superType = newSuperType; + } + + public String toString() { + return type.getClassName(); + } + +} diff --git a/src/main/java/com/j2js/dom/VariableBinding.java b/src/main/java/com/j2js/dom/VariableBinding.java new file mode 100644 index 0000000..c8ef7d3 --- /dev/null +++ b/src/main/java/com/j2js/dom/VariableBinding.java @@ -0,0 +1,83 @@ +package com.j2js.dom; + +import org.apache.bcel.generic.Type; + +import com.j2js.visitors.AbstractVisitor; + +/** + * @author wolfgang + */ +public class VariableBinding extends Expression implements Assignable { + private boolean field; + private VariableDeclaration decl; + private boolean isTemporary = false; + + public static boolean isBoolean(Expression expr) { + if (expr == null || !(expr instanceof VariableBinding)) return false; + if (((VariableBinding) expr).getVariableDeclaration().getType() != Type.BOOLEAN) return false; + return true; + } + + public VariableBinding(VariableDeclaration theDecl) { + super(); + decl = theDecl; + decl.vbs.add(this); + setTypeBinding(theDecl.getType()); + } + + public Object clone() { + // TODO: Make cloning explicit. + VariableBinding other = (VariableBinding) super.clone(); + decl.vbs.add(other); + return other; + } + + public void visit(AbstractVisitor visitor) { + visitor.visit(this); + } + + public boolean isSame(Object other) { + if (other == null || !(other instanceof VariableBinding)) return false; + return decl == ((VariableBinding) other).decl; + } + + /** + * @return Returns the name. + */ + public String getName() { + return decl.getName(); + } + + /** + * @return Returns the field. + */ + public boolean isField() { + return field; + } + + /** + * @param theField The field to set. + */ + public void setField(boolean theField) { + field = theField; + } + + /** + * @return Returns the decl. + */ + public VariableDeclaration getVariableDeclaration() { + return decl; + } + + public String toString() { + return super.toString() + ' ' + decl.getName(); + } + + public boolean isTemporary() { + return isTemporary; + } + + public void setTemporary(boolean isTemporary) { + this.isTemporary = isTemporary; + } +} diff --git a/src/main/java/com/j2js/dom/VariableDeclaration.java b/src/main/java/com/j2js/dom/VariableDeclaration.java new file mode 100644 index 0000000..20cddb9 --- /dev/null +++ b/src/main/java/com/j2js/dom/VariableDeclaration.java @@ -0,0 +1,111 @@ +package com.j2js.dom; + +import com.j2js.J2JSCompiler; + +import java.util.List; +import java.util.ArrayList; + +import com.j2js.visitors.AbstractVisitor; + +import org.apache.bcel.classfile.LocalVariable; +import org.apache.bcel.classfile.Method; +import org.apache.bcel.generic.Type; + +/** + * @author wolfgang + */ +public class VariableDeclaration extends ASTNode { + public static int LOCAL = 0; + public static int NON_LOCAL = 1; + public static int LOCAL_PARAMETER = 2; + + private String name; + private Type type; + private int modifiers; + private int location; + private boolean isInitialized; + public List vbs = new ArrayList(); + + public static String getLocalVariableName(Method method, int slot, int pc) { + if (false && method.getLocalVariableTable() != null) { + // TODO: Use source variable name as comment only. + LocalVariable[] table = method.getLocalVariableTable().getLocalVariableTable(); + LocalVariable lvar = null; + for (int i=0; i + + + J2JS Package Documentation + + + + + + + + + +

+

+ This document describes the production patterns for byte code by the + jdk 1.4.2 compiler. +

+
+ +
+ An if statement is compiled as follows: +
+        cond(A) block A
+ + An if-else statement is compiled as follows: +
+        cond(A) block goto(B) A block B
+
+ +
+ +
+
+        aload         // Load object reference.
+        dup           // Duplicate object reference.
+        getfield      // Fetch field oldValue.
+        delta         // Can be any value, could even be an expression.
+        add/sub       // Increment/decrement value.
+                      // Stack: ref newValue
+        dup_x1        // Duplicate top and put it on third position.
+                      // Stack: newValue ref newValue.
+        putfield      // Store field value.
+                      // Stack: newValue
+ + Reduction: + ++field, --field, or (field = field + delta), if delta not equal to constant +/-1. +
+ +
+
+        aload         // Load object reference.
+        dup           // Duplicate object reference.
+        getfield      // Fetch field value.
+                      // Stack: ref oldValue
+        dup_x1        // Duplicate top and put it on third position.
+                      // Stack: oldValue ref oldValue
+        const         // Must be constant +/-1.
+        add/sub       // Increment/decrement value.
+                      // Stack: oldValue ref newValue
+        putfield      // Store field value.
+                      // Stack: oldValue.
+ + Reduction: + field++ or field--. +
+ +
+
+        iinc(delta)   // Increment variable.
+        load          // Load variable.
+                      // Stack: newValue
+
+ +
+
+        load          // Load variable. 
+        delta         // Any expression.
+        add           // Increment.
+        dup           // Stack: newValue newValue
+        store         // Store to variable.
+                      // Stack: newValue
+
+ +
+
+	 load          // Load variable.
+	 iinc(delta)   // Increment variable.
+	 // Stack: oldValue
+
+ +

+ Note that we could match the pattern [load, iinc, load] + with either (E) [i++, i] or (C) [i, ++i]. + Of these obviously equivalent alternatives we choose (E). +

+ +
+ +
+ +
+    While statement:
+       goto(B) A block B cond(A)
+ +
+    Do statement:
+       A block cond(A)
+      
+ +
+    For statement (equivalent to a do statement):
+       init A block increment cond(A)
+      
+ + +
+ +
+

+ In Java, a try statement has the following structure: +

+
+               try Block Catch* (Catch | Finally)
+      
+ +
+ + A try block with finally clause has the following structure: + +
+    TryCatchFinally:
+        tryBlock 
+        Handler  // 0..n times
+        DefaultHandler
+        B Finally 
+        A jsr(B) 
+	
+
+ + Each time the control flow exits the try block or one of the non-default handlers, + a jsr(B) is prepended. If the try block or one of the non-default + handlers are exited by default (fall-through), then a goto(A) is appended at the end of the block. + +
+ There must be at least one handler. All handlers are non-default. Typically, goreth is a goto(A), + but this must not be the case. +
+    TryCatchFinally:
+        tryBlock goreth  
+        Handler goreth  // 0..n
+        Handler
+        A
+	
+
+ +
+    DefaultHandler: (Any Exception)
+        astore_exception jsr(B) aload_exception athrow
+      
+ +
+    Handler:
+        astore_exception catchBlock
+      
+ +
+    Finally:
+        astore_address finallyBlock ret
+      
+ +

+ The store operations in the handlers save the exception to a local variable, whereas the store + operation at the beginning of the subroutine saves the return address to local variable. +

+

+ For each catch block, a codeException(BeginPC, EndPC, HandlerPC) is recorded, + where HandlerPC = begin(Default?Handler) and +

    +
  1. BeginPC = begin(tryBlock), EndPC = begin(first Handler)-1, i.e. including the goto(A) + for each non-default handler, or both +
  2. +
  3. + BeginPC = begin(tryBlock), EndPC = end(last Handler) and +
  4. +
  5. + BeginPC = A = begin(Tail), EndPC = end(Tail) for the default handler. +
  6. +
+ +

+ Note that from the byte code we cannot deduce the end of the last catch clause in the + absense of a finally clause. This is also manifested by the equivalence of the following + two Java code fracments: +

+
+    foo: {
+        try {
+           A;
+           break foo;
+        } catch(e) {
+           B;
+        }
+        C;
+    }
+    
+    foo: {
+        try {
+           A;
+           break foo;
+        } catch(e) {
+           B;
+           C;
+        }
+    }
+      
+
+ +
+
+ + +Last modified: Sat Oct 15 20:44:54 Westeuropäische Sommerzeit 2005 + + + diff --git a/src/main/java/com/j2js/util/BuilderUtils.java b/src/main/java/com/j2js/util/BuilderUtils.java new file mode 100644 index 0000000..79478e9 --- /dev/null +++ b/src/main/java/com/j2js/util/BuilderUtils.java @@ -0,0 +1,89 @@ +package com.j2js.util; + +import java.io.File; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.io.FileUtils; + + +public final class BuilderUtils { + + public static String removePrefixPath(File baseDir, File file) { + return baseDir.toURI().relativize(file.toURI()).toString(); + } + + private static String findGreatestCommonPrefix(String a, String b) { + int previousSlashIndex = -1; + int i; + for (i=0; i + + StringBuilder sb = new StringBuilder(); + sb.append("id\\s*=\\s*[\'\"]j2js-loader[\'\"].*src\\s*=\\s*[\'\"]([^\'\"]+)/0\\.js[\'\"]"); + + Pattern p = Pattern.compile(sb.toString(), Pattern.DOTALL | Pattern.CASE_INSENSITIVE); + return p.matcher(htmlContent); + } + + public static String extractScriptSrc(File htmlFile) throws IOException { + String htmlContent = FileUtils.readFileToString(htmlFile); + Matcher matcher = getProtectedRegion(htmlContent); + if (!matcher.find()) return null; + + String scriptSrc = htmlContent.substring(matcher.start(1), matcher.end(1)); + scriptSrc = scriptSrc.trim(); + + if (scriptSrc.length() == 0) return null; + return scriptSrc; + } + +} diff --git a/src/main/java/com/j2js/util/XmlBeanMapper.java b/src/main/java/com/j2js/util/XmlBeanMapper.java new file mode 100644 index 0000000..c048504 --- /dev/null +++ b/src/main/java/com/j2js/util/XmlBeanMapper.java @@ -0,0 +1,1001 @@ +package com.j2js.util; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Stack; +import java.util.StringTokenizer; +import java.util.logging.Level; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import java.rmi.activation.ActivationException; + +/** + Class XmlBeanMapper offers a generic way to instanciate and initialize a JavaBean + from an Xml document. + +

Document Object Model

+ The Xml document corresponds to a hierachy of values. A value is + either a JavaBean or a primitive type. Each value except the root value + is contained by its parent value. + + The document root corresponds to the JavaBean. + Now we recursively apply the following rules: + +
    +
  1. An element or an attribute corresponds to a value if the enclosing value is a JavaBean + which has a setter of the same name. The value is created and passed to the setter. + An attribute can only be of primitive type. +
  2. +
  3. An element corresponds to a list of values if the enclosing value + is a JavaBean and has an adder of the same name in singular. +
  4. +
  5. An element corresponds to a value if the enclosing value is a list. + The value is created and passed to the adder of the enclosing value. +
  6. +
  7. The root element corresponds to the requested JavaBean. + The name of the root element is not relevant but should coincide with + the classname of the JavaBean. +
  8. +
+ +

Example

+ +
+  <person age="35">
+    <name>Scott Miller</name>
+    <addresses>
+      <address>
+        <street>Augusta Ave 7</street>
+      </address>
+      <address>
+        <street>Chestnut Grove 53</street>
+      </address>
+    </addresses>
+  </person>
+
+  public class Person {
+    public void setName(String name) {}
+    public void setAge(int age) {}
+    public void addAddress(Address address) {}
+  }
+
+  public class Address {
+    public void setStreet(String street) {};
+  }
+  
+ + It is up to the user of Class XmlBeanMapper to provide a proper implementation + for the mapped classes. + +

Supported Primitive Types

+ Supported primitive types are boolean, int, long, double and String. +

Furthermore the following datatypes are supported

+
    +
  • Dates (java.sql.Date and java.util.Date)
  • +
  • array of long, double, int and string
  • +
  • Double, Long, Integer
  • +
+

+ Valid values are + the same as the valid arguments to the one-parameter constructors + Boolean(String), Integer(String), Long(String), Double(String) and String(String) +

+ +

Advanced Usage

+ + By default, the parameter of the setter or adder determines the class of + the newly instanciated value. Of course, this will not work if the value + has to be a subclass or an implementing class to an interfaces. +

+ In these cases, the target class must be indicated by the metaInfClass + attribute of the corresponding element, for example + +

+  <address country="Germany" metaInfClass="OffshoreAddress">
+    <street>Berliner Platz 11</street>
+  </address>
+
+  public class OffshoreAddress extends Address {
+    public void setCountry(String country) {};
+  }
+  
+

+ +
+  <metaInf>
+    <types>
+      <type elementName="name of element" className="full name of class"/>
+      ...
+    </types>
+  </metaInf>
+  
+ +

Tips and Tricks

+ Furthermore it is possible to use the valuestack for instructing the beanmapper to use + some predefined values (setValueStack). + If you use
id="pop#5"
or +
the beanmapper will use the specified entry (in the example the fifth) of the + given hashmap (setValueStack()) for initializing the corresponding field or attribute. + Reference to constructor + Url trick with recursive mapping; Multiple mapping. + TODO: Complete documentation + + @deprecated + + */ +public class XmlBeanMapper { + + /** + * Structure to hold a key-value pair. + */ + private class BeanInfo { + Object bean; + String key; + + /** + * Constructor for the BeanInfo-Class. + * @param newKey the key + * @param newBean the bean + */ + BeanInfo(String newKey, Object newBean) { + key = newKey; + bean = newBean; + } + } + + public class MetaInf { + + public class Type { + String elementName; // Element name. + String className; + + public Type() { + super(); + } + + public void setElement(String newElementName) { + elementName = newElementName; + } + public void setClass(String newClassName) { + className = newClassName; + } + } + + private HashMap types = new HashMap(); + + public MetaInf() { + super(); + } + + public void addType(Type type) { + log(Level.FINEST, "Mapping element " + type.elementName + " to " + type.className); + types.put(type.elementName, type.className); + } + + public String getType(String elementName) { + return types.get(elementName); + } + + public java.util.Map getTypes() { + return types; + } + } + + private static final int MAX_LINE_LENGTH = 76; + + private HashMap valueStack = new HashMap(); + private Stack stack = new Stack(); + private boolean ignore = false; + private boolean trim = true; + private MetaInf metaInf; + private java.util.logging.Logger logger = null; + private java.io.PrintStream printStream = null; + private Level logLevel; + private SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy HH:mm"); + + /** + * Creates a new instance of XmlBeanMapper. + * + * @deprecated + */ + public XmlBeanMapper() { + super(); + } + + /** + * Allows to ignore values that cannot be matched. Default is false. + */ + public void setIgnoreMismatches(boolean theIgnore) { + ignore = theIgnore; + } + + /** + * If true, all String-typed values will have their leading and trailing whitespace omitted. + * Default is true. + */ + public void setTrimWhitespace(boolean b) { + trim = b; + } + + /** + * Sets the dateFormat used to parse the date values in the xml file. + * @param dateFormat the date format. Default is "dd.MM.yyyy HH:mm". + */ + public void setDateFormat(String dateFormat) { + dateFormatter = new SimpleDateFormat(dateFormat); + } + + /** + * Sets a specified stream for logging at a specified logging level. + */ + public void setLogStream(PrintStream newPrintStream, Level newLogLevel) { + printStream = newPrintStream; + logLevel = newLogLevel; + } + + /** + * Sets a specified stream for logging at a specified logging level. + */ + public void setLogFile(java.io.File file, Level level) throws IOException { + setLogStream(new java.io.PrintStream(new java.io.FileOutputStream(file)), level); + } + + /** + * Sets a specified logger for logging. + */ + public void setLogger(java.util.logging.Logger theLogger) { + logger = theLogger; + } + + public void setMetaInf(MetaInf theMetaInf) { + metaInf = theMetaInf; + } + + public MetaInf getMetaInf() { + return metaInf; + } + + /** + * See {@link #createBeanFromString(Class, String, Object) createBeanFromString} + */ + public Object createBeanFromString(Class clazz, String xml) + throws IOException, ActivationException { + return createBeanFromString(clazz, xml, null); + } + + /** + * Instanciate a bean for a given class from an Xml-string using a reference. + * If you already have an instance try loadBean. + * + * @param clazz the class to instanciate from + * @param xml the Xml-string + * @param refObject the reference object + * @return the created bean + */ + public Object createBeanFromString(Class clazz, String xml, Object refObject) + throws IOException, ActivationException { + // Log only about MAX_LINE_LENGTH characters wide. + String xmlString = xml; + if (xml.length() > MAX_LINE_LENGTH) { + xml.substring(0, MAX_LINE_LENGTH); + } + log(Level.INFO, "Creating " + clazz + " from string\n" + xmlString + " ..."); + return createBean(refObject, getDocumentElement(new java.io.ByteArrayInputStream(xml.getBytes())), + clazz).bean; + } + + public void loadBeanFromString(Object bean, String xml) + throws IOException, ActivationException { + Class clazz; + if (bean instanceof Class) { + clazz = (Class) bean; + bean = null; + } else { + clazz = bean.getClass(); + } + // Log only about 76 characters wide if string is longer than 76 chars + // otherwise log the whole string + int length = 0; + if (xml.length() >= MAX_LINE_LENGTH) { + length = MAX_LINE_LENGTH; + } else { + length = xml.length(); + } + log(Level.INFO, "Loading" + clazz + + " from string\n" + xml.substring(0, length) + + " ..."); + Element root = getDocumentElement(new java.io.ByteArrayInputStream(xml.getBytes())); + loadBean(clazz, bean, root); + } + + /** + * See {@link #createBeanFromFile(Class, String, Object) createBeanFromFile} + */ + public Object createBeanFromFile(Class clazz, String path) + throws IOException, ActivationException { + return createBeanFromFile(clazz, path, null); + } + + public Object createBeanFromFile(String path) + throws IOException, ActivationException { + return createBeanFromFile(null, path, null); + } + + /** + * Instanciate a bean for a given class from an Xml-file using a reference. + * + * @param clazz the class to instanciate from + * @param path the path to the Xml-file. + * @param refObject the reference object + */ + public Object createBeanFromFile(Class clazz, String path, Object refObject) + throws IOException, ActivationException { + Node document = getDocumentElement(new FileInputStream(path)); + if (clazz == null) { + String className = getMetaInfClass(document); + if (className == null) throw new ActivationException("Need to specify a class name with attribute 'metaInfClass'"); + try { + clazz = Thread.currentThread().getContextClassLoader().loadClass(className); + } catch (ClassNotFoundException e) { + throw new ActivationException("Class " + className + " not found"); + } + } + log(Level.INFO, "Creating " + clazz + " from file " + path); + BeanInfo beanInfo = createBean(refObject, document, clazz); + return beanInfo.bean; + } + + /** + * Load a file into a bean. + * + * @param bean the bean to load the file into. + * @param path the path of the file. + */ + public void loadBean(Object bean, String path) throws IOException, ActivationException { + Class clazz; + if (bean instanceof Class) { + clazz = (Class) bean; + bean = null; + } else { + clazz = bean.getClass(); + } + log(Level.INFO, "Loading " + clazz + " from file " + path); + Element root = getDocumentElement(new FileInputStream(path)); + loadBean(clazz, bean, root); + } + + /** + * Load a file into a bean. + * + * @param bean the bean to load the file into. + * @param stream an input stream + */ + public void loadBean(Object bean, java.io.InputStream stream) throws IOException, ActivationException { + Class clazz; + if (bean instanceof Class) { + clazz = (Class) bean; + bean = null; + } else { + clazz = bean.getClass(); + } + Element root = getDocumentElement(stream); + loadBean(clazz, bean, root); + } + + /** + * Load a file into a bean. + * + * @param bean the bean to load the file into. + * @param root the path of the file. + */ + public void loadBean(Object bean, Element root) throws ActivationException { + Class clazz; + if (bean instanceof Class) { + clazz = (Class) bean; + bean = null; + } else { + clazz = bean.getClass(); + } + log(Level.INFO, "Loading " + clazz + " from Dom element"); + loadBean(clazz, bean, root); + } + + /** + * Utility to find a setter for a given set of methods. If a Class is specified, + * then the setter will have an argument of that class. + * + * @param methods the methods + * @param name the name of the setter + * @param clazz the argument of the setter + * + * @return the index of the setter, or -1 if no suitable setter was found. + */ + public int getSetter(Method[] methods, String name, Class clazz) { + //name = name.substring(0,1).toUpperCase() + name.substring(1); + + name = name.toLowerCase(); + String setter = "set" + name; + int i = 0; + int stringSetter = -1; + int anySetter = -1; + + for (i = 0; i < methods.length; i++) { + String methodName = methods[i].getName().toLowerCase(); + if (!methodName.equals(setter)) continue; + + Class[] parameters = methods[i].getParameterTypes(); + if (parameters.length == 1) { + if (clazz != null && parameters[0].isAssignableFrom(clazz)) { + return i; + } + if (parameters[0].equals(String.class)) { + stringSetter = i; + } else { + anySetter = i; + } + } else if (parameters.length == 2 && parameters[0].equals(String.class)) { + // key-value setter + if (clazz != null && parameters[1].isAssignableFrom(clazz)) { + return i; + } + if (parameters[1].equals(String.class)) { + stringSetter = i; + } else { + anySetter = i; + } + } + } + if (stringSetter != -1) return stringSetter; + return anySetter; + } + + /** + * Utility to find an adder for a given set of methods. + * + * @param methods the methods + * @param name the name of the adder + * + * @return the index of the adder, or -1 if no suitable adder was found. + */ + public int getAdder(Method[] methods, String name, Class clazz) { + name = name.toLowerCase(); + String adder1; + String adder2; + /* + * If the name is a plural, then form a singular. For example, map + * DataSources to DataSource or Entries to Entry. + */ + if (name.endsWith("ies")) { + adder1 = name.substring(0, name.length() - 3) + "y"; + adder2 = ""; + } else { + adder1 = name.substring(0, name.length() - 1); + adder2 = name.substring(0, name.length() - 2); + } + int i = 0; + for (i = 0; i < methods.length; i++) { + String methodName = methods[i].getName().toLowerCase(); + if (clazz != null) { + Class[] parameters = methods[i].getParameterTypes(); + if (parameters.length != 1 || !parameters[0].isAssignableFrom(clazz)) { + continue; + } + } + if (methodName.startsWith("add")) { + String s = methodName.substring(3, methodName.length()); + if (s.equals(adder1) || s.equals(adder2)) { + return i; + } + } else if (methodName.equals(adder1) || methodName.equals(adder2)) { + return i; + } + } + return -1; + } + + protected void log(Level level, String msg) { + if (logger != null) { + logger.log(level, msg); + } + if (printStream != null && level.intValue() >= logLevel.intValue()) { + printStream.println(msg); + } + } + + private Element getDocumentElement(java.io.InputStream stream) throws IOException { + DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); + dfactory.setNamespaceAware(true); + + BufferedInputStream bStream = new BufferedInputStream(stream); + + Document document = null; + try { + document = dfactory.newDocumentBuilder().parse(bStream); + } catch (javax.xml.parsers.ParserConfigurationException e) { + throw new IOException(e.getMessage()); + } catch (org.xml.sax.SAXParseException e) { + throw new IOException(e.getMessage() + " in (line/column): (" + + e.getLineNumber() + "/" + e.getColumnNumber() + ")"); + } catch (org.xml.sax.SAXException e) { + throw new IOException(e.getMessage()); + } + + return document.getDocumentElement(); + } + + private String getMetaInfClass(Node node) { + if (node.getNodeType() != Node.ELEMENT_NODE) { + return null; + } + Node n = node.getAttributes().getNamedItem("metaInfClass"); + if (n == null) { + return null; + } + return n.getNodeValue(); + } + + /** + * Load an element node into a bean. + * + * @param bean the JavaBean to load into. + * @param element the element to load. + */ + private String loadBean(Class clazz, Object bean, Element element) throws ActivationException { + //Class clazz = bean.getClass(); + Method[] methods = clazz.getMethods(); + String key = null; + + // Load all child-elements. + Element child = getFirstElementChild(element); + while (child != null) { + String name = child.getNodeName(); + int index; + + if (name.equals("metaInf")) { + /* metaInf elements are loaded into this XmlBeanMapper, not + * into the specified bean. + */ + MetaInf mi = new MetaInf(); + loadBean(mi.getClass(), mi, child); + setMetaInf(mi); + } else { + Class c = null; + + String className = getMetaInfClass(child); + if (className != null) { + try { + c = Thread.currentThread().getContextClassLoader().loadClass(className); + } catch (ClassNotFoundException e) { + throw new ActivationException("Class " + className + " not found"); + } + } + + if ((index = getSetter(methods, name, c)) >= 0) { + /* Register single node. */ + loadProperty(methods[index], bean, child); + } else if ((index = getAdder(methods, name, c)) >= 0) { + /* Register list of nodes. */ + Element elem = getFirstElementChild(child); + while (elem != null) { + loadProperty(methods[index], bean, elem); + elem = getNextElement(elem); + } + } else { + if (!ignore) { + throw new ActivationException("Could not match element " + name + "(" + + clazz.getName() + ")"); + } + log(Level.WARNING, "Ignoring " + name); + } + } + + child = getNextElement(child); + } + + // Load all attributes. + NamedNodeMap map = element.getAttributes(); + for (int i = 0; i < map.getLength(); i++) { + Node node = map.item(i); + String name = node.getNodeName(); + if (name.equals("metaInfClass")) { + continue; + } + if (name.equals("metaInfKey")) { + key = node.getNodeValue(); + continue; + } + int index = getSetter(methods, name, null); + if (index >= 0) { + loadProperty(methods[index], bean, node); + } else { + if (!ignore) { + throw new ActivationException( + "Could not match attribute " + name + " for " + clazz); + } + log(Level.WARNING, "Ignoring " + name); + } + } + return key; + } + + /** + * Instantiates an object for a given class using a single-argument constructor. + * The argument type of the constructor must match the type of at least one + * reference object on the stack. The top-most references on the stack is then + * passed to the constructor. + *

+ * Warning: If there is more than one suitable constructor, it is undefined which one of + * these constructors are called. + * + * @return the instantiated object or null, if no suitable constructor was found + * @throws ActivationException if a suitable constructor could not be invoked + */ + private Object createBean(Class clazz) throws ActivationException { + Constructor[] constructors = clazz.getConstructors(); + // Loop over all constructors with single argument. + for (int i=0; i= 0; j--) { + Object ref = stack.get(j); + if (ref != null && types[0].equals(ref.getClass())) { + // Found the specific constructor. + try { + return constructors[i].newInstance(new Object[]{ref}); + } catch (Exception e) { + // InstantiationException or IllegalAccessException + throw new ActivationException("Could not instantiate " + clazz + + " using constructor with argument " + ref.getClass()); + } + } + } + } + return null; + } + + private String checkPrimitiveType(Node node) throws ActivationException { + if (node.getNodeType() != Node.ELEMENT_NODE) { + return null; + } + NamedNodeMap map = node.getAttributes(); + if (map.getLength() == 0) { + return null; + } + Node attribute = map.item(0); + if (!ignore + && !attribute.getNodeName().equals("pop") + && !attribute.getNodeName().equals("metaInfKey")) { + throw new ActivationException( + "Could not match " + attribute.getNodeName() + + " of primitive type or Class or String " + + node.getNodeName() + " has attribute "); + } + return attribute.getNodeValue(); + } + + /** + * Instanciates a bean for a given class from a node element using a reference object. + * If the class has a one-parameter constructor of the same type as the reference object, + * then the reference object is passed to that constructor. If the reference object is null, + * or if no suitable one-parameter constructor excists, then the default constructor + * is used. + * Important: java.util.Date will experience special treatment. + * + * @param refObject the reference object (may be null) + * @param node the node element + * @param clazz the class of the bean + * @return the created bean + */ + private BeanInfo createBean(Object refObject, Node node, Class clazz) throws ActivationException { + stack.push(refObject); + + Object bean = null; + String key = null; + + String nodeValue = ""; + NamedNodeMap map = node.getAttributes(); + if (map != null && map.getLength() != 0) { + Node attribute = map.item(0); + if (attribute.getNodeName().equals("pop")) { + nodeValue = (String) valueStack.get(attribute.getNodeValue()); + } else { + nodeValue = getNodeValue(node); + } + } else { + nodeValue = getNodeValue(node); + if (nodeValue.indexOf("pop#") >= 0) { + nodeValue = nodeValue.substring(nodeValue.indexOf("pop#") + 4); + nodeValue = (String) valueStack.get(nodeValue); + } + } + + String className = clazz.toString(); + if (clazz.equals(String.class)) { + key = checkPrimitiveType(node); + bean = nodeValue; + } else if (clazz.equals(Class.class)) { + try { + key = checkPrimitiveType(node); + bean = Thread.currentThread().getContextClassLoader().loadClass(nodeValue); + } catch (ClassNotFoundException e) { + throw new ActivationException("Class " + nodeValue + " not found"); + } + } else if (!className.startsWith("class") && !className.startsWith("interface")) { + // Primitive type. + key = checkPrimitiveType(node); + + if (clazz.equals(String.class)) { + bean = nodeValue; + } else if (className.equals("byte")) { + bean = new Byte(nodeValue); + } else if (className.equals("char")) { + String s = nodeValue; + if (s.length() != 1) { + throw new ActivationException("Character expected, but found '" + s + "'"); + } + bean = new Character(s.charAt(0)); + } else if (className.equals("double")) { + bean = new Double(nodeValue); + } else if (className.equals("float")) { + bean = new Float(nodeValue); + } else if (className.equals("int")) { + bean = new Integer(nodeValue); + } else if (className.equals("long")) { + bean = new Long(nodeValue); + } else if (className.equals("short")) { + bean = new Short(nodeValue); + } else if (className.equals("boolean")) { + bean = new Boolean(nodeValue); + } + // arrays: + // long:class [J + // double:class [D + // int:class [I + // String:class [Ljava.lang.String; + } else if (className.equals("class [J")) { + StringTokenizer tokenizer = new StringTokenizer(nodeValue, ","); + long[] array = new long[tokenizer.countTokens()]; + for (int i = 0; tokenizer.countTokens() > 0; i++) { + array[i] = Long.parseLong(tokenizer.nextToken()); + } + bean = array; + } else if (className.equals("class [D")) { + StringTokenizer tokenizer = new StringTokenizer(nodeValue, ","); + double[] array = new double[tokenizer.countTokens()]; + for (int i = 0; tokenizer.countTokens() > 0; i++) { + array[i] = Double.parseDouble(tokenizer.nextToken()); + } + bean = array; + } else if (className.equals("class [I")) { + StringTokenizer tokenizer = new StringTokenizer(nodeValue, ","); + int[] array = new int[tokenizer.countTokens()]; + for (int i = 0; tokenizer.countTokens() > 0; i++) { + array[i] = Integer.parseInt(tokenizer.nextToken()); + } + bean = array; + } else if (className.equals("class [Ljava.lang.String;")) { + StringTokenizer tokenizer = new StringTokenizer(nodeValue, ","); + String[] array = new String[tokenizer.countTokens()]; + for (int i = 0; tokenizer.countTokens() > 0; i++) { + array[i] = tokenizer.nextToken(); + } + bean = array; + } else if (className.equals("class java.lang.Double")) { + bean = new Double(nodeValue); + } else if (className.equals("class java.lang.Boolean")) { + bean = new Boolean(nodeValue); + } else if (className.equals("class java.lang.Long")) { + bean = new Long(nodeValue); + } else if (className.equals("class java.lang.Integer")) { + bean = new Integer(nodeValue); + } else if (className.indexOf("java.util.Date") > 0) { + // we have a date => some kind of primitive type + // special treating because of all useful methods being deprecated + try { + bean = dateFormatter.parse(nodeValue); + } catch (ParseException e) { + throw new ActivationException( + "Problems parsing a date field.", e); + } + } else if (className.indexOf("java.sql.Date") > 0) { + // we have a date => some kind of primitive type + // special treating because of all useful methods being deprecated + try { + bean = new java.sql.Date(dateFormatter.parse(nodeValue).getTime()); + } catch (ParseException e) { + throw new ActivationException( + "Problems parsing a date field.", e); + } + } else { + int modifiers = clazz.getModifiers(); + if ((modifiers & Modifier.ABSTRACT) != 0) { // Interface or abstract class. + throw new ActivationException( + "Cannot instantiate " + Modifier.toString(modifiers) + " " + clazz.getName()); + } + + if (stack.size() > 0) { + /** + * We have to instantiate the bean. Note that newInstance() will not do when + * a) the class is an inner class, + * b) a non-default constructor should be used. + * In these cases we have to find the specific constructor which has a + * single argument of the same type as the parent bean. + */ + bean = createBean(clazz); + } + + if (bean == null) { + try { + bean = clazz.newInstance(); + } catch (Exception e) { + // InstantiationException or IllegalAccessException + throw new ActivationException("Could not instantiate " + clazz + + " using default constructor"); + } + } + + key = loadBean(bean.getClass(), bean, (Element) node); + } + stack.pop(); + return new BeanInfo(key, bean); + } + + /** + * Load a node into a JavaBean and register it with a parent bean using + * the specified method. If the method does not allow arguments, no node is + * loaded. This corresponds to executing an action. + * + * @param method the setter or adder + * @param obj the parent bean + * @param the node to load + */ + private void loadProperty(Method method, Object obj, Node node) throws ActivationException { + Object[] args = null; + Class[] types = method.getParameterTypes(); + Class type = null; + + if (types.length==1 || types.length==2) { + args = new Object[types.length]; + + String className = getMetaInfClass(node); + if (className==null && metaInf!=null && metaInf.getType(node.getNodeName())!=null) { + className = metaInf.getType(node.getNodeName()); + } + + if (className!=null) { + try { + type = Thread.currentThread().getContextClassLoader().loadClass(className); + } catch (ClassNotFoundException e) { + throw new ActivationException("Could not load class " + className + " used by method " + + method.getDeclaringClass() + "." + method.getName()); + } + } else { + type = types[types.length-1]; + } + + BeanInfo beanInfo = createBean(obj, node, type); + args[types.length - 1] = beanInfo.bean; + if (types.length == 2) { + args[0] = beanInfo.key; + log(Level.FINER, "Invoking " + + method.getName() + + "(" + args[0] + ", " + args[1] + ")"); + } else { + log(Level.FINER, "Invoking " + + method.getName() + + "(" + args[0] + ")"); + } + } else if (types.length == 0) { + log(Level.FINER, "Invoking " + method.getName() + "()"); + } else { + throw new ActivationException("Method " + method.getName() + " has too many arguments"); + } + + try { + method.invoke(obj, args); + } catch (IllegalAccessException e) { + throw new ActivationException("Cannot access method " + method.getName() + + " of " + method.getDeclaringClass()); + } catch (IllegalArgumentException e) { + /* + All that can go wrong here is that + 1) an unwrapping conversion for primitive arguments failed, or, + 2) after possible unwrapping, a parameter value cannot be converted to + the corresponding formal parameter type by a method invocation conversion. + */ + throw new ActivationException("Cannot invoke " + method.getName() + + " of " + method.getDeclaringClass() + + (type == null ? " without an argument" : " with an argument of " + type)); + } catch (InvocationTargetException e) { + throw new ActivationException("Method " + method.getName() + + " of " + method.getDeclaringClass() + " has thrown an exception", e); + } + + } + + private String getNodeValue(Node node) { + StringBuffer s = new StringBuffer(); + if (node.getNodeType()==Node.ELEMENT_NODE) { + node = node.getFirstChild(); + while (node != null) { + if (node.getNodeType() == Node.TEXT_NODE || node.getNodeType() == Node.CDATA_SECTION_NODE) { + s.append(node.getNodeValue()); + } + node = node.getNextSibling(); + } + } else { + s.append(node.getNodeValue()); + } + + if (trim) { + return s.toString().trim(); + } + return s.toString(); + + } + + /** + * Fetches the first child element node of a given node. + */ + private Element getFirstElementChild(Node root) { + Node node = root.getFirstChild(); + while (node!=null) { + if (node.getNodeType()==Node.ELEMENT_NODE) { + return (Element) node; + } + node = node.getNextSibling(); + } + return null; + } + + /** + * Fetches the next sibling element node of a given node. + */ + private Element getNextElement(Node root) { + Node node = root.getNextSibling(); + while (node != null) { + if (node.getNodeType() == Node.ELEMENT_NODE) { + return (Element) node; + } + node = node.getNextSibling(); + } + return null; + } + + /** + * @return Returns the valueStack. + */ + public HashMap getValueStack() { + return valueStack; + } + + /** + * The value is used if you use the attribute pop="NUMBER" or "pop#NUMBER" as attribut value. + * @param newValueStack The valueStack to set. + */ + public void setValueStack(HashMap newValueStack) { + valueStack = newValueStack; + } + +} diff --git a/src/main/java/com/j2js/visitors/AbstractVisitor.java b/src/main/java/com/j2js/visitors/AbstractVisitor.java new file mode 100644 index 0000000..14e588f --- /dev/null +++ b/src/main/java/com/j2js/visitors/AbstractVisitor.java @@ -0,0 +1,206 @@ +/* + * Created on Feb 2, 2005 + */ +package com.j2js.visitors; + +import com.j2js.dom.ASTNode; +import com.j2js.dom.ArrayAccess; +import com.j2js.dom.ArrayCreation; +import com.j2js.dom.ArrayInitializer; +import com.j2js.dom.Assignment; +import com.j2js.dom.Block; +import com.j2js.dom.BooleanLiteral; +import com.j2js.dom.BreakStatement; +import com.j2js.dom.CastExpression; +import com.j2js.dom.CatchClause; +import com.j2js.dom.ClassInstanceCreation; +import com.j2js.dom.ClassLiteral; +import com.j2js.dom.ConditionalExpression; +import com.j2js.dom.ContinueStatement; +import com.j2js.dom.DoStatement; +import com.j2js.dom.FieldAccess; +import com.j2js.dom.IfStatement; +import com.j2js.dom.InfixExpression; +import com.j2js.dom.InstanceofExpression; +import com.j2js.dom.Name; +import com.j2js.dom.PostfixExpression; +import com.j2js.dom.PrefixExpression; +import com.j2js.dom.MethodDeclaration; +import com.j2js.dom.MethodInvocation; +import com.j2js.dom.NullLiteral; +import com.j2js.dom.NumberLiteral; +import com.j2js.dom.PrimitiveCast; +import com.j2js.dom.ReturnStatement; +import com.j2js.dom.StringLiteral; +import com.j2js.dom.SwitchCase; +import com.j2js.dom.SwitchStatement; +import com.j2js.dom.SynchronizedBlock; +import com.j2js.dom.ThisExpression; +import com.j2js.dom.ThrowStatement; +import com.j2js.dom.TryStatement; +import com.j2js.dom.TypeDeclaration; +import com.j2js.dom.VariableBinding; +import com.j2js.dom.VariableDeclaration; +import com.j2js.dom.WhileStatement; + +/** + * Copyright by Wolfgang Kuehn 2005 + */ +public abstract class AbstractVisitor { + + + public abstract void visit(ASTNode node); + + public void visit(TypeDeclaration node) { + visit((ASTNode) node); + } + + public void visit(MethodDeclaration node) { + visit((ASTNode) node); + } + + public void visit(DoStatement node) { + visit((ASTNode) node); + } + + public void visit(WhileStatement node) { + visit((ASTNode) node); + } + + public void visit(IfStatement node) { + visit((ASTNode) node); + } + + public void visit(TryStatement node) { + visit((ASTNode) node); + } + + public void visit(Block node) { + visit((ASTNode) node); + } + + public void visit(InfixExpression node) { + visit((ASTNode) node); + } + + public void visit(PrefixExpression node) { + visit((ASTNode) node); + } + + public void visit(PostfixExpression node) { + visit((ASTNode) node); + } + + public void visit(SwitchStatement node) { + visit((ASTNode) node); + } + + public void visit(SwitchCase node) { + visit((ASTNode) node); + } + + public void visit(CatchClause node) { + visit((ASTNode) node); + } + + public void visit(ReturnStatement node) { + visit((ASTNode) node); + } + + public void visit(Assignment node) { + visit((ASTNode) node); + } + + public void visit(NumberLiteral node) { + visit((ASTNode) node); + } + + public void visit(StringLiteral node) { + visit((ASTNode) node); + } + + public void visit(ClassLiteral node) { + visit((ASTNode) node); + } + + public void visit(NullLiteral node) { + visit((ASTNode) node); + } + + public void visit(MethodInvocation node) { + visit((ASTNode) node); + } + + public void visit(ClassInstanceCreation node) { + visit((ASTNode) node); + } + + public void visit(ArrayInitializer node) { + visit((ASTNode) node); + } + + public void visit(ArrayCreation node) { + visit((ASTNode) node); + } + + public void visit(ArrayAccess node) { + visit((ASTNode) node); + } + + public void visit(VariableDeclaration node) { + visit((ASTNode) node); + } + + public void visit(VariableBinding node) { + visit((ASTNode) node); + } + + public void visit(ThisExpression node) { + visit((ASTNode) node); + } + + public void visit(FieldAccess node) { + visit((ASTNode) node); + } + + public void visit(BreakStatement node) { + visit((ASTNode) node); + } + + public void visit(ContinueStatement node) { + visit((ASTNode) node); + } + + public void visit(CastExpression node) { + visit((ASTNode) node); + } + + public void visit(BooleanLiteral node) { + visit((ASTNode) node); + } + + public void visit(ThrowStatement node) { + visit((ASTNode) node); + } + + public void visit(Name node) { + visit((ASTNode) node); + } + + public void visit(InstanceofExpression node) { + visit((ASTNode) node); + } + + public void visit(ConditionalExpression node) { + visit((ASTNode) node); + } + + public void visit(SynchronizedBlock node) { + visit((ASTNode) node); + } + + public void visit(PrimitiveCast node) { + visit((ASTNode) node); + } + +} \ No newline at end of file diff --git a/src/main/java/com/j2js/visitors/Generator.java b/src/main/java/com/j2js/visitors/Generator.java new file mode 100644 index 0000000..cca1d61 --- /dev/null +++ b/src/main/java/com/j2js/visitors/Generator.java @@ -0,0 +1,80 @@ +package com.j2js.visitors; + +import com.j2js.J2JSCompiler; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; + +import com.j2js.Log; +import com.j2js.dom.TypeDeclaration; + +public abstract class Generator extends AbstractVisitor { + + final String whiteSpace; + int depth; + char lastChar; + String[] indents; + private PrintStream stream; + + TypeDeclaration typeDecl; + + public Generator() { + if (J2JSCompiler.compiler.isCompression()) { + whiteSpace = ""; + } else { + whiteSpace = " "; + } + } + + public PrintStream getOutputStream() { + return stream; + } + + public void setOutputPath(String path) throws FileNotFoundException { + Log.getLogger().info("Destination file is " + path); + setOutputStream(new PrintStream(new FileOutputStream(path))); + } + + public void setOutputStream(PrintStream theStream) { + stream = theStream; + } + + public void flush() { + stream.flush(); + } + + void indent() { + // No indentation if compression is on. + if (J2JSCompiler.compiler.isCompression()) return; + String INDENT = "\t"; + if (indents == null || depth >= indents.length) { + indents = new String[2 * depth]; + indents[0] = ""; + for (int i=1; i0) lastChar = s.charAt(s.length()-1); + } + + void println(String s) { + print(s); + stream.println(""); + } + + void indentln(String s) { + indent(); + println(s); + } + + void indent(String s) { + indent(); + print(s); + } +} diff --git a/src/main/java/com/j2js/visitors/JavaGenerator.java b/src/main/java/com/j2js/visitors/JavaGenerator.java new file mode 100644 index 0000000..4e7286a --- /dev/null +++ b/src/main/java/com/j2js/visitors/JavaGenerator.java @@ -0,0 +1,105 @@ +package com.j2js.visitors; + +import java.io.PrintStream; +import java.lang.reflect.Modifier; +import java.util.Iterator; + +import com.j2js.Log; +import com.j2js.dom.*; +import com.j2js.Utils; + +/** + * @author kuehn + */ +public class JavaGenerator extends Generator { + + /** Creates a new instance of Generator */ + public JavaGenerator() { + } + + public JavaGenerator(PrintStream targetStream) { + setOutputStream(targetStream); + } + + public void visit(ASTNode node) {} + + /** + * This method must be call first because it sets the global className. + */ + public void visit(TypeDeclaration theTypeDecl) { + Log logger = Log.getLogger(); + logger.info("Generating Java for " + theTypeDecl); + + depth = 0; + typeDecl = theTypeDecl; + + println("package " + theTypeDecl.getPackageName() + ";"); + println(""); + print("public "); + if (Modifier.isFinal(theTypeDecl.getAccess())) print("final "); + + println("class " + theTypeDecl.getUnQualifiedName() + " {"); + + depth++; + + MethodDeclaration[] methods = theTypeDecl.getMethods(); + for (int i=0; i iterator = method.getParameters().iterator(); + while (iterator.hasNext()) { + VariableDeclaration decl = iterator.next(); + decl.visit(this); + print(iterator.hasNext() ? ", " : ""); + } + + println(") {"); + + depth = 1; + + // prefix must be _. + println("var _=j2js;"); + + // Generate local variable declarations. + for (VariableDeclaration decl : method.getLocalVariables()) { + indent(); + decl.visit(this); + println(";"); + } + + depth = 0; + + visit_(method.getBody()); + + println(closingString); + + unit.setData(reset()); + Log.getLogger().debug("Generating JavaScript for " + unit); + } + + public void visit(DoStatement doStmt) { + println("do {"); + visit_(doStmt.getBlock()); + indent("} while ("); + doStmt.getExpression().visit(this); + print(")"); + } + + public void visit(WhileStatement whileStmt) { + print("while ("); + whileStmt.getExpression().visit(this); + println(") {"); + visit_(whileStmt.getBlock()); + indent("}"); + } + + public void visit(IfStatement ifStmt) { + print("if ("); + ifStmt.getExpression().visit(this); + println(") {"); + visit_(ifStmt.getIfBlock()); + indent("}"); + if (ifStmt.getElseBlock()!=null) { + println(" else {"); + visit_(ifStmt.getElseBlock()); + indent("}"); + } + } + + /** + * A try statement has the following structure: + * TryStatement : + * try Block Catch* (Catch | Finally) + * + * Because ECMAScript3 does not support multiple catch clauses, we will generate the following code. + * TryStatement : + * try Block catch(ex) { Catch } Finally? + * try Block catch(ex) { if (ex ...) { Catch } else if(ex ...) ... else throw ex } Finally? + * + */ + public void visit(TryStatement tryStmt) { + println("try {"); + visit_(tryStmt.getTryBlock()); + indent("} "); + Block clauses = tryStmt.getCatchStatements(); + CatchClause clause = (CatchClause) clauses.getFirstChild(); + + // Note: We have to declare variable 'ex_' because we cannot use method local variables due to + // a JavaScript bug in some clients: var l0 = "foo"; try { ... } catch (l0) { /* Now l0 == "foo" */ } + String ex = null; + if (clause != null) { + ex = clause.getException().getName(); + } + + if (clauses.getChildCount()==1) { + print("catch(" + ex + ") "); + clause.visit(this); + } else if (clauses.getChildCount()>1) { + println("catch(" + ex + ") {"); + depth++; + indent(); + while (clause != null) { + if (clause.getException().getType() != null) + print("if (" + prefix + "isInstanceof(" + ex + + ", \"" + Utils.getSignature(clause.getException().getType()) + "\")) "); + clause.visit(this); + clause = (CatchClause) clause.getNextSibling(); + if (clause == null) break; + print(" else "); + } + println(""); + depth--; + indent("}"); + } + + Block finallyBlock = tryStmt.getFinallyBlock(); + if (finallyBlock != null) { // There is a finally clause. + println(" finally {"); + visit_(finallyBlock); + indent("}"); + } + } + + public void visit(CatchClause clause) { + visit((Block) clause); + } + + public void visit_(Block block) { + depth++; + ASTNode node = block.getFirstChild(); + while (node != null) { + currentNode = node; + if (J2JSCompiler.compiler.isGenerateLineNumbers()) { + int lineNumber = currentMethodDeclaration.getLineNumberCursor().getAndMarkLineNumber(node); + if (lineNumber != -1) { + print(prefix + "ln=" + lineNumber + ";\n"); + } + } + + indent(); + if (node instanceof Block && ((Block) node).isLabeled()) { + print(((Block) node).getLabel() + ": "); + } + + node.visit(this); + + if (lastChar == '}') { + println(""); + } else { + println(";"); + } + node = node.getNextSibling(); + } + depth--; + } + + public void visit(Block block) { + println("{"); + visit_(block); + indent("}"); + } + + public void visit(SynchronizedBlock block) { + println("{ // Synchronized."); + visit_(block); + indent("}"); + } + + public void visit(PrefixExpression binOp) { + print(binOp.getOperator().toString() + "("); + binOp.getOperand().visit(this); + print(")"); + } + + public void visit(PostfixExpression binOp) { + // Note that we do not need parenthese here. + binOp.getOperand().visit(this); + print(binOp.getOperator().toString()); + } + + private void bracket(ASTNode node, InfixExpression.Operator op) { + if ((node instanceof InfixExpression && ((InfixExpression) node).getOperator()==op) + || + node instanceof NumberLiteral + || + node instanceof NullLiteral + || + node instanceof FieldAccess + || + node instanceof VariableBinding) { + node.visit(this); + } else { + print("("); + node.visit(this); + print(")"); + } + } + + public void visit(InfixExpression binOp) { + InfixExpression.Operator op = binOp.getOperator(); + Expression left = binOp.getLeftOperand(); + Expression right = binOp.getRightOperand(); + + boolean isTruncate = false; + Type type = binOp.getTypeBinding(); + + /* There is no integral type division in ECMAScript, so we need to + truncate the result. + Note that the % operation works the same in ECMAScript and Java, + i.e. in accepting floating-points. + */ + if (op == InfixExpression.Operator.DIVIDE && + (type.equals(Type.LONG) || type.equals(Type.INT))) { + isTruncate = true; + print(" " + prefix + "trunc("); + } + + bracket(left, op); + print(" " + op + " "); + bracket(right, op); + + if (isTruncate) { + print(")"); + } + } + + public void visit(ConditionalExpression ce) { + ce.getConditionExpression().visit(this); + print("?"); + ce.getThenExpression().visit(this); + print(":"); + ce.getElseExpression().visit(this); + } + + public void visit(InstanceofExpression node) { + print(prefix + "isInstanceof("); + node.getLeftOperand().visit(this); + print(", \""); + Signature signature = Project.getSingleton().getArraySignature(node.getRightOperand()); + print(signature.toString()); + print("\")"); + } + + public void visit(SwitchStatement switchStmt) { + print("switch ("); + switchStmt.getExpression().visit(this); + println(") {"); + ASTNode node = switchStmt.getFirstChild(); + while (node != null) { + SwitchCase sc = (SwitchCase) node; + sc.visit(this); + node = node.getNextSibling(); + } + indentln("}"); + } + + public void visit(SwitchCase switchCase) { + Iterator iter = switchCase.getExpressions().iterator(); + if (iter.hasNext()) { + while (iter.hasNext()) { + NumberLiteral expression = iter.next(); + indent("case "); + expression.visit(this); + println(":"); + } + } else { + indentln("default:"); + } + visit_(switchCase); // Generate switchCase as block! + } + + public void visit(ASTNode stmt) { + print(stmt.toString()); + } + + public void visit(ReturnStatement r) { + print("return"); + if (r.getExpression() != null) { + print(" "); + r.getExpression().visit(this); + } + } + + public void visit(Assignment a) { + Expression rhs = a.getRightHandSide(); + + if (rhs instanceof ClassInstanceCreation) { + ClassInstanceCreation cic = (ClassInstanceCreation) rhs; + if (cic.getTypeBinding().toString().equals("java.lang.String")) { + // Do not generate String creation. + // TODO: Move this to the optimize phase. + return; + } + } + + a.getLeftHandSide().visit(this); + print(" " + a.getOperator() + " "); + if (VariableBinding.isBoolean(a.getLeftHandSide())) { + if (NumberLiteral.isZero(rhs)) { + print("false"); + } if (NumberLiteral.isOne(rhs)) { + print("true"); + } else { + rhs.visit(this); + } + } else { + rhs.visit(this); + } + } + + public void visit(NumberLiteral literal) { + print("" + literal.getValue()); + } + + public void visit(StringLiteral literal) { + print(Utils.escape(literal.getValue())); + } + + public void visit(ClassLiteral literal) { + MethodBinding binding = MethodBinding.lookup("java.lang.Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); + MethodInvocation mi = new MethodInvocation(currentMethodDeclaration, binding); + mi.addArgument(new StringLiteral(literal.getSignature().toString())); + visit(mi); + } + + public void visit(NullLiteral literal) { + consume(literal); + print("null"); + } + + private void generateList(List arguments) { + for (int i=0; i 0, but was" + ac.getDimensions().size()); + } + + if (ac.getInitializer() != null) { + ac.getInitializer().visit(this); + } else { + print("j2js.newArray('"); + Signature signature = Project.getSingleton().getArraySignature(ac.getTypeBinding()); + print(signature.toString()); + print("', ["); + for (int i=0; iget and opt + * methods for accessing the values by index, and put methods for + * adding or replacing values. The values can be any of these types: + * Boolean, JSONArray, JSONObject, + * Number, String, or the + * JSONObject.NULL object. + *

+ * The constructor can convert a JSON text into a Java object. The + * toString method converts to JSON text. + *

+ * A get method returns a value if one can be found, and throws an + * exception if one cannot be found. An opt method returns a + * default value instead of throwing an exception, and so is useful for + * obtaining optional values. + *

+ * The generic get() and opt() methods return an + * object which you can cast or query for type. There are also typed + * get and opt methods that do type checking and type + * coersion for you. + *

+ * The texts produced by the toString methods strictly conform to + * JSON syntax rules. The constructors are more forgiving in the texts they will + * accept: + *

    + *
  • An extra , (comma) may appear just + * before the closing bracket.
  • + *
  • The null value will be inserted when there + * is , (comma) elision.
  • + *
  • Strings may be quoted with ' (single + * quote).
  • + *
  • Strings do not need to be quoted at all if they do not begin with a quote + * or single quote, and if they do not contain leading or trailing spaces, + * and if they do not contain any of these characters: + * { } [ ] / \ : , = ; # and if they do not look like numbers + * and if they are not the reserved words true, + * false, or null.
  • + *
  • Values can be separated by ; (semicolon) as + * well as by , (comma).
  • + *
  • Numbers may have the 0- (octal) or + * 0x- (hex) prefix.
  • + *
  • Comments written in the slashshlash, slashstar, and hash conventions + * will be ignored.
  • + *
+ + * @author JSON.org + * @version 2 + */ +public class JSONArray { + + + /** + * The arrayList where the JSONArray's properties are kept. + */ + private ArrayList myArrayList; + + + /** + * Construct an empty JSONArray. + */ + public JSONArray() { + this.myArrayList = new ArrayList(); + } + + /** + * Construct a JSONArray from a JSONTokener. + * @param x A JSONTokener + * @throws JSONException If there is a syntax error. + */ + public JSONArray(JSONTokener x) throws JSONException { + this(); + if (x.nextClean() != '[') { + throw x.syntaxError("A JSONArray text must start with '['"); + } + if (x.nextClean() == ']') { + return; + } + x.back(); + for (;;) { + if (x.nextClean() == ',') { + x.back(); + this.myArrayList.add(null); + } else { + x.back(); + this.myArrayList.add(x.nextValue()); + } + switch (x.nextClean()) { + case ';': + case ',': + if (x.nextClean() == ']') { + return; + } + x.back(); + break; + case ']': + return; + default: + throw x.syntaxError("Expected a ',' or ']'"); + } + } + } + + + /** + * Construct a JSONArray from a source sJSON text. + * @param string A string that begins with + * [ (left bracket) + * and ends with ] (right bracket). + * @throws JSONException If there is a syntax error. + */ + public JSONArray(String string) throws JSONException { + this(new JSONTokener(string)); + } + + + /** + * Construct a JSONArray from a Collection. + * @param collection A Collection. + */ + public JSONArray(Collection collection) { + this.myArrayList = (collection == null) ? + new ArrayList() : + new ArrayList(collection); + } + + + /** + * Construct a JSONArray from an array + * @throws JSONException If not an array. + */ + public JSONArray(Object array) throws JSONException { + this(); + if (array.getClass().isArray()) { + int length = Array.getLength(array); + for (int i = 0; i < length; i += 1) { + this.put(Array.get(array, i)); + } + } else { + throw new JSONException("JSONArray initial value should be a string or collection or array."); + } + } + + + /** + * Get the object value associated with an index. + * @param index + * The index must be between 0 and length() - 1. + * @return An object value. + * @throws JSONException If there is no value for the index. + */ + public Object get(int index) throws JSONException { + Object o = opt(index); + if (o == null) { + throw new JSONException("JSONArray[" + index + "] not found."); + } + return o; + } + + + /** + * Get the boolean value associated with an index. + * The string values "true" and "false" are converted to boolean. + * + * @param index The index must be between 0 and length() - 1. + * @return The truth. + * @throws JSONException If there is no value for the index or if the + * value is not convertable to boolean. + */ + public boolean getBoolean(int index) throws JSONException { + Object o = get(index); + if (o.equals(Boolean.FALSE) || + (o instanceof String && + ((String)o).equalsIgnoreCase("false"))) { + return false; + } else if (o.equals(Boolean.TRUE) || + (o instanceof String && + ((String)o).equalsIgnoreCase("true"))) { + return true; + } + throw new JSONException("JSONArray[" + index + "] is not a Boolean."); + } + + + /** + * Get the double value associated with an index. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException If the key is not found or if the value cannot + * be converted to a number. + */ + public double getDouble(int index) throws JSONException { + Object o = get(index); + try { + return o instanceof Number ? + ((Number)o).doubleValue() : + Double.valueOf((String)o).doubleValue(); + } catch (Exception e) { + throw new JSONException("JSONArray[" + index + + "] is not a number."); + } + } + + + /** + * Get the int value associated with an index. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException If the key is not found or if the value cannot + * be converted to a number. + * if the value cannot be converted to a number. + */ + public int getInt(int index) throws JSONException { + Object o = get(index); + return o instanceof Number ? + ((Number)o).intValue() : (int)getDouble(index); + } + + + /** + * Get the JSONArray associated with an index. + * @param index The index must be between 0 and length() - 1. + * @return A JSONArray value. + * @throws JSONException If there is no value for the index. or if the + * value is not a JSONArray + */ + public JSONArray getJSONArray(int index) throws JSONException { + Object o = get(index); + if (o instanceof JSONArray) { + return (JSONArray)o; + } + throw new JSONException("JSONArray[" + index + + "] is not a JSONArray."); + } + + + /** + * Get the JSONObject associated with an index. + * @param index subscript + * @return A JSONObject value. + * @throws JSONException If there is no value for the index or if the + * value is not a JSONObject + */ + public JSONObject getJSONObject(int index) throws JSONException { + Object o = get(index); + if (o instanceof JSONObject) { + return (JSONObject)o; + } + throw new JSONException("JSONArray[" + index + + "] is not a JSONObject."); + } + + + /** + * Get the long value associated with an index. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + * @throws JSONException If the key is not found or if the value cannot + * be converted to a number. + */ + public long getLong(int index) throws JSONException { + Object o = get(index); + return o instanceof Number ? + ((Number)o).longValue() : (long)getDouble(index); + } + + + /** + * Get the string associated with an index. + * @param index The index must be between 0 and length() - 1. + * @return A string value. + * @throws JSONException If there is no value for the index. + */ + public String getString(int index) throws JSONException { + return get(index).toString(); + } + + + /** + * Determine if the value is null. + * @param index The index must be between 0 and length() - 1. + * @return true if the value at the index is null, or if there is no value. + */ + public boolean isNull(int index) { + return JSONObject.NULL.equals(opt(index)); + } + + + /** + * Make a string from the contents of this JSONArray. The + * separator string is inserted between each element. + * Warning: This method assumes that the data structure is acyclical. + * @param separator A string that will be inserted between the elements. + * @return a string. + * @throws JSONException If the array contains an invalid number. + */ + public String join(String separator) throws JSONException { + int len = length(); + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < len; i += 1) { + if (i > 0) { + sb.append(separator); + } + sb.append(JSONObject.valueToString(this.myArrayList.get(i))); + } + return sb.toString(); + } + + + /** + * Get the number of elements in the JSONArray, included nulls. + * + * @return The length (or size). + */ + public int length() { + return this.myArrayList.size(); + } + + + /** + * Get the optional object value associated with an index. + * @param index The index must be between 0 and length() - 1. + * @return An object value, or null if there is no + * object at that index. + */ + public Object opt(int index) { + return (index < 0 || index >= length()) ? + null : this.myArrayList.get(index); + } + + + /** + * Get the optional boolean value associated with an index. + * It returns false if there is no value at that index, + * or if the value is not Boolean.TRUE or the String "true". + * + * @param index The index must be between 0 and length() - 1. + * @return The truth. + */ + public boolean optBoolean(int index) { + return optBoolean(index, false); + } + + + /** + * Get the optional boolean value associated with an index. + * It returns the defaultValue if there is no value at that index or if + * it is not a Boolean or the String "true" or "false" (case insensitive). + * + * @param index The index must be between 0 and length() - 1. + * @param defaultValue A boolean default. + * @return The truth. + */ + public boolean optBoolean(int index, boolean defaultValue) { + try { + return getBoolean(index); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get the optional double value associated with an index. + * NaN is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + */ + public double optDouble(int index) { + return optDouble(index, Double.NaN); + } + + + /** + * Get the optional double value associated with an index. + * The defaultValue is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * + * @param index subscript + * @param defaultValue The default value. + * @return The value. + */ + public double optDouble(int index, double defaultValue) { + try { + return getDouble(index); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get the optional int value associated with an index. + * Zero is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + */ + public int optInt(int index) { + return optInt(index, 0); + } + + + /** + * Get the optional int value associated with an index. + * The defaultValue is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * @param index The index must be between 0 and length() - 1. + * @param defaultValue The default value. + * @return The value. + */ + public int optInt(int index, int defaultValue) { + try { + return getInt(index); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get the optional JSONArray associated with an index. + * @param index subscript + * @return A JSONArray value, or null if the index has no value, + * or if the value is not a JSONArray. + */ + public JSONArray optJSONArray(int index) { + Object o = opt(index); + return o instanceof JSONArray ? (JSONArray)o : null; + } + + + /** + * Get the optional JSONObject associated with an index. + * Null is returned if the key is not found, or null if the index has + * no value, or if the value is not a JSONObject. + * + * @param index The index must be between 0 and length() - 1. + * @return A JSONObject value. + */ + public JSONObject optJSONObject(int index) { + Object o = opt(index); + return o instanceof JSONObject ? (JSONObject)o : null; + } + + + /** + * Get the optional long value associated with an index. + * Zero is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * + * @param index The index must be between 0 and length() - 1. + * @return The value. + */ + public long optLong(int index) { + return optLong(index, 0); + } + + + /** + * Get the optional long value associated with an index. + * The defaultValue is returned if there is no value for the index, + * or if the value is not a number and cannot be converted to a number. + * @param index The index must be between 0 and length() - 1. + * @param defaultValue The default value. + * @return The value. + */ + public long optLong(int index, long defaultValue) { + try { + return getLong(index); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get the optional string value associated with an index. It returns an + * empty string if there is no value at that index. If the value + * is not a string and is not null, then it is coverted to a string. + * + * @param index The index must be between 0 and length() - 1. + * @return A String value. + */ + public String optString(int index) { + return optString(index, ""); + } + + + /** + * Get the optional string associated with an index. + * The defaultValue is returned if the key is not found. + * + * @param index The index must be between 0 and length() - 1. + * @param defaultValue The default value. + * @return A String value. + */ + public String optString(int index, String defaultValue) { + Object o = opt(index); + return o != null ? o.toString() : defaultValue; + } + + + /** + * Append a boolean value. This increases the array's length by one. + * + * @param value A boolean value. + * @return this. + */ + public JSONArray put(boolean value) { + put(value ? Boolean.TRUE : Boolean.FALSE); + return this; + } + + + /** + * Put a value in the JSONArray, where the value will be a + * JSONArray which is produced from a Collection. + * @param value A Collection value. + * @return this. + */ + public JSONArray put(Collection value) { + put(new JSONArray(value)); + return this; + } + + + /** + * Append a double value. This increases the array's length by one. + * + * @param value A double value. + * @throws JSONException if the value is not finite. + * @return this. + */ + public JSONArray put(double value) throws JSONException { + Double d = new Double(value); + JSONObject.testValidity(d); + put(d); + return this; + } + + + /** + * Append an int value. This increases the array's length by one. + * + * @param value An int value. + * @return this. + */ + public JSONArray put(int value) { + put(new Integer(value)); + return this; + } + + + /** + * Append an long value. This increases the array's length by one. + * + * @param value A long value. + * @return this. + */ + public JSONArray put(long value) { + put(new Long(value)); + return this; + } + + + /** + * Put a value in the JSONArray, where the value will be a + * JSONObject which is produced from a Map. + * @param value A Map value. + * @return this. + */ + public JSONArray put(Map value) { + put(new JSONObject(value)); + return this; + } + + + /** + * Append an object value. This increases the array's length by one. + * @param value An object value. The value should be a + * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the + * JSONObject.NULL object. + * @return this. + */ + public JSONArray put(Object value) { + this.myArrayList.add(value); + return this; + } + + + /** + * Put or replace a boolean value in the JSONArray. If the index is greater + * than the length of the JSONArray, then null elements will be added as + * necessary to pad it out. + * @param index The subscript. + * @param value A boolean value. + * @return this. + * @throws JSONException If the index is negative. + */ + public JSONArray put(int index, boolean value) throws JSONException { + put(index, value ? Boolean.TRUE : Boolean.FALSE); + return this; + } + + + /** + * Put a value in the JSONArray, where the value will be a + * JSONArray which is produced from a Collection. + * @param index The subscript. + * @param value A Collection value. + * @return this. + * @throws JSONException If the index is negative or if the value is + * not finite. + */ + public JSONArray put(int index, Collection value) throws JSONException { + put(index, new JSONArray(value)); + return this; + } + + + /** + * Put or replace a double value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad + * it out. + * @param index The subscript. + * @param value A double value. + * @return this. + * @throws JSONException If the index is negative or if the value is + * not finite. + */ + public JSONArray put(int index, double value) throws JSONException { + put(index, new Double(value)); + return this; + } + + + /** + * Put or replace an int value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad + * it out. + * @param index The subscript. + * @param value An int value. + * @return this. + * @throws JSONException If the index is negative. + */ + public JSONArray put(int index, int value) throws JSONException { + put(index, new Integer(value)); + return this; + } + + + /** + * Put or replace a long value. If the index is greater than the length of + * the JSONArray, then null elements will be added as necessary to pad + * it out. + * @param index The subscript. + * @param value A long value. + * @return this. + * @throws JSONException If the index is negative. + */ + public JSONArray put(int index, long value) throws JSONException { + put(index, new Long(value)); + return this; + } + + + /** + * Put a value in the JSONArray, where the value will be a + * JSONObject which is produced from a Map. + * @param index The subscript. + * @param value The Map value. + * @return this. + * @throws JSONException If the index is negative or if the the value is + * an invalid number. + */ + public JSONArray put(int index, Map value) throws JSONException { + put(index, new JSONObject(value)); + return this; + } + + + /** + * Put or replace an object value in the JSONArray. If the index is greater + * than the length of the JSONArray, then null elements will be added as + * necessary to pad it out. + * @param index The subscript. + * @param value The value to put into the array. The value should be a + * Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the + * JSONObject.NULL object. + * @return this. + * @throws JSONException If the index is negative or if the the value is + * an invalid number. + */ + public JSONArray put(int index, Object value) throws JSONException { + JSONObject.testValidity(value); + if (index < 0) { + throw new JSONException("JSONArray[" + index + "] not found."); + } + if (index < length()) { + this.myArrayList.set(index, value); + } else { + while (index != length()) { + put(JSONObject.NULL); + } + put(value); + } + return this; + } + + + /** + * Produce a JSONObject by combining a JSONArray of names with the values + * of this JSONArray. + * @param names A JSONArray containing a list of key strings. These will be + * paired with the values. + * @return A JSONObject, or null if there are no names or if this JSONArray + * has no values. + * @throws JSONException If any of the names are null. + */ + public JSONObject toJSONObject(JSONArray names) throws JSONException { + if (names == null || names.length() == 0 || length() == 0) { + return null; + } + JSONObject jo = new JSONObject(); + for (int i = 0; i < names.length(); i += 1) { + jo.put(names.getString(i), this.opt(i)); + } + return jo; + } + + + /** + * Make a JSON text of this JSONArray. For compactness, no + * unnecessary whitespace is added. If it is not possible to produce a + * syntactically correct JSON text then null will be returned instead. This + * could occur if the array contains an invalid number. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @return a printable, displayable, transmittable + * representation of the array. + */ + public String toString() { + try { + return '[' + join(",") + ']'; + } catch (Exception e) { + return null; + } + } + + + /** + * Make a prettyprinted JSON text of this JSONArray. + * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with [ (left bracket) and ending + * with ] (right bracket). + * @throws JSONException + */ + public String toString(int indentFactor) throws JSONException { + return toString(indentFactor, 0); + } + + + /** + * Make a prettyprinted JSON text of this JSONArray. + * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @param indent The indention of the top level. + * @return a printable, displayable, transmittable + * representation of the array. + * @throws JSONException + */ + String toString(int indentFactor, int indent) throws JSONException { + int len = length(); + if (len == 0) { + return "[]"; + } + int i; + StringBuffer sb = new StringBuffer("["); + if (len == 1) { + sb.append(JSONObject.valueToString(this.myArrayList.get(0), + indentFactor, indent)); + } else { + int newindent = indent + indentFactor; + sb.append('\n'); + for (i = 0; i < len; i += 1) { + if (i > 0) { + sb.append(",\n"); + } + for (int j = 0; j < newindent; j += 1) { + sb.append(' '); + } + sb.append(JSONObject.valueToString(this.myArrayList.get(i), + indentFactor, newindent)); + } + sb.append('\n'); + for (i = 0; i < indent; i += 1) { + sb.append(' '); + } + } + sb.append(']'); + return sb.toString(); + } + + + /** + * Write the contents of the JSONArray as JSON text to a writer. + * For compactness, no whitespace is added. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @return The writer. + * @throws JSONException + */ + public Writer write(Writer writer) throws JSONException { + try { + boolean b = false; + int len = length(); + + writer.write('['); + + for (int i = 0; i < len; i += 1) { + if (b) { + writer.write(','); + } + Object v = this.myArrayList.get(i); + if (v instanceof JSONObject) { + ((JSONObject)v).write(writer); + } else if (v instanceof JSONArray) { + ((JSONArray)v).write(writer); + } else { + writer.write(JSONObject.valueToString(v)); + } + b = true; + } + writer.write(']'); + return writer; + } catch (IOException e) { + throw new JSONException(e); + } + } +} diff --git a/src/main/java/org/json/JSONException.java b/src/main/java/org/json/JSONException.java new file mode 100644 index 0000000..7d2a78c --- /dev/null +++ b/src/main/java/org/json/JSONException.java @@ -0,0 +1,28 @@ +package org.json; + +/** + * The JSONException is thrown by the JSON.org classes then things are amiss. + * @author JSON.org + * @version 2 + */ +public class JSONException extends Exception { + private Throwable cause; + + /** + * Constructs a JSONException with an explanatory message. + * @param message Detail about the reason for the exception. + */ + public JSONException(String message) { + super(message); + } + + public JSONException(Throwable t) { + super(t.getMessage()); + this.cause = t; + } + + public Throwable getCause() { + return this.cause; + } +} + diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java new file mode 100644 index 0000000..2fbd522 --- /dev/null +++ b/src/main/java/org/json/JSONObject.java @@ -0,0 +1,1327 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +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 shall be used for Good, not Evil. + +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.IOException; +import java.io.Writer; +import java.util.Collection; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * A JSONObject is an unordered collection of name/value pairs. Its + * external form is a string wrapped in curly braces with colons between the + * names and values, and commas between the values and names. The internal form + * is an object having get and opt methods for + * accessing the values by name, and put methods for adding or + * replacing values by name. The values can be any of these types: + * Boolean, JSONArray, JSONObject, + * Number, String, or the JSONObject.NULL + * object. A JSONObject constructor can be used to convert an external form + * JSON text into an internal form whose values can be retrieved with the + * get and opt methods, or to convert values into a + * JSON text using the put and toString methods. + * A get method returns a value if one can be found, and throws an + * exception if one cannot be found. An opt method returns a + * default value instead of throwing an exception, and so is useful for + * obtaining optional values. + *

+ * The generic get() and opt() methods return an + * object, which you can cast or query for type. There are also typed + * get and opt methods that do type checking and type + * coersion for you. + *

+ * The put methods adds values to an object. For example,

+ *     myString = new JSONObject().put("JSON", "Hello, World!").toString();
+ * produces the string {"JSON": "Hello, World"}. + *

+ * The texts produced by the toString methods strictly conform to + * the JSON sysntax rules. + * The constructors are more forgiving in the texts they will accept: + *

    + *
  • An extra , (comma) may appear just + * before the closing brace.
  • + *
  • Strings may be quoted with ' (single + * quote).
  • + *
  • Strings do not need to be quoted at all if they do not begin with a quote + * or single quote, and if they do not contain leading or trailing spaces, + * and if they do not contain any of these characters: + * { } [ ] / \ : , = ; # and if they do not look like numbers + * and if they are not the reserved words true, + * false, or null.
  • + *
  • Keys can be followed by = or => as well as + * by :.
  • + *
  • Values can be followed by ; (semicolon) as + * well as by , (comma).
  • + *
  • Numbers may have the 0- (octal) or + * 0x- (hex) prefix.
  • + *
  • Comments written in the slashshlash, slashstar, and hash conventions + * will be ignored.
  • + *
+ * @author JSON.org + * @version 2 + */ +public class JSONObject { + + /** + * JSONObject.NULL is equivalent to the value that JavaScript calls null, + * whilst Java's null is equivalent to the value that JavaScript calls + * undefined. + */ + private static final class Null { + + /** + * There is only intended to be a single instance of the NULL object, + * so the clone method returns itself. + * @return NULL. + */ + protected final Object clone() { + return this; + } + + + /** + * A Null object is equal to the null value and to itself. + * @param object An object to test for nullness. + * @return true if the object parameter is the JSONObject.NULL object + * or null. + */ + public boolean equals(Object object) { + return object == null || object == this; + } + + + /** + * Get the "null" string value. + * @return The string "null". + */ + public String toString() { + return "null"; + } + } + + + /** + * The hash map where the JSONObject's properties are kept. + */ + private HashMap myHashMap; + + + /** + * It is sometimes more convenient and less ambiguous to have a + * NULL object than to use Java's null value. + * JSONObject.NULL.equals(null) returns true. + * JSONObject.NULL.toString() returns "null". + */ + public static final Object NULL = new Null(); + + + /** + * Construct an empty JSONObject. + */ + public JSONObject() { + this.myHashMap = new HashMap(); + } + + + /** + * Construct a JSONObject from a subset of another JSONObject. + * An array of strings is used to identify the keys that should be copied. + * Missing keys are ignored. + * @param jo A JSONObject. + * @param sa An array of strings. + * @exception JSONException If a value is a non-finite number. + */ + public JSONObject(JSONObject jo, String[] sa) throws JSONException { + this(); + for (int i = 0; i < sa.length; i += 1) { + putOpt(sa[i], jo.opt(sa[i])); + } + } + + + /** + * Construct a JSONObject from a JSONTokener. + * @param x A JSONTokener object containing the source string. + * @throws JSONException If there is a syntax error in the source string. + */ + public JSONObject(JSONTokener x) throws JSONException { + this(); + char c; + String key; + + if (x.nextClean() != '{') { + throw x.syntaxError("A JSONObject text must begin with '{'"); + } + for (;;) { + c = x.nextClean(); + switch (c) { + case 0: + throw x.syntaxError("A JSONObject text must end with '}'"); + case '}': + return; + default: + x.back(); + key = x.nextValue().toString(); + } + + /* + * The key is followed by ':'. We will also tolerate '=' or '=>'. + */ + + c = x.nextClean(); + if (c == '=') { + if (x.next() != '>') { + x.back(); + } + } else if (c != ':') { + throw x.syntaxError("Expected a ':' after a key"); + } + put(key, x.nextValue()); + + /* + * Pairs are separated by ','. We will also tolerate ';'. + */ + + switch (x.nextClean()) { + case ';': + case ',': + if (x.nextClean() == '}') { + return; + } + x.back(); + break; + case '}': + return; + default: + throw x.syntaxError("Expected a ',' or '}'"); + } + } + } + + + /** + * Construct a JSONObject from a Map. + * @param map A map object that can be used to initialize the contents of + * the JSONObject. + */ + public JSONObject(Map map) { + this.myHashMap = (map == null) ? + new HashMap() : + new HashMap(map); + } + + + /** + * Construct a JSONObject from an Object using bean getters. + * It reflects on all of the public methods of the object. + * For each of the methods with no parameters and a name starting + * with "get" or "is" followed by an uppercase letter, + * the method is invoked, and a key and the value returned from the getter method + * are put into the new JSONObject. + * + * The key is formed by removing the "get" or "is" prefix. If the second remaining + * character is not upper case, then the first + * character is converted to lower case. + * + * For example, if an object has a method named "getName", and + * if the result of calling object.getName() is "Larry Fine", + * then the JSONObject will contain "name": "Larry Fine". + * + * @param bean An object that has getter methods that should be used + * to make a JSONObject. + */ + public JSONObject(Object bean) { + this(); + Class c = bean.getClass(); + Method[] methods = c.getMethods(); + for (int i = 0; i < methods.length; i += 1) { + try { + Method method = methods[i]; + String name = method.getName(); + String key = ""; + if (name.startsWith("get")) { + key = name.substring(3); + } else if (name.startsWith("is")) { + key = name.substring(2); + } + if (key.length() > 0 && + Character.isUpperCase(key.charAt(0)) && + method.getParameterTypes().length == 0) { + if (key.length() == 1) { + key = key.toLowerCase(); + } else if (!Character.isUpperCase(key.charAt(1))) { + key = key.substring(0, 1).toLowerCase() + + key.substring(1); + } + this.put(key, method.invoke(bean, null)); + } + } catch (Exception e) { + /* forget about it */ + } + } + } + + /** + * Construct a JSONObject from an Object, using reflection to find the + * public members. The resulting JSONObject's keys will be the strings + * from the names array, and the values will be the field values associated + * with those keys in the object. If a key is not found or not visible, + * then it will not be copied into the new JSONObject. + * @param object An object that has fields that should be used to make a + * JSONObject. + * @param names An array of strings, the names of the fields to be obtained + * from the object. + */ + public JSONObject(Object object, String names[]) { + this(); + Class c = object.getClass(); + for (int i = 0; i < names.length; i += 1) { + try { + String name = names[i]; + Field field = c.getField(name); + Object value = field.get(object); + this.put(name, value); + } catch (Exception e) { + /* forget about it */ + } + } + } + + + /** + * Construct a JSONObject from a string. + * This is the most commonly used JSONObject constructor. + * @param string A string beginning + * with { (left brace) and ending + * with } (right brace). + * @exception JSONException If there is a syntax error in the source string. + */ + public JSONObject(String string) throws JSONException { + this(new JSONTokener(string)); + } + + + /** + * Accumulate values under a key. It is similar to the put method except + * that if there is already an object stored under the key then a + * JSONArray is stored under the key to hold all of the accumulated values. + * If there is already a JSONArray, then the new value is appended to it. + * In contrast, the put method replaces the previous value. + * @param key A key string. + * @param value An object to be accumulated under the key. + * @return this. + * @throws JSONException If the value is an invalid number + * or if the key is null. + */ + public JSONObject accumulate(String key, Object value) + throws JSONException { + testValidity(value); + Object o = opt(key); + if (o == null) { + put(key, value instanceof JSONArray ? + new JSONArray().put(value) : + value); + } else if (o instanceof JSONArray) { + ((JSONArray)o).put(value); + } else { + put(key, new JSONArray().put(o).put(value)); + } + return this; + } + + + /** + * Append values to the array under a key. If the key does not exist in the + * JSONObject, then the key is put in the JSONObject with its value being a + * JSONArray containing the value parameter. If the key was already + * associated with a JSONArray, then the value parameter is appended to it. + * @param key A key string. + * @param value An object to be accumulated under the key. + * @return this. + * @throws JSONException If the key is null or if the current value + * associated with the key is not a JSONArray. + */ + public JSONObject append(String key, Object value) + throws JSONException { + testValidity(value); + Object o = opt(key); + if (o == null) { + put(key, new JSONArray().put(value)); + } else if (o instanceof JSONArray) { + put(key, ((JSONArray)o).put(value)); + } else { + throw new JSONException("JSONObject[" + key + + "] is not a JSONArray."); + } + return this; + } + + + /** + * Produce a string from a double. The string "null" will be returned if + * the number is not finite. + * @param d A double. + * @return A String. + */ + static public String doubleToString(double d) { + if (Double.isInfinite(d) || Double.isNaN(d)) { + return "null"; + } + +// Shave off trailing zeros and decimal point, if possible. + + String s = Double.toString(d); + if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) { + while (s.endsWith("0")) { + s = s.substring(0, s.length() - 1); + } + if (s.endsWith(".")) { + s = s.substring(0, s.length() - 1); + } + } + return s; + } + + + /** + * Get the value object associated with a key. + * + * @param key A key string. + * @return The object associated with the key. + * @throws JSONException if the key is not found. + */ + public Object get(String key) throws JSONException { + Object o = opt(key); + if (o == null) { + throw new JSONException("JSONObject[" + quote(key) + + "] not found."); + } + return o; + } + + + /** + * Get the boolean value associated with a key. + * + * @param key A key string. + * @return The truth. + * @throws JSONException + * if the value is not a Boolean or the String "true" or "false". + */ + public boolean getBoolean(String key) throws JSONException { + Object o = get(key); + if (o.equals(Boolean.FALSE) || + (o instanceof String && + ((String)o).equalsIgnoreCase("false"))) { + return false; + } else if (o.equals(Boolean.TRUE) || + (o instanceof String && + ((String)o).equalsIgnoreCase("true"))) { + return true; + } + throw new JSONException("JSONObject[" + quote(key) + + "] is not a Boolean."); + } + + + /** + * Get the double value associated with a key. + * @param key A key string. + * @return The numeric value. + * @throws JSONException if the key is not found or + * if the value is not a Number object and cannot be converted to a number. + */ + public double getDouble(String key) throws JSONException { + Object o = get(key); + try { + return o instanceof Number ? + ((Number)o).doubleValue() : + Double.valueOf((String)o).doubleValue(); + } catch (Exception e) { + throw new JSONException("JSONObject[" + quote(key) + + "] is not a number."); + } + } + + + /** + * Get the int value associated with a key. If the number value is too + * large for an int, it will be clipped. + * + * @param key A key string. + * @return The integer value. + * @throws JSONException if the key is not found or if the value cannot + * be converted to an integer. + */ + public int getInt(String key) throws JSONException { + Object o = get(key); + return o instanceof Number ? + ((Number)o).intValue() : (int)getDouble(key); + } + + + /** + * Get the JSONArray value associated with a key. + * + * @param key A key string. + * @return A JSONArray which is the value. + * @throws JSONException if the key is not found or + * if the value is not a JSONArray. + */ + public JSONArray getJSONArray(String key) throws JSONException { + Object o = get(key); + if (o instanceof JSONArray) { + return (JSONArray)o; + } + throw new JSONException("JSONObject[" + quote(key) + + "] is not a JSONArray."); + } + + + /** + * Get the JSONObject value associated with a key. + * + * @param key A key string. + * @return A JSONObject which is the value. + * @throws JSONException if the key is not found or + * if the value is not a JSONObject. + */ + public JSONObject getJSONObject(String key) throws JSONException { + Object o = get(key); + if (o instanceof JSONObject) { + return (JSONObject)o; + } + throw new JSONException("JSONObject[" + quote(key) + + "] is not a JSONObject."); + } + + + /** + * Get the long value associated with a key. If the number value is too + * long for a long, it will be clipped. + * + * @param key A key string. + * @return The long value. + * @throws JSONException if the key is not found or if the value cannot + * be converted to a long. + */ + public long getLong(String key) throws JSONException { + Object o = get(key); + return o instanceof Number ? + ((Number)o).longValue() : (long)getDouble(key); + } + + + /** + * Get the string associated with a key. + * + * @param key A key string. + * @return A string which is the value. + * @throws JSONException if the key is not found. + */ + public String getString(String key) throws JSONException { + return get(key).toString(); + } + + + /** + * Determine if the JSONObject contains a specific key. + * @param key A key string. + * @return true if the key exists in the JSONObject. + */ + public boolean has(String key) { + return this.myHashMap.containsKey(key); + } + + + /** + * Determine if the value associated with the key is null or if there is + * no value. + * @param key A key string. + * @return true if there is no value associated with the key or if + * the value is the JSONObject.NULL object. + */ + public boolean isNull(String key) { + return JSONObject.NULL.equals(opt(key)); + } + + + /** + * Get an enumeration of the keys of the JSONObject. + * + * @return An iterator of the keys. + */ + public Iterator keys() { + return this.myHashMap.keySet().iterator(); + } + + + /** + * Get the number of keys stored in the JSONObject. + * + * @return The number of keys in the JSONObject. + */ + public int length() { + return this.myHashMap.size(); + } + + + /** + * Produce a JSONArray containing the names of the elements of this + * JSONObject. + * @return A JSONArray containing the key strings, or null if the JSONObject + * is empty. + */ + public JSONArray names() { + JSONArray ja = new JSONArray(); + Iterator keys = keys(); + while (keys.hasNext()) { + ja.put(keys.next()); + } + return ja.length() == 0 ? null : ja; + } + + /** + * Produce a string from a Number. + * @param n A Number + * @return A String. + * @throws JSONException If n is a non-finite number. + */ + static public String numberToString(Number n) + throws JSONException { + if (n == null) { + throw new JSONException("Null pointer"); + } + testValidity(n); + +// Shave off trailing zeros and decimal point, if possible. + + String s = n.toString(); + if (s.indexOf('.') > 0 && s.indexOf('e') < 0 && s.indexOf('E') < 0) { + while (s.endsWith("0")) { + s = s.substring(0, s.length() - 1); + } + if (s.endsWith(".")) { + s = s.substring(0, s.length() - 1); + } + } + return s; + } + + + /** + * Get an optional value associated with a key. + * @param key A key string. + * @return An object which is the value, or null if there is no value. + */ + public Object opt(String key) { + return key == null ? null : this.myHashMap.get(key); + } + + + /** + * Get an optional boolean associated with a key. + * It returns false if there is no such key, or if the value is not + * Boolean.TRUE or the String "true". + * + * @param key A key string. + * @return The truth. + */ + public boolean optBoolean(String key) { + return optBoolean(key, false); + } + + + /** + * Get an optional boolean associated with a key. + * It returns the defaultValue if there is no such key, or if it is not + * a Boolean or the String "true" or "false" (case insensitive). + * + * @param key A key string. + * @param defaultValue The default. + * @return The truth. + */ + public boolean optBoolean(String key, boolean defaultValue) { + try { + return getBoolean(key); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Put a key/value pair in the JSONObject, where the value will be a + * JSONArray which is produced from a Collection. + * @param key A key string. + * @param value A Collection value. + * @return this. + * @throws JSONException + */ + public JSONObject put(String key, Collection value) throws JSONException { + put(key, new JSONArray(value)); + return this; + } + + + /** + * Get an optional double associated with a key, + * or NaN if there is no such key or if its value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A string which is the key. + * @return An object which is the value. + */ + public double optDouble(String key) { + return optDouble(key, Double.NaN); + } + + + /** + * Get an optional double associated with a key, or the + * defaultValue if there is no such key or if its value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public double optDouble(String key, double defaultValue) { + try { + Object o = opt(key); + return o instanceof Number ? ((Number)o).doubleValue() : + new Double((String)o).doubleValue(); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get an optional int value associated with a key, + * or zero if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @return An object which is the value. + */ + public int optInt(String key) { + return optInt(key, 0); + } + + + /** + * Get an optional int value associated with a key, + * or the default if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public int optInt(String key, int defaultValue) { + try { + return getInt(key); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get an optional JSONArray associated with a key. + * It returns null if there is no such key, or if its value is not a + * JSONArray. + * + * @param key A key string. + * @return A JSONArray which is the value. + */ + public JSONArray optJSONArray(String key) { + Object o = opt(key); + return o instanceof JSONArray ? (JSONArray)o : null; + } + + + /** + * Get an optional JSONObject associated with a key. + * It returns null if there is no such key, or if its value is not a + * JSONObject. + * + * @param key A key string. + * @return A JSONObject which is the value. + */ + public JSONObject optJSONObject(String key) { + Object o = opt(key); + return o instanceof JSONObject ? (JSONObject)o : null; + } + + + /** + * Get an optional long value associated with a key, + * or zero if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @return An object which is the value. + */ + public long optLong(String key) { + return optLong(key, 0); + } + + + /** + * Get an optional long value associated with a key, + * or the default if there is no such key or if the value is not a number. + * If the value is a string, an attempt will be made to evaluate it as + * a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public long optLong(String key, long defaultValue) { + try { + return getLong(key); + } catch (Exception e) { + return defaultValue; + } + } + + + /** + * Get an optional string associated with a key. + * It returns an empty string if there is no such key. If the value is not + * a string and is not null, then it is coverted to a string. + * + * @param key A key string. + * @return A string which is the value. + */ + public String optString(String key) { + return optString(key, ""); + } + + + /** + * Get an optional string associated with a key. + * It returns the defaultValue if there is no such key. + * + * @param key A key string. + * @param defaultValue The default. + * @return A string which is the value. + */ + public String optString(String key, String defaultValue) { + Object o = opt(key); + return o != null ? o.toString() : defaultValue; + } + + + /** + * Put a key/boolean pair in the JSONObject. + * + * @param key A key string. + * @param value A boolean which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(String key, boolean value) throws JSONException { + put(key, value ? Boolean.TRUE : Boolean.FALSE); + return this; + } + + + /** + * Put a key/double pair in the JSONObject. + * + * @param key A key string. + * @param value A double which is the value. + * @return this. + * @throws JSONException If the key is null or if the number is invalid. + */ + public JSONObject put(String key, double value) throws JSONException { + put(key, new Double(value)); + return this; + } + + + /** + * Put a key/int pair in the JSONObject. + * + * @param key A key string. + * @param value An int which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(String key, int value) throws JSONException { + put(key, new Integer(value)); + return this; + } + + + /** + * Put a key/long pair in the JSONObject. + * + * @param key A key string. + * @param value A long which is the value. + * @return this. + * @throws JSONException If the key is null. + */ + public JSONObject put(String key, long value) throws JSONException { + put(key, new Long(value)); + return this; + } + + + /** + * Put a key/value pair in the JSONObject, where the value will be a + * JSONObject which is produced from a Map. + * @param key A key string. + * @param value A Map value. + * @return this. + * @throws JSONException + */ + public JSONObject put(String key, Map value) throws JSONException { + put(key, new JSONObject(value)); + return this; + } + + + /** + * Put a key/value pair in the JSONObject. If the value is null, + * then the key will be removed from the JSONObject if it is present. + * @param key A key string. + * @param value An object which is the value. It should be of one of these + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, + * or the JSONObject.NULL object. + * @return this. + * @throws JSONException If the value is non-finite number + * or if the key is null. + */ + public JSONObject put(String key, Object value) throws JSONException { + if (key == null) { + throw new JSONException("Null key."); + } + if (value != null) { + testValidity(value); + this.myHashMap.put(key, value); + } else { + remove(key); + } + return this; + } + + + /** + * Put a key/value pair in the JSONObject, but only if the + * key and the value are both non-null. + * @param key A key string. + * @param value An object which is the value. It should be of one of these + * types: Boolean, Double, Integer, JSONArray, JSONObject, Long, String, + * or the JSONObject.NULL object. + * @return this. + * @throws JSONException If the value is a non-finite number. + */ + public JSONObject putOpt(String key, Object value) throws JSONException { + if (key != null && value != null) { + put(key, value); + } + return this; + } + + + /** + * Produce a string in double quotes with backslash sequences in all the + * right places. A backslash will be inserted within = '\u0080' && c < '\u00a0') || + (c >= '\u2000' && c < '\u2100')) { + t = "000" + Integer.toHexString(c); + sb.append("\\u" + t.substring(t.length() - 4)); + } else { + sb.append(c); + } + } + } + sb.append('"'); + return sb.toString(); + } + + /** + * Remove a name and its value, if present. + * @param key The name to be removed. + * @return The value that was associated with the name, + * or null if there was no value. + */ + public Object remove(String key) { + return this.myHashMap.remove(key); + } + + + /** + * Throw an exception if the object is an NaN or infinite number. + * @param o The object to test. + * @throws JSONException If o is a non-finite number. + */ + static void testValidity(Object o) throws JSONException { + if (o != null) { + if (o instanceof Double) { + if (((Double)o).isInfinite() || ((Double)o).isNaN()) { + throw new JSONException( + "JSON does not allow non-finite numbers."); + } + } else if (o instanceof Float) { + if (((Float)o).isInfinite() || ((Float)o).isNaN()) { + throw new JSONException( + "JSON does not allow non-finite numbers."); + } + } + } + } + + + /** + * Produce a JSONArray containing the values of the members of this + * JSONObject. + * @param names A JSONArray containing a list of key strings. This + * determines the sequence of the values in the result. + * @return A JSONArray of values. + * @throws JSONException If any of the values are non-finite numbers. + */ + public JSONArray toJSONArray(JSONArray names) throws JSONException { + if (names == null || names.length() == 0) { + return null; + } + JSONArray ja = new JSONArray(); + for (int i = 0; i < names.length(); i += 1) { + ja.put(this.opt(names.getString(i))); + } + return ja; + } + + /** + * Make a JSON text of this JSONObject. For compactness, no whitespace + * is added. If this would not result in a syntactically correct JSON text, + * then null will be returned instead. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @return a printable, displayable, portable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + */ + public String toString() { + try { + Iterator keys = keys(); + StringBuffer sb = new StringBuffer("{"); + + while (keys.hasNext()) { + if (sb.length() > 1) { + sb.append(','); + } + Object o = keys.next(); + sb.append(quote(o.toString())); + sb.append(':'); + sb.append(valueToString(this.myHashMap.get(o))); + } + sb.append('}'); + return sb.toString(); + } catch (Exception e) { + return null; + } + } + + + /** + * Make a prettyprinted JSON text of this JSONObject. + *

+ * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @return a printable, displayable, portable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + * @throws JSONException If the object contains an invalid number. + */ + public String toString(int indentFactor) throws JSONException { + return toString(indentFactor, 0); + } + + + /** + * Make a prettyprinted JSON text of this JSONObject. + *

+ * Warning: This method assumes that the data structure is acyclical. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @param indent The indentation of the top level. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + * @throws JSONException If the object contains an invalid number. + */ + String toString(int indentFactor, int indent) throws JSONException { + int i; + int n = length(); + if (n == 0) { + return "{}"; + } + Iterator keys = keys(); + StringBuffer sb = new StringBuffer("{"); + int newindent = indent + indentFactor; + Object o; + if (n == 1) { + o = keys.next(); + sb.append(quote(o.toString())); + sb.append(": "); + sb.append(valueToString(this.myHashMap.get(o), indentFactor, + indent)); + } else { + while (keys.hasNext()) { + o = keys.next(); + if (sb.length() > 1) { + sb.append(",\n"); + } else { + sb.append('\n'); + } + for (i = 0; i < newindent; i += 1) { + sb.append(' '); + } + sb.append(quote(o.toString())); + sb.append(": "); + sb.append(valueToString(this.myHashMap.get(o), indentFactor, + newindent)); + } + if (sb.length() > 1) { + sb.append('\n'); + for (i = 0; i < indent; i += 1) { + sb.append(' '); + } + } + } + sb.append('}'); + return sb.toString(); + } + + + /** + * Make a JSON text of an Object value. If the object has an + * value.toJSONString() method, then that method will be used to produce + * the JSON text. The method is required to produce a strictly + * conforming text. If the object does not contain a toJSONString + * method (which is the most common case), then a text will be + * produced by other means. If the value is an array or Collection, + * then a JSONArray will be made from it and its toJSONString method + * will be called. If the value is a MAP, then a JSONObject will be made + * from it and its toJSONString method will be called. Otherwise, the + * value's toString method will be called, and the result will be quoted. + * + *

+ * Warning: This method assumes that the data structure is acyclical. + * @param value The value to be serialized. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + * @throws JSONException If the value is or contains an invalid number. + */ + static String valueToString(Object value) throws JSONException { + if (value == null || value.equals(null)) { + return "null"; + } + if (value instanceof JSONString) { + Object o; + try { + o = ((JSONString)value).toJSONString(); + } catch (Exception e) { + throw new JSONException(e); + } + if (o instanceof String) { + return (String)o; + } + throw new JSONException("Bad value from toJSONString: " + o); + } + if (value instanceof Number) { + return numberToString((Number) value); + } + if (value instanceof Boolean || value instanceof JSONObject || + value instanceof JSONArray) { + return value.toString(); + } + if (value instanceof Map) { + return new JSONObject((Map)value).toString(); + } + if (value instanceof Collection) { + return new JSONArray((Collection)value).toString(); + } + if (value.getClass().isArray()) { + return new JSONArray(value).toString(); + } + return quote(value.toString()); + } + + + /** + * Make a prettyprinted JSON text of an object value. + *

+ * Warning: This method assumes that the data structure is acyclical. + * @param value The value to be serialized. + * @param indentFactor The number of spaces to add to each level of + * indentation. + * @param indent The indentation of the top level. + * @return a printable, displayable, transmittable + * representation of the object, beginning + * with { (left brace) and ending + * with } (right brace). + * @throws JSONException If the object contains an invalid number. + */ + static String valueToString(Object value, int indentFactor, int indent) + throws JSONException { + if (value == null || value.equals(null)) { + return "null"; + } + try { + if (value instanceof JSONString) { + Object o = ((JSONString)value).toJSONString(); + if (o instanceof String) { + return (String)o; + } + } + } catch (Exception e) { + /* forget about it */ + } + if (value instanceof Number) { + return numberToString((Number) value); + } + if (value instanceof Boolean) { + return value.toString(); + } + if (value instanceof JSONObject) { + return ((JSONObject)value).toString(indentFactor, indent); + } + if (value instanceof JSONArray) { + return ((JSONArray)value).toString(indentFactor, indent); + } + return quote(value.toString()); + } + + + /** + * Write the contents of the JSONObject as JSON text to a writer. + * For compactness, no whitespace is added. + *

+ * Warning: This method assumes that the data structure is acyclical. + * + * @return The writer. + * @throws JSONException + */ + public Writer write(Writer writer) throws JSONException { + try { + boolean b = false; + Iterator keys = keys(); + writer.write('{'); + + while (keys.hasNext()) { + if (b) { + writer.write(','); + } + Object k = keys.next(); + writer.write(quote(k.toString())); + writer.write(':'); + Object v = this.myHashMap.get(k); + if (v instanceof JSONObject) { + ((JSONObject)v).write(writer); + } else if (v instanceof JSONArray) { + ((JSONArray)v).write(writer); + } else { + writer.write(valueToString(v)); + } + b = true; + } + writer.write('}'); + return writer; + } catch (IOException e) { + throw new JSONException(e); + } + } +} diff --git a/src/main/java/org/json/JSONString.java b/src/main/java/org/json/JSONString.java new file mode 100644 index 0000000..3aba6b7 --- /dev/null +++ b/src/main/java/org/json/JSONString.java @@ -0,0 +1,19 @@ +package org.json; +/** + * The JSONString interface allows a toJSONString() + * method so that a class can change the behavior of + * JSONObject.toString(), JSONArray.toString(), + * and JSONWriter.value(Object). The + * toJSONString method will be used instead of the default behavior + * of using the Object's toString() method and quoting the result. + */ +public interface JSONString { + /** + * The toJSONString method allows a class to produce its own JSON + * serialization. + * + * @return A strictly syntactically correct JSON text. + */ + public String toJSONString(); +} + diff --git a/src/main/java/org/json/JSONStringer.java b/src/main/java/org/json/JSONStringer.java new file mode 100644 index 0000000..0382801 --- /dev/null +++ b/src/main/java/org/json/JSONStringer.java @@ -0,0 +1,79 @@ +package org.json; + +/* +Copyright (c) 2006 JSON.org + +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 shall be used for Good, not Evil. + +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.StringWriter; + +/** + * JSONStringer provides a quick and convenient way of producing JSON text. + * The texts produced strictly conform to JSON syntax rules. No whitespace is + * added, so the results are ready for transmission or storage. Each instance of + * JSONStringer can produce one JSON text. + *

+ * A JSONStringer instance provides a value method for appending + * values to the + * text, and a key + * method for adding keys before values in objects. There are array + * and endArray methods that make and bound array values, and + * object and endObject methods which make and bound + * object values. All of these methods return the JSONWriter instance, + * permitting cascade style. For example,

+ * myString = new JSONStringer()
+ *     .object()
+ *         .key("JSON")
+ *         .value("Hello, World!")
+ *     .endObject()
+ *     .toString();
which produces the string
+ * {"JSON":"Hello, World!"}
+ *

+ * The first method called must be array or object. + * There are no methods for adding commas or colons. JSONStringer adds them for + * you. Objects and arrays can be nested up to 20 levels deep. + *

+ * This can sometimes be easier than using a JSONObject to build a string. + * @author JSON.org + * @version 2 + */ +public class JSONStringer extends JSONWriter { + /** + * Make a fresh JSONStringer. It can be used to build one JSON text. + */ + public JSONStringer() { + super(new StringWriter()); + } + + /** + * Return the JSON text. This method is used to obtain the product of the + * JSONStringer instance. It will return null if there was a + * problem in the construction of the JSON text (such as the calls to + * array were not properly balanced with calls to + * endArray). + * @return The JSON text. + */ + public String toString() { + return this.mode == 'd' ? this.writer.toString() : null; + } +} + diff --git a/src/main/java/org/json/JSONTokener.java b/src/main/java/org/json/JSONTokener.java new file mode 100644 index 0000000..a1b54d9 --- /dev/null +++ b/src/main/java/org/json/JSONTokener.java @@ -0,0 +1,462 @@ +package org.json; + +/* +Copyright (c) 2002 JSON.org + +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 shall be used for Good, not Evil. + +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. +*/ + +/** + * A JSONTokener takes a source string and extracts characters and tokens from + * it. It is used by the JSONObject and JSONArray constructors to parse + * JSON source strings. + * @author JSON.org + * @version 2 + */ +public class JSONTokener { + + /** + * The index of the next character. + */ + private int myIndex; + + + /** + * The source string being tokenized. + */ + private String mySource; + + + /** + * Construct a JSONTokener from a string. + * + * @param s A source string. + */ + public JSONTokener(String s) { + this.myIndex = 0; + this.mySource = s; + } + + + /** + * Back up one character. This provides a sort of lookahead capability, + * so that you can test for a digit or letter before attempting to parse + * the next number or identifier. + */ + public void back() { + if (this.myIndex > 0) { + this.myIndex -= 1; + } + } + + + + /** + * Get the hex value of a character (base16). + * @param c A character between '0' and '9' or between 'A' and 'F' or + * between 'a' and 'f'. + * @return An int between 0 and 15, or -1 if c was not a hex digit. + */ + public static int dehexchar(char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + if (c >= 'A' && c <= 'F') { + return c - ('A' - 10); + } + if (c >= 'a' && c <= 'f') { + return c - ('a' - 10); + } + return -1; + } + + + /** + * Determine if the source string still contains characters that next() + * can consume. + * @return true if not yet at the end of the source. + */ + public boolean more() { + return this.myIndex < this.mySource.length(); + } + + + /** + * Get the next character in the source string. + * + * @return The next character, or 0 if past the end of the source string. + */ + public char next() { + if (more()) { + char c = this.mySource.charAt(this.myIndex); + this.myIndex += 1; + return c; + } + return 0; + } + + + /** + * Consume the next character, and check that it matches a specified + * character. + * @param c The character to match. + * @return The character. + * @throws JSONException if the character does not match. + */ + public char next(char c) throws JSONException { + char n = next(); + if (n != c) { + throw syntaxError("Expected '" + c + "' and instead saw '" + + n + "'"); + } + return n; + } + + + /** + * Get the next n characters. + * + * @param n The number of characters to take. + * @return A string of n characters. + * @throws JSONException + * Substring bounds error if there are not + * n characters remaining in the source string. + */ + public String next(int n) throws JSONException { + int i = this.myIndex; + int j = i + n; + if (j >= this.mySource.length()) { + throw syntaxError("Substring bounds error"); + } + this.myIndex += n; + return this.mySource.substring(i, j); + } + + + /** + * Get the next char in the string, skipping whitespace + * and comments (slashslash, slashstar, and hash). + * @throws JSONException + * @return A character, or 0 if there are no more characters. + */ + public char nextClean() throws JSONException { + for (;;) { + char c = next(); + if (c == '/') { + switch (next()) { + case '/': + do { + c = next(); + } while (c != '\n' && c != '\r' && c != 0); + break; + case '*': + for (;;) { + c = next(); + if (c == 0) { + throw syntaxError("Unclosed comment"); + } + if (c == '*') { + if (next() == '/') { + break; + } + back(); + } + } + break; + default: + back(); + return '/'; + } + } else if (c == '#') { + do { + c = next(); + } while (c != '\n' && c != '\r' && c != 0); + } else if (c == 0 || c > ' ') { + return c; + } + } + } + + + /** + * Return the characters up to the next close quote character. + * Backslash processing is done. The formal JSON format does not + * allow strings in single quotes, but an implementation is allowed to + * accept them. + * @param quote The quoting character, either + * " (double quote) or + * ' (single quote). + * @return A String. + * @throws JSONException Unterminated string. + */ + public String nextString(char quote) throws JSONException { + char c; + StringBuffer sb = new StringBuffer(); + for (;;) { + c = next(); + switch (c) { + case 0: + case '\n': + case '\r': + throw syntaxError("Unterminated string"); + case '\\': + c = next(); + switch (c) { + case 'b': + sb.append('\b'); + break; + case 't': + sb.append('\t'); + break; + case 'n': + sb.append('\n'); + break; + case 'f': + sb.append('\f'); + break; + case 'r': + sb.append('\r'); + break; + case 'u': + sb.append((char)Integer.parseInt(next(4), 16)); + break; + case 'x' : + sb.append((char) Integer.parseInt(next(2), 16)); + break; + default: + sb.append(c); + } + break; + default: + if (c == quote) { + return sb.toString(); + } + sb.append(c); + } + } + } + + + /** + * Get the text up but not including the specified character or the + * end of line, whichever comes first. + * @param d A delimiter character. + * @return A string. + */ + public String nextTo(char d) { + StringBuffer sb = new StringBuffer(); + for (;;) { + char c = next(); + if (c == d || c == 0 || c == '\n' || c == '\r') { + if (c != 0) { + back(); + } + return sb.toString().trim(); + } + sb.append(c); + } + } + + + /** + * Get the text up but not including one of the specified delimeter + * characters or the end of line, whichever comes first. + * @param delimiters A set of delimiter characters. + * @return A string, trimmed. + */ + public String nextTo(String delimiters) { + char c; + StringBuffer sb = new StringBuffer(); + for (;;) { + c = next(); + if (delimiters.indexOf(c) >= 0 || c == 0 || + c == '\n' || c == '\r') { + if (c != 0) { + back(); + } + return sb.toString().trim(); + } + sb.append(c); + } + } + + + /** + * Get the next value. The value can be a Boolean, Double, Integer, + * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object. + * @throws JSONException If syntax error. + * + * @return An object. + */ + public Object nextValue() throws JSONException { + char c = nextClean(); + String s; + + switch (c) { + case '"': + case '\'': + return nextString(c); + case '{': + back(); + return new JSONObject(this); + case '[': + back(); + return new JSONArray(this); + } + + /* + * Handle unquoted text. This could be the values true, false, or + * null, or it can be a number. An implementation (such as this one) + * is allowed to also accept non-standard forms. + * + * Accumulate characters until we reach the end of the text or a + * formatting character. + */ + + StringBuffer sb = new StringBuffer(); + char b = c; + while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { + sb.append(c); + c = next(); + } + back(); + + /* + * If it is true, false, or null, return the proper value. + */ + + s = sb.toString().trim(); + if (s.equals("")) { + throw syntaxError("Missing value"); + } + if (s.equalsIgnoreCase("true")) { + return Boolean.TRUE; + } + if (s.equalsIgnoreCase("false")) { + return Boolean.FALSE; + } + if (s.equalsIgnoreCase("null")) { + return JSONObject.NULL; + } + + /* + * If it might be a number, try converting it. We support the 0- and 0x- + * conventions. If a number cannot be produced, then the value will just + * be a string. Note that the 0-, 0x-, plus, and implied string + * conventions are non-standard. A JSON parser is free to accept + * non-JSON forms as long as it accepts all correct JSON forms. + */ + + if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { + if (b == '0') { + if (s.length() > 2 && + (s.charAt(1) == 'x' || s.charAt(1) == 'X')) { + try { + return new Integer(Integer.parseInt(s.substring(2), + 16)); + } catch (Exception e) { + /* Ignore the error */ + } + } else { + try { + return new Integer(Integer.parseInt(s, 8)); + } catch (Exception e) { + /* Ignore the error */ + } + } + } + try { + return new Integer(s); + } catch (Exception e) { + try { + return new Long(s); + } catch (Exception f) { + try { + return new Double(s); + } catch (Exception g) { + return s; + } + } + } + } + return s; + } + + + /** + * Skip characters until the next character is the requested character. + * If the requested character is not found, no characters are skipped. + * @param to A character to skip to. + * @return The requested character, or zero if the requested character + * is not found. + */ + public char skipTo(char to) { + char c; + int index = this.myIndex; + do { + c = next(); + if (c == 0) { + this.myIndex = index; + return c; + } + } while (c != to); + back(); + return c; + } + + + /** + * Skip characters until past the requested string. + * If it is not found, we are left at the end of the source. + * @param to A string to skip past. + */ + public boolean skipPast(String to) { + this.myIndex = this.mySource.indexOf(to, this.myIndex); + if (this.myIndex < 0) { + this.myIndex = this.mySource.length(); + return false; + } + this.myIndex += to.length(); + return true; + + } + + + /** + * Make a JSONException to signal a syntax error. + * + * @param message The error message. + * @return A JSONException object, suitable for throwing + */ + public JSONException syntaxError(String message) { + return new JSONException(message + toString()); + } + + + /** + * Make a printable string of this JSONTokener. + * + * @return " at character [this.myIndex] of [this.mySource]" + */ + public String toString() { + return " at character " + this.myIndex + " of " + this.mySource; + } +} diff --git a/src/main/java/org/json/JSONWriter.java b/src/main/java/org/json/JSONWriter.java new file mode 100644 index 0000000..c3fc4c0 --- /dev/null +++ b/src/main/java/org/json/JSONWriter.java @@ -0,0 +1,319 @@ +package org.json; + +import java.io.IOException; +import java.io.Writer; + +/* +Copyright (c) 2006 JSON.org + +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 shall be used for Good, not Evil. + +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. +*/ + +/** + * JSONWriter provides a quick and convenient way of producing JSON text. + * The texts produced strictly conform to JSON syntax rules. No whitespace is + * added, so the results are ready for transmission or storage. Each instance of + * JSONWriter can produce one JSON text. + *

+ * A JSONWriter instance provides a value method for appending + * values to the + * text, and a key + * method for adding keys before values in objects. There are array + * and endArray methods that make and bound array values, and + * object and endObject methods which make and bound + * object values. All of these methods return the JSONWriter instance, + * permitting a cascade style. For example,

+ * new JSONWriter(myWriter)
+ *     .object()
+ *         .key("JSON")
+ *         .value("Hello, World!")
+ *     .endObject();
which writes
+ * {"JSON":"Hello, World!"}
+ *

+ * The first method called must be array or object. + * There are no methods for adding commas or colons. JSONWriter adds them for + * you. Objects and arrays can be nested up to 20 levels deep. + *

+ * This can sometimes be easier than using a JSONObject to build a string. + * @author JSON.org + * @version 2 + */ +public class JSONWriter { + private static final int maxdepth = 20; + + /** + * The comma flag determines if a comma should be output before the next + * value. + */ + private boolean comma; + + /** + * The current mode. Values: + * 'a' (array), + * 'd' (done), + * 'i' (initial), + * 'k' (key), + * 'o' (object). + */ + protected char mode; + + /** + * The object/array stack. + */ + private char stack[]; + + /** + * The stack top index. A value of 0 indicates that the stack is empty. + */ + private int top; + + /** + * The writer that will receive the output. + */ + protected Writer writer; + + /** + * Make a fresh JSONWriter. It can be used to build one JSON text. + */ + public JSONWriter(Writer w) { + this.comma = false; + this.mode = 'i'; + this.stack = new char[maxdepth]; + this.top = 0; + this.writer = w; + } + + /** + * Append a value. + * @param s A string value. + * @return this + * @throws JSONException If the value is out of sequence. + */ + private JSONWriter append(String s) throws JSONException { + if (s == null) { + throw new JSONException("Null pointer"); + } + if (this.mode == 'o' || this.mode == 'a') { + try { + if (this.comma && this.mode == 'a') { + this.writer.write(','); + } + this.writer.write(s); + } catch (IOException e) { + throw new JSONException(e); + } + if (this.mode == 'o') { + this.mode = 'k'; + } + this.comma = true; + return this; + } + throw new JSONException("Value out of sequence."); + } + + /** + * Begin appending a new array. All values until the balancing + * endArray will be appended to this array. The + * endArray method must be called to mark the array's end. + * @return this + * @throws JSONException If the nesting is too deep, or if the object is + * started in the wrong place (for example as a key or after the end of the + * outermost array or object). + */ + public JSONWriter array() throws JSONException { + if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') { + this.push('a'); + this.append("["); + this.comma = false; + return this; + } + throw new JSONException("Misplaced array."); + } + + /** + * End something. + * @param m Mode + * @param c Closing character + * @return this + * @throws JSONException If unbalanced. + */ + private JSONWriter end(char m, char c) throws JSONException { + if (this.mode != m) { + throw new JSONException(m == 'o' ? "Misplaced endObject." : + "Misplaced endArray."); + } + this.pop(m); + try { + this.writer.write(c); + } catch (IOException e) { + throw new JSONException(e); + } + this.comma = true; + return this; + } + + /** + * End an array. This method most be called to balance calls to + * array. + * @return this + * @throws JSONException If incorrectly nested. + */ + public JSONWriter endArray() throws JSONException { + return this.end('a', ']'); + } + + /** + * End an object. This method most be called to balance calls to + * object. + * @return this + * @throws JSONException If incorrectly nested. + */ + public JSONWriter endObject() throws JSONException { + return this.end('k', '}'); + } + + /** + * Append a key. The key will be associated with the next value. In an + * object, every value must be preceded by a key. + * @param s A key string. + * @return this + * @throws JSONException If the key is out of place. For example, keys + * do not belong in arrays or if the key is null. + */ + public JSONWriter key(String s) throws JSONException { + if (s == null) { + throw new JSONException("Null key."); + } + if (this.mode == 'k') { + try { + if (this.comma) { + this.writer.write(','); + } + this.writer.write(JSONObject.quote(s)); + this.writer.write(':'); + this.comma = false; + this.mode = 'o'; + return this; + } catch (IOException e) { + throw new JSONException(e); + } + } + throw new JSONException("Misplaced key."); + } + + + /** + * Begin appending a new object. All keys and values until the balancing + * endObject will be appended to this object. The + * endObject method must be called to mark the object's end. + * @return this + * @throws JSONException If the nesting is too deep, or if the object is + * started in the wrong place (for example as a key or after the end of the + * outermost array or object). + */ + public JSONWriter object() throws JSONException { + if (this.mode == 'i') { + this.mode = 'o'; + } + if (this.mode == 'o' || this.mode == 'a') { + this.append("{"); + this.push('k'); + this.comma = false; + return this; + } + throw new JSONException("Misplaced object."); + + } + + + /** + * Pop an array or object scope. + * @param c The scope to close. + * @throws JSONException If nesting is wrong. + */ + private void pop(char c) throws JSONException { + if (this.top <= 0 || this.stack[this.top - 1] != c) { + throw new JSONException("Nesting error."); + } + this.top -= 1; + this.mode = this.top == 0 ? 'd' : this.stack[this.top - 1]; + } + + /** + * Push an array or object scope. + * @param c The scope to open. + * @throws JSONException If nesting is too deep. + */ + private void push(char c) throws JSONException { + if (this.top >= maxdepth) { + throw new JSONException("Nesting too deep."); + } + this.stack[this.top] = c; + this.mode = c; + this.top += 1; + } + + + /** + * Append either the value true or the value + * false. + * @param b A boolean. + * @return this + * @throws JSONException + */ + public JSONWriter value(boolean b) throws JSONException { + return this.append(b ? "true" : "false"); + } + + /** + * Append a double value. + * @param d A double. + * @return this + * @throws JSONException If the number is not finite. + */ + public JSONWriter value(double d) throws JSONException { + return this.value(new Double(d)); + } + + /** + * Append a long value. + * @param l A long. + * @return this + * @throws JSONException + */ + public JSONWriter value(long l) throws JSONException { + return this.append(Long.toString(l)); + } + + + /** + * Append an object value. + * @param o The object to append. It can be null, or a Boolean, Number, + * String, JSONObject, or JSONArray, or an object with a toJSONString() + * method. + * @return this + * @throws JSONException If the value is out of sequence. + */ + public JSONWriter value(Object o) throws JSONException { + return this.append(JSONObject.valueToString(o)); + } +} + diff --git a/src/main/java/scratch.jpage b/src/main/java/scratch.jpage new file mode 100644 index 0000000..47c4ead --- /dev/null +++ b/src/main/java/scratch.jpage @@ -0,0 +1,16 @@ +System.getProperty("user.dir")(java.lang.String) D:\workspace\j2js-compiler new java.io.File(System.getProperty("user.dir")).getName()(java.lang.String) j2js-compiler String s = "aaas\nsdsd"; s.replaceAll("\\n", "\\\\n") false == false new java.io.File("d:\\data").isDirectory() java.net.URLEncoder.encode("foo/ bar")(java.lang.String) foo%2F+bar(java.lang.String) foo%2Fbar java.io.File file = new java.io.File("data/foo"); file.getCanonicalPath()(java.lang.String) D:\workspace\j2js-Compiler\data\foo java.net.URI base = new java.net.URI("file:docs/tutorial1.html"); java.net.URI uri = new java.net.URI("file:projects/j2js-Demos/src/site/HelloWorld1.html.html"); base.relativize(uri) java.io.File baseFile = new java.io.File("src"); baseFile.getCanonicalPath() (java.lang.String) D:\workspace\j2js-Compiler\src int i; double d = 1; for (i=0; i<30; i++) { d = d*(365-i)/365; } 1-d new Character('|').toString() "a^b:c,b".split("[:,]")(java.lang.String[]) [a^b, c, b] "01".matches("0*[1-9]\\d*")(boolean) true "foo\r\nbar".replaceAll("\\r", "").split("\n"); "%a".split("%")(java.lang.String[]) [, a] java.util.Formatter f = new java.util.Formatter(); String.format("%1$ta, %1$td %1$tb %1$tY %1$tT %1$tZ", new java.util.Date()); "j2js.demo.powerdash.Shapes#compare(java.lang.Object,java.lang.Object)".matches(".*#compare\\(java\\.lang\\.Object,java\\.lang\\.Object\\)");(boolean) true String pattern = "*#compare(java.lang.Object,java.lang.Object)"; pattern = pattern.replaceAll("\\.", "\\\\."); pattern = pattern.replaceAll("\\*", ".*"); pattern = pattern.replaceAll("\\(", "\\\\("); pattern = pattern.replaceAll("\\)", "\\\\)"); "j2js.demo.powerdash.Shapes#compare(java.lang.Object,java.lang.Object)".matches(pattern) "foo(bar".replaceAll("\\(", "\\\\\\\\(") "foo.bar".split("\\.") "fo.o.bar".replaceAll("\\.[^.]*$", "") java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("id\\s*=\\s*[\'\"]j2js-loader[\'\"].*src\\s*=\\s*[\'\"]([^\'\"]+)/0\\.js[\'\"]", java.util.regex.Pattern.DOTALL | java.util.regex.Pattern.CASE_INSENSITIVE); java.util.regex.Matcher matcher = pattern.matcher("\n\n"); matcher.find(); matcher.group(1) matcher.find(); matcher.group(0); matcher.find(); matcher.group(0); "foo\n\\bar".replaceAll("\\\\", "\\\\\\\\").replaceAll("\\\\\\\\", "\\\\")(java.lang.String) foo +\bar " // foo".matches("\\s*//.*") " /*dsd".matches("\\s*/\\*.*") "+NaN ".matches("(\\+|\\-)?NaN") java.net.URI uri = new java.net.URI("http://foo.bar/foo/skin/text.txt"); java.net.URI root = new java.net.URI("http://foo.bar/foo/print?a=b"); root.resolve("../").relativize(uri)(java.net.URI) foo/skin/text.txt java.net.URI rel = root.relativize(uri1); if (!rel.isAbsolute()) { int i = rel.getPath().split("/").length - 1; String s = ""; for (int j=0; j + + + + + + + + + +

Generic J2JS Automation Client

+ +
+ + + + + + diff --git a/src/main/resources/instructions.xml b/src/main/resources/instructions.xml new file mode 100644 index 0000000..e1d5afa --- /dev/null +++ b/src/main/resources/instructions.xml @@ -0,0 +1,1920 @@ + + + + aaload + 50 +
+ arrayref + index + objectref +
+
+ + + aastore + 83 +
+ arrayref + index + value +
+
+ + + aconst_null + 1 +
+ null +
+
+ + + aload + 25 +
+ index + objectref +
+
+ + + aload_0 + 42 +
+ objectref +
+
+ + + aload_1 + 43 +
+ objectref +
+
+ + + aload_2 + 44 +
+ objectref +
+
+ + + aload_3 + 45 +
+ objectref +
+
+ + + anewarray + 189 +
+ index + count + arrayref +
+
+ + + areturn + 176 +
+ objectref + + +
+ + + arraylength + 190 +
+ arrayref + length +
+
+ + + astore + 58 +
+ index + objectref +
+
+ + + astore_0 + 75 +
+ objectref +
+
+ + + astore_1 + 76 +
+ objectref +
+
+ + + astore_2 + 77 +
+ objectref +
+
+ + + astore_3 + 78 +
+ objectref +
+
+ + + athrow + 191 +
+ objectref + objectref +
+
+ + + baload + 51 +
+ arrayref + index + value +
+
+ + + bastore + 84 +
+ arrayref + index + value +
+
+ + + bipush + 16 +
+ byte + value +
+
+ + + + new + 187 +
+ index + objectref +
+
+ + + newarray + 188 +
+ atype + count + arrayref +
+
+ + + nop + 0 +
+
+
+ + + pop + 87 +
+ value +
+
+ + + pop2 + 88 +
+ value +
+
+ value2 + value1 +
+
+ + + putfield + 181 +
+ index + objectref + value +
+
+ + + putstatic + 179 +
+ index + value +
+
+ + + ret + 169 +
+ index +
+
+ + + return + 177 +
+ + +
+ + + saload + 53 +
+ arrayref + index + value +
+
+ + + sastore + 86 +
+ array + index + value +
+
+ + + sipush + 17 +
+ byte byte1 + byte byte2 + value +
+
+ + + swap + 95 +
+ value2 + value1 + value1 + value2 +
+
+ + + tableswitch + 170 +
+ padding + padding + padding + default + low + high + + index +
+
+ + + wide + 196 +
+
+
+ + + caload + 52 +
+ arrayref + index + value +
+
+ + + castore + 85 +
+ arrayref + index + value +
+
+ + + checkcast + 192 +
+ index + objectref + objectref +
+
+ + + d2f + 144 +
+ value + result +
+
+ + + d2i + 142 +
+ value + result +
+
+ + + d2l + 143 +
+ value + result +
+
+ + + dadd + 99 +
+ value1 + value2 + result +
+
+ + + daload + 49 +
+ arrayref + index + value +
+
+ + + dastore + 82 +
+ arrayref + index + value +
+
+ + + dcmpl + 151 +
+ value1 + value2 + result +
+
+ + + dcmpg + 152 +
+ value1 + value2 + result +
+
+ + + dconst_0 + 14 +
+ d +
+
+ + + dconst_1 + 15 +
+ d +
+
+ + + ddiv + 111 +
+ value1 + value2 + result +
+
+ + + dload + 24 +
+ index + value +
+
+ + + dload_0 + 38 +
+ value +
+
+ + + dload_1 + 39 +
+ value +
+
+ + + dload_2 + 40 +
+ value +
+
+ + + dload_3 + 41 +
+ value +
+
+ + + dmul + 107 +
+ value1 + value2 + result +
+
+ + + dneg + 119 +
+ value + result +
+
+ + + drem + 115 +
+ value1 + value2 + result +
+
+ + + dreturn + 175 +
+ value + + +
+ + + dstore + 57 +
+ index + value +
+
+ + + dstore_0 + 71 +
+ value +
+
+ + + dstore_1 + 72 +
+ value +
+
+ + + dstore_2 + 73 +
+ value +
+
+ + + dstore_3 + 74 +
+ value +
+
+ + + dsub + 103 +
+ value1 + value2 + result +
+
+ + + dup + 89 +
+ value + value + value +
+
+ + + dup_x1 + 90 +
+ value2 + value1 + value1 + value2 + value1 +
+
+ + + dup_x2 + 91 +
+ value3 + value2 + value1 + value1 + value3 + value2 + value1 +
+
+ value2 + value1 + value1 + value2 + value1 +
+
+ + + dup2 + 92 +
+ value2 + value1 + value2 + value1 + value2 + value1 +
+
+ value + value + value +
+
+ + + dup2_x1 + 93 +
+ value3 + value2 + value1 + value2 + value1 + value3 + value2 + value1 +
+
+ value2 + value1 + value1 + value2 + value1 +
+
+ + + dup2_x2 + 94 +
+ value4 + value3 + value2 + value1 + value2 + value1 + value4 + value3 + value2 + value1 +
+
+ value3 + value2 + value1 + value1 + value3 + value2 + value1 +
+
+ value3 + value2 + value1 + value2 + value1 + value3 + value2 + value1 +
+
+ value2 + value1 + value1 + value2 + value1 +
+
+ + + f2d + 141 +
+ value + result +
+
+ + + f2i + 139 +
+ value + result +
+
+ + + f2l + 140 +
+ value + result +
+
+ + + fadd + 98 +
+ value1 + value2 + result +
+
+ + + faload + 48 +
+ arrayref + index + value +
+
+ + + fastore + 81 +
+ arrayref + index + value +
+
+ + + fcmpl + 149 +
+ value1 + value2 + result +
+
+ + + fcmpg + 150 +
+ value1 + value2 + result +
+
+ + + fconst_0 + 11 +
+ f +
+
+ + + fconst_1 + 12 +
+ f +
+
+ + + fconst_2 + 13 +
+ f +
+
+ + + fdiv + 110 +
+ value1 + value2 + result +
+
+ + + fload + 23 +
+ index + value +
+
+ + + fload_0 + 34 +
+ value +
+
+ + + fload_1 + 35 +
+ value +
+
+ + + fload_2 + 36 +
+ value +
+
+ + + fload_3 + 37 +
+ value +
+
+ + + fmul + 106 +
+ value1 + value2 + result +
+
+ + + fneg + 118 +
+ value + result +
+
+ + + frem + 114 +
+ value1 + value2 + result +
+
+ + + freturn + 174 +
+ value + + +
+ + + fstore + 56 +
+ index + value +
+
+ + + fstore_0 + 67 +
+ value +
+
+ + + fstore_1 + 68 +
+ value +
+
+ + + fstore_2 + 69 +
+ value +
+
+ + + fstore_3 + 70 +
+ value +
+
+ + + fsub + 102 +
+ value1 + value2 + result +
+
+ + + getfield + 180 +
+ index + objectref + value +
+
+ + + getstatic + 178 +
+ index + value +
+
+ + + goto + 167 +
+ branch +
+
+ + + goto_w + 200 +
+ branch +
+
+ + + i2b + 145 +
+ value + result +
+
+ + + i2c + 146 +
+ value + result +
+
+ + + i2d + 135 +
+ value + result +
+
+ + + i2f + 134 +
+ value + result +
+
+ + + i2l + 133 +
+ value + result +
+
+ + + i2s + 147 +
+ value + result +
+
+ + + iadd + 96 +
+ value1 + value2 + result +
+
+ + + iaload + 46 +
+ arrayref + index + value +
+
+ + + iand + 126 +
+ value1 + value2 + result +
+
+ + + iastore + 79 +
+ arrayref + index + value +
+
+ + + iconst_m1 + 2 +
+ i +
+
+ + + iconst_0 + 3 +
+ i +
+
+ + + iconst_1 + 4 +
+ i +
+
+ + + iconst_2 + 5 +
+ i +
+
+ + + iconst_3 + 6 +
+ i +
+
+ + + iconst_4 + 7 +
+ i +
+
+ + + iconst_5 + 8 +
+ i +
+
+ + + idiv + 108 +
+ value1 + value2 + result +
+
+ + + if_acmpeq + 165 +
+ branch + value1 + value2 +
+
+ + + if_acmpne + 166 +
+ branch + value1 + value2 +
+
+ + + if_icmpeq + 159 +
+ branch + value1 + value2 +
+
+ + + if_icmpne + 160 +
+ branch + value1 + value2 +
+
+ + if_icmplt + 161 +
+ branch + value1 + value2 +
+
+ + if_icmpge + 162 +
+ branch + value1 + value2 +
+
+ + if_icmpgt + 163 +
+ branch + value1 + value2 +
+
+ + if_icmple + 164 +
+ branch + value1 + value2 +
+
+ + + ifeq + 153 +
+ branch + value +
+
+ + + ifne + 154 +
+ branch + value +
+
+ + + iflt + 155 +
+ branch + value +
+
+ + + ifge + 156 +
+ branch + value +
+
+ + + ifgt + 157 +
+ branch + value +
+
+ + + ifle + 158 +
+ branch + value +
+
+ + + ifnonnull + 199 +
+ branch + value +
+
+ + + ifnull + 198 +
+ branch + value +
+
+ + + iinc + 132 +
+ index + const +
+
+ + + iload + 21 +
+ index + value +
+
+ + + iload_0 + 26 +
+ value +
+
+ + + iload_1 + 27 +
+ value +
+
+ + + iload_2 + 28 +
+ value +
+
+ + + iload_3 + 29 +
+ value +
+
+ + + imul + 104 +
+ value1 + value2 + result +
+
+ + + ineg + 116 +
+ value + result +
+
+ + + instanceof + 193 +
+ index + objectref + result +
+
+ + + invokeinterface + 185 +
+ index + count + 0 + objectref + arg1 + ... + argN +
+
+ + + index + invokespecial + 183 +
+ objectref + arg1 + ... + argN +
+
+ + + invokestatic + 184 +
+ index + arg1 + ... + argN +
+
+ + + invokevirtual + 182 +
+ objectref + arg1 + ... + argN +
+
+ + + ior + 128 +
+ value1 + value2 + result +
+
+ + + irem + 112 +
+ value1 + value2 + result +
+
+ + + ireturn + 172 +
+ value + + +
+ + + ishl + 120 +
+ value1 + value2 + result +
+
+ + + ishr + 122 +
+ value1 + value2 + result +
+
+ + + istore + 54 +
+ index + value +
+
+ + + istore_0 + 59 +
+ value +
+
+ + + istore_1 + 60 +
+ value +
+
+ + + istore_2 + 61 +
+ value +
+
+ + + istore_3 + 62 +
+ value +
+
+ + + isub + 100 +
+ value1 + value2 + result +
+
+ + + iushr + 124 +
+ value1 + value2 + result +
+
+ + + ixor + 130 +
+ value1 + value2 + result +
+
+ + + jsr + 168 +
+ branch + address +
+
+ + + jsr_w + 201 +
+ branch + address +
+
+ + + l2d + 138 +
+ value + result +
+
+ + + l2f + 137 +
+ value + result +
+
+ + + l2i + 136 +
+ value + result +
+
+ + + ladd + 97 +
+ value1 + value2 + result +
+
+ + + laload + 47 +
+ arrayref + index + value +
+
+ + + land + 127 +
+ value1 + value2 + result +
+
+ + + lastore + 80 +
+ arrayref + index + value +
+
+ + + lcmp + 148 +
+ value1 + value2 + result +
+
+ + + lconst_0 + 9 +
+ l +
+
+ + + lconst_1 + 10 +
+ l +
+
+ + + ldc + 18 +
+ index + value +
+
+ + + ldc_w + 19 +
+ value +
+
+ + + ldc2_w + 20 +
+ value +
+
+ + + ldiv + 109 +
+ value1 + value2 + result +
+
+ + + lload + 22 +
+ index + value +
+
+ + + lload_0 + 30 +
+ value +
+
+ + + lload_1 + 31 +
+ value +
+
+ + + lload_2 + 32 +
+ value +
+
+ + + lload_3 + 33 +
+ value +
+
+ + + lmul + 105 +
+ value1 + value2 + result +
+
+ + + lneg + 117 +
+ value + result +
+
+ + + lookupswitch + 171 +
+ padding + padding + padding + default + npairs + + key +
+
+ + + lor + 129 +
+ value1 + value2 + result +
+
+ + + lrem + 113 +
+ value1 + value2 + result +
+
+ + + lreturn + 173 +
+ value + + +
+ + + lshl + 121 +
+ value1 + value2 + result +
+
+ + + lshr + 123 +
+ value1 + value2 + result +
+
+ + + lstore + 55 +
+ index + value +
+
+ + + lstore_0 + 63 +
+ value +
+
+ + + lstore_1 + 64 +
+ value +
+
+ + + lstore_2 + 65 +
+ value +
+
+ + + lstore_3 + 66 +
+ value +
+
+ + + lsub + 101 +
+ value1 + value2 + result +
+
+ + + lushr + 125 +
+ value1 + value2 + result +
+
+ + + lxor + 131 +
+ value1 + value2 + result +
+
+ + + monitorenter + 194 +
+ objectref +
+
+ + + monitorexit + 195 +
+ objectref +
+
+ + + multianewarray + 197 +
+ index + dimension N + count1 + ... + countN + arrayref +
+
+ + + xxxunusedxxx + 186 +
+
+
+ +
diff --git a/src/main/resources/instructions.xsl b/src/main/resources/instructions.xsl new file mode 100644 index 0000000..fd40da1 --- /dev/null +++ b/src/main/resources/instructions.xsl @@ -0,0 +1,50 @@ + + + + + + + package com.j2js; + public class Const { + + public static InstructionType[] instructionTypes = new InstructionType[]; + + + + static { + InstructionType i; + Form f; + + + + } + } + + + + + i = new InstructionType((short), "", ); + + instructionTypes[] = i; + + + + f = new Form(); + f.setIns(new Form.Value[]{}); + f.setOuts(new Form.Value[]{}); + f.setOperands(new Form.Value[]{}); + i.setForm(f, ); + + + + public static final int = ; + + + new Form.Value("",""), + + new Form.Value("",""), + + new Form.Value("",""), + + diff --git a/src/main/resources/j2js.properties b/src/main/resources/j2js.properties new file mode 100644 index 0000000..2a76496 --- /dev/null +++ b/src/main/resources/j2js.properties @@ -0,0 +1,25 @@ +j2js.version = 1.2 + +# See documentation in file compile.html. +# TODO: Add classes needed for annotation support! +# Begin preTaintedSignatures +j2js.preTaintedSignatures = \ + java.lang.NullPointerException#(java.lang.String)void; \ + java.lang.RuntimeException#(java.lang.String)void; \ + java.lang.Throwable#printStackTrace()void; \ + java.lang.Throwable#fillInStackTrace()java.lang.Throwable; \ + java.lang.Throwable#toString()java.lang.String; \ + com.j2js.prodmode.ContextImpl#premain(java.lang.String,java.lang.String)void; \ + java.lang.reflect.Proxy#invoke(\ + java.lang.reflect.Proxy,\ + java.lang.String,java.lang.Object[])java.lang.Object; \ + j2js.client.Engine#getEngine()j2js.client.Engine; +# End preTaintedSignatures + +# See documentation in file compile.html. +# Begin taintIfInstantiated +j2js.taintIfInstantiated = \ + *#handleEvent(*)void; \ + *#compare(java.lang.Object,java.lang.Object)int; \ + *#invoke(*)void +# End taintIfInstantiated \ No newline at end of file diff --git a/src/main/resources/notfound.html b/src/main/resources/notfound.html new file mode 100644 index 0000000..c8d2499 --- /dev/null +++ b/src/main/resources/notfound.html @@ -0,0 +1,9 @@ + + +404 Not Found + +

Not Found

+

The requested URL $target was not found on this server.

+
+
Embedded Jetty at $ServerName Port $port
+ diff --git a/src/main/resources/smalllogo.gif b/src/main/resources/smalllogo.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b25eaf6a16eeb7069822e9e074414c865353c5b GIT binary patch literal 883 zcmZ?wbhEHb6k`x%_|5=s8UjN-1P&ZH@E_=h{|x`Z z6p#k8fItW2F;HG`;D}%lylN0H+!}GXMYp literal 0 HcmV?d00001