From b14787dd813cd111cc0a02c985565fe6098f0def Mon Sep 17 00:00:00 2001 From: hns Date: Fri, 29 Dec 2000 17:58:10 +0000 Subject: [PATCH] Check in modified FESI 1.1.4 --- src/FESI/AST/ASTAllocationExpression.java | 28 + src/FESI/AST/ASTAndExpressionSequence.java | 28 + src/FESI/AST/ASTAssignmentExpression.java | 28 + src/FESI/AST/ASTBinaryExpressionSequence.java | 28 + src/FESI/AST/ASTBreakStatement.java | 28 + src/FESI/AST/ASTCompositeReference.java | 28 + src/FESI/AST/ASTConditionalExpression.java | 28 + src/FESI/AST/ASTContinueStatement.java | 28 + src/FESI/AST/ASTEmptyExpression.java | 28 + src/FESI/AST/ASTExpressionList.java | 28 + src/FESI/AST/ASTForInStatement.java | 28 + src/FESI/AST/ASTForStatement.java | 28 + src/FESI/AST/ASTForVarInStatement.java | 28 + src/FESI/AST/ASTForVarStatement.java | 28 + src/FESI/AST/ASTFormalParameterList.java | 39 + src/FESI/AST/ASTFunctionCallParameters.java | 28 + src/FESI/AST/ASTFunctionDeclaration.java | 38 + src/FESI/AST/ASTIdentifier.java | 50 + src/FESI/AST/ASTIfStatement.java | 28 + src/FESI/AST/ASTLiteral.java | 210 + src/FESI/AST/ASTOperator.java | 44 + src/FESI/AST/ASTOrExpressionSequence.java | 28 + src/FESI/AST/ASTPostfixExpression.java | 28 + src/FESI/AST/ASTProgram.java | 28 + .../AST/ASTPropertyIdentifierReference.java | 28 + src/FESI/AST/ASTPropertyValueReference.java | 28 + src/FESI/AST/ASTReturnStatement.java | 28 + src/FESI/AST/ASTStatement.java | 28 + src/FESI/AST/ASTStatementList.java | 28 + src/FESI/AST/ASTThisReference.java | 28 + src/FESI/AST/ASTUnaryExpression.java | 28 + src/FESI/AST/ASTVariableDeclaration.java | 28 + src/FESI/AST/ASTWhileStatement.java | 28 + src/FESI/AST/ASTWithStatement.java | 40 + src/FESI/AST/EcmaScriptDumpVisitor.java | 263 + src/FESI/AST/EcmaScriptTreeConstants.java | 81 + src/FESI/AST/EcmaScriptVisitor.java | 42 + src/FESI/AST/JJTEcmaScriptState.java | 123 + src/FESI/AST/Node.java | 37 + src/FESI/AST/SimpleNode.java | 129 + src/FESI/ClassFile/Attribute.java | 111 + src/FESI/ClassFile/ClassConstant.java | 111 + src/FESI/ClassFile/ClassFile.java | 469 ++ src/FESI/ClassFile/Code.java | 702 +++ src/FESI/ClassFile/ConstantPoolEntry.java | 133 + src/FESI/ClassFile/ConstantValue.java | 157 + src/FESI/ClassFile/DoubleConstant.java | 91 + src/FESI/ClassFile/EventAdaptorClassFile.java | 809 +++ src/FESI/ClassFile/Exceptions.java | 160 + src/FESI/ClassFile/FieldConstant.java | 49 + src/FESI/ClassFile/FieldDesc.java | 107 + src/FESI/ClassFile/FloatConstant.java | 93 + src/FESI/ClassFile/IntegerConstant.java | 91 + .../ClassFile/InterfaceMethodConstant.java | 50 + src/FESI/ClassFile/LongConstant.java | 91 + src/FESI/ClassFile/MethodConstant.java | 49 + src/FESI/ClassFile/MethodDesc.java | 104 + src/FESI/ClassFile/NameAndTypeConstant.java | 115 + src/FESI/ClassFile/RefConstant.java | 112 + src/FESI/ClassFile/StringConstant.java | 105 + src/FESI/ClassFile/UTF8Constant.java | 89 + src/FESI/Data/ArrayObject.java | 185 + src/FESI/Data/ArrayPrototype.java | 585 +++ src/FESI/Data/BooleanObject.java | 123 + src/FESI/Data/BooleanPrototype.java | 80 + src/FESI/Data/BuiltinFunctionObject.java | 70 + src/FESI/Data/CompatibilityDescriptor.java | 83 + src/FESI/Data/ConstructedFunctionObject.java | 256 + src/FESI/Data/DateObject.java | 803 +++ src/FESI/Data/DatePrototype.java | 225 + src/FESI/Data/ESArguments.java | 253 + src/FESI/Data/ESArrayWrapper.java | 319 ++ src/FESI/Data/ESBeans.java | 149 + src/FESI/Data/ESBoolean.java | 106 + src/FESI/Data/ESLoader.java | 494 ++ src/FESI/Data/ESNull.java | 72 + src/FESI/Data/ESNumber.java | 115 + src/FESI/Data/ESObject.java | 775 +++ src/FESI/Data/ESPackages.java | 142 + src/FESI/Data/ESPrimitive.java | 95 + src/FESI/Data/ESReference.java | 137 + src/FESI/Data/ESString.java | 109 + src/FESI/Data/ESUndefined.java | 101 + src/FESI/Data/ESValue.java | 338 ++ src/FESI/Data/ESWrapper.java | 1484 ++++++ src/FESI/Data/FunctionObject.java | 153 + src/FESI/Data/FunctionPrototype.java | 142 + src/FESI/Data/GlobalObject.java | 455 ++ src/FESI/Data/JSGlobalWrapper.java | 143 + src/FESI/Data/JSWrapper.java | 505 ++ src/FESI/Data/MathObject.java | 262 + src/FESI/Data/NumberObject.java | 136 + src/FESI/Data/NumberPrototype.java | 80 + src/FESI/Data/ObjectObject.java | 85 + src/FESI/Data/ObjectPrototype.java | 41 + src/FESI/Data/StringObject.java | 340 ++ src/FESI/Data/StringPrototype.java | 92 + src/FESI/Data/ValueDescription.java | 89 + src/FESI/Exceptions/EcmaScriptException.java | 184 + .../EcmaScriptLexicalException.java | 78 + .../Exceptions/EcmaScriptParseException.java | 135 + src/FESI/Exceptions/ProgrammingError.java | 49 + src/FESI/Extensions/BasicIO.java | 252 + src/FESI/Extensions/BasicIOInterface.java | 35 + src/FESI/Extensions/BasicIOs.java | 224 + src/FESI/Extensions/BasicIOw.java | 224 + src/FESI/Extensions/Database.java | 1013 ++++ src/FESI/Extensions/Extension.java | 26 + src/FESI/Extensions/FileIO.java | 1095 ++++ src/FESI/Extensions/GNURegExp.java | 567 ++ src/FESI/Extensions/JavaAccess.java | 99 + src/FESI/Extensions/ORORegExp.java | 437 ++ src/FESI/Extensions/OptionalRegExp.java | 97 + src/FESI/FESI.changes | 17 + src/FESI/Interpreter/ClassInfo.java | 541 ++ .../EcmaScriptEvaluateVisitor.java | 1358 +++++ .../EcmaScriptFunctionVisitor.java | 298 ++ .../EcmaScriptVariableVisitor.java | 274 + src/FESI/Interpreter/EvaluationSource.java | 69 + src/FESI/Interpreter/Evaluator.java | 1060 ++++ src/FESI/Interpreter/EventAdaptor.java | 419 ++ .../Interpreter/EventAdaptorGenerator.java | 262 + .../Interpreter/FESIResourceConnection.java | 78 + src/FESI/Interpreter/FesiHashtable.java | 512 ++ .../Interpreter/FileEvaluationSource.java | 39 + .../Interpreter/FunctionEvaluationSource.java | 43 + src/FESI/Interpreter/Interpret.java | 1526 ++++++ src/FESI/Interpreter/JarEvaluationSource.java | 44 + .../Interpreter/LineEvaluationSource.java | 52 + src/FESI/Interpreter/LocalClassLoader.java | 375 ++ src/FESI/Interpreter/ParsedProgram.java | 74 + src/FESI/Interpreter/ScopeChain.java | 147 + .../Interpreter/StringEvaluationSource.java | 66 + .../Interpreter/UserEvaluationSource.java | 40 + src/FESI/Parser/ASCII_CharStream.java | 377 ++ src/FESI/Parser/EcmaScript.java | 4566 +++++++++++++++++ src/FESI/Parser/EcmaScriptConstants.java | 213 + src/FESI/Parser/EcmaScriptTokenManager.java | 1661 ++++++ src/FESI/Parser/ParseException.java | 196 + src/FESI/Parser/Token.java | 81 + src/FESI/Parser/TokenMgrError.java | 133 + src/FESI/jslib/JSException.java | 122 + src/FESI/jslib/JSExtension.java | 44 + src/FESI/jslib/JSFunction.java | 60 + src/FESI/jslib/JSFunctionAdapter.java | 52 + src/FESI/jslib/JSGlobalObject.java | 74 + src/FESI/jslib/JSObject.java | 177 + src/FESI/jslib/JSUtil.java | 69 + 148 files changed, 34934 insertions(+) create mode 100644 src/FESI/AST/ASTAllocationExpression.java create mode 100644 src/FESI/AST/ASTAndExpressionSequence.java create mode 100644 src/FESI/AST/ASTAssignmentExpression.java create mode 100644 src/FESI/AST/ASTBinaryExpressionSequence.java create mode 100644 src/FESI/AST/ASTBreakStatement.java create mode 100644 src/FESI/AST/ASTCompositeReference.java create mode 100644 src/FESI/AST/ASTConditionalExpression.java create mode 100644 src/FESI/AST/ASTContinueStatement.java create mode 100644 src/FESI/AST/ASTEmptyExpression.java create mode 100644 src/FESI/AST/ASTExpressionList.java create mode 100644 src/FESI/AST/ASTForInStatement.java create mode 100644 src/FESI/AST/ASTForStatement.java create mode 100644 src/FESI/AST/ASTForVarInStatement.java create mode 100644 src/FESI/AST/ASTForVarStatement.java create mode 100644 src/FESI/AST/ASTFormalParameterList.java create mode 100644 src/FESI/AST/ASTFunctionCallParameters.java create mode 100644 src/FESI/AST/ASTFunctionDeclaration.java create mode 100644 src/FESI/AST/ASTIdentifier.java create mode 100644 src/FESI/AST/ASTIfStatement.java create mode 100644 src/FESI/AST/ASTLiteral.java create mode 100644 src/FESI/AST/ASTOperator.java create mode 100644 src/FESI/AST/ASTOrExpressionSequence.java create mode 100644 src/FESI/AST/ASTPostfixExpression.java create mode 100644 src/FESI/AST/ASTProgram.java create mode 100644 src/FESI/AST/ASTPropertyIdentifierReference.java create mode 100644 src/FESI/AST/ASTPropertyValueReference.java create mode 100644 src/FESI/AST/ASTReturnStatement.java create mode 100644 src/FESI/AST/ASTStatement.java create mode 100644 src/FESI/AST/ASTStatementList.java create mode 100644 src/FESI/AST/ASTThisReference.java create mode 100644 src/FESI/AST/ASTUnaryExpression.java create mode 100644 src/FESI/AST/ASTVariableDeclaration.java create mode 100644 src/FESI/AST/ASTWhileStatement.java create mode 100644 src/FESI/AST/ASTWithStatement.java create mode 100644 src/FESI/AST/EcmaScriptDumpVisitor.java create mode 100644 src/FESI/AST/EcmaScriptTreeConstants.java create mode 100644 src/FESI/AST/EcmaScriptVisitor.java create mode 100644 src/FESI/AST/JJTEcmaScriptState.java create mode 100644 src/FESI/AST/Node.java create mode 100644 src/FESI/AST/SimpleNode.java create mode 100644 src/FESI/ClassFile/Attribute.java create mode 100644 src/FESI/ClassFile/ClassConstant.java create mode 100644 src/FESI/ClassFile/ClassFile.java create mode 100644 src/FESI/ClassFile/Code.java create mode 100644 src/FESI/ClassFile/ConstantPoolEntry.java create mode 100644 src/FESI/ClassFile/ConstantValue.java create mode 100644 src/FESI/ClassFile/DoubleConstant.java create mode 100644 src/FESI/ClassFile/EventAdaptorClassFile.java create mode 100644 src/FESI/ClassFile/Exceptions.java create mode 100644 src/FESI/ClassFile/FieldConstant.java create mode 100644 src/FESI/ClassFile/FieldDesc.java create mode 100644 src/FESI/ClassFile/FloatConstant.java create mode 100644 src/FESI/ClassFile/IntegerConstant.java create mode 100644 src/FESI/ClassFile/InterfaceMethodConstant.java create mode 100644 src/FESI/ClassFile/LongConstant.java create mode 100644 src/FESI/ClassFile/MethodConstant.java create mode 100644 src/FESI/ClassFile/MethodDesc.java create mode 100644 src/FESI/ClassFile/NameAndTypeConstant.java create mode 100644 src/FESI/ClassFile/RefConstant.java create mode 100644 src/FESI/ClassFile/StringConstant.java create mode 100644 src/FESI/ClassFile/UTF8Constant.java create mode 100644 src/FESI/Data/ArrayObject.java create mode 100644 src/FESI/Data/ArrayPrototype.java create mode 100644 src/FESI/Data/BooleanObject.java create mode 100644 src/FESI/Data/BooleanPrototype.java create mode 100644 src/FESI/Data/BuiltinFunctionObject.java create mode 100644 src/FESI/Data/CompatibilityDescriptor.java create mode 100644 src/FESI/Data/ConstructedFunctionObject.java create mode 100644 src/FESI/Data/DateObject.java create mode 100644 src/FESI/Data/DatePrototype.java create mode 100644 src/FESI/Data/ESArguments.java create mode 100644 src/FESI/Data/ESArrayWrapper.java create mode 100644 src/FESI/Data/ESBeans.java create mode 100644 src/FESI/Data/ESBoolean.java create mode 100644 src/FESI/Data/ESLoader.java create mode 100644 src/FESI/Data/ESNull.java create mode 100644 src/FESI/Data/ESNumber.java create mode 100644 src/FESI/Data/ESObject.java create mode 100644 src/FESI/Data/ESPackages.java create mode 100644 src/FESI/Data/ESPrimitive.java create mode 100644 src/FESI/Data/ESReference.java create mode 100644 src/FESI/Data/ESString.java create mode 100644 src/FESI/Data/ESUndefined.java create mode 100644 src/FESI/Data/ESValue.java create mode 100644 src/FESI/Data/ESWrapper.java create mode 100644 src/FESI/Data/FunctionObject.java create mode 100644 src/FESI/Data/FunctionPrototype.java create mode 100644 src/FESI/Data/GlobalObject.java create mode 100644 src/FESI/Data/JSGlobalWrapper.java create mode 100644 src/FESI/Data/JSWrapper.java create mode 100644 src/FESI/Data/MathObject.java create mode 100644 src/FESI/Data/NumberObject.java create mode 100644 src/FESI/Data/NumberPrototype.java create mode 100644 src/FESI/Data/ObjectObject.java create mode 100644 src/FESI/Data/ObjectPrototype.java create mode 100644 src/FESI/Data/StringObject.java create mode 100644 src/FESI/Data/StringPrototype.java create mode 100644 src/FESI/Data/ValueDescription.java create mode 100644 src/FESI/Exceptions/EcmaScriptException.java create mode 100644 src/FESI/Exceptions/EcmaScriptLexicalException.java create mode 100644 src/FESI/Exceptions/EcmaScriptParseException.java create mode 100644 src/FESI/Exceptions/ProgrammingError.java create mode 100644 src/FESI/Extensions/BasicIO.java create mode 100644 src/FESI/Extensions/BasicIOInterface.java create mode 100644 src/FESI/Extensions/BasicIOs.java create mode 100644 src/FESI/Extensions/BasicIOw.java create mode 100644 src/FESI/Extensions/Database.java create mode 100644 src/FESI/Extensions/Extension.java create mode 100644 src/FESI/Extensions/FileIO.java create mode 100644 src/FESI/Extensions/GNURegExp.java create mode 100644 src/FESI/Extensions/JavaAccess.java create mode 100644 src/FESI/Extensions/ORORegExp.java create mode 100644 src/FESI/Extensions/OptionalRegExp.java create mode 100644 src/FESI/FESI.changes create mode 100644 src/FESI/Interpreter/ClassInfo.java create mode 100644 src/FESI/Interpreter/EcmaScriptEvaluateVisitor.java create mode 100644 src/FESI/Interpreter/EcmaScriptFunctionVisitor.java create mode 100644 src/FESI/Interpreter/EcmaScriptVariableVisitor.java create mode 100644 src/FESI/Interpreter/EvaluationSource.java create mode 100644 src/FESI/Interpreter/Evaluator.java create mode 100644 src/FESI/Interpreter/EventAdaptor.java create mode 100644 src/FESI/Interpreter/EventAdaptorGenerator.java create mode 100644 src/FESI/Interpreter/FESIResourceConnection.java create mode 100644 src/FESI/Interpreter/FesiHashtable.java create mode 100644 src/FESI/Interpreter/FileEvaluationSource.java create mode 100644 src/FESI/Interpreter/FunctionEvaluationSource.java create mode 100644 src/FESI/Interpreter/Interpret.java create mode 100644 src/FESI/Interpreter/JarEvaluationSource.java create mode 100644 src/FESI/Interpreter/LineEvaluationSource.java create mode 100644 src/FESI/Interpreter/LocalClassLoader.java create mode 100644 src/FESI/Interpreter/ParsedProgram.java create mode 100644 src/FESI/Interpreter/ScopeChain.java create mode 100644 src/FESI/Interpreter/StringEvaluationSource.java create mode 100644 src/FESI/Interpreter/UserEvaluationSource.java create mode 100644 src/FESI/Parser/ASCII_CharStream.java create mode 100644 src/FESI/Parser/EcmaScript.java create mode 100644 src/FESI/Parser/EcmaScriptConstants.java create mode 100644 src/FESI/Parser/EcmaScriptTokenManager.java create mode 100644 src/FESI/Parser/ParseException.java create mode 100644 src/FESI/Parser/Token.java create mode 100644 src/FESI/Parser/TokenMgrError.java create mode 100644 src/FESI/jslib/JSException.java create mode 100644 src/FESI/jslib/JSExtension.java create mode 100644 src/FESI/jslib/JSFunction.java create mode 100644 src/FESI/jslib/JSFunctionAdapter.java create mode 100644 src/FESI/jslib/JSGlobalObject.java create mode 100644 src/FESI/jslib/JSObject.java create mode 100644 src/FESI/jslib/JSUtil.java diff --git a/src/FESI/AST/ASTAllocationExpression.java b/src/FESI/AST/ASTAllocationExpression.java new file mode 100644 index 00000000..20017f57 --- /dev/null +++ b/src/FESI/AST/ASTAllocationExpression.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTAllocationExpression.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTAllocationExpression extends SimpleNode { + public ASTAllocationExpression(int id) { + super(id); + } + + public ASTAllocationExpression(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTAllocationExpression(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTAllocationExpression(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTAndExpressionSequence.java b/src/FESI/AST/ASTAndExpressionSequence.java new file mode 100644 index 00000000..3232ec54 --- /dev/null +++ b/src/FESI/AST/ASTAndExpressionSequence.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTAndExpressionSequence.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTAndExpressionSequence extends SimpleNode { + public ASTAndExpressionSequence(int id) { + super(id); + } + + public ASTAndExpressionSequence(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTAndExpressionSequence(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTAndExpressionSequence(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTAssignmentExpression.java b/src/FESI/AST/ASTAssignmentExpression.java new file mode 100644 index 00000000..f1528f62 --- /dev/null +++ b/src/FESI/AST/ASTAssignmentExpression.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTAssignmentExpression.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTAssignmentExpression extends SimpleNode { + public ASTAssignmentExpression(int id) { + super(id); + } + + public ASTAssignmentExpression(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTAssignmentExpression(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTAssignmentExpression(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTBinaryExpressionSequence.java b/src/FESI/AST/ASTBinaryExpressionSequence.java new file mode 100644 index 00000000..fa9c3d7f --- /dev/null +++ b/src/FESI/AST/ASTBinaryExpressionSequence.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTBinaryExpressionSequence.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTBinaryExpressionSequence extends SimpleNode { + public ASTBinaryExpressionSequence(int id) { + super(id); + } + + public ASTBinaryExpressionSequence(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTBinaryExpressionSequence(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTBinaryExpressionSequence(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTBreakStatement.java b/src/FESI/AST/ASTBreakStatement.java new file mode 100644 index 00000000..69ad9d8f --- /dev/null +++ b/src/FESI/AST/ASTBreakStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTBreakStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTBreakStatement extends SimpleNode { + public ASTBreakStatement(int id) { + super(id); + } + + public ASTBreakStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTBreakStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTBreakStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTCompositeReference.java b/src/FESI/AST/ASTCompositeReference.java new file mode 100644 index 00000000..aa3fc24d --- /dev/null +++ b/src/FESI/AST/ASTCompositeReference.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTCompositeReference.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTCompositeReference extends SimpleNode { + public ASTCompositeReference(int id) { + super(id); + } + + public ASTCompositeReference(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTCompositeReference(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTCompositeReference(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTConditionalExpression.java b/src/FESI/AST/ASTConditionalExpression.java new file mode 100644 index 00000000..dfd727bb --- /dev/null +++ b/src/FESI/AST/ASTConditionalExpression.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTConditionalExpression.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTConditionalExpression extends SimpleNode { + public ASTConditionalExpression(int id) { + super(id); + } + + public ASTConditionalExpression(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTConditionalExpression(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTConditionalExpression(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTContinueStatement.java b/src/FESI/AST/ASTContinueStatement.java new file mode 100644 index 00000000..6a7570b8 --- /dev/null +++ b/src/FESI/AST/ASTContinueStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTContinueStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTContinueStatement extends SimpleNode { + public ASTContinueStatement(int id) { + super(id); + } + + public ASTContinueStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTContinueStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTContinueStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTEmptyExpression.java b/src/FESI/AST/ASTEmptyExpression.java new file mode 100644 index 00000000..a5749a6e --- /dev/null +++ b/src/FESI/AST/ASTEmptyExpression.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTEmptyExpression.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTEmptyExpression extends SimpleNode { + public ASTEmptyExpression(int id) { + super(id); + } + + public ASTEmptyExpression(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTEmptyExpression(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTEmptyExpression(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTExpressionList.java b/src/FESI/AST/ASTExpressionList.java new file mode 100644 index 00000000..9a12e43c --- /dev/null +++ b/src/FESI/AST/ASTExpressionList.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTExpressionList.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTExpressionList extends SimpleNode { + public ASTExpressionList(int id) { + super(id); + } + + public ASTExpressionList(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTExpressionList(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTExpressionList(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTForInStatement.java b/src/FESI/AST/ASTForInStatement.java new file mode 100644 index 00000000..6e7b3319 --- /dev/null +++ b/src/FESI/AST/ASTForInStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTForInStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTForInStatement extends SimpleNode { + public ASTForInStatement(int id) { + super(id); + } + + public ASTForInStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTForInStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTForInStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTForStatement.java b/src/FESI/AST/ASTForStatement.java new file mode 100644 index 00000000..17beb278 --- /dev/null +++ b/src/FESI/AST/ASTForStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTForStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTForStatement extends SimpleNode { + public ASTForStatement(int id) { + super(id); + } + + public ASTForStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTForStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTForStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTForVarInStatement.java b/src/FESI/AST/ASTForVarInStatement.java new file mode 100644 index 00000000..b0128297 --- /dev/null +++ b/src/FESI/AST/ASTForVarInStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTForVarInStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTForVarInStatement extends SimpleNode { + public ASTForVarInStatement(int id) { + super(id); + } + + public ASTForVarInStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTForVarInStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTForVarInStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTForVarStatement.java b/src/FESI/AST/ASTForVarStatement.java new file mode 100644 index 00000000..7f56b6d7 --- /dev/null +++ b/src/FESI/AST/ASTForVarStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTForVarStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTForVarStatement extends SimpleNode { + public ASTForVarStatement(int id) { + super(id); + } + + public ASTForVarStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTForVarStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTForVarStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTFormalParameterList.java b/src/FESI/AST/ASTFormalParameterList.java new file mode 100644 index 00000000..28f7b66d --- /dev/null +++ b/src/FESI/AST/ASTFormalParameterList.java @@ -0,0 +1,39 @@ +/* Generated By:JJTree: Do not edit this line. ASTFormalParameterList.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTFormalParameterList extends SimpleNode { + public ASTFormalParameterList(int id) { + super(id); + } + + public ASTFormalParameterList(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTFormalParameterList(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTFormalParameterList(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } + + // JMCL + public String [] getArguments() { + int n = jjtGetNumChildren(); + String [] args = new String[n]; + for (int i=0; i"; + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTIfStatement.java b/src/FESI/AST/ASTIfStatement.java new file mode 100644 index 00000000..d611ccdf --- /dev/null +++ b/src/FESI/AST/ASTIfStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTIfStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTIfStatement extends SimpleNode { + public ASTIfStatement(int id) { + super(id); + } + + public ASTIfStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTIfStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTIfStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTLiteral.java b/src/FESI/AST/ASTLiteral.java new file mode 100644 index 00000000..1fc0f46c --- /dev/null +++ b/src/FESI/AST/ASTLiteral.java @@ -0,0 +1,210 @@ +/* Generated By:JJTree: Do not edit this line. ASTLiteral.java */ + +package FESI.AST; + +import FESI.Parser.*; +import FESI.Data.*; +import FESI.Exceptions.*; + + +public class ASTLiteral extends SimpleNode { + + private ESValue theValue = null; + + public ASTLiteral(int id) { + super(id); + } + + public ASTLiteral(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTLiteral(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTLiteral(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } + + // JMCL + public ESValue getValue() { + return theValue; + } + + static final int hexval(char c) throws ProgrammingError { + switch(c) + { + case '0' : + return 0; + case '1' : + return 1; + case '2' : + return 2; + case '3' : + return 3; + case '4' : + return 4; + case '5' : + return 5; + case '6' : + return 6; + case '7' : + return 7; + case '8' : + return 8; + case '9' : + return 9; + + case 'a' : + case 'A' : + return 10; + case 'b' : + case 'B' : + return 11; + case 'c' : + case 'C' : + return 12; + case 'd' : + case 'D' : + return 13; + case 'e' : + case 'E' : + return 14; + case 'f' : + case 'F' : + return 15; + } + + throw new ProgrammingError("Illegal hex or unicode constant"); // Should never come here + } + static final int octval(char c) throws ProgrammingError { + switch(c) + { + case '0' : + return 0; + case '1' : + return 1; + case '2' : + return 2; + case '3' : + return 3; + case '4' : + return 4; + case '5' : + return 5; + case '6' : + return 6; + case '7' : + return 7; + case '8' : + return 8; + case '9' : + return 9; + + case 'a' : + case 'A' : + return 10; + case 'b' : + case 'B' : + return 11; + case 'c' : + case 'C' : + return 12; + case 'd' : + case 'D' : + return 13; + case 'e' : + case 'E' : + return 14; + case 'f' : + case 'F' : + return 15; + } + + throw new ProgrammingError("Illegal octal constant"); // Should never come here + } + + public void setStringValue(String image) { + int l = image.length(); + StringBuffer sb = new StringBuffer(l); + for (int i=0; i='0' && c <= '7') { + c = (char)(octval(image.charAt(i))); + if ((image.length()>i) && + (image.charAt(i+1)>='0') && (image.charAt(i+1)<='7')) { + i++; + c = (char) ((c<<4) | octval(image.charAt(i))); + } + } + } + sb.append(c); + } + theValue = new ESString(sb.toString()); + } + public void setDecimalValue(String image) { + try { + theValue = new ESNumber(Long.parseLong(image)); + } catch (NumberFormatException e) { + Double value = new Double(image); + theValue = new ESNumber(value.doubleValue()); + } + } + public void setOctalValue(String image) { + try { + String imageWithout0 = image.substring(1); + theValue = new ESNumber(Long.parseLong(imageWithout0,8)); + } catch (NumberFormatException e) { + Double value = new Double(image); + theValue = new ESNumber(value.doubleValue()); + } + } + public void setHexValue(String image) { + try { + String imageWithout0x = image.substring(2); + theValue = new ESNumber(Long.parseLong(imageWithout0x,16)); + } catch (NumberFormatException e) { + Double value = new Double(image); + theValue = new ESNumber(value.doubleValue()); + } + } + public void setFloatingPointValue(String image) { + Double value = new Double(image); + theValue = new ESNumber(value.doubleValue()); + } + public void setBooleanValue(boolean value) { + theValue = ESBoolean.makeBoolean(value); + } + public void setNullValue() { + theValue = ESNull.theNull; + } + + public String toString() { + return "[" + theValue.toString() + "]"; + } + +} \ No newline at end of file diff --git a/src/FESI/AST/ASTOperator.java b/src/FESI/AST/ASTOperator.java new file mode 100644 index 00000000..b39355af --- /dev/null +++ b/src/FESI/AST/ASTOperator.java @@ -0,0 +1,44 @@ +/* Generated By:JJTree: Do not edit this line. ASTOperator.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTOperator extends SimpleNode { + + private int operatorCode = EOF; + + public ASTOperator(int id) { + super(id); + } + + public ASTOperator(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTOperator(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTOperator(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } + + // JMCL + public void setOperator(int operatorCode) { + this.operatorCode = operatorCode; + } + public int getOperator() { + return operatorCode; + } + + public String toString() { + return "<" + tokenImage[operatorCode] + ">"; + } + +} \ No newline at end of file diff --git a/src/FESI/AST/ASTOrExpressionSequence.java b/src/FESI/AST/ASTOrExpressionSequence.java new file mode 100644 index 00000000..435885e7 --- /dev/null +++ b/src/FESI/AST/ASTOrExpressionSequence.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTOrExpressionSequence.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTOrExpressionSequence extends SimpleNode { + public ASTOrExpressionSequence(int id) { + super(id); + } + + public ASTOrExpressionSequence(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTOrExpressionSequence(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTOrExpressionSequence(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTPostfixExpression.java b/src/FESI/AST/ASTPostfixExpression.java new file mode 100644 index 00000000..87039b7d --- /dev/null +++ b/src/FESI/AST/ASTPostfixExpression.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTPostfixExpression.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTPostfixExpression extends SimpleNode { + public ASTPostfixExpression(int id) { + super(id); + } + + public ASTPostfixExpression(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTPostfixExpression(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTPostfixExpression(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTProgram.java b/src/FESI/AST/ASTProgram.java new file mode 100644 index 00000000..eaf5ecbb --- /dev/null +++ b/src/FESI/AST/ASTProgram.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTProgram.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTProgram extends SimpleNode { + public ASTProgram(int id) { + super(id); + } + + public ASTProgram(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTProgram(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTProgram(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTPropertyIdentifierReference.java b/src/FESI/AST/ASTPropertyIdentifierReference.java new file mode 100644 index 00000000..a1b3cf55 --- /dev/null +++ b/src/FESI/AST/ASTPropertyIdentifierReference.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTPropertyIdentifierReference.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTPropertyIdentifierReference extends SimpleNode { + public ASTPropertyIdentifierReference(int id) { + super(id); + } + + public ASTPropertyIdentifierReference(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTPropertyIdentifierReference(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTPropertyIdentifierReference(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTPropertyValueReference.java b/src/FESI/AST/ASTPropertyValueReference.java new file mode 100644 index 00000000..aabaf213 --- /dev/null +++ b/src/FESI/AST/ASTPropertyValueReference.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTPropertyValueReference.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTPropertyValueReference extends SimpleNode { + public ASTPropertyValueReference(int id) { + super(id); + } + + public ASTPropertyValueReference(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTPropertyValueReference(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTPropertyValueReference(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTReturnStatement.java b/src/FESI/AST/ASTReturnStatement.java new file mode 100644 index 00000000..065ae925 --- /dev/null +++ b/src/FESI/AST/ASTReturnStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTReturnStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTReturnStatement extends SimpleNode { + public ASTReturnStatement(int id) { + super(id); + } + + public ASTReturnStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTReturnStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTReturnStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTStatement.java b/src/FESI/AST/ASTStatement.java new file mode 100644 index 00000000..b3637fd7 --- /dev/null +++ b/src/FESI/AST/ASTStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTStatement extends SimpleNode { + public ASTStatement(int id) { + super(id); + } + + public ASTStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTStatementList.java b/src/FESI/AST/ASTStatementList.java new file mode 100644 index 00000000..092c55dc --- /dev/null +++ b/src/FESI/AST/ASTStatementList.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTStatementList.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTStatementList extends SimpleNode { + public ASTStatementList(int id) { + super(id); + } + + public ASTStatementList(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTStatementList(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTStatementList(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTThisReference.java b/src/FESI/AST/ASTThisReference.java new file mode 100644 index 00000000..5ed38f5e --- /dev/null +++ b/src/FESI/AST/ASTThisReference.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTThisReference.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTThisReference extends SimpleNode { + public ASTThisReference(int id) { + super(id); + } + + public ASTThisReference(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTThisReference(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTThisReference(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTUnaryExpression.java b/src/FESI/AST/ASTUnaryExpression.java new file mode 100644 index 00000000..7d94dfec --- /dev/null +++ b/src/FESI/AST/ASTUnaryExpression.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTUnaryExpression.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTUnaryExpression extends SimpleNode { + public ASTUnaryExpression(int id) { + super(id); + } + + public ASTUnaryExpression(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTUnaryExpression(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTUnaryExpression(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTVariableDeclaration.java b/src/FESI/AST/ASTVariableDeclaration.java new file mode 100644 index 00000000..88ab3a34 --- /dev/null +++ b/src/FESI/AST/ASTVariableDeclaration.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTVariableDeclaration.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTVariableDeclaration extends SimpleNode { + public ASTVariableDeclaration(int id) { + super(id); + } + + public ASTVariableDeclaration(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTVariableDeclaration(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTVariableDeclaration(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTWhileStatement.java b/src/FESI/AST/ASTWhileStatement.java new file mode 100644 index 00000000..4ab28485 --- /dev/null +++ b/src/FESI/AST/ASTWhileStatement.java @@ -0,0 +1,28 @@ +/* Generated By:JJTree: Do not edit this line. ASTWhileStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTWhileStatement extends SimpleNode { + public ASTWhileStatement(int id) { + super(id); + } + + public ASTWhileStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTWhileStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTWhileStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } +} \ No newline at end of file diff --git a/src/FESI/AST/ASTWithStatement.java b/src/FESI/AST/ASTWithStatement.java new file mode 100644 index 00000000..d8ca850a --- /dev/null +++ b/src/FESI/AST/ASTWithStatement.java @@ -0,0 +1,40 @@ +/* Generated By:JJTree: Do not edit this line. ASTWithStatement.java */ + +package FESI.AST; + +import FESI.Parser.*; + +public class ASTWithStatement extends SimpleNode { + + Object evaluationSource = null; + + public ASTWithStatement(int id) { + super(id); + } + + public ASTWithStatement(EcmaScript p, int id) { + super(p, id); + } + + public static Node jjtCreate(int id) { + return new ASTWithStatement(id); + } + + public static Node jjtCreate(EcmaScript p, int id) { + return new ASTWithStatement(p, id); + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } + + // JMCL + public void setEvaluationSource(Object evaluationSource) { + this.evaluationSource = evaluationSource; + } + + public Object getEvaluationSource() { + return evaluationSource; + } +} \ No newline at end of file diff --git a/src/FESI/AST/EcmaScriptDumpVisitor.java b/src/FESI/AST/EcmaScriptDumpVisitor.java new file mode 100644 index 00000000..860a2909 --- /dev/null +++ b/src/FESI/AST/EcmaScriptDumpVisitor.java @@ -0,0 +1,263 @@ +package FESI.AST; + +import FESI.Parser.*; + +public class EcmaScriptDumpVisitor implements EcmaScriptVisitor +{ + private int indent = 0; + + private String indentString() { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < indent; ++i) { + sb.append(" "); + } + return sb.toString(); + } + + public Object visit(SimpleNode node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTProgram node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTStatementList node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTFunctionDeclaration node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTFormalParameterList node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTVariableDeclaration node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTIfStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTWhileStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTForStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTForInStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTForVarStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTForVarInStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTContinueStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTBreakStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTReturnStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTWithStatement node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTThisReference node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTCompositeReference node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTFunctionCallParameters node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTPropertyIdentifierReference node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTPropertyValueReference node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTAllocationExpression node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTOperator node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTPostfixExpression node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTUnaryExpression node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTBinaryExpressionSequence node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTOrExpressionSequence node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTAndExpressionSequence node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTConditionalExpression node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTAssignmentExpression node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTExpressionList node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTEmptyExpression node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTLiteral node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + public Object visit(ASTIdentifier node, Object data) { + System.out.println(indentString() + node); + ++indent; + data = node.childrenAccept(this, data); + --indent; + return data; + } + +} \ No newline at end of file diff --git a/src/FESI/AST/EcmaScriptTreeConstants.java b/src/FESI/AST/EcmaScriptTreeConstants.java new file mode 100644 index 00000000..fe8d6322 --- /dev/null +++ b/src/FESI/AST/EcmaScriptTreeConstants.java @@ -0,0 +1,81 @@ +/* Generated By:JJTree: Do not edit this line. EcmaScriptTreeConstants.java */ + +package FESI.AST; + +public interface EcmaScriptTreeConstants +{ + public int JJTLITERAL = 0; + public int JJTIDENTIFIER = 1; + public int JJTVOID = 2; + public int JJTTHISREFERENCE = 3; + public int JJTCOMPOSITEREFERENCE = 4; + public int JJTFUNCTIONCALLPARAMETERS = 5; + public int JJTPROPERTYVALUEREFERENCE = 6; + public int JJTPROPERTYIDENTIFIERREFERENCE = 7; + public int JJTALLOCATIONEXPRESSION = 8; + public int JJTOPERATOR = 9; + public int JJTPOSTFIXEXPRESSION = 10; + public int JJTUNARYEXPRESSION = 11; + public int JJTBINARYEXPRESSIONSEQUENCE = 12; + public int JJTANDEXPRESSIONSEQUENCE = 13; + public int JJTOREXPRESSIONSEQUENCE = 14; + public int JJTCONDITIONALEXPRESSION = 15; + public int JJTASSIGNMENTEXPRESSION = 16; + public int JJTEXPRESSIONLIST = 17; + public int JJTSTATEMENT = 18; + public int JJTSTATEMENTLIST = 19; + public int JJTVARIABLEDECLARATION = 20; + public int JJTIFSTATEMENT = 21; + public int JJTWHILESTATEMENT = 22; + public int JJTFORSTATEMENT = 23; + public int JJTEMPTYEXPRESSION = 24; + public int JJTFORVARSTATEMENT = 25; + public int JJTFORINSTATEMENT = 26; + public int JJTFORVARINSTATEMENT = 27; + public int JJTCONTINUESTATEMENT = 28; + public int JJTBREAKSTATEMENT = 29; + public int JJTRETURNSTATEMENT = 30; + public int JJTWITHSTATEMENT = 31; + public int JJTFUNCTIONDECLARATION = 32; + public int JJTFORMALPARAMETERLIST = 33; + public int JJTPROGRAM = 34; + + + public String[] jjtNodeName = { + "Literal", + "Identifier", + "void", + "ThisReference", + "CompositeReference", + "FunctionCallParameters", + "PropertyValueReference", + "PropertyIdentifierReference", + "AllocationExpression", + "Operator", + "PostfixExpression", + "UnaryExpression", + "BinaryExpressionSequence", + "AndExpressionSequence", + "OrExpressionSequence", + "ConditionalExpression", + "AssignmentExpression", + "ExpressionList", + "Statement", + "StatementList", + "VariableDeclaration", + "IfStatement", + "WhileStatement", + "ForStatement", + "EmptyExpression", + "ForVarStatement", + "ForInStatement", + "ForVarInStatement", + "ContinueStatement", + "BreakStatement", + "ReturnStatement", + "WithStatement", + "FunctionDeclaration", + "FormalParameterList", + "Program", + }; +} diff --git a/src/FESI/AST/EcmaScriptVisitor.java b/src/FESI/AST/EcmaScriptVisitor.java new file mode 100644 index 00000000..116eb4ac --- /dev/null +++ b/src/FESI/AST/EcmaScriptVisitor.java @@ -0,0 +1,42 @@ +/* Generated By:JJTree: Do not edit this line. EcmaScriptVisitor.java */ + +package FESI.AST; + +public interface EcmaScriptVisitor +{ + public Object visit(SimpleNode node, Object data); + public Object visit(ASTLiteral node, Object data); + public Object visit(ASTIdentifier node, Object data); + public Object visit(ASTThisReference node, Object data); + public Object visit(ASTCompositeReference node, Object data); + public Object visit(ASTFunctionCallParameters node, Object data); + public Object visit(ASTPropertyValueReference node, Object data); + public Object visit(ASTPropertyIdentifierReference node, Object data); + public Object visit(ASTAllocationExpression node, Object data); + public Object visit(ASTOperator node, Object data); + public Object visit(ASTPostfixExpression node, Object data); + public Object visit(ASTUnaryExpression node, Object data); + public Object visit(ASTBinaryExpressionSequence node, Object data); + public Object visit(ASTAndExpressionSequence node, Object data); + public Object visit(ASTOrExpressionSequence node, Object data); + public Object visit(ASTConditionalExpression node, Object data); + public Object visit(ASTAssignmentExpression node, Object data); + public Object visit(ASTExpressionList node, Object data); + public Object visit(ASTStatement node, Object data); + public Object visit(ASTStatementList node, Object data); + public Object visit(ASTVariableDeclaration node, Object data); + public Object visit(ASTIfStatement node, Object data); + public Object visit(ASTWhileStatement node, Object data); + public Object visit(ASTForStatement node, Object data); + public Object visit(ASTEmptyExpression node, Object data); + public Object visit(ASTForVarStatement node, Object data); + public Object visit(ASTForInStatement node, Object data); + public Object visit(ASTForVarInStatement node, Object data); + public Object visit(ASTContinueStatement node, Object data); + public Object visit(ASTBreakStatement node, Object data); + public Object visit(ASTReturnStatement node, Object data); + public Object visit(ASTWithStatement node, Object data); + public Object visit(ASTFunctionDeclaration node, Object data); + public Object visit(ASTFormalParameterList node, Object data); + public Object visit(ASTProgram node, Object data); +} diff --git a/src/FESI/AST/JJTEcmaScriptState.java b/src/FESI/AST/JJTEcmaScriptState.java new file mode 100644 index 00000000..023928ed --- /dev/null +++ b/src/FESI/AST/JJTEcmaScriptState.java @@ -0,0 +1,123 @@ +/* Generated By:JJTree: Do not edit this line. JJTEcmaScriptState.java */ + +package FESI.AST; + +public class JJTEcmaScriptState { + private java.util.Stack nodes; + private java.util.Stack marks; + + private int sp; // number of nodes on stack + private int mk; // current mark + private boolean node_created; + + public JJTEcmaScriptState() { + nodes = new java.util.Stack(); + marks = new java.util.Stack(); + sp = 0; + mk = 0; + } + + /* Determines whether the current node was actually closed and + pushed. This should only be called in the final user action of a + node scope. */ + public boolean nodeCreated() { + return node_created; + } + + /* Call this to reinitialize the node stack. It is called + automatically by the parser's ReInit() method. */ + public void reset() { + nodes.removeAllElements(); + marks.removeAllElements(); + sp = 0; + mk = 0; + } + + /* Returns the root node of the AST. It only makes sense to call + this after a successful parse. */ + public Node rootNode() { + return (Node)nodes.elementAt(0); + } + + /* Pushes a node on to the stack. */ + public void pushNode(Node n) { + nodes.push(n); + ++sp; + } + + /* Returns the node on the top of the stack, and remove it from the + stack. */ + public Node popNode() { + if (--sp < mk) { + mk = ((Integer)marks.pop()).intValue(); + } + return (Node)nodes.pop(); + } + + /* Returns the node currently on the top of the stack. */ + public Node peekNode() { + return (Node)nodes.peek(); + } + + /* Returns the number of children on the stack in the current node + scope. */ + public int nodeArity() { + return sp - mk; + } + + + public void clearNodeScope(Node n) { + while (sp > mk) { + popNode(); + } + mk = ((Integer)marks.pop()).intValue(); + } + + + public void openNodeScope(Node n) { + marks.push(new Integer(mk)); + mk = sp; + n.jjtOpen(); + } + + + /* A definite node is constructed from a specified number of + children. That number of nodes are popped from the stack and + made the children of the definite node. Then the definite node + is pushed on to the stack. */ + public void closeNodeScope(Node n, int num) { + mk = ((Integer)marks.pop()).intValue(); + while (num-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, num); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } + + + /* A conditional node is constructed if its condition is true. All + the nodes that have been pushed since the node was opened are + made children of the the conditional node, which is then pushed + on to the stack. If the condition is false the node is not + constructed and they are left on the stack. */ + public void closeNodeScope(Node n, boolean condition) { + if (condition) { + int a = nodeArity(); + mk = ((Integer)marks.pop()).intValue(); + while (a-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, a); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } else { + mk = ((Integer)marks.pop()).intValue(); + node_created = false; + } + } +} diff --git a/src/FESI/AST/Node.java b/src/FESI/AST/Node.java new file mode 100644 index 00000000..18fa417a --- /dev/null +++ b/src/FESI/AST/Node.java @@ -0,0 +1,37 @@ +/* Generated By:JJTree: Do not edit this line. Node.java */ + +package FESI.AST; + +/* All AST nodes must implement this interface. It provides basic + machinery for constructing the parent and child relationships + between nodes. */ + +public interface Node { + + /** This method is called after the node has been made the current + node. It indicates that child nodes can now be added to it. */ + public void jjtOpen(); + + /** This method is called after all the child nodes have been + added. */ + public void jjtClose(); + + /** This pair of methods are used to inform the node of its + parent. */ + public void jjtSetParent(Node n); + public Node jjtGetParent(); + + /** This method tells the node to add its argument to the node's + list of children. */ + public void jjtAddChild(Node n, int i); + + /** This method returns a child node. The children are numbered + from zero, left to right. */ + public Node jjtGetChild(int i); + + /** Return the number of children the node has. */ + public int jjtGetNumChildren(); + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data); +} \ No newline at end of file diff --git a/src/FESI/AST/SimpleNode.java b/src/FESI/AST/SimpleNode.java new file mode 100644 index 00000000..3e74dec2 --- /dev/null +++ b/src/FESI/AST/SimpleNode.java @@ -0,0 +1,129 @@ +/* Generated By:JJTree: Do not edit this line. SimpleNode.java */ + +package FESI.AST; + +import FESI.Parser.*; +import FESI.Exceptions.*; + +public abstract class SimpleNode implements Node, EcmaScriptConstants { + protected Node parent; + protected Node[] children; + protected int id; + protected EcmaScript parser; + protected int line = 0; // JMCL + + public SimpleNode(int i) { + id = i; + } + + public SimpleNode(EcmaScript p, int i) { + this(i); + parser = p; + } + + public void jjtOpen() { + } + + public void jjtClose() { + } + + public void jjtSetParent(Node n) { parent = n; } + public Node jjtGetParent() { return parent; } + + public void jjtAddChild(Node n, int i) { + if (children == null) { + children = new Node[i + 1]; + } else if (i >= children.length) { + Node c[] = new Node[i + 1]; + System.arraycopy(children, 0, c, 0, children.length); + children = c; + } + children[i] = n; + } + + public Node jjtGetChild(int i) { + return children[i]; + } + + public int jjtGetNumChildren() { + return (children == null) ? 0 : children.length; + } + + /** Accept the visitor. **/ + public Object jjtAccept(EcmaScriptVisitor visitor, Object data) { + return visitor.visit(this, data); + } + + /** Accept the visitor. **/ + public Object childrenAccept(EcmaScriptVisitor visitor, Object data) { + if (children != null) { + for (int i = 0; i < children.length; ++i) { + children[i].jjtAccept(visitor, data); + } + } + return data; + } + + /* You can override these two methods in subclasses of SimpleNode to + customize the way the node appears when the tree is dumped. If + your output uses more than one line you should override + toString(String), otherwise overriding toString() is probably all + you need to do. */ + + // JMCL + public String toString() { + return EcmaScriptTreeConstants.jjtNodeName[id]; + } + public String toString(String prefix) { return prefix + toString(); } + + /* Override this method if you want to customize how the node dumps + out its children. */ + + public void dump(String prefix) { + System.out.println(toString(prefix)); + if (children != null) { + for (int i = 0; i < children.length; ++i) { + SimpleNode n = (SimpleNode)children[i]; + if (n != null) { + n.dump(prefix + " "); + } + } + } + } + + // JMCL + public void setLineNumber(int line) { + this.line = line; + } + + public int getLineNumber() { + return line; + } + + public void assertNoChildren() { + if (jjtGetNumChildren()>0) { + throw new ProgrammingError("AST Should have no children"); + } + } + public void assertOneChild() { + if (jjtGetNumChildren()!=1) { + throw new ProgrammingError("AST Should have 1 child"); + } + } + public void assertTwoChildren() { + if (jjtGetNumChildren()!=2) { + throw new ProgrammingError("AST Should have 2 children"); + } + } + public void assertThreeChildren() { + if (jjtGetNumChildren()!=3) { + throw new ProgrammingError("AST Should have 3 children"); + } + } + public void assertFourChildren() { + if (jjtGetNumChildren()!=4) { + throw new ProgrammingError("AST Should have 4 children"); + } + } + +} \ No newline at end of file diff --git a/src/FESI/ClassFile/Attribute.java b/src/FESI/ClassFile/Attribute.java new file mode 100644 index 00000000..a484b19e --- /dev/null +++ b/src/FESI/ClassFile/Attribute.java @@ -0,0 +1,111 @@ +/* + * + * @(#) Attribute.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.Attribute + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; +import FESI.ClassFile.UTF8Constant; + +/** + *

+ * The Attribute class is an abstract base class for all Attribute types + * found in the Java VM ClassFile format specification. This is a simple + * implementationd designed to support the minimal functionaliuty required + * to emit a valid ClassFile stream. + *

+ */ + +abstract class Attribute { + + final static String SOURCEFILE = "SourceFile"; + final static String CONSTANTVALUE = "ConstantValue"; + final static String LOCALVARIABLETABLE = "LocalVariableTable"; + final static String EXCEPTIONS = "Exceptions"; + final static String LINENUMBERTABLE = "LineNumberTable"; + final static String CODE = "Code"; + + private UTF8Constant name; + private ClassFile classFile; + + /** + *

Construct an Attribute, enter it into the ConstantPool.

+ */ + + protected Attribute(String n, ClassFile cf) { + UTF8Constant utf8 = (UTF8Constant) + cf.match(ConstantPoolEntry.CONSTANT_UTF8, (Object)n); + + if (utf8 == null) utf8 = new UTF8Constant(n, cf); + + name = utf8; + classFile = cf; + } + + /** + * @return the ClassFile this Attribute is contained within + */ + + ClassFile getClassFile() { return classFile; } + + /** + * @return the "name" of the Attribute. + */ + + String getName() { return name.getString(); } + + /** + * @return get the index of this Attribute in the ConstantPool + */ + + short getNameConstantPoolIndex() { + return name.getConstantPoolIndex(); + } + + /** + * @return the length of the attribute as defined by the concrete subclass. + */ + + abstract int getLength(); + + /** + *

write the concrete Attribute subclass to the stream

+ * + * @throws IOException + */ + + abstract void write(DataOutputStream dos) throws IOException; + + /** + *

Compare this Attribute with the object and return equality.

+ * + * @return is it equal + */ + + abstract public boolean equals(Object o); + +} diff --git a/src/FESI/ClassFile/ClassConstant.java b/src/FESI/ClassFile/ClassConstant.java new file mode 100644 index 00000000..2e8dac53 --- /dev/null +++ b/src/FESI/ClassFile/ClassConstant.java @@ -0,0 +1,111 @@ +/* + * + * @(#) ClassConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.ClassConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; +import FESI.ClassFile.UTF8Constant; + +class ClassConstant extends ConstantPoolEntry { + + private UTF8Constant name; + + /** + *

Construct a CONSTANT_CLASS constant pool entry

+ */ + + ClassConstant(String className, ClassFile cf) { + super(CONSTANT_CLASS, cf); + + name = cf.addUTF8Constant(ClassFile.fullyQualifiedForm(className)); + + addToConstantPool(); + } + + /** + *

write the CONSTANT_CLASS to the stream

+ * + * @param dos the stream. + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + + if (debug()) { + System.err.println(getConstantPoolIndex() + + " CLASS: " + + name.getConstantPoolIndex() + ); + } + + dos.writeByte(getTag()); + dos.writeShort(name.getConstantPoolIndex()); + } + + /** + *

return the class represented by the CONSTANT_CLASS

+ * + * @return the name of the class + */ + + String getClassName() { return name.getString(); } + + /** + *

returns the Class object for the class represented by the constant.

+ * + * @return The java.lang.Class object for the class. + */ + + Class getClassObject() throws ClassNotFoundException { + return Class.forName(name.getString()); + } + + /** + *

compare the object, by name or value.

+ * + * @param the object for comparison + * + * @return object equality. + */ + + public boolean equals(Object o) { + if (o == null) return false; + + if (o instanceof String) { + return ((String)o).equals(name.getString()); + } else if (o instanceof ClassConstant) { + ClassConstant cc = (ClassConstant)o; + + return name.getString().equals(cc.getClassName()); + } + + return false; + } +} diff --git a/src/FESI/ClassFile/ClassFile.java b/src/FESI/ClassFile/ClassFile.java new file mode 100644 index 00000000..9e82d9c2 --- /dev/null +++ b/src/FESI/ClassFile/ClassFile.java @@ -0,0 +1,469 @@ +/* + * + * @(#) ClassFile.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.ClassFile + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import java.util.Vector; + +import FESI.ClassFile.Attribute; +import FESI.ClassFile.ClassConstant; +import FESI.ClassFile.ConstantPoolEntry; +import FESI.ClassFile.FieldDesc; +import FESI.ClassFile.MethodDesc; + +/** + *

+ * The ClassFile class is designed to provide lightweight, minimal support + * for the runtime construction of Java VM ClassFile's, or Class + * implementations. + *

+ *

+ * The ClassFile provides API's to construct an in-core description of a + * Java class implementation, and subsequently write that description to + * a stream which may then be either loaded into the VM via a ClassLoader + * or written to some persistent store. + *

+ *

+ * It should be noted that the ClassFile provide little or no validation of + * the Class it describes during the construction of that description, and + * therefore users of this class and package should be familiar with the + * contents of the Java VM Specification published by Addison-Wesley. + *

+ */ + +final class ClassFile { + + /** + *

the magic number for Java VM class files.

+ */ + + final private static int MAGIC = 0xcafebabe; + + /** + *

the major and minor version numbers for Java VM class files.

+ */ + + final private static short MAJOR = 45; + final private static short MINOR = 3; + + /** + *

the access flags constants for Java VM class files.

+ */ + + final static short ACC_PUBLIC = 0x0001; + final static short ACC_FINAL = 0x0010; + final static short ACC_SUPER = 0x0020; + final static short ACC_INTERFACE = 0x0200; + final static short ACC_ABSTRACT = 0x0400; + + /* + * inst vars represent the format of the classfile itself. + */ + + private Vector constantPool = new Vector(1); + + private short accessFlags = (short)(ACC_PUBLIC | ACC_SUPER); + + private ClassConstant thisClass; + private ClassConstant superClass; + + private Vector interfaces; + private Vector fields; + private Vector methods; + private Vector attributes; + + /** + * @return are we debuging (used to print audit trail). + */ + + static boolean debug() { return false; } + + /** + *

Construct a new ClassFile object.

+ * + * @param tClass name of "this" class + * + * @param sClass name of superclass + * + */ + + ClassFile(String tClass, String sClass) { + thisClass = addClassConstant(tClass); + superClass = addClassConstant(sClass); + } + + /** + *

Write the constant pool to the stream

+ * + * @param dos the stream to write to. + */ + + private void writeConstantPool(DataOutputStream dos) throws IOException { + + if (debug()) System.err.println("write constant pool: " + constantPool.size()); + + dos.writeShort(constantPool.size() + 1); // for index zero + + for (int i = 0; i < constantPool.size(); i++) { + ((ConstantPoolEntry)constantPool.elementAt(i)).write(dos); + } + } + + /** + *

Write the list of interfaces to the stream

+ * + * @param dos the stream to write to. + */ + + private void writeInterfaces(DataOutputStream dos) throws IOException { + if (interfaces != null) { + if (debug()) System.err.println("write interfaces: " + interfaces.size()); + dos.writeShort(interfaces.size()); + + for (int i = 0; i < interfaces.size(); i++) { + dos.writeShort( + ((ConstantPoolEntry)interfaces.elementAt(i)).getConstantPoolIndex() + ); + } + } else dos.writeShort(0); + } + + /** + *

Write the list of Fields defs to the stream

+ * + * @param dos the stream to write to. + */ + + private void writeFields(DataOutputStream dos) throws IOException { + if (fields != null) { + if (debug()) System.err.println("write fields: " + fields.size()); + + dos.writeShort(fields.size()); + + for (int i = 0; i < fields.size(); i++) { + ((FieldDesc)fields.elementAt(i)).write(dos); + } + } else dos.writeShort(0); + } + + /** + *

Write the list of Method defs to the stream.

+ * + * @param dos the stream to write to. + */ + + private void writeMethods(DataOutputStream dos) throws IOException { + if (methods != null) { + if (debug()) System.err.println("write methods: " + methods.size()); + + dos.writeShort(methods.size()); + + for (int i = 0; i < methods.size(); i++) { + ((MethodDesc)methods.elementAt(i)).write(dos); + } + } else dos.writeShort(0); + + } + + /** + *

Write the list of Attributes to the stream

+ * + * @param dos the stream to write to. + */ + + private void writeAttributes(DataOutputStream dos) throws IOException { + if (attributes != null) { + if (debug()) System.err.println("write attributes: " + attributes.size()); + + dos.writeShort(attributes.size()); + + for (int i = 0; i < attributes.size(); i++) { + ((Attribute)attributes.elementAt(i)).write(dos); + } + } else dos.writeShort(0); + } + + /** + *

Write the ClassFile to the Stream

+ * + * @param os the stream to write to. + */ + + public synchronized void write(OutputStream os) throws IOException { + DataOutputStream dos = new DataOutputStream(os); + + try { + dos.writeInt(MAGIC); + + dos.writeShort(MINOR); + dos.writeShort(MAJOR); + + writeConstantPool(dos); + + if (debug()) System.err.println("access: " + accessFlags); + + dos.writeShort(accessFlags); + + dos.writeShort(thisClass.getConstantPoolIndex()); + dos.writeShort(superClass.getConstantPoolIndex()); + + writeInterfaces(dos); + + writeFields(dos); + + writeMethods(dos); + + writeAttributes(dos); + + dos.close(); // all done! + } catch (IOException ioe) { + System.err.println("Bad IO"); + } catch (Exception e) { + System.err.println("Oops"); + } + } + + /** + *

Add an entry to the Constant Pool.

+ * + * @param cpe the new constant pool entry + * + * @return the index of the new entry in the pool + */ + + public synchronized short addConstantPoolEntry(ConstantPoolEntry cpe) { + if (!constantPool.contains(cpe)) constantPool.addElement(cpe); + + return (short)(constantPool.indexOf(cpe) + 1); + } + + /** + *

Find a matching Constant Pool Entry.

+ * + * @param tag The tag value of the constant pool entries to match on. + * @param value The value to match on. + * + * @return the matching entry or null. + */ + + synchronized ConstantPoolEntry match(byte tag, Object value) { + for (int i = 0; i < constantPool.size(); i++) { + ConstantPoolEntry cpe = (ConstantPoolEntry)constantPool.elementAt(i); + + if (cpe.getTag() == tag && cpe.equals(value)) + return cpe; + } + + return null; + } + + /** + * @return the current value of the accessFlags. + */ + + public synchronized short getAccessFlags() { return accessFlags; } + + /** + *

modify the value of the Class File's access flags

+ * + * @param newf the new flag values. [NOT VALIDATED] + */ + + public synchronized void setAccessFlags(short newf) { + + // TODO - verify new flag combination. + + accessFlags = newf; + } + + /** + * @param newMethod the method desc to add to the class file. + */ + + public synchronized void addMethodDesc(MethodDesc newMethod) { + if (methods == null) methods = new Vector(1); + + methods.addElement(newMethod); + } + + /** + * @param newField the field desc to add to the class file. + */ + + public synchronized void addFieldDesc(FieldDesc newField) { + if (fields == null) fields = new Vector(1); + + fields.addElement(newField); + } + + /** + * @param sConstant add a CONSTANT_STRING to the ClassFile. + * + * @param sConstant the string value to add. + * + * @return The new StringConstant + */ + + public StringConstant addStringConstant(String sConstant) { + UTF8Constant c = (UTF8Constant)match(ConstantPoolEntry.CONSTANT_UTF8, sConstant); + + if (c == null) { + c = new UTF8Constant(sConstant, this); + } + + StringConstant s = new StringConstant(c, this); + + return s; + } + + /** + *

Add a new CONSTANT_INTEGER to the Constant Pool

+ * + * @param iConstant the integer value to add. + * + * @return the new IntegerConstant. + */ + + public IntegerConstant addIntegerConstant(int iConstant) { + IntegerConstant c = (IntegerConstant)match(ConstantPoolEntry.CONSTANT_INTEGER, new Integer(iConstant)); + + if (c == null) { + c = new IntegerConstant(iConstant, this); + } + + return c; + } + + /** + *

Add a new UTF8_CONSTANT to the constant pool

+ * + * @param sConstant the string to add. + * + * @return the new UUTF8Constant + */ + + public UTF8Constant addUTF8Constant(String sConstant) { + UTF8Constant c = (UTF8Constant)match(ConstantPoolEntry.CONSTANT_UTF8, sConstant); + + if (c == null) { + c = new UTF8Constant(sConstant, this); + } + + return c; + } + + /** + *

add a new CONSTANT_CLASS to the Constant Pool

+ * + * @param classConstant the name of the class to add + * + * @return the newly ClassConstant + */ + + public ClassConstant addClassConstant(String classConstant) { + ClassConstant c = (ClassConstant)match(ConstantPoolEntry.CONSTANT_CLASS, classConstant); + + if (c == null) { + c = new ClassConstant(classConstant, this); + } + + return c; + } + + /** + *

add a CONSTANT_METHOD to the constant pool

+ * + * @param cName the name of the defining class + * @param mName the method name + * @param tName the fully qualified type descriptor for the method + * + * @return the new created CONSTANT_METHOD + */ + + public MethodConstant addMethodConstant(String cName, String mName, String tName) { + return new MethodConstant(cName, mName, tName, this); + } + + /** + * + * + * @param cName the name of the defining class + * @param fName the name of the field + * @param tName the fully qualified type descriptor of the field + * + * @return the new created CONSTANT_FIELD + */ + + public FieldConstant addFieldConstant(String cName, String fName, String tName) { + return new FieldConstant(cName, fName, tName, this); + } + + /** + *

add the name of an interface this class implements to the constant pool

+ * + * @param iName the name of the interface + */ + + public void addInterface(String iName) { + if (interfaces == null) interfaces = new Vector(1); + + interfaces.addElement((Object)addClassConstant(iName)); + } + + /** + *

+ * convenience routine to take a type name and map it to the internal form. + * java.lang.Object -> java/lang/Object + *

+ * + * @param str the string to map + * + * @return the mapped string value. + */ + + public static String fullyQualifiedForm(String str) { + return str.replace('.', '/'); + } + + + /** + *

+ * convenience routine to construct type descriptors from fully + * qualified names, e.g: java.lang.Object => Ljava/lang/Object; + *

+ * + * @param str name of a java "type" + * + * @return the class descriptor. + */ + + public static String fieldType(String str) { + return "L" + ClassFile.fullyQualifiedForm(str) + ";"; + } + +} diff --git a/src/FESI/ClassFile/Code.java b/src/FESI/ClassFile/Code.java new file mode 100644 index 00000000..9639c761 --- /dev/null +++ b/src/FESI/ClassFile/Code.java @@ -0,0 +1,702 @@ +/* + * + * @(#) Code.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.Code + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + + +import java.io.DataOutputStream; +import java.io.IOException; + +import java.util.Vector; + +import FESI.ClassFile.Attribute; +import FESI.ClassFile.ClassConstant; + +/** + *

+ * The Code attribute is defined to describe the implementation for each + * Method Implementation in a class. In particular it contains the byte + * codes and exception information. + *

+ */ + +final class Code extends Attribute { + + final static byte OP_NOP = (byte) 0x00; + final static byte OP_ACONST_NULL = (byte) 0x01; + + // int consts + + final static byte OP_ICONST_m1 = (byte) 0x02; + final static byte OP_ICONST_0 = (byte) 0x03; + final static byte OP_ICONST_1 = (byte) 0x04; + final static byte OP_ICONST_2 = (byte) 0x05; + final static byte OP_ICONST_3 = (byte) 0x06; + final static byte OP_ICONST_4 = (byte) 0x07; + final static byte OP_ICONST_5 = (byte) 0x08; + + // long consts + + final static byte OP_LCONST_0 = (byte) 0x09; + final static byte OP_LCONST_1 = (byte) 0x0A; + + // float consts + + final static byte OP_FCONST_0 = (byte) 0x0B; + final static byte OP_FCONST_1 = (byte) 0x0C; + final static byte OP_FCONST_2 = (byte) 0x0D; + + // double consts + + final static byte OP_DCONST_0 = (byte) 0x0E; + final static byte OP_DCONST_1 = (byte) 0x0F; + + final static byte OP_BIPUSH = (byte) 0x10; + final static byte OP_SIPUSH = (byte) 0x11; + + final static byte OP_LDC = (byte) 0x12; + final static byte OP_LDC_WIDE = (byte) 0x13; + final static byte OP_LDC2_WIDE = (byte) 0x14; + + + // typed loads local + + final static byte OP_ILOAD = (byte) 0x15; + final static byte OP_LLOAD = (byte) 0x16; + final static byte OP_FLOAD = (byte) 0x17; + final static byte OP_DLOAD = (byte) 0x18; + final static byte OP_ALOAD = (byte) 0x19; + + // int loads + + final static byte OP_ILOAD_0 = (byte) 0x1A; + final static byte OP_ILOAD_1 = (byte) 0x1B; + final static byte OP_ILOAD_2 = (byte) 0x1C; + final static byte OP_ILOAD_3 = (byte) 0x1D; + + // long loads + + final static byte OP_LLOAD_0 = (byte) 0x1E; + final static byte OP_LLOAD_1 = (byte) 0x1F; + final static byte OP_LLOAD_2 = (byte) 0x20; + final static byte OP_LLOAD_3 = (byte) 0x21; + + // float loads + + final static byte OP_FLOAD_0 = (byte) 0x22; + final static byte OP_FLOAD_1 = (byte) 0x23; + final static byte OP_FLOAD_2 = (byte) 0x24; + final static byte OP_FLOAD_3 = (byte) 0x25; + + // double loads + + final static byte OP_DLOAD_0 = (byte) 0x26; + final static byte OP_DLOAD_1 = (byte) 0x27; + final static byte OP_DLOAD_2 = (byte) 0x28; + final static byte OP_DLOAD_3 = (byte) 0x29; + + // ref loads + + final static byte OP_ALOAD_0 = (byte) 0x2A; + final static byte OP_ALOAD_1 = (byte) 0x2B; + final static byte OP_ALOAD_2 = (byte) 0x2C; + final static byte OP_ALOAD_3 = (byte) 0x2D; + + final static byte OP_IALOAD = (byte) 0x2E; + final static byte OP_LALOAD = (byte) 0x2F; + + // array loads + + final static byte OP_FALOAD = (byte) 0x30; + final static byte OP_DALOAD = (byte) 0x31; + final static byte OP_AALOAD = (byte) 0x32; + final static byte OP_BALOAD = (byte) 0x33; + final static byte OP_CALOAD = (byte) 0x34; + final static byte OP_SALOAD = (byte) 0x35; + + final static byte OP_ISTORE = (byte) 0x36; + final static byte OP_LSTORE = (byte) 0x37; + final static byte OP_FSTORE = (byte) 0x38; + final static byte OP_DSTORE = (byte) 0x39; + final static byte OP_ASTORE = (byte) 0x3A; + + // int stores + + final static byte OP_ISTORE_0 = (byte) 0x3B; + final static byte OP_ISTORE_1 = (byte) 0x3C; + final static byte OP_ISTORE_2 = (byte) 0x3D; + final static byte OP_ISTORE_3 = (byte) 0x3E; + + // long stores + + final static byte OP_LSTORE_0 = (byte) 0x3F; + final static byte OP_LSTORE_1 = (byte) 0x40; + final static byte OP_LSTORE_2 = (byte) 0x41; + final static byte OP_LSTORE_3 = (byte) 0x42; + + // float stores + + final static byte OP_FSTORE_0 = (byte) 0x43; + final static byte OP_FSTORE_1 = (byte) 0x44; + final static byte OP_FSTORE_2 = (byte) 0x45; + final static byte OP_FSTORE_3 = (byte) 0x46; + + // double stores + + final static byte OP_DSTORE_0 = (byte) 0x47; + final static byte OP_DSTORE_1 = (byte) 0x48; + final static byte OP_DSTORE_2 = (byte) 0x49; + final static byte OP_DSTORE_3 = (byte) 0x4A; + + // ref stores + + final static byte OP_ASTORE_0 = (byte) 0x4B; + final static byte OP_ASTORE_1 = (byte) 0x4C; + final static byte OP_ASTORE_2 = (byte) 0x4D; + final static byte OP_ASTORE_3 = (byte) 0x4E; + + final static byte OP_IASTORE = (byte) 0x4F; + + // array stores + + final static byte OP_LASTORE = (byte) 0x50; + final static byte OP_FASTORE = (byte) 0x51; + final static byte OP_DASTORE = (byte) 0x52; + final static byte OP_AASTORE = (byte) 0x53; + final static byte OP_BASTORE = (byte) 0x54; + final static byte OP_CASTORE = (byte) 0x55; + final static byte OP_SASTORE = (byte) 0x56; + + final static byte OP_POP = (byte) 0x57; + final static byte OP_POP2 = (byte) 0x58; + + // dup's + + final static byte OP_DUP = (byte) 0x59; + final static byte OP_DUP_X1 = (byte) 0x5A; + final static byte OP_DUP_X2 = (byte) 0x5B; + final static byte OP_DUP2 = (byte) 0x5C; + final static byte OP_DUP2_X1 = (byte) 0x5D; + final static byte OP_DUP2_X2 = (byte) 0x5E; + final static byte OP_SWAP = (byte) 0x5F; + + // arith + + final static byte OP_IADD = (byte) 0x60; + final static byte OP_LADD = (byte) 0x61; + final static byte OP_FADD = (byte) 0x62; + final static byte OP_DADD = (byte) 0x63; + + final static byte OP_ISUB = (byte) 0x64; + final static byte OP_LSUB = (byte) 0x65; + final static byte OP_FSUB = (byte) 0x66; + final static byte OP_DSUB = (byte) 0x67; + + final static byte OP_IMUL = (byte) 0x68; + final static byte OP_LMUL = (byte) 0x69; + final static byte OP_FMUL = (byte) 0x6A; + final static byte OP_DMUL = (byte) 0x6B; + + final static byte OP_IDIV = (byte) 0x6C; + final static byte OP_FDIV = (byte) 0x6E; + final static byte OP_LDIV = (byte) 0x6D; + final static byte OP_DDIV = (byte) 0x6F; + + // arith misc + + final static byte OP_IREM = (byte) 0x70; + final static byte OP_LREM = (byte) 0x71; + final static byte OP_FREM = (byte) 0x72; + final static byte OP_DREM = (byte) 0x73; + + final static byte OP_INEG = (byte) 0x74; + final static byte OP_LNEG = (byte) 0x75; + final static byte OP_FNEG = (byte) 0x76; + final static byte OP_DNEG = (byte) 0x77; + + final static byte OP_ISHL = (byte) 0x78; + final static byte OP_LSHL = (byte) 0x79; + + final static byte OP_ISHR = (byte) 0x7A; + final static byte OP_LSHR = (byte) 0x7B; + + final static byte OP_IUSHR = (byte) 0x7C; + final static byte OP_LUSHR = (byte) 0x7D; + + final static byte OP_IAND = (byte) 0x7E; + final static byte OP_LAND = (byte) 0x7F; + + final static byte OP_IOR = (byte) 0x80; + final static byte OP_LOR = (byte) 0x81; + + final static byte OP_IXOR = (byte) 0x82; + final static byte OP_LXOR = (byte) 0x83; + + // local int += const + + final static byte OP_IINC = (byte) 0x84; + + // int conversions + + final static byte OP_I2L = (byte) 0x85; + final static byte OP_I2F = (byte) 0x86; + final static byte OP_I2D = (byte) 0x87; + + // long conversions + + final static byte OP_L2I = (byte) 0x88; + final static byte OP_L2F = (byte) 0x89; + final static byte OP_L2D = (byte) 0x8A; + + // float conversions + + final static byte OP_F2I = (byte) 0x8B; + final static byte OP_F2L = (byte) 0x8C; + final static byte OP_F2D = (byte) 0x8D; + + // double conversions + + final static byte OP_D2I = (byte) 0x8E; + final static byte OP_D2L = (byte) 0x8F; + final static byte OP_D2F = (byte) 0x90; + + // int conversions + + final static byte OP_I2B = (byte) 0x91; + final static byte OP_I2C = (byte) 0x92; + final static byte OP_I2S = (byte) 0x93; + + // long comparision's + + final static byte OP_LCMP = (byte) 0x94; + + // float comparision's + + final static byte OP_FCMPL = (byte) 0x95; + final static byte OP_FCMPG = (byte) 0x96; + + // double comparision's + + final static byte OP_DCMPL = (byte) 0x97; + final static byte OP_DCMPG = (byte) 0x98; + + // int to zero comparisions + + final static byte OP_IFEQ = (byte) 0x99; + final static byte OP_IFNE = (byte) 0x9A; + final static byte OP_IFLT = (byte) 0x9B; + final static byte OP_IFGE = (byte) 0x9C; + final static byte OP_IFGT = (byte) 0x9D; + final static byte OP_IFLE = (byte) 0x9E; + + // int to int comparision's + + final static byte OP_IFICMPEQ = (byte) 0x9F; + final static byte OP_IFICMPNE = (byte) 0xA0; + final static byte OP_IFICMPLT = (byte) 0xA1; + final static byte OP_IFICMPGE = (byte) 0xA2; + final static byte OP_IFICMPGT = (byte) 0xA3; + final static byte OP_IFICMPLE = (byte) 0xA4; + + // ref comparisions + + final static byte OP_IFACMPEQ = (byte) 0xA5; + final static byte OP_IFACMPNE = (byte) 0xA6; + + // goto + + final static byte OP_GOTO = (byte) 0xA7; + + final static byte OP_JSR = (byte) 0xA8; + + final static byte OP_RET = (byte) 0xA9; + + final static byte OP_TABLESWITCH = (byte) 0xAA; + + final static byte OP_LOOKUP_SWITCH = (byte) 0xAB; + + + // return's + + final static byte OP_IRETURN = (byte) 0xAC; + final static byte OP_LRETURN = (byte) 0xAD; + final static byte OP_FRETURN = (byte) 0xAE; + final static byte OP_DRETURN = (byte) 0xAF; + final static byte OP_ARETURN = (byte) 0xB0; + final static byte OP_RETURN = (byte) 0xB1; + + + // getfield's + + final static byte OP_GETSTATIC = (byte) 0xB2; + final static byte OP_GETFIELD = (byte) 0xB4; + + // invoke virtual + + final static byte OP_INVOKE_VIRTUAL = (byte) 0xB6; + + // invoke static + + final static byte OP_INVOKE_STATIC = (byte) 0xB8; + + // method invocation + + final static byte OP_INVOKE_SPECIAL = (byte) 0xB7; + + // invoke interface + + final static byte OP_INVOKE_INTERFACE = (byte) 0xB9; + + // new + + final static byte OP_NEW = (byte) 0xBB; + + // array misc + + final static byte OP_NEWARRAY = (byte) 0xBD; + + final static byte ARRAY_T_BOOLEAN = (byte) 0x4; + final static byte ARRAY_T_CHAR = (byte) 0x5; + final static byte ARRAY_T_FLOAT = (byte) 0x6; + final static byte ARRAY_T_DOUBLE = (byte) 0x7; + final static byte ARRAY_T_BYTE = (byte) 0x8; + final static byte ARRAY_T_SHORT = (byte) 0x9; + final static byte ARRAY_T_INT = (byte) 0xA; + final static byte ARRAY_T_LONG = (byte) 0xB; + + // putfield's + + final static byte OP_PUTSTATIC = (byte) 0xB3; + final static byte OP_PUTFIELD = (byte) 0xB5; + + // array's + + final static byte OP_ANEWARRAY = (byte) 0xBD; + final static byte OP_ARRAYLENGTH = (byte) 0xBE; + + // exceptions + + final static byte OP_ATHROW = (byte) 0xBF; + + // cast + + final static byte OP_CHECKCAST = (byte) 0xC0; + + // instanceof + + final static byte OP_INSTANCEOF = (byte) 0xC1; + + // monitor + + final static byte OP_MONITOR_ENTER = (byte) 0xC2; + final static byte OP_MONITOR_EXIT = (byte) 0xC3; + + // wide + + final static byte OP_WIDE = (byte) 0xC4; + + // arrays + + final static byte OP_MULTI_NEW_ARRAY = (byte) 0xC5; + + // compare to null + + final static byte OP_IFNULL = (byte) 0xc6; + final static byte OP_IFNONNULL = (byte) 0xc7; + + // goto wide + + final static byte OP_GOTO_WIDE = (byte) 0xc8; + + final static byte OP_JSR_WIDE = (byte) 0xc9; + + + /* + * inst vars + */ + + private Vector attributes; + + private int length = 12; // starting value + + private short currentPC; + + private short maxLocals; + + private short maxStack; + + private Vector byteCodes = new Vector(1); + + private Vector exceptions; + + /** + *

construct a Code Attribute

+ * + * @param locals number of words used to describe local vars + * @param maxstack max number of stack words used. + * + */ + + Code(ClassFile cf, short locals, short stack) { + super(CODE, cf); + + maxLocals = (locals >= 0 ? locals : 0); + maxStack = (stack > 2 ? stack : 2); + } + + /** + *

write the code attribute to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + int i; + + dos.writeShort(getNameConstantPoolIndex()); + dos.writeInt(getLength()); + dos.writeShort(maxStack); + dos.writeShort(maxLocals); + + // write the code ... + + dos.writeInt(byteCodes.size()); + + for (i = 0; i < byteCodes.size(); i++) { + dos.writeByte(((Byte)byteCodes.elementAt(i)).byteValue()); + } + + // write exceptions (if any) + + if (exceptions != null) { + dos.writeShort(exceptions.size()); + + for (i = 0; i < exceptions.size(); i++) { + ((ExceptionTableEntry)exceptions.elementAt(i)).write(dos); + } + } else dos.writeShort(0); + + // write attributes (if any) + + if (attributes != null) { + dos.writeShort(attributes.size()); + + for (i = 0; i < attributes.size(); i ++) { + ((Attribute)attributes.elementAt(i)).write(dos); + } + } else dos.writeShort(0); + } + + /** + *

returns the length of the Code attribute in bytes

+ * + * @return the length of the attribute. + */ + + int getLength() { return length; } + + /** + * @return object equality. + */ + + public boolean equals(Object o) { + return ((Object)this).equals(o); + } + + /** + * @return the current PC offset from the start of the method. + */ + + short getCurrentPC() { return currentPC; } + + /** + *

+ * adds per Code attribute, can be used for SourceFile, LocalVariable, + * and LineNumberTable attributes etc. + *

+ * + * @param attr Attribte to be added. + */ + + void addAttribute(Attribute attr) { + if (attributes == null) attributes = new Vector(1); + + attributes.addElement(attr); + length += attr.getLength() + 6; // sizeof(Attribute) + } + + /** + *

+ * Adds an entry to the Exception handler table for this Code attribute. + * An entry describes the start and stop pc offset within the Code fragment + * for which an exception handler is provided, the start pc of the handler + * code within the fragment itself, and the class of the exception type + * for this handler. + *

+ * + * @param start start pc offset for this exception handler range + * @param stop stop pc offset for this exception handler range + * @param handler handler pc start offset for this exception + * @param ct CONSTANT_CLASS describing the exception class handled + */ + + void addExceptionTableEntry(short start, short stop, + short handler, ClassConstant ct) { + exceptions.addElement( + new ExceptionTableEntry(start, stop, handler, ct) + ); + + length += 8; // sizeof(ExceptionTableEntry) + } + + /** + *

add an opcode to the implementation

+ */ + + void addOp(byte opCode) { + byteCodes.addElement(new Byte(opCode)); + currentPC++; + length++; + } + + /** + *

add an opcode and a 1 byte operand

+ */ + + void addOp1(byte opCode, byte op1) { + byteCodes.addElement(new Byte(opCode)); + byteCodes.addElement(new Byte(op1)); + currentPC += 2; + length += 2; + } + + /** + *

add an opcode and 2, 1 byte operands

+ */ + + void addOp2(byte opCode, byte op1, byte op2) { + byteCodes.addElement(new Byte(opCode)); + byteCodes.addElement(new Byte(op1)); + byteCodes.addElement(new Byte(op2)); + currentPC += 3; + length += 3; + } + + /** + *

add an opcode and 4, 1 byte operands

+ */ + + void addOp4(byte opCode, byte op1, byte op2, byte op3, byte op4) { + byteCodes.addElement(new Byte(opCode)); + byteCodes.addElement(new Byte(op1)); + byteCodes.addElement(new Byte(op2)); + byteCodes.addElement(new Byte(op3)); + byteCodes.addElement(new Byte(op4)); + currentPC += 5; + length += 5; + + } + + /** + *

add an opcode and a 2 byte operand

+ */ + + void addOpShort(byte opCode,short op) { + addOp2(opCode, + (byte)((op >>> 8) & 0xff), + (byte)( op & 0xff) + ); + } + + /** + *

add an opcode and a 4 byte operand

+ */ + + void addOpInt(byte opCode,int op) { + addOp4(opCode, + (byte)((op >>> 24) & 0xff), + (byte)((op >>> 16) & 0xff), + (byte)((op >>> 8) & 0xff), + (byte)( op & 0xff) + ); + } + + /** + *

increment the local word count

+ * + * @param n the number of local words to increment by. + */ + + void incrLocals(short n) { maxLocals += n; } + + /** + *

increment the max operand stack word count

+ * + * @param n the number of words to increment the max stack count by + */ + + void incrMaxStack(short n) { maxStack += n; } +} + +/* + * private implementation class to represent exception table entries. + */ + +final class ExceptionTableEntry { + private short startPC; + private short stopPC; + private short handlerPC; + private ClassConstant exceptionType; + + /* + * construct and Exception Table Entry + */ + + ExceptionTableEntry(short start, short stop, + short handler, ClassConstant eType) { + super(); + + startPC = start; + stopPC = stop; + handlerPC = handler; + exceptionType = eType; + } + + /* + * wrote the exception table entry to the stream + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeShort(startPC); + dos.writeShort(stopPC); + dos.writeShort(handlerPC); + if (exceptionType != null) + dos.writeShort(exceptionType.getConstantPoolIndex()); + else + dos.writeShort(0); + } +} \ No newline at end of file diff --git a/src/FESI/ClassFile/ConstantPoolEntry.java b/src/FESI/ClassFile/ConstantPoolEntry.java new file mode 100644 index 00000000..726543e2 --- /dev/null +++ b/src/FESI/ClassFile/ConstantPoolEntry.java @@ -0,0 +1,133 @@ +/* + * + * @(#) ConstantPoolEntry.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.ConstantPoolEntry + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; + +/** + *

+ * The ConstantPoolEntry is an abstract base class representing common + * behaviors of specific subtypes, as defined below and in the VM spec. + *

+ * + *

+ * In particular this class handles, equality, sharing, output and indexing + * of all subtypes. + *

+ */ + +abstract class ConstantPoolEntry { + + /* + * subtype tag values. + */ + + final static byte CONSTANT_UTF8 = 1; + final static byte CONSTANT_UNICODE = 2; + final static byte CONSTANT_INTEGER = 3; + final static byte CONSTANT_FLOAT = 4; + final static byte CONSTANT_LONG = 5; + final static byte CONSTANT_DOUBLE = 6; + final static byte CONSTANT_CLASS = 7; + final static byte CONSTANT_STRING = 8; + final static byte CONSTANT_FIELDREF = 9; + final static byte CONSTANT_METHODREF = 10; + final static byte CONSTANT_INTERFACEMETHODREF = 11; + final static byte CONSTANT_NAMEANDTYPE = 12; + + /* + * + */ + + private byte tag; + + private ClassFile classFile; + + private short index = -1; + + /** + *

construct the CPE, set the type tag and class file

+ */ + + ConstantPoolEntry(byte t, ClassFile cf) { + tag = t; + classFile = cf; + } + + /** + * + */ + + byte getTag() { return tag; } + + /** + * @return the CPE's constant pool index. + */ + + short getConstantPoolIndex() { + if (index == -1) index = classFile.addConstantPoolEntry(this); + + return (short)index; + } + + /** + * @return the Class File this CPE is contained within. + */ + + ClassFile getClassFile() { return classFile; }; + + /** + *

* write the CPE to the stream

+ * + * @throws IOException + */ + + abstract void write(DataOutputStream dos) throws IOException; + + /** + *

test the CPE for equality

+ * + * @return object's equality. + */ + + public abstract boolean equals(Object o); + + /** + *

add the CPE into the Class File's constant pool

+ */ + + protected void addToConstantPool() { + if (index == -1) index = classFile.addConstantPoolEntry(this); + } + + /** + * @return are we in debug mode? + */ + + protected static boolean debug() { return ClassFile.debug(); } +} diff --git a/src/FESI/ClassFile/ConstantValue.java b/src/FESI/ClassFile/ConstantValue.java new file mode 100644 index 00000000..fbbe4d9d --- /dev/null +++ b/src/FESI/ClassFile/ConstantValue.java @@ -0,0 +1,157 @@ +/* + * + * @(#) ConstantValue.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.ConstantValue + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.Attribute; +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; +import FESI.ClassFile.IntegerConstant; +import FESI.ClassFile.FloatConstant; +import FESI.ClassFile.DoubleConstant; +import FESI.ClassFile.LongConstant; +import FESI.ClassFile.StringConstant; + +/** + *

+ * This class provides Constant Pool support for all the simple constant + * value data types supported in the class file format. + *

+ */ + +class ConstantValue extends Attribute { + + private ConstantPoolEntry constant; + + /** + *

construct an Attribute describing a Constant

+ * + * @param cf the class file + * @param cpe the cpe of the constant + */ + + private ConstantValue(ClassFile cf, ConstantPoolEntry cpe) { + super(Attribute.CONSTANTVALUE, cf); + constant = cpe; + } + + /** + *

Integer Constant

+ * + * @param cf the class file + * @param ic the Integer Constant + */ + + ConstantValue(ClassFile cf, IntegerConstant ic) { + this(cf, (ConstantPoolEntry)ic); + } + + /** + *

Long Constant

+ * + * @param cf the class file + * @param lc the Long Constant + */ + + ConstantValue(ClassFile cf, LongConstant lc) { + this(cf, (ConstantPoolEntry)lc); + } + + /** + *

Float Constant

+ * + * @param cf the class file + * @param fc the Float Constant + */ + + ConstantValue(ClassFile cf, FloatConstant fc) { + this(cf, (ConstantPoolEntry)fc); + } + + /** + *

Double Constant

+ * + * @param cf the class file + * @param dc the Double Constant + */ + + ConstantValue(ClassFile cf, DoubleConstant dc) { + this(cf, (ConstantPoolEntry)dc); + } + + /** + *

String Constant

+ * + * @param cf the class file + * @param sc the String Constant + */ + + ConstantValue(ClassFile cf, StringConstant sc) { + this(cf, (ConstantPoolEntry)sc); + } + + /** + * @return the length of this ConstantValue Attribute (minus header) + */ + + int getLength() { return 2; } + + /** + * @return the CPE of the constant represented + */ + + ConstantPoolEntry getConstant() { return constant; } + + /** + * @return the CPE type tag of the constant represented + */ + + byte getConstantTag() { return constant.getTag(); } + + /** + *

write the Attribute to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeShort(getNameConstantPoolIndex()); + dos.writeInt(getLength()); + dos.writeShort(constant.getConstantPoolIndex()); + } + + /** + * @return the objects equality. + */ + + public boolean equals(Object o) { + return constant.equals(o); + } +} diff --git a/src/FESI/ClassFile/DoubleConstant.java b/src/FESI/ClassFile/DoubleConstant.java new file mode 100644 index 00000000..f821e165 --- /dev/null +++ b/src/FESI/ClassFile/DoubleConstant.java @@ -0,0 +1,91 @@ +/* + * + * @(#) DoubleConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.DoubleConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; + +/** + *

implements a DOUBLE_CONSTANT CPE

+ */ + +class DoubleConstant extends ConstantPoolEntry { + + private double doubler; + + /** + *

construct a DOUBLE_CONSTANT CPE

+ * + * @param d the double constant + * @param cf the class file + */ + + DoubleConstant(double d, ClassFile cf) { + super(CONSTANT_DOUBLE, cf); + + doubler = d; + + addToConstantPool(); + } + + /** + *

write the constant CPE to the stream

+ * + * @param dos the stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeByte(getTag()); + dos.writeDouble(doubler); + } + + /** + * @return the double constant value. + */ + + double getValue() { return doubler; } + + /** + * @return the object's equality. + */ + + public boolean equals(Object o) { + if (o instanceof Double) { + return doubler == ((Double)o).doubleValue(); + } else if (o instanceof DoubleConstant) { + DoubleConstant dc = (DoubleConstant)o; + + return doubler == dc.getValue(); + } + + return false; + } +} diff --git a/src/FESI/ClassFile/EventAdaptorClassFile.java b/src/FESI/ClassFile/EventAdaptorClassFile.java new file mode 100644 index 00000000..2d6c7384 --- /dev/null +++ b/src/FESI/ClassFile/EventAdaptorClassFile.java @@ -0,0 +1,809 @@ +/* + * + * @(#) EncapsulatedEventAdaptorClassFile.java 1.3@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.EncapsulatedEventAdaptorClassFile + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + +package FESI.ClassFile; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.FileOutputStream; +import java.io.OutputStream; + +import java.io.IOException; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import java.util.Vector; + +import FESI.Interpreter.EventAdaptor; +import FESI.Interpreter.EventAdaptorGenerator; + +import FESI.ClassFile.Attribute; +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ClassConstant; +import FESI.ClassFile.Code; +import FESI.ClassFile.ConstantPoolEntry; +import FESI.ClassFile.Exceptions; +import FESI.ClassFile.IntegerConstant; +import FESI.ClassFile.FieldDesc; +import FESI.ClassFile.FieldConstant; +import FESI.ClassFile.MethodDesc; +import FESI.ClassFile.MethodConstant; +import FESI.ClassFile.StringConstant; + +/** + *

+ * This class is used by the EventAdaptorGenerator to author the + * implementation of the EventAdaptor classes that it is responsible + * for generating and loading. + *

+ * + *

+ * This class wraps all the ClassFile generic support classes and provides + * the adaptor specific implemenetation. + *

+ * + * @see FESI.Interpreter.EventAdaptorGenerator + */ + +public final class EventAdaptorClassFile { + + private static String superClassName = + "FESI.Interpreter.EventAdaptor"; + + /* + * + */ + + private String listenerName; + private Class listenerClass; + + private String adaptorName; + private ClassFile classFile; + + private Method[] listenerMethods; + + /* + * + */ + + private StringConstant listenerNameConst; + + private FieldConstant methodsField; + private FieldConstant clazzField; + + private MethodConstant fireMethod; + private MethodConstant crackedFireMethod; + + private MethodConstant forNameMethod; + + private MethodConstant getMethodsMethod; + + /** + *

+ * This statis function creates the class file implementation and writes + * it to the stream for loading ... + *

+ * + * @param className the name of the adaptor class to synthesize. + * @param os the stream to write the class file into + * @exception IOException If any IO error occured during class loading + * @exception ClassNotFoundException If the class could not be loaded + * + * @returns + */ + + public EventAdaptorClassFile(String className, OutputStream os) + throws IOException, ClassNotFoundException { + + adaptorName = className; + listenerName = EventAdaptorGenerator.getBaseNameFromAdaptorName(className); + + listenerClass = Class.forName(listenerName); + + listenerMethods = listenerClass.getMethods(); + + classFile = new ClassFile(className, superClassName); + + // generate the misc class descriptions ... + + generateClassSundries(); + + // generate the class initializer + + generateInitializer(); + + // now the constructor ... + + generateConstructor(); + + // now the methods ... + + generateListenerMethods(); + + // write the resulting adaptor class to the stream provided. + + write(os); + } + + /** + * Are we running debug for this Adaptor generation? + */ + + private boolean debug() { return false; } + + /** + * Generate misc constant pool entries etc etc ... + */ + + private void generateClassSundries() { + + // the adaptor implements the Listener interface. + + classFile.addInterface(ClassFile.fullyQualifiedForm(listenerName)); + + listenerNameConst = classFile.addStringConstant(listenerName); + + /* + * private static java.lang.reflect.Method[] methods; + */ + + classFile.addFieldDesc( + new FieldDesc( + "methods", + "[Ljava/lang/reflect/Method;", + (short)(FieldDesc.ACC_STATIC | FieldDesc.ACC_PRIVATE), + classFile, + (Attribute[])null + ) + ); + + methodsField = classFile.addFieldConstant(adaptorName, + "methods", + "[Ljava/lang/reflect/Method;" + ); + + /* + * java.lang.reflect.Method[] java.lang.reflect.Method.getMethods(); + */ + + getMethodsMethod = classFile.addMethodConstant( + "java/lang/Class", + "getMethods", + "()[Ljava/lang/reflect/Method;" + ); + + /* + * java.lang.Class java.lang.Class.forName(); + */ + + forNameMethod = classFile.addMethodConstant( + "java/lang/Class", + "forName", + "(Ljava/lang/String;)Ljava/lang/Class;" + ); + /* + * private static java.lang.Class clazz; + */ + + classFile.addFieldDesc( + new FieldDesc( + "clazz", + "Ljava/lang/Class;", + (short)(FieldDesc.ACC_STATIC | FieldDesc.ACC_PRIVATE), + classFile, + (Attribute[])null + ) + ); + + clazzField = classFile.addFieldConstant(adaptorName, + "clazz", + "Ljava/lang/Class;" + ); + + /* + * these are superclass methods called from listener stubs ... + */ + + fireMethod = classFile.addMethodConstant( + adaptorName, + "fire", + "(Ljava/util/EventObject;Ljava/lang/reflect/Method;)V" + ); + + crackedFireMethod = classFile.addMethodConstant( + adaptorName, + "fire", + "([Ljava/lang/Object;Ljava/lang/reflect/Method;)V" + ); + + /* + * stub out base class abstract method: + * + * public static Class getListenerClass() { return clazz; } + * + */ + + Code c = new Code(classFile, (short)1, (short)2); + + c.addOpShort(Code.OP_GETSTATIC, clazzField.getConstantPoolIndex()); + c.addOp (Code.OP_ARETURN); + + Code[] ary = { c }; + + classFile.addMethodDesc( + new MethodDesc( + "getListenerClass", + "()Ljava/lang/Class;", + (short)MethodDesc.ACC_PUBLIC, + classFile, + ary + ) + ); + } + + /** + *

Generate class Initializer method

+ */ + + private void generateInitializer() { + Code c = new Code(classFile, (short)0, (short)3); + Code[] ary = { c }; + short i = listenerNameConst.getConstantPoolIndex(); + + + // clazz = Class.forName( ); + + if (i <= 255) + c.addOp1(Code.OP_LDC, (byte)i); + else + c.addOpShort(Code.OP_LDC_WIDE, i); + + c.addOpShort(Code.OP_INVOKE_STATIC, + forNameMethod.getConstantPoolIndex() + ); + + c.addOp(Code.OP_DUP); + + c.addOpShort(Code.OP_PUTSTATIC, + clazzField.getConstantPoolIndex() + ); + + + // methods = clazz.getMethods(); + + c.addOpShort(Code.OP_INVOKE_VIRTUAL, + getMethodsMethod.getConstantPoolIndex() + ); + + c.addOpShort(Code.OP_PUTSTATIC, + methodsField.getConstantPoolIndex() + ); + + c.addOp (Code.OP_RETURN); + + classFile.addMethodDesc( + new MethodDesc( + "", + "()V", + (short)(MethodDesc.ACC_PRIVATE | MethodDesc.ACC_STATIC), + classFile, + ary + ) + ); + } + + /** + * Author the no-args public constructor for this Adaptor + * + * public void () { super(); } + */ + + private void generateConstructor() { + Code c = new Code(classFile, (short)1, (short)2); + Code[] ary = { c }; + MethodConstant mc; + + // get a MethodConstant for the superclass constructor + + mc = classFile.addMethodConstant( + ClassFile.fullyQualifiedForm(superClassName), + "", + "()V" + ); + + // push this onto the stack + + c.addOp (Code.OP_ALOAD_0); + + // call the superclass constructor + + c.addOpShort(Code.OP_INVOKE_SPECIAL, mc.getConstantPoolIndex()); + + c.addOp (Code.OP_RETURN); + + + // now add a method to the class file describing the constructor ... + + classFile.addMethodDesc( + new MethodDesc( + "", + "()V", + (short)MethodDesc.ACC_PUBLIC, + classFile, + ary + ) + ); + } + + /** + * Author the Listener Method Stubs for the EventListener interface + * this class is adapting to the EventListener interface. + */ + + private void generateListenerMethods() { + for (int i = 0; i < listenerMethods.length; i++) { + + /* we can only generate code for EventListener methods of + * the form: + * + * void ( ) + * or: + * void ( {} ) + * + * if we dont match these patterns we drop the method on the + * floor. + */ + + if (!Void.TYPE.equals(listenerMethods[i].getReturnType())) { + System.err.println( + "Detected unexpected method signature: " + + listenerMethods[i] + + " in interface: " + + listenerName + ); + } else { + Class[] lmParams = listenerMethods[i].getParameterTypes(); + Class[] lmExceptions = listenerMethods[i].getExceptionTypes(); + + + if (lmParams != null && + lmParams.length == 1 && + java.util.EventObject.class.isAssignableFrom(lmParams[0])) { + generateSimpleListenerMethodStub(listenerMethods[i], + lmParams[0], + lmExceptions, + i + ); + } else { + generateCrackedListenerMethodStub(listenerMethods[i], + lmParams, + lmExceptions, + i + ); + } + } + } + } + + /** + * Generate a simple EventListener interface method stub + */ + + private void generateSimpleListenerMethodStub(Method listenerMethod, Class listenerParam, Class[] listenerExceptions, int listenerMethodTableIndex) { + Code c = new Code(classFile, (short)2, (short)4); + Attribute[] ary; + + /* + * public void ( e) + * { + * EncapsulatedEvent t = new EncapsulatedEvent(e); + * Method m = findListenerMethod(); + * + * fire(t, m); + * } + */ + + c.addOp (Code.OP_ALOAD_0); // this + c.addOp (Code.OP_ALOAD_1); // event object + + c.addOpShort(Code.OP_GETSTATIC, + methodsField.getConstantPoolIndex() + ); + + if (listenerMethodTableIndex <= 255) { + c.addOp1(Code.OP_BIPUSH, (byte)listenerMethodTableIndex); + } else { + short i = classFile.addIntegerConstant(listenerMethodTableIndex).getConstantPoolIndex(); + + if (i <= 255) + c.addOp1(Code.OP_LDC, (byte)i); + else + c.addOpShort(Code.OP_LDC_WIDE, i); + } + + c.addOp (Code.OP_AALOAD); + + c.addOpShort(Code.OP_INVOKE_VIRTUAL, + fireMethod.getConstantPoolIndex() + ); // call fire(); + + c.addOp (Code.OP_RETURN); // get out of here + + if (listenerExceptions != null && listenerExceptions.length > 0) { + ary = new Attribute[2]; + + ary[1] = new Exceptions(listenerExceptions, classFile); + } else { + ary = new Attribute[1]; + } + + ary[0] = c; + + // define the listener method + + classFile.addMethodDesc( + new MethodDesc( + listenerMethod.getName(), + "(" + ClassFile.fieldType(listenerParam.getName()) + ")V", + (short)(listenerMethod.getModifiers() & ~MethodDesc.ACC_ABSTRACT), + classFile, + ary + ) + ); + } + + /** + * Generate a cracked EventListener interface method stub + */ + + private void generateCrackedListenerMethodStub(Method listenerMethod, Class[] listenerParams, Class[] listenerExceptions, int listenerMethodTableIndex) { + Code c = new Code(classFile, + (short)(listenerParams.length * 2 + 1), + (short)9 + ); + Attribute[] ary; + String methodPDesc = ""; + boolean wasDoubleWord; // was the last param processed double? + + c.addOp (Code.OP_ALOAD_0); // this + + /* + * For cracked Event listener methods we construct an array of Objects + * to contain the cracked actual parameters ... primitive types are + * wrapped in a container object suitable for their type. + */ + + if (listenerParams.length <= 255) { + c.addOp1(Code.OP_BIPUSH, (byte)listenerParams.length); + } else { + short i = classFile.addIntegerConstant(listenerParams.length).getConstantPoolIndex(); + + if (i <= 255) + c.addOp1(Code.OP_LDC, (byte)i); + else + c.addOpShort(Code.OP_LDC_WIDE, (short)i); + } + + c.addOpShort(Code.OP_ANEWARRAY, + classFile.addClassConstant("java.lang.Object").getConstantPoolIndex() + ); + + /* + * we've now constructed and array of java/lang/Object ... now populate + * it with the actual params. + */ + + int lvarIdx = 1; // because locals[0] == this + + /* + * for each formal parameter, generate code to load the actual + * param from this methods local vars, then if it is a primitive + * type, then construct a container object and initialize it + * to the primitives value. + * + * as a side effect of this loop we also construct the methods + * descriptor to optimise processing of the type info + */ + + for (int i = 0; i < listenerParams.length; i++, lvarIdx += (wasDoubleWord ? 2 : 1)) { + + c.addOp(Code.OP_DUP); // the array reference + + if (lvarIdx <= 255) { // the array index + c.addOp1(Code.OP_BIPUSH, (byte)i); + } else { + short ic = classFile.addIntegerConstant(i).getConstantPoolIndex(); + if (ic < 255) + c.addOp1(Code.OP_LDC, (byte)ic); + else + c.addOpShort(Code.OP_LDC_WIDE, (short)ic); + } + + /* + * get the param value onto TOS + * as a side effect gather method descriptor string. + */ + + String s = processParam(c, listenerParams[i], lvarIdx); + + c.addOp(Code.OP_AASTORE); // arrayref, index, value + + wasDoubleWord = s.equals("J") || s.equals("D"); + + methodPDesc += s; + } + + // that's the array constructed ... now lets call my superclass fire + + // but first we need to tell that method which listener is firing ... + + c.addOpShort(Code.OP_GETSTATIC, + methodsField.getConstantPoolIndex() + ); + + if (listenerMethodTableIndex <= 255) { + c.addOp1(Code.OP_BIPUSH, (byte)listenerMethodTableIndex); + } else { + short i = classFile.addIntegerConstant(listenerMethodTableIndex).getConstantPoolIndex(); + + if (i <= 255) + c.addOp1(Code.OP_LDC, (byte)i); + else + c.addOpShort(Code.OP_LDC_WIDE, i); + } + + c.addOp (Code.OP_AALOAD); // this, array, method + + // now we can call the fire method + + c.addOpShort(Code.OP_INVOKE_VIRTUAL, + crackedFireMethod.getConstantPoolIndex() + ); // call fire(); + + c.addOp (Code.OP_RETURN); // get out of here + + if (listenerExceptions != null && listenerExceptions.length > 0) { + ary = new Attribute[2]; + + ary[1] = new Exceptions(listenerExceptions, classFile); + } else { + ary = new Attribute[1]; + } + + ary[0] = c; + + // define the listener method + + classFile.addMethodDesc( + new MethodDesc( + listenerMethod.getName(), + "(" + methodPDesc + ")V", + (short)(listenerMethod.getModifiers() & ~MethodDesc.ACC_ABSTRACT), + classFile, + ary + ) + ); + } + + /* + * This method is used to generate code for cracked event listener + * stubs. Its job is to generate code to load the appropriate parameter + * data type onto the stack, create a wrapper object if needed and leave + * the appropriate value on TOS for storing into the objects array. + */ + + private String processParam(Code c, Class pClass, int pIdx) { + ClassConstant cc = null; + MethodConstant mc = null; + byte ldOpCode = Code.OP_ALOAD; // load ref by default + byte convOpCode = 0; + boolean singleWordParam = true; + Class pType = pClass; + boolean isPrimitive; + boolean isArrayRef; + + String pDesc = ""; + + // is this an array reference? + + while (pType.isArray()) { // side - effect: construct array param desc + pType = pType.getComponentType(); + pDesc += "["; + } + + isPrimitive = pType.isPrimitive(); + isArrayRef = pClass.isArray(); + + if (isPrimitive) { // builtin datatype + if (pType.equals(java.lang.Long.TYPE)) { + pDesc += "J"; + + if (!isArrayRef) { + cc = classFile.addClassConstant("java/lang/Long"); + + mc = classFile.addMethodConstant( + "java/lang/Long", + "", + "(J)V" + ); + + ldOpCode = Code.OP_LLOAD; + singleWordParam = false; + } + } else if (pType.equals(java.lang.Float.TYPE)) { + pDesc += "F"; + + if (!isArrayRef) { + cc = classFile.addClassConstant("java/lang/Float"); + + mc = classFile.addMethodConstant( + "java/lang/Float", + "", + "(F)V" + ); + + ldOpCode = Code.OP_FLOAD; + } + } else if (pType.equals(java.lang.Double.TYPE)) { + pDesc += "D"; + + if (!isArrayRef) { + cc = classFile.addClassConstant("java/lang/Double"); + + mc = classFile.addMethodConstant( + "java/lang/Double", + "", + "(D)V" + ); + + ldOpCode = Code.OP_DLOAD; + singleWordParam = false; + } + } else { // integer, array or objref computational types ... + + ldOpCode = Code.OP_ILOAD; + + if (pType.equals(java.lang.Boolean.TYPE)) { + pDesc += "Z"; + + if (!isArrayRef) { + cc = classFile.addClassConstant("java/lang/Boolean"); + + mc = classFile.addMethodConstant( + "java/lang/Boolean", + "", + "(Z)V" + ); + + convOpCode = Code.OP_I2B; + } + } else if (pType.equals(java.lang.Character.TYPE)) { + pDesc += "C"; + + if (!isArrayRef) { + cc = classFile.addClassConstant("java/lang/Character"); + + mc = classFile.addMethodConstant( + "java/lang/Character", + "", + "(C)V" + ); + + convOpCode = Code.OP_I2C; + } + } else if (pType.equals(java.lang.Byte.TYPE)) { + pDesc += "B"; + + if (!isArrayRef) { + cc = classFile.addClassConstant("java/lang/Byte"); + + mc = classFile.addMethodConstant( + "java/lang/Character", + "", + "(C)V" + ); + + convOpCode = Code.OP_I2B; + } + } else if (pType.equals(java.lang.Short.TYPE)) { + pDesc += "S"; + + if (!isArrayRef) { + cc = classFile.addClassConstant("java/lang/Short"); + + mc = classFile.addMethodConstant( + "java/lang/Short", + "", + "(S)V" + ); + + convOpCode = Code.OP_I2S; + } + } else if (pType.equals(java.lang.Integer.TYPE)) { + pDesc += "I"; + + if (!isArrayRef) { + cc = classFile.addClassConstant("java/lang/Integer"); + + mc = classFile.addMethodConstant( + "java/lang/Integer", + "", + "(I)V" + ); + } + } + } + } else { // handle descriptors for non-primitives ... + pDesc += ClassFile.fieldType(pType.getName()); + } + + // now load the param value onto TOS ... + + if (pIdx < 255) + c.addOp1(ldOpCode, (byte)pIdx); + else { + c.addOp(Code.OP_WIDE); + c.addOpShort(ldOpCode, (short)pIdx); + } + + if (isPrimitive && !isArrayRef) { // additional processing for primitives + if (convOpCode != 0) { // narrow Int? + c.addOp(convOpCode); // then widen the reference + } + + // we now have the param's value of TOS, + // construct a container object for it + + c.addOpShort(Code.OP_NEW, (short)cc.getConstantPoolIndex()); + + if (singleWordParam) { + c.addOp(Code.OP_DUP_X1); // this, , this + c.addOp(Code.OP_SWAP); // this, + } else { + c.addOp(Code.OP_DUP_X2); // this, , this + c.addOp(Code.OP_DUP_X2); // this, this, , this + c.addOp(Code.OP_POP); // this, this, + } + + c.addOpShort(Code.OP_INVOKE_SPECIAL, mc.getConstantPoolIndex()); + } + + // param value on TOS + + return pDesc; // type descriptor - side effect + } + + /** + *

write the class file to the stream

+ * + * @param os the output stream + * + * @throws IOException + */ + + private void write(OutputStream os) throws IOException { + classFile.write(os); + } +} \ No newline at end of file diff --git a/src/FESI/ClassFile/Exceptions.java b/src/FESI/ClassFile/Exceptions.java new file mode 100644 index 00000000..c11ecb1a --- /dev/null +++ b/src/FESI/ClassFile/Exceptions.java @@ -0,0 +1,160 @@ +/* + * + * @(#) Exceptions.java 1.3@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.Exceptions + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.Attribute; +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ClassConstant; + +/** + *

+ * The Exceptions class extends the Attribute class to enumerate the + * exception types generated by method implementations in a class file + *

+ */ + +class Exceptions extends Attribute { + + private ClassConstant[] exceptions; + + /** + *

construct an Exceptions attribute that enumerates the exceptions

+ * + * @param exs[] an array of exception class constants + * @param cf the containing class file + */ + + Exceptions(ClassConstant[] exs, ClassFile cf) { + super(Attribute.EXCEPTIONS, cf); + + // we should validate that the ClassConstants are all + // subclasses of Exception here ... + + exceptions = exs; + } + + /** + *

construct an Exceptions attribute that enumerates the exceptions

+ * + * @param exs[] an array of exception class types + * @param cf the containing class file + * + */ + Exceptions(Class[] exs, ClassFile cf) { + super(Attribute.EXCEPTIONS, cf); + + // we should validate that the ClassConstants are all + // subclasses of Exception here ... + + ClassConstant[] cc = new ClassConstant[exs.length]; + + for (int i = 0; i < exs.length; i++) + cc[i] = cf.addClassConstant(exs[i].getName()); + + exceptions = cc; + } + + /** + *

write the Exceptions attribute to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeShort(getNameConstantPoolIndex()); + dos.writeInt(getLength()); + + if (exceptions != null && exceptions.length > 0) { + dos.writeShort(exceptions.length); + + for (int i = 0; i < exceptions.length; i++) { + dos.writeShort(exceptions[i].getConstantPoolIndex()); + } + } else dos.writeShort(0); + } + + /** + * @return the Object's equality + */ + + public boolean equals(Object o) { + if (o instanceof Exceptions) { + Exceptions other = (Exceptions)o; + + if (exceptions.length == other.exceptions.length) { + for (int i = 0; i < exceptions.length; i++) { + if (!exceptions[i].equals(other.exceptions[i])) + return false; + } + + return true; + } + } + + return false; + } + + /** + * @return the length of the Attribute in bytes + */ + + int getLength() { return exceptions.length * 2 + 2; } + + /** + *

adds exception class to the attribute.

+ * + * @param a class constant to add to the attribute + * + */ + + void addException(ClassConstant ex) { + + // should verify that ClassConstant is exception subclass and not + // already in the attribute + + if (exceptions == null) { + exceptions = new ClassConstant[1]; + + exceptions[0] = ex; + } else { + ClassConstant[] temp = new ClassConstant[exceptions.length + 1]; + int i; + + for (i = 0; i < exceptions.length; i++) { + temp[i] = exceptions[i]; + } + + temp[i] = ex; + + exceptions = temp; + } + } +} diff --git a/src/FESI/ClassFile/FieldConstant.java b/src/FESI/ClassFile/FieldConstant.java new file mode 100644 index 00000000..59dfea99 --- /dev/null +++ b/src/FESI/ClassFile/FieldConstant.java @@ -0,0 +1,49 @@ +/* + * + * @(#) FieldConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.FieldConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.RefConstant; + +/** + *

implements a CONSTANT_FIELDREF CPE

+ */ + +final class FieldConstant extends RefConstant { + + /** + *

construct a CONSTANT_FIELDREF CPE

+ * + * @param cName the class name + * @param nName the name of the field + * @param tName the type descriptor for the field + * @param cf the class file + */ + + FieldConstant(String cName, String nName, String tName, ClassFile cf) { + super(CONSTANT_FIELDREF, cName, nName, tName, cf); + } +} diff --git a/src/FESI/ClassFile/FieldDesc.java b/src/FESI/ClassFile/FieldDesc.java new file mode 100644 index 00000000..27ec3ceb --- /dev/null +++ b/src/FESI/ClassFile/FieldDesc.java @@ -0,0 +1,107 @@ +/* + * + * @(#) FieldDesc.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.FieldDesc + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.UTF8Constant; +import FESI.ClassFile.Attribute; + +/** + *

+ * Implements the field_info structure of a class file, used to describe + * the attributes of all fields implemented by this class. The class provides + * minimal support to write the formatted structure to the stream. + *

+ */ + +final class FieldDesc { + + final static short ACC_PUBLIC = 0x0001; + final static short ACC_PRIVATE = 0x0002; + final static short ACC_PROTECTED = 0x0004; + final static short ACC_STATIC = 0x0008; + final static short ACC_FINAL = 0x0010; + final static short ACC_VOLATILE = 0x0040; + final static short ACC_TRANSIENT = 0x0080; + + private UTF8Constant name; + private UTF8Constant descriptor; + + private short accessFlags; + + private ClassFile classFile; + + private Attribute[] attributes; + + /** + *

construct a descriptor for a field.

+ * + * @param field name + * @param desc its type descriptor + * @param flags access flags + * @param cf the class file + * @param attrs any associated attributes + * + */ + + FieldDesc(String field, String desc, short flags, ClassFile cf, Attribute[] attrs) { + super(); + + // we would validate here ... + + name = new UTF8Constant(field, cf); + descriptor = new UTF8Constant(desc, cf); + accessFlags = flags; + classFile = cf; + attributes = attrs; + } + + /** + *

write the field to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeShort(accessFlags); + dos.writeShort(name.getConstantPoolIndex()); + dos.writeShort(descriptor.getConstantPoolIndex()); + + if (attributes != null && attributes.length == 0) { + dos.writeShort(attributes.length); + + for (int i = 0; i < attributes.length; i++) { + attributes[i].write(dos); + } + } else dos.writeShort(0); + } +} diff --git a/src/FESI/ClassFile/FloatConstant.java b/src/FESI/ClassFile/FloatConstant.java new file mode 100644 index 00000000..ab0e260b --- /dev/null +++ b/src/FESI/ClassFile/FloatConstant.java @@ -0,0 +1,93 @@ +/* + * + * @(#) FloatConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.FloatConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; + + /** + *

provides minimal support for FLOAT_CONSTANT CPE

+ */ + +class FloatConstant extends ConstantPoolEntry { + + private float floating; + + /** + *

construct a CONSTANT_FLOAT

+ * + * @param f the float value + * @param cf the class file + */ + + FloatConstant(float f, ClassFile cf) { + super(CONSTANT_FLOAT, cf); + + floating = f; + + addToConstantPool(); + } + + /** + *

write the CONSTANT_FLOAT to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeByte(getTag()); + dos.writeFloat(floating); + } + + /** + *

return the value of the constant

+ * + * @return the value of the CONSTANT_FLOAT + */ + + float getValue() { return floating; } + + /** + * @return object equality + */ + + public boolean equals(Object o) { + if (o instanceof Float) { + return floating == ((Float)o).floatValue(); + } else if (o instanceof FloatConstant) { + FloatConstant fc = (FloatConstant)o; + + return floating == fc.getValue(); + } + + return false; + } +} diff --git a/src/FESI/ClassFile/IntegerConstant.java b/src/FESI/ClassFile/IntegerConstant.java new file mode 100644 index 00000000..ce14be27 --- /dev/null +++ b/src/FESI/ClassFile/IntegerConstant.java @@ -0,0 +1,91 @@ +/* + * + * @(#) IntegerConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.IntegerConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; + +/** + *

this class provides minimal support for the CONSTANT_INTEGER CPE

+ */ + +class IntegerConstant extends ConstantPoolEntry { + + private int integer; + + /** + *

construct a CONSTANT_INTEGER CPE

+ * + * @param i the integer constant + * @param cf the class file + */ + + IntegerConstant(int i, ClassFile cf) { + super(CONSTANT_INTEGER, cf); + + integer = i; + + addToConstantPool(); + } + + /** + *

write the CONSTANT_INTEGER to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeByte(getTag()); + dos.writeInt(integer); + } + + /** + * @return the value of the CONSTANT_INTEGER + */ + + int getValue() { return integer; } + + /** + * @return object equality + */ + + public boolean equals(Object o) { + if (o instanceof Integer) { + return integer == ((Integer)o).intValue(); + } else if (o instanceof IntegerConstant) { + IntegerConstant ic = (IntegerConstant)o; + + return integer == ic.getValue(); + } + + return false; + } +} diff --git a/src/FESI/ClassFile/InterfaceMethodConstant.java b/src/FESI/ClassFile/InterfaceMethodConstant.java new file mode 100644 index 00000000..a5c6dd38 --- /dev/null +++ b/src/FESI/ClassFile/InterfaceMethodConstant.java @@ -0,0 +1,50 @@ +/* + * + * @(#) InterfaceMethodConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.InterfaceMethodConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.RefConstant; + +/** + *

this class provides minimal support for CONSTANT_INTERFACEMETHODREF CPE's

+ */ + +class InterfaceMethodConstant extends RefConstant { + + /** + *

construct a CONSTANT_INTERFACEMETHODREF

+ * + * @param cName name of interface + * @param nName name of method + * @param tName method type descriptor + * @param cf class file + * + */ + + InterfaceMethodConstant(String cName, String nName, String tName, ClassFile cf) { + super(CONSTANT_INTERFACEMETHODREF, cName, nName, tName, cf); + } +} diff --git a/src/FESI/ClassFile/LongConstant.java b/src/FESI/ClassFile/LongConstant.java new file mode 100644 index 00000000..8a1a1713 --- /dev/null +++ b/src/FESI/ClassFile/LongConstant.java @@ -0,0 +1,91 @@ +/* + * + * @(#) LongConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.LongConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; + +/** + *

this class provides minimal support for CONSTANT_LONG CPE's

+ */ + +class LongConstant extends ConstantPoolEntry { + + private long longish; + + /** + *

construct a CONSTANT_LONG

+ * + * @param l the long constant + * @param cf the class file + */ + + LongConstant(long l, ClassFile cf) { + super(CONSTANT_LONG, cf); + + longish = l; + + addToConstantPool(); + } + + /** + *

write the CONSTANT_LONG to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeByte(getTag()); + dos.writeLong(longish); + } + + /** + * @return the long constant value + */ + + long getValue() { return longish; } + + /** + * @return object equality + */ + + public boolean equals(Object o) { + if (o instanceof Long) { + return longish == ((Long)o).longValue(); + } else if (o instanceof LongConstant) { + LongConstant lc = (LongConstant)o; + + return longish == lc.getValue(); + } + + return false; + } +} diff --git a/src/FESI/ClassFile/MethodConstant.java b/src/FESI/ClassFile/MethodConstant.java new file mode 100644 index 00000000..eb30187e --- /dev/null +++ b/src/FESI/ClassFile/MethodConstant.java @@ -0,0 +1,49 @@ +/* + * + * @(#) MethodConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.MethodConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.RefConstant; + +/** + *

this class provides minimal support for the CONSTANT_METHODREF CPE

+ */ + +class MethodConstant extends RefConstant { + + /** + *

construct a CONSTANT_METHODREF

+ * + * @param cName the name of the implementing class + * @param nName the name of the method + * @param tName the type descriptor of the method + * @param cf the class file + */ + + MethodConstant(String cName, String nName, String tName, ClassFile cf) { + super(CONSTANT_METHODREF, cName, nName, tName, cf); + } +} diff --git a/src/FESI/ClassFile/MethodDesc.java b/src/FESI/ClassFile/MethodDesc.java new file mode 100644 index 00000000..4fd3cd84 --- /dev/null +++ b/src/FESI/ClassFile/MethodDesc.java @@ -0,0 +1,104 @@ +/* + * + * @(#) MethodDesc.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.MethodDesc + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.UTF8Constant; +import FESI.ClassFile.Attribute; + +/** + *

this class provides minimal support for method_info structures

+ */ + +final class MethodDesc { + + final static short ACC_PUBLIC = 0x0001; + final static short ACC_PRIVATE = 0x0002; + final static short ACC_PROTECTED = 0x0004; + final static short ACC_STATIC = 0x0008; + final static short ACC_FINAL = 0x0010; + final static short ACC_SYNCHRONIZED = 0x0020; + final static short ACC_NATIVE = 0x0100; + final static short ACC_ABSTRACT = 0x0400; + + private UTF8Constant name; + private UTF8Constant descriptor; + + private short accessFlags; + + private ClassFile classFile; + + private Attribute[] attributes; + + /** + *

construct a descriptor for a method

+ * + * @param method the name of the method + * @param desc a type descriptor for its signature + * @param flags access flags + * @param cf the class file + * @param attrs arbitrary attributes + * + */ + + MethodDesc(String method, String desc, short flags, ClassFile cf, Attribute[] attrs) { + super(); + + // we would validate here ... + + name = new UTF8Constant(method, cf); + descriptor = new UTF8Constant(desc, cf); + accessFlags = flags; + classFile = cf; + attributes = attrs; + } + + /** + *

write the method to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeShort(accessFlags); + dos.writeShort(name.getConstantPoolIndex()); + dos.writeShort(descriptor.getConstantPoolIndex()); + + if (attributes != null && attributes.length > 0) { + dos.writeShort(attributes.length); + + for (int i = 0; i < attributes.length; i++) { + attributes[i].write(dos); + } + } else dos.writeShort(0); + } +} diff --git a/src/FESI/ClassFile/NameAndTypeConstant.java b/src/FESI/ClassFile/NameAndTypeConstant.java new file mode 100644 index 00000000..1db88c26 --- /dev/null +++ b/src/FESI/ClassFile/NameAndTypeConstant.java @@ -0,0 +1,115 @@ +/* + * + * @(#) NameAndTypeConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.NameAndTypeConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; +import FESI.ClassFile.UTF8Constant; + +/** + *

this class provides minimal support for NAME_AND_TYPE CPE's

+ */ + +class NameAndTypeConstant extends ConstantPoolEntry { + + private UTF8Constant name; + private UTF8Constant desc; + + /** + *

construct a CONSTANT_NAMEANDTYPE CPE

+ * + * @param n the name + * @param d the type + * @param cf the class file + */ + + NameAndTypeConstant(String n, String d, ClassFile cf) { + super(CONSTANT_NAMEANDTYPE, cf); + + name = new UTF8Constant(n, cf); + desc = new UTF8Constant(d, cf); + + addToConstantPool(); + } + + /** + *

write the CPE to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + + if (debug()) { + System.err.println(getConstantPoolIndex() + + " NAME: " + + name.getConstantPoolIndex() + + " TYPE: " + + desc.getConstantPoolIndex() + ); + } + + dos.writeByte(getTag()); + dos.writeShort(name.getConstantPoolIndex()); + dos.writeShort(desc.getConstantPoolIndex()); + } + + /** + * @return the name string + */ + + String getName() { return name.getString(); } + + /** + * @return the type descriptor string + */ + + String getDescriptor() { return desc.getString(); } + + /** + * @return object equality + */ + + public boolean equals(Object o) { + if (o instanceof String) { + return name.getString().equals(o) || + desc.getString().equals(o); + } else if (o instanceof NameAndTypeConstant) { + NameAndTypeConstant nandt = (NameAndTypeConstant)o; + + return name.equals(nandt.getName()) && + desc.equals(nandt.getDescriptor()); + + } + + return false; + } +} diff --git a/src/FESI/ClassFile/RefConstant.java b/src/FESI/ClassFile/RefConstant.java new file mode 100644 index 00000000..6a871378 --- /dev/null +++ b/src/FESI/ClassFile/RefConstant.java @@ -0,0 +1,112 @@ +/* + * + * @(#) RefConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.RefConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; +import FESI.ClassFile.ClassConstant; +import FESI.ClassFile.NameAndTypeConstant; + +/** + *

+ * this base class provides minimal support for METHODREF, FIELDREF, and + * INTERFACEMETHODREF CPE's + *

+ */ + +class RefConstant extends ConstantPoolEntry { + + private ClassConstant clazz; + private NameAndTypeConstant nandt; + + /** + *

construct a CPE

+ * + * @param t the CPE tag value + * @param cName the class name + * @param nName the name of the referenced field or method + * @param tName the type descriptor of the field or method + * @param cf the class file + * + */ + + protected RefConstant(byte t, String cName, + String nName, String tName, ClassFile cf) { + super(t, cf); + + clazz = new ClassConstant(cName, cf); + nandt = new NameAndTypeConstant(nName, tName, cf); + + addToConstantPool(); + } + + /** + *

write the referenced object to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeByte(getTag()); + dos.writeShort(clazz.getConstantPoolIndex()); + dos.writeShort(nandt.getConstantPoolIndex()); + } + + /** + * @return the class constant for the referenced object + */ + + ClassConstant getClassObject() { return clazz; } + + /** + * @return the name and type CPE for the referenced object + */ + + NameAndTypeConstant getNameAndType() { return nandt; } + + /** + * @return object equality + */ + + public boolean equals(Object o) { + if (o instanceof String) { + return ((String)o).equals(nandt.getName()); + } else if (o instanceof RefConstant) { + RefConstant rc = (RefConstant)o; + + return clazz.equals(rc.getClassObject()) && + nandt.equals(rc.getNameAndType()); + } + + return false; + } + +} diff --git a/src/FESI/ClassFile/StringConstant.java b/src/FESI/ClassFile/StringConstant.java new file mode 100644 index 00000000..28dca795 --- /dev/null +++ b/src/FESI/ClassFile/StringConstant.java @@ -0,0 +1,105 @@ +/* + * + * @(#) StringConstant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.StringConstant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; +import FESI.ClassFile.UTF8Constant; + +/** + *

this class provides minimal support for CONSTANT_STRING CPE's

+ */ + +final class StringConstant extends ConstantPoolEntry { + + private UTF8Constant string; + + /** + *

construct a CONSTANT_STRING CPE

+ * + * @param str the constant + * @param cf the class file + */ + + StringConstant(String str, ClassFile cf) { + super(CONSTANT_STRING, cf); + + string = new UTF8Constant(str, cf); + + addToConstantPool(); + } + + /** + *

construct a CONSTANT_STRING CPE

+ * + * @param utf8 the utf8 constant + * @param cf the class file + */ + + StringConstant(UTF8Constant utf8, ClassFile cf) { + super(CONSTANT_STRING, cf); + + string = utf8; + + addToConstantPool(); + } + + /** + *

write the constant to the stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeByte(getTag()); + dos.writeShort(string.getConstantPoolIndex()); + } + + /** + * @return the string constant + */ + + String getString() { return string.getString(); } + + /** + * @return object equality + */ + + public boolean equals(Object o) { + if (o instanceof String) { + return string.equals(o); + } else if (o instanceof StringConstant) { + return string.equals(((StringConstant)o).getString()); + } + + return false; + } +} diff --git a/src/FESI/ClassFile/UTF8Constant.java b/src/FESI/ClassFile/UTF8Constant.java new file mode 100644 index 00000000..35ad763f --- /dev/null +++ b/src/FESI/ClassFile/UTF8Constant.java @@ -0,0 +1,89 @@ +/* + * + * @(#) UTF8Constant.java 1.2@(#) + * + * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. + * + * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE + * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES + * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING + * THIS SOFTWARE OR ITS DERIVATIVES. + * + */ + +/** + *

+ * FESI.ClassFile.UTF8Constant + *

+ * + * @version 1.0 + * @author Laurence P. G. Cable + */ + + +package FESI.ClassFile; + +import java.io.DataOutputStream; +import java.io.IOException; + +import FESI.ClassFile.ClassFile; +import FESI.ClassFile.ConstantPoolEntry; + +/** + *

this class provides minimal support for CONSTANT_UTF8 CPE's

+ */ + +class UTF8Constant extends ConstantPoolEntry { + + private String string; + + /** + *

construct a CONSTANT_UTF8 CPE

+ * + * @param s the string + * @param cf the class file + */ + + UTF8Constant(String s, ClassFile cf) { + super(CONSTANT_UTF8, cf); + + string = s; + + addToConstantPool(); + } + + /** + *

write the CPE to the output stream

+ * + * @param dos the output stream + * + * @throws IOException + */ + + void write(DataOutputStream dos) throws IOException { + dos.writeByte(getTag()); + dos.writeUTF(string); + } + + /** + * @return the string constant + */ + + String getString() { return string; } + + /** + * @return object equality + */ + + public boolean equals(Object o) { + if (o instanceof String) { + return string.equals((String)o); + } else if (o instanceof UTF8Constant) { + return string.equals(((UTF8Constant)o).getString()); + } + + return false; + } +} diff --git a/src/FESI/Data/ArrayObject.java b/src/FESI/Data/ArrayObject.java new file mode 100644 index 00000000..724b909f --- /dev/null +++ b/src/FESI/Data/ArrayObject.java @@ -0,0 +1,185 @@ +// ArrayObject.java +// FESI Copyright (c) Jean-Marc Lugrin, 1999 +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. + +// This program 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 +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package FESI.Data; + +import java.util.Hashtable; +import FESI.Exceptions.*; +import FESI.Interpreter.*; + +/** + * Implements the Array EcmaScript object. This is a singleton + */ +public class ArrayObject extends BuiltinFunctionObject { + + private static final String JOINstring = ("join").intern(); + private static final int JOINhash = JOINstring.hashCode(); + private static final String LENGTHstring = ("length").intern(); + private static final int LENGTHhash = LENGTHstring.hashCode(); + private static final String ZEROstring = ("0").intern(); + private static final int ZEROhash = ZEROstring.hashCode(); + + /** + * Create a new Array object - used by makeArrayObject + * + * @param prototype Must be an ArrayPrototype + * @param evaluator the evaluator + */ + private ArrayObject(ESObject prototype, Evaluator evaluator) { + super(prototype, evaluator, "Array", 1); + } + + + // overrides + public ESValue callFunction(ESObject thisObject, + ESValue[] arguments) + throws EcmaScriptException { + return doConstruct(thisObject, arguments); + } + + + // overrides + public ESObject doConstruct(ESObject thisObject, + ESValue[] arguments) + throws EcmaScriptException { + ESObject ap = evaluator.getArrayPrototype(); + ArrayPrototype theArray = new ArrayPrototype(ap, evaluator); + if (arguments.length > 1) { + for (int i=0; i 0) { + separator = arguments[0].toString(); + } + int length = (thisObject.getProperty(ArrayObject.LENGTHstring, ArrayObject.LENGTHhash)).toInt32(); + for (int i =0; i0) buffer.append(separator); + String iString = Integer.toString(i); + ESValue value = thisObject.getProperty(iString,iString.hashCode()); + if (value!=ESUndefined.theUndefined && value!=ESNull.theNull) { + buffer.append(value.toString()); + } + } + return new ESString(buffer.toString()); + } + } + class ArrayPrototypeReverse extends BuiltinFunctionObject { + ArrayPrototypeReverse(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 0); + } + public ESValue callFunction(ESObject thisObject, + ESValue[] arguments) + throws EcmaScriptException { + if (!(thisObject instanceof ArrayPrototype)) { + throw new EcmaScriptException ("reverse only implemented for arrays"); + } + return ((ArrayPrototype) thisObject).reverse(); + } + } + class ArrayPrototypeSort extends BuiltinFunctionObject { + ArrayPrototypeSort(String name, Evaluator evaluator, FunctionPrototype fp) { + super(fp, evaluator, name, 1); + } + public ESValue callFunction(ESObject thisObject, + ESValue[] arguments) + throws EcmaScriptException { + if (!(thisObject instanceof ArrayPrototype)) { + throw new EcmaScriptException ("sort only implemented for arrays"); + } + ESValue compareFn = null; + if (arguments.length>0) compareFn = arguments[0]; + return ((ArrayPrototype) thisObject).sort(compareFn); + } + } + + arrayObject.putHiddenProperty("prototype",arrayPrototype); + arrayObject.putHiddenProperty(LENGTHstring,new ESNumber(1)); + + arrayPrototype.putHiddenProperty("constructor",arrayObject); + arrayPrototype.putHiddenProperty("toString", + new ArrayPrototypeToString("toString", evaluator, functionPrototype)); + arrayPrototype.putHiddenProperty("join", + new ArrayPrototypeJoin("join", evaluator, functionPrototype)); + arrayPrototype.putHiddenProperty("reverse", + new ArrayPrototypeReverse("reverse", evaluator, functionPrototype)); + arrayPrototype.putHiddenProperty("sort", + new ArrayPrototypeSort("sort", evaluator, functionPrototype)); + } catch (EcmaScriptException e) { + e.printStackTrace(); + throw new ProgrammingError(e.getMessage()); + } + + evaluator.setArrayPrototype(arrayPrototype); + + return arrayObject; + } +} \ No newline at end of file diff --git a/src/FESI/Data/ArrayPrototype.java b/src/FESI/Data/ArrayPrototype.java new file mode 100644 index 00000000..c9b4d495 --- /dev/null +++ b/src/FESI/Data/ArrayPrototype.java @@ -0,0 +1,585 @@ +// ArrayPrototype.java +// FESI Copyright (c) Jean-Marc Lugrin, 1999 +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. + +// This program 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 +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package FESI.Data; + +import FESI.Exceptions.*; +import FESI.Interpreter.*; + +import java.util.Vector; +import java.util.Enumeration; +import java.lang.reflect.Array; + +/** + * Implements the prototype and is the class of all Array objects + */ +public class ArrayPrototype extends ESObject { + + private static final String LENGTHstring = ("length").intern(); + private static final int LENGTHhash = LENGTHstring.hashCode(); + + // The array value + // We could use a non synchronized vector or directly and array + protected Vector theArray = new Vector(); + + /** + * Create a new empty array + * @param prototype the ArrayPrototype + * @param evaluator The evaluator + */ + public ArrayPrototype(ESObject prototype, Evaluator evaluator) { + super(prototype, evaluator); + } + + // overrides + public String getESClassName() { + return "Array"; + } + + /** + * Return a Java array object which is the object to pass to Java routines + * called by FESI. + * @ param componentType the type of the component of the array + * @return a java array object + */ + public Object toJavaArray(Class componentType) throws EcmaScriptException { + int l = size(); + Object array = Array.newInstance(componentType, l); + if (l ==0) return array; + for (int i =0; i0) { + Vector reversed = new Vector(size); + reversed.setSize(size); + for (int i = 0, j=size-1; i b) return a number > 0; + * if (a == b) return 0; + * if (a < b) return a number < 0. + **/ + int compare(ESValue a, ESValue b) throws EcmaScriptException; + } + + static class DefaultComparer implements Comparer { + public int compare(ESValue v1, ESValue v2) throws EcmaScriptException { + ESValue v1p = v1.toESPrimitive(ESValue.EStypeNumber); + ESValue v2p = v2.toESPrimitive(ESValue.EStypeNumber); + if (v1p == ESUndefined.theUndefined && v2p == ESUndefined.theUndefined) return 0; + if (v1p == ESUndefined.theUndefined ) return 1; + if (v2p == ESUndefined.theUndefined ) return -1; + //System.out.println("v1p = " + v1 + " v2p = " + v2); + String s1 = v1.toString(); + String s2 = v2.toString(); + //System.out.println("s1 = " + s1 + " s2 = " + s2); + return s1.compareTo(s2); + } + } + + /** + * This is the main sort() routine. It performs a quicksort on the elements + * of array a between the element from and the element to. + * The Comparer argument c is used to perform + * comparisons between elements of the array. + **/ + private void sort(int from, int to, + Comparer c) throws EcmaScriptException + { + // If there is nothing to sort, return + if (theArray.size() < 2) return; + + // This is the basic quicksort algorithm, stripped of frills that can make + // it faster but even more confusing than it already is. You should + // understand what the code does, but don't have to understand just + // why it is guaranteed to sort the array... + // Note the use of the compare() method of the Comparer object. + int i = from, j = to; + ESValue center = (ESValue) theArray.elementAt((from + to) / 2); + do { + ESValue ai = (ESValue) theArray.elementAt(i); + ESValue aj = (ESValue) theArray.elementAt(j); + while((i < to) && (c.compare(center, ai) > 0)) { i++; ai = (ESValue) theArray.elementAt(i);} + while((j > from) && (c.compare(center, aj) < 0)) {j--; aj = (ESValue) theArray.elementAt(j);} + if (i < j) { + Object tmp = ai; theArray.setElementAt(aj,i); theArray.setElementAt(tmp, j); + } + if (i <= j) { i++; j--; } + } while(i <= j); + if (from < j) sort(from, j, c); // recursively sort the rest + if (i < to) sort(i, to, c); + } + + /** + * Sort the array with a specified compare routine + * @param compareFn A function returning a comparer + * @return the sorted array (in place) + */ + public ESValue sort(ESValue compareFn) throws EcmaScriptException { + if ((compareFn != null) && + (!(compareFn instanceof FunctionPrototype))) { + throw new EcmaScriptException("Compare function not a function: " + compareFn); + } + Comparer c = null; + if (compareFn != null) + c = new FunctionComparer((FunctionPrototype) compareFn); + else + c = new DefaultComparer(); + + sort(0, theArray.size()-1, c); + return this; + } + + // overrides + public void putProperty(String propertyName, ESValue propertyValue, int hash) + throws EcmaScriptException { + if (hash==LENGTHhash && propertyName.equals(LENGTHstring)) { + int length = (int) (((ESPrimitive) propertyValue).doubleValue()); + if (length<0) { + throw new EcmaScriptException("Invalid length value: " + propertyValue); + } + theArray.setSize(length); + } else { + int index = -1; // indicates not a valid index value + try { + index = Integer.parseInt(propertyName); // should be uint + } catch (NumberFormatException e) { + } + if (index<0) { + super.putProperty(propertyName, propertyValue, hash); + } else { + putProperty(index, propertyValue); + } + } + } + + // overrides + public void putProperty(int index, ESValue propertyValue) + throws EcmaScriptException { + + if (index>=theArray.size()) { + theArray.setSize(index+1); + } + theArray.setElementAt(propertyValue, index); + } + + // overrides + public ESValue getPropertyInScope(String propertyName, ScopeChain previousScope, int hash) + throws EcmaScriptException { + if (hash==LENGTHhash && propertyName.equals(LENGTHstring)) { + return new ESNumber(theArray.size()); + } + if (hasProperty(propertyName, hash)) { + return getProperty(propertyName, hash); + } + if (previousScope == null) { + throw new EcmaScriptException("global variable '" + propertyName + "' does not have a value"); + } else { + return previousScope.getValue(propertyName, hash); + } + } + + // overrides + public ESValue getProperty(String propertyName, int hash) + throws EcmaScriptException { + if (hash==LENGTHhash && propertyName.equals(LENGTHstring)) { + return new ESNumber(theArray.size()); + } else { + int index = -1; // indicates not a valid index value + try { + index = Integer.parseInt(propertyName); // should be uint + } catch (NumberFormatException e) { + } + if (index<0) { + return super.getProperty(propertyName, hash); + } else { + return getProperty(index); + } + } + } + + // overrides + public ESValue getProperty(int index) + throws EcmaScriptException { + Object theElement = null; + if (index Skip elements which were never set (are null), as Netscape + * SHOULD USE SUPER INSTEAD ! + * @return the enumerator + */ + public Enumeration getProperties() { + return new Enumeration() { + Enumeration props = properties.keys(); + Object currentKey = null; + int currentHash = 0; + int nextIndex = 0; + boolean inside = false; + ESObject prototype = ArrayPrototype.this.getPrototype(); + public boolean hasMoreElements() { + // Check if hasMoreElements was already called + if (currentKey != null) return true; + + // Check if a numeric key is appropriate + while ( (nextIndex