From 98762d6ee02e40111558f0e8502ad35f64d0fb22 Mon Sep 17 00:00:00 2001 From: Jim Laskey Date: Fri, 21 Dec 2012 16:36:24 -0400 Subject: [PATCH] 8005403: Open-source Nashorn Co-authored-by: Akhil Arora Co-authored-by: Andreas Woess Co-authored-by: Attila Szegedi Co-authored-by: Hannes Wallnoefer Co-authored-by: Henry Jen Co-authored-by: Marcus Lagergren Co-authored-by: Pavel Semenov Co-authored-by: Pavel Stepanov Co-authored-by: Petr Hejl Co-authored-by: Petr Pisl Co-authored-by: Sundararajan Athijegannathan Reviewed-by: attila, hannesw, lagergren, sundar --- nashorn/.hgignore | 23 +- nashorn/ASSEMBLY_EXCEPTION | 27 + nashorn/LICENSE | 347 + nashorn/README | 147 + nashorn/RELEASE_README | 20 + nashorn/THIRD_PARTY_README | 69 + nashorn/bin/checkintest.sh | 266 + nashorn/bin/fixorphantests.sh | 52 + nashorn/bin/fixwhitespace.sh | 30 + nashorn/bin/jjs | 29 + nashorn/bin/jjs.bat | 27 + nashorn/bin/jjssecure | 29 + nashorn/bin/jjssecure.bat | 27 + nashorn/bin/nashorn | 29 + nashorn/bin/nashorn.bat | 27 + nashorn/bin/rm-non-tracked.sh | 24 + nashorn/bin/verbose_octane.bat | 59 + nashorn/bin/verbose_octane.sh | 58 + nashorn/buildtools/nasgen/README | 34 + nashorn/buildtools/nasgen/build.xml | 60 + nashorn/buildtools/nasgen/nasgen.iml | 39 + nashorn/buildtools/nasgen/project.properties | 52 + .../nasgen/src/META-INF/MANIFEST.MF | 4 + .../internal/tools/nasgen/ClassGenerator.java | 334 + .../tools/nasgen/ConstructorGenerator.java | 276 + .../nashorn/internal/tools/nasgen/Main.java | 181 + .../internal/tools/nasgen/MemberInfo.java | 377 + .../tools/nasgen/MethodGenerator.java | 426 + .../internal/tools/nasgen/NullVisitor.java | 88 + .../tools/nasgen/PrototypeGenerator.java | 184 + .../tools/nasgen/ScriptClassInfo.java | 237 + .../nasgen/ScriptClassInfoCollector.java | 331 + .../tools/nasgen/ScriptClassInstrumentor.java | 309 + .../tools/nasgen/StringConstants.java | 113 + nashorn/docs/DEVELOPER_README | 445 + nashorn/docs/genshelldoc.js | 90 + nashorn/make/Makefile | 224 + nashorn/make/build-benchmark.xml | 348 + nashorn/make/build-nasgen.xml | 86 + nashorn/make/build.xml | 355 + nashorn/make/nbproject/ide-file-targets.xml | 59 + nashorn/make/nbproject/ide-targets.xml | 41 + nashorn/make/nbproject/jdk.xml | 179 + nashorn/make/nbproject/nbjdk.properties | 24 + nashorn/make/nbproject/nbjdk.xml | 48 + nashorn/make/nbproject/project.xml | 177 + nashorn/make/project.properties | 223 + nashorn/samples/counters.js | 39 + nashorn/samples/letter.js | 49 + nashorn/samples/parser.js | 43 + nashorn/samples/shell.js | 78 + nashorn/samples/test.js | 32 + nashorn/samples/uniq.js | 55 + nashorn/src/META-INF/MANIFEST.MF | 5 + .../services/javax.script.ScriptEngineFactory | 25 + .../api/scripting/NashornException.java | 121 + .../api/scripting/NashornScriptEngine.java | 521 + .../scripting/NashornScriptEngineFactory.java | 179 + .../api/scripting/ScriptObjectMirror.java | 323 + .../nashorn/api/scripting/package-info.java | 38 + .../nashorn/api/scripting/resources/engine.js | 58 + .../internal/codegen/AccessSpecializer.java | 428 + .../internal/codegen/BranchOptimizer.java | 199 + .../internal/codegen/ClassEmitter.java | 620 + .../internal/codegen/CodeGenerator.java | 3266 ++ .../nashorn/internal/codegen/CompileUnit.java | 95 + .../nashorn/internal/codegen/Compiler.java | 685 + .../internal/codegen/CompilerConstants.java | 687 + .../internal/codegen/ConstantData.java | 165 + .../jdk/nashorn/internal/codegen/Emitter.java | 49 + .../jdk/nashorn/internal/codegen/Frame.java | 196 + .../internal/codegen/FunctionSignature.java | 209 + .../jdk/nashorn/internal/codegen/Lower.java | 3057 ++ .../internal/codegen/MethodEmitter.java | 2349 ++ .../nashorn/internal/codegen/Namespace.java | 101 + .../internal/codegen/RuntimeCallSite.java | 701 + .../internal/codegen/SharedScopeCall.java | 192 + .../nashorn/internal/codegen/Splitter.java | 403 + .../nashorn/internal/codegen/Transform.java | 33 + .../nashorn/internal/codegen/WeighNodes.java | 308 + .../codegen/objects/FieldObjectCreator.java | 186 + .../objects/FunctionObjectCreator.java | 133 + .../internal/codegen/objects/MapCreator.java | 163 + .../codegen/objects/ObjectClassGenerator.java | 762 + .../codegen/objects/ObjectCreator.java | 175 + .../codegen/objects/ObjectMapCreator.java | 54 + .../internal/codegen/types/ArrayType.java | 107 + .../internal/codegen/types/BitwiseType.java | 44 + .../internal/codegen/types/BooleanType.java | 161 + .../codegen/types/BytecodeArrayOps.java | 78 + .../codegen/types/BytecodeBitwiseOps.java | 96 + .../codegen/types/BytecodeNumericOps.java | 93 + .../internal/codegen/types/BytecodeOps.java | 158 + .../internal/codegen/types/IntType.java | 260 + .../internal/codegen/types/LongType.java | 229 + .../internal/codegen/types/NumberType.java | 177 + .../internal/codegen/types/NumericType.java | 43 + .../internal/codegen/types/ObjectType.java | 174 + .../nashorn/internal/codegen/types/Type.java | 882 + .../jdk/nashorn/internal/ir/AccessNode.java | 166 + .../jdk/nashorn/internal/ir/Assignment.java | 63 + .../src/jdk/nashorn/internal/ir/BaseNode.java | 101 + .../jdk/nashorn/internal/ir/BinaryNode.java | 246 + .../src/jdk/nashorn/internal/ir/Block.java | 591 + .../jdk/nashorn/internal/ir/BreakNode.java | 97 + .../nashorn/internal/ir/BreakableNode.java | 68 + .../src/jdk/nashorn/internal/ir/CallNode.java | 271 + .../src/jdk/nashorn/internal/ir/CaseNode.java | 138 + .../jdk/nashorn/internal/ir/CatchNode.java | 161 + .../jdk/nashorn/internal/ir/ContinueNode.java | 90 + .../jdk/nashorn/internal/ir/DoWhileNode.java | 82 + .../jdk/nashorn/internal/ir/EmptyNode.java | 71 + .../jdk/nashorn/internal/ir/ExecuteNode.java | 108 + .../src/jdk/nashorn/internal/ir/ForNode.java | 213 + .../jdk/nashorn/internal/ir/FunctionCall.java | 39 + .../jdk/nashorn/internal/ir/FunctionNode.java | 1242 + .../jdk/nashorn/internal/ir/IdentNode.java | 221 + .../src/jdk/nashorn/internal/ir/IfNode.java | 131 + .../jdk/nashorn/internal/ir/IndexNode.java | 160 + .../jdk/nashorn/internal/ir/LabelNode.java | 155 + .../jdk/nashorn/internal/ir/LabeledNode.java | 124 + .../nashorn/internal/ir/LineNumberNode.java | 97 + .../jdk/nashorn/internal/ir/LiteralNode.java | 785 + .../src/jdk/nashorn/internal/ir/Location.java | 142 + nashorn/src/jdk/nashorn/internal/ir/Node.java | 432 + .../jdk/nashorn/internal/ir/ObjectNode.java | 135 + .../jdk/nashorn/internal/ir/PropertyKey.java | 39 + .../jdk/nashorn/internal/ir/PropertyNode.java | 190 + .../nashorn/internal/ir/ReferenceNode.java | 92 + .../jdk/nashorn/internal/ir/ReturnNode.java | 167 + .../jdk/nashorn/internal/ir/RuntimeNode.java | 395 + .../jdk/nashorn/internal/ir/SplitNode.java | 221 + .../jdk/nashorn/internal/ir/SwitchNode.java | 182 + .../src/jdk/nashorn/internal/ir/Symbol.java | 610 + .../jdk/nashorn/internal/ir/TernaryNode.java | 140 + .../jdk/nashorn/internal/ir/ThrowNode.java | 119 + .../src/jdk/nashorn/internal/ir/TryNode.java | 233 + .../jdk/nashorn/internal/ir/TypeOverride.java | 58 + .../jdk/nashorn/internal/ir/UnaryNode.java | 233 + .../src/jdk/nashorn/internal/ir/VarNode.java | 249 + .../jdk/nashorn/internal/ir/WhileNode.java | 164 + .../src/jdk/nashorn/internal/ir/WithNode.java | 124 + .../internal/ir/annotations/ChildNode.java | 42 + .../internal/ir/annotations/Ignore.java | 43 + .../internal/ir/annotations/ParentNode.java | 44 + .../internal/ir/annotations/Reference.java | 42 + .../nashorn/internal/ir/debug/ASTWriter.java | 244 + .../nashorn/internal/ir/debug/JSONWriter.java | 1012 + .../internal/ir/debug/PrintVisitor.java | 436 + .../ir/visitor/NodeOperatorVisitor.java | 1287 + .../internal/ir/visitor/NodeVisitor.java | 882 + .../objects/AccessorPropertyDescriptor.java | 210 + .../internal/objects/ArrayBufferView.java | 370 + .../objects/DataPropertyDescriptor.java | 197 + .../nashorn/internal/objects/DateParser.java | 705 + .../objects/GenericPropertyDescriptor.java | 169 + .../jdk/nashorn/internal/objects/Global.java | 1663 + .../internal/objects/NativeArguments.java | 625 + .../nashorn/internal/objects/NativeArray.java | 1281 + .../internal/objects/NativeArrayBuffer.java | 114 + .../internal/objects/NativeBoolean.java | 181 + .../nashorn/internal/objects/NativeDate.java | 1335 + .../nashorn/internal/objects/NativeDebug.java | 274 + .../nashorn/internal/objects/NativeError.java | 325 + .../internal/objects/NativeEvalError.java | 87 + .../internal/objects/NativeFloat32Array.java | 186 + .../internal/objects/NativeFloat64Array.java | 196 + .../internal/objects/NativeFunction.java | 252 + .../internal/objects/NativeInt16Array.java | 144 + .../internal/objects/NativeInt32Array.java | 148 + .../internal/objects/NativeInt8Array.java | 138 + .../internal/objects/NativeJSAdapter.java | 739 + .../nashorn/internal/objects/NativeJSON.java | 545 + .../nashorn/internal/objects/NativeJava.java | 385 + .../internal/objects/NativeJavaImporter.java | 151 + .../nashorn/internal/objects/NativeMath.java | 700 + .../internal/objects/NativeNumber.java | 388 + .../internal/objects/NativeObject.java | 412 + .../internal/objects/NativeRangeError.java | 86 + .../objects/NativeReferenceError.java | 86 + .../internal/objects/NativeRegExp.java | 772 + .../objects/NativeRegExpExecResult.java | 84 + .../objects/NativeStrictArguments.java | 147 + .../internal/objects/NativeString.java | 937 + .../internal/objects/NativeSyntaxError.java | 88 + .../internal/objects/NativeTypeError.java | 86 + .../internal/objects/NativeURIError.java | 85 + .../internal/objects/NativeUint16Array.java | 144 + .../internal/objects/NativeUint32Array.java | 162 + .../internal/objects/NativeUint8Array.java | 137 + .../objects/NativeUint8ClampedArray.java | 154 + .../internal/objects/PrototypeObject.java | 111 + .../internal/objects/ScriptFunctionImpl.java | 345 + .../objects/annotations/Attribute.java | 51 + .../objects/annotations/Constructor.java | 49 + .../objects/annotations/Function.java | 62 + .../internal/objects/annotations/Getter.java | 55 + .../objects/annotations/Property.java | 60 + .../objects/annotations/ScriptClass.java | 44 + .../internal/objects/annotations/Setter.java | 55 + .../annotations/SpecializedConstructor.java | 47 + .../annotations/SpecializedFunction.java | 46 + .../internal/objects/annotations/Where.java | 38 + .../internal/objects/package-info.java | 33 + .../internal/parser/AbstractParser.java | 458 + .../nashorn/internal/parser/JSONParser.java | 346 + .../jdk/nashorn/internal/parser/Lexer.java | 1647 + .../jdk/nashorn/internal/parser/Parser.java | 2981 ++ .../jdk/nashorn/internal/parser/RegExp.java | 180 + .../internal/parser/RegExpScanner.java | 1414 + .../jdk/nashorn/internal/parser/Scanner.java | 193 + .../jdk/nashorn/internal/parser/Token.java | 152 + .../nashorn/internal/parser/TokenKind.java | 50 + .../nashorn/internal/parser/TokenLookup.java | 222 + .../nashorn/internal/parser/TokenStream.java | 212 + .../nashorn/internal/parser/TokenType.java | 284 + .../internal/runtime/AccessorProperty.java | 353 + .../nashorn/internal/runtime/BitVector.java | 278 + .../internal/runtime/CodeInstaller.java | 47 + .../nashorn/internal/runtime/ConsString.java | 117 + .../jdk/nashorn/internal/runtime/Context.java | 872 + .../jdk/nashorn/internal/runtime/Debug.java | 120 + .../nashorn/internal/runtime/DebugLogger.java | 187 + .../runtime/DefaultPropertyAccess.java | 243 + .../nashorn/internal/runtime/ECMAErrors.java | 242 + .../internal/runtime/ECMAException.java | 326 + .../internal/runtime/ErrorManager.java | 236 + .../internal/runtime/FindProperty.java | 209 + .../internal/runtime/FunctionScope.java | 93 + .../internal/runtime/GlobalFunctions.java | 460 + .../internal/runtime/GlobalObject.java | 238 + .../nashorn/internal/runtime/JSErrorType.java | 46 + .../jdk/nashorn/internal/runtime/JSType.java | 928 + .../jdk/nashorn/internal/runtime/Logging.java | 151 + .../internal/runtime/NashornLoader.java | 138 + .../internal/runtime/NativeJavaPackage.java | 189 + .../internal/runtime/NumberToString.java | 786 + .../internal/runtime/ParserException.java | 138 + .../nashorn/internal/runtime/Property.java | 477 + .../internal/runtime/PropertyAccess.java | 365 + .../internal/runtime/PropertyDescriptor.java | 155 + .../internal/runtime/PropertyHashMap.java | 649 + .../internal/runtime/PropertyListener.java | 57 + .../runtime/PropertyListenerManager.java | 192 + .../nashorn/internal/runtime/PropertyMap.java | 919 + .../runtime/QuotedStringTokenizer.java | 156 + .../nashorn/internal/runtime/RegExpMatch.java | 80 + .../jdk/nashorn/internal/runtime/Scope.java | 55 + .../internal/runtime/ScriptFunction.java | 1002 + .../internal/runtime/ScriptLoader.java | 73 + .../internal/runtime/ScriptObject.java | 3427 ++ .../internal/runtime/ScriptRuntime.java | 876 + .../internal/runtime/ScriptingFunctions.java | 114 + .../jdk/nashorn/internal/runtime/Source.java | 436 + .../internal/runtime/SpillProperty.java | 118 + .../internal/runtime/StructureLoader.java | 145 + .../nashorn/internal/runtime/URIUtils.java | 297 + .../nashorn/internal/runtime/Undefined.java | 205 + .../runtime/UserAccessorProperty.java | 163 + .../jdk/nashorn/internal/runtime/Version.java | 73 + .../nashorn/internal/runtime/WithObject.java | 274 + .../internal/runtime/arrays/ArrayData.java | 507 + .../internal/runtime/arrays/ArrayFilter.java | 194 + .../internal/runtime/arrays/ArrayIndex.java | 247 + .../runtime/arrays/ArrayIterator.java | 88 + .../runtime/arrays/ArrayLikeIterator.java | 156 + .../runtime/arrays/DeletedArrayFilter.java | 182 + .../arrays/DeletedRangeArrayFilter.java | 245 + .../arrays/EmptyArrayLikeIterator.java | 51 + .../runtime/arrays/FrozenArrayFilter.java | 78 + .../internal/runtime/arrays/IntArrayData.java | 274 + .../arrays/InvalidArrayIndexException.java | 66 + .../runtime/arrays/IteratorAction.java | 139 + .../runtime/arrays/LongArrayData.java | 236 + .../internal/runtime/arrays/MapIterator.java | 76 + .../runtime/arrays/NoTypeArrayData.java | 181 + .../runtime/arrays/NumberArrayData.java | 219 + .../runtime/arrays/ObjectArrayData.java | 195 + .../runtime/arrays/ReverseArrayIterator.java | 59 + .../runtime/arrays/ReverseMapIterator.java | 55 + .../runtime/arrays/SealedArrayFilter.java | 64 + .../runtime/arrays/SparseArrayData.java | 336 + .../runtime/arrays/UndefinedArrayFilter.java | 210 + .../internal/runtime/linker/Bootstrap.java | 208 + .../internal/runtime/linker/InvokeByName.java | 116 + .../runtime/linker/JSObjectLinker.java | 232 + .../runtime/linker/JavaAdapterFactory.java | 1061 + .../linker/JavaArgumentConverters.java | 302 + .../runtime/linker/LinkerCallSite.java | 540 + .../internal/runtime/linker/Lookup.java | 214 + .../internal/runtime/linker/Mangler.java | 140 + .../runtime/linker/MethodHandleFactory.java | 633 + .../linker/MethodHandleFunctionality.java | 305 + .../runtime/linker/NashornBottomLinker.java | 172 + .../linker/NashornCallSiteDescriptor.java | 287 + .../linker/NashornGuardedInvocation.java | 68 + .../runtime/linker/NashornGuards.java | 131 + .../runtime/linker/NashornLinker.java | 141 + .../linker/NashornPrimitiveLinker.java | 228 + .../runtime/linker/PrimitiveLookup.java | 108 + .../runtime/options/KeyValueOption.java | 93 + .../internal/runtime/options/Option.java | 61 + .../runtime/options/OptionTemplate.java | 367 + .../internal/runtime/options/Options.java | 657 + .../internal/runtime/options/ValueOption.java | 59 + .../runtime/resources/Messages.properties | 137 + .../runtime/resources/Options.properties | 301 + .../runtime/resources/mozilla_compat.js | 301 + .../internal/runtime/resources/parser.js | 63 + .../resources/version.properties-template | 27 + .../src/jdk/nashorn/internal/scripts/JO$.java | 62 + .../src/jdk/nashorn/internal/scripts/JS$.java | 33 + nashorn/src/jdk/nashorn/tools/Shell.java | 396 + .../nashorn/tools/resources/Shell.properties | 32 + .../src/jdk/nashorn/tools/resources/shell.js | 72 + nashorn/src/netscape/javascript/JSObject.java | 101 + nashorn/src/overview.html | 113 + nashorn/test/README | 78 + nashorn/test/examples/dual-fields-micro.js | 48 + nashorn/test/examples/innerbench.js | 60 + nashorn/test/examples/typechain.js | 46 + nashorn/test/lib/benchmark.js | 52 + nashorn/test/opt/add.js | 58 + nashorn/test/opt/add_constant.js | 45 + nashorn/test/opt/add_reuse_callsite.js | 48 + nashorn/test/opt/add_revert2.js | 46 + nashorn/test/opt/cascade_specialize.js | 40 + nashorn/test/script/assert.js | 63 + nashorn/test/script/basic/NASHORN-100.js | 39 + .../test/script/basic/NASHORN-100.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-101.js | 58 + .../test/script/basic/NASHORN-101.js.EXPECTED | 9 + nashorn/test/script/basic/NASHORN-102.js | 43 + .../test/script/basic/NASHORN-102.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-103.js | 39 + nashorn/test/script/basic/NASHORN-104.js | 35 + .../test/script/basic/NASHORN-104.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-105.js | 50 + .../test/script/basic/NASHORN-105.js.EXPECTED | 18 + nashorn/test/script/basic/NASHORN-106.js | 39 + .../test/script/basic/NASHORN-106.js.EXPECTED | 9 + nashorn/test/script/basic/NASHORN-107.js | 33 + nashorn/test/script/basic/NASHORN-108.js | 32 + .../test/script/basic/NASHORN-108.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-109.js | 43 + .../test/script/basic/NASHORN-109.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-11.js | 38 + .../test/script/basic/NASHORN-11.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-111.js | 38 + .../test/script/basic/NASHORN-111.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-113.js | 34 + .../test/script/basic/NASHORN-113.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-114.js | 45 + nashorn/test/script/basic/NASHORN-115.js | 48 + .../test/script/basic/NASHORN-115.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-117.js | 160 + nashorn/test/script/basic/NASHORN-118.js | 43 + .../test/script/basic/NASHORN-118.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-119.js | 37 + .../test/script/basic/NASHORN-119.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-12.js | 145 + nashorn/test/script/basic/NASHORN-120.js | 59 + nashorn/test/script/basic/NASHORN-122.js | 36 + .../test/script/basic/NASHORN-122.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-126.js | 34 + .../test/script/basic/NASHORN-126.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-127.js | 39 + .../test/script/basic/NASHORN-127.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-130.js | 38 + nashorn/test/script/basic/NASHORN-132.js | 70 + .../test/script/basic/NASHORN-132.js.EXPECTED | 10 + nashorn/test/script/basic/NASHORN-133.js | 46 + .../test/script/basic/NASHORN-133.js.EXPECTED | 7 + nashorn/test/script/basic/NASHORN-135.js | 49 + nashorn/test/script/basic/NASHORN-136.js | 77 + .../test/script/basic/NASHORN-136.js.EXPECTED | 24 + nashorn/test/script/basic/NASHORN-14.js | 39 + .../test/script/basic/NASHORN-14.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-148.js | 83 + .../test/script/basic/NASHORN-148.js.EXPECTED | 20 + nashorn/test/script/basic/NASHORN-15.js | 46 + .../test/script/basic/NASHORN-15.js.EXPECTED | 10 + nashorn/test/script/basic/NASHORN-153.js | 35 + nashorn/test/script/basic/NASHORN-156.js | 38 + nashorn/test/script/basic/NASHORN-157.js | 38 + nashorn/test/script/basic/NASHORN-163.js | 41 + .../test/script/basic/NASHORN-163.js.EXPECTED | 8 + nashorn/test/script/basic/NASHORN-164.js | 37 + nashorn/test/script/basic/NASHORN-165.js | 35 + nashorn/test/script/basic/NASHORN-166.js | 46 + nashorn/test/script/basic/NASHORN-168.js | 54 + .../test/script/basic/NASHORN-168.js.EXPECTED | 16 + nashorn/test/script/basic/NASHORN-169.js | 33 + nashorn/test/script/basic/NASHORN-172.js | 55 + nashorn/test/script/basic/NASHORN-173.js | 72 + .../test/script/basic/NASHORN-173.js.EXPECTED | 247 + nashorn/test/script/basic/NASHORN-174.js | 47 + nashorn/test/script/basic/NASHORN-175.js | 31 + nashorn/test/script/basic/NASHORN-176.js | 40 + nashorn/test/script/basic/NASHORN-177.js | 37 + .../test/script/basic/NASHORN-177.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-178.js | 46 + .../test/script/basic/NASHORN-178.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-179.js | 41 + nashorn/test/script/basic/NASHORN-18.js | 41 + .../test/script/basic/NASHORN-18.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-181.js | 40 + nashorn/test/script/basic/NASHORN-182.js | 54 + nashorn/test/script/basic/NASHORN-183.js | 55 + nashorn/test/script/basic/NASHORN-184.js | 38 + .../test/script/basic/NASHORN-184.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-185.js | 37 + .../test/script/basic/NASHORN-185.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-187.js | 48 + nashorn/test/script/basic/NASHORN-188.js | 66 + .../test/script/basic/NASHORN-188.js.EXPECTED | 208 + nashorn/test/script/basic/NASHORN-19.js | 279 + .../test/script/basic/NASHORN-19.js.EXPECTED | 177 + nashorn/test/script/basic/NASHORN-190.js | 78 + nashorn/test/script/basic/NASHORN-192.js | 71 + nashorn/test/script/basic/NASHORN-194.js | 48 + nashorn/test/script/basic/NASHORN-196.js | 39 + nashorn/test/script/basic/NASHORN-198.js | 39 + nashorn/test/script/basic/NASHORN-20.js | 33 + .../test/script/basic/NASHORN-20.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-201.js | 36 + nashorn/test/script/basic/NASHORN-202.js | 33 + nashorn/test/script/basic/NASHORN-203.js | 40 + nashorn/test/script/basic/NASHORN-204.js | 46 + nashorn/test/script/basic/NASHORN-205.js | 65 + nashorn/test/script/basic/NASHORN-206.js | 38 + nashorn/test/script/basic/NASHORN-207.js | 132 + nashorn/test/script/basic/NASHORN-207_2.js | 237 + nashorn/test/script/basic/NASHORN-208.js | 70 + .../test/script/basic/NASHORN-208.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-209.js | 42 + .../test/script/basic/NASHORN-209.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-21.js | 47 + .../test/script/basic/NASHORN-21.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-211.js | 50 + nashorn/test/script/basic/NASHORN-212.js | 72 + nashorn/test/script/basic/NASHORN-213.js | 40 + nashorn/test/script/basic/NASHORN-215.js | 100 + .../test/script/basic/NASHORN-215.js.EXPECTED | 15 + nashorn/test/script/basic/NASHORN-216.js | 41 + nashorn/test/script/basic/NASHORN-217.js | 54 + .../test/script/basic/NASHORN-217.js.EXPECTED | 10 + nashorn/test/script/basic/NASHORN-219.js | 31 + .../test/script/basic/NASHORN-219.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-22.js | 42 + .../test/script/basic/NASHORN-22.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-221.js | 51 + nashorn/test/script/basic/NASHORN-222.js | 44 + nashorn/test/script/basic/NASHORN-223.js | 40 + nashorn/test/script/basic/NASHORN-225.js | 40 + nashorn/test/script/basic/NASHORN-226.js | 51 + nashorn/test/script/basic/NASHORN-227.js | 46 + nashorn/test/script/basic/NASHORN-228.js | 54 + nashorn/test/script/basic/NASHORN-229.js | 42 + .../test/script/basic/NASHORN-229_subtest.js | 41 + nashorn/test/script/basic/NASHORN-23.js | 46 + .../test/script/basic/NASHORN-23.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-232.js | 44 + nashorn/test/script/basic/NASHORN-234.js | 58 + nashorn/test/script/basic/NASHORN-235.js | 45 + nashorn/test/script/basic/NASHORN-236.js | 30 + nashorn/test/script/basic/NASHORN-237.js | 37 + nashorn/test/script/basic/NASHORN-239.js | 35 + nashorn/test/script/basic/NASHORN-24.js | 47 + .../test/script/basic/NASHORN-24.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-241.js | 59 + nashorn/test/script/basic/NASHORN-242.js | 40 + nashorn/test/script/basic/NASHORN-245.js | 46 + nashorn/test/script/basic/NASHORN-247.js | 55 + nashorn/test/script/basic/NASHORN-25.js | 48 + .../test/script/basic/NASHORN-25.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-251.js | 103 + nashorn/test/script/basic/NASHORN-252.js | 42 + nashorn/test/script/basic/NASHORN-253.js | 74 + nashorn/test/script/basic/NASHORN-256.js | 74 + nashorn/test/script/basic/NASHORN-258.js | 67 + .../test/script/basic/NASHORN-258.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-26.js | 53 + .../test/script/basic/NASHORN-26.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-260.js | 54 + nashorn/test/script/basic/NASHORN-261.js | 85 + nashorn/test/script/basic/NASHORN-262.js | 40 + nashorn/test/script/basic/NASHORN-263.js | 59 + nashorn/test/script/basic/NASHORN-264.js | 47 + nashorn/test/script/basic/NASHORN-265.js | 46 + .../test/script/basic/NASHORN-265.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-266.js | 66 + nashorn/test/script/basic/NASHORN-269.js | 67 + nashorn/test/script/basic/NASHORN-27.js | 41 + .../test/script/basic/NASHORN-27.js.EXPECTED | 9 + nashorn/test/script/basic/NASHORN-270.js | 46 + nashorn/test/script/basic/NASHORN-271.js | 46 + nashorn/test/script/basic/NASHORN-275.js | 81 + nashorn/test/script/basic/NASHORN-276.js | 38 + nashorn/test/script/basic/NASHORN-277.js | 34 + nashorn/test/script/basic/NASHORN-278.js | 42 + nashorn/test/script/basic/NASHORN-28.js | 54 + .../test/script/basic/NASHORN-28.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-281.js | 54 + nashorn/test/script/basic/NASHORN-284.js | 48 + .../test/script/basic/NASHORN-284.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-285.js | 60 + .../test/script/basic/NASHORN-285.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-288.js | 56 + nashorn/test/script/basic/NASHORN-29.js | 42 + .../test/script/basic/NASHORN-29.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-293.js | 54 + .../test/script/basic/NASHORN-293.js.EXPECTED | 9 + nashorn/test/script/basic/NASHORN-294.js | 46 + nashorn/test/script/basic/NASHORN-296.js | 53 + nashorn/test/script/basic/NASHORN-297.js | 46 + nashorn/test/script/basic/NASHORN-30.js | 48 + .../test/script/basic/NASHORN-30.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-300.js | 43 + nashorn/test/script/basic/NASHORN-301.js | 35 + .../test/script/basic/NASHORN-301.js.EXPECTED | 35 + nashorn/test/script/basic/NASHORN-304.js | 52 + nashorn/test/script/basic/NASHORN-310.js | 57 + .../test/script/basic/NASHORN-310.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-318.js | 36 + .../test/script/basic/NASHORN-318.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-32.js | 71 + .../test/script/basic/NASHORN-32.js.EXPECTED | 12 + nashorn/test/script/basic/NASHORN-321.js | 43 + .../test/script/basic/NASHORN-321.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-323.js | 38 + .../test/script/basic/NASHORN-323.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-324.js | 47 + nashorn/test/script/basic/NASHORN-33.js | 45 + .../test/script/basic/NASHORN-33.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-331.js | 60 + .../test/script/basic/NASHORN-331.js.EXPECTED | 24 + nashorn/test/script/basic/NASHORN-337.js | 43 + .../test/script/basic/NASHORN-337.js.EXPECTED | 8 + nashorn/test/script/basic/NASHORN-34.js | 49 + .../test/script/basic/NASHORN-34.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-340.js | 44 + .../test/script/basic/NASHORN-340.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-349.js | 48 + nashorn/test/script/basic/NASHORN-354.js | 41 + .../test/script/basic/NASHORN-354.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-355.js | 42 + .../test/script/basic/NASHORN-355.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-36.js | 48 + .../test/script/basic/NASHORN-36.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-365.js | 45 + nashorn/test/script/basic/NASHORN-366.js | 35 + .../test/script/basic/NASHORN-366.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-368.js | 40 + .../test/script/basic/NASHORN-368.js.EXPECTED | 20 + nashorn/test/script/basic/NASHORN-37.js | 75 + .../test/script/basic/NASHORN-37.js.EXPECTED | 20 + nashorn/test/script/basic/NASHORN-375.js | 53 + nashorn/test/script/basic/NASHORN-376.js | 46 + nashorn/test/script/basic/NASHORN-377.js | 226 + .../test/script/basic/NASHORN-377.js.EXPECTED | 34 + nashorn/test/script/basic/NASHORN-378.js | 59 + nashorn/test/script/basic/NASHORN-38.js | 43 + .../test/script/basic/NASHORN-38.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-380.js | 37 + .../test/script/basic/NASHORN-380.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-381.js | 47 + nashorn/test/script/basic/NASHORN-382.js | 40 + nashorn/test/script/basic/NASHORN-383.js | 54 + nashorn/test/script/basic/NASHORN-384.js | 34 + .../test/script/basic/NASHORN-384.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-385.js | 69 + .../test/script/basic/NASHORN-385.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-389.js | 40 + .../test/script/basic/NASHORN-389.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-393.js | 37 + .../test/script/basic/NASHORN-393.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-394.js | 34 + .../test/script/basic/NASHORN-394.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-396.js | 47 + nashorn/test/script/basic/NASHORN-397.js | 48 + nashorn/test/script/basic/NASHORN-398.js | 72 + nashorn/test/script/basic/NASHORN-40.js | 41 + .../test/script/basic/NASHORN-40.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-400.js | 66 + .../test/script/basic/NASHORN-400.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-401.js | 43 + .../test/script/basic/NASHORN-401.js.EXPECTED | 9 + nashorn/test/script/basic/NASHORN-402.js | 44 + .../test/script/basic/NASHORN-402.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-404.js | 43 + nashorn/test/script/basic/NASHORN-405.js | 35 + .../test/script/basic/NASHORN-405.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-406.js | 83 + nashorn/test/script/basic/NASHORN-408.js | 38 + .../test/script/basic/NASHORN-408.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-415.js | 35 + .../test/script/basic/NASHORN-415.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-416.js | 51 + nashorn/test/script/basic/NASHORN-417.js | 47 + nashorn/test/script/basic/NASHORN-418.js | 81 + nashorn/test/script/basic/NASHORN-420.js | 45 + nashorn/test/script/basic/NASHORN-421.js | 63 + nashorn/test/script/basic/NASHORN-423.js | 4030 +++ .../test/script/basic/NASHORN-423.js.EXPECTED | 4000 ++ nashorn/test/script/basic/NASHORN-423a.js | 2030 ++ nashorn/test/script/basic/NASHORN-424.js | 83 + .../test/script/basic/NASHORN-424.js.EXPECTED | 33 + nashorn/test/script/basic/NASHORN-425.js | 44 + .../test/script/basic/NASHORN-425.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-426.js | 54 + nashorn/test/script/basic/NASHORN-427.js | 75 + nashorn/test/script/basic/NASHORN-428.js | 53 + nashorn/test/script/basic/NASHORN-429.js | 40 + nashorn/test/script/basic/NASHORN-432.js | 39 + nashorn/test/script/basic/NASHORN-433.js | 47 + nashorn/test/script/basic/NASHORN-434.js | 61 + nashorn/test/script/basic/NASHORN-435.js | 40 + nashorn/test/script/basic/NASHORN-437.js | 51 + nashorn/test/script/basic/NASHORN-44.js | 52 + .../test/script/basic/NASHORN-44.js.EXPECTED | 12 + nashorn/test/script/basic/NASHORN-441.js | 89 + .../test/script/basic/NASHORN-441.js.EXPECTED | 17 + nashorn/test/script/basic/NASHORN-442.js | 50 + nashorn/test/script/basic/NASHORN-443.js | 48 + nashorn/test/script/basic/NASHORN-444.js | 71 + .../test/script/basic/NASHORN-444.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-445.js | 56 + nashorn/test/script/basic/NASHORN-446.js | 45 + nashorn/test/script/basic/NASHORN-447.js | 46 + nashorn/test/script/basic/NASHORN-448.js | 44 + nashorn/test/script/basic/NASHORN-449.js | 53 + .../test/script/basic/NASHORN-449.js.EXPECTED | 0 nashorn/test/script/basic/NASHORN-45.js | 62 + .../test/script/basic/NASHORN-45.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-450.js | 47 + nashorn/test/script/basic/NASHORN-452.js | 79 + nashorn/test/script/basic/NASHORN-459.js | 67 + nashorn/test/script/basic/NASHORN-46.js | 45 + .../test/script/basic/NASHORN-46.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-462.js | 43 + nashorn/test/script/basic/NASHORN-463.js | 36 + nashorn/test/script/basic/NASHORN-468.js | 3035 ++ nashorn/test/script/basic/NASHORN-47.js | 46 + nashorn/test/script/basic/NASHORN-473.js | 42 + .../test/script/basic/NASHORN-473.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-474.js | 54 + .../test/script/basic/NASHORN-474.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-478.js | 115 + nashorn/test/script/basic/NASHORN-48.js | 73 + .../test/script/basic/NASHORN-48.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-481.js | 10035 ++++++ .../test/script/basic/NASHORN-481.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-482.js | 41 + nashorn/test/script/basic/NASHORN-484.js | 34 + .../test/script/basic/NASHORN-484.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-486.js | 81 + nashorn/test/script/basic/NASHORN-487.js | 43 + nashorn/test/script/basic/NASHORN-488.js | 48 + nashorn/test/script/basic/NASHORN-49.js | 63 + .../test/script/basic/NASHORN-49.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-490.js | 48 + nashorn/test/script/basic/NASHORN-494.js | 57 + nashorn/test/script/basic/NASHORN-497.js | 44 + nashorn/test/script/basic/NASHORN-498.js | 42 + nashorn/test/script/basic/NASHORN-499.js | 38 + nashorn/test/script/basic/NASHORN-50.js | 55 + .../test/script/basic/NASHORN-50.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-500.js | 66 + nashorn/test/script/basic/NASHORN-503.js | 52 + .../test/script/basic/NASHORN-503.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-51.js | 62 + .../test/script/basic/NASHORN-51.js.EXPECTED | 24 + nashorn/test/script/basic/NASHORN-511.js | 55 + nashorn/test/script/basic/NASHORN-515.js | 145 + .../test/script/basic/NASHORN-515.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-516.js | 49 + nashorn/test/script/basic/NASHORN-52.js | 38 + nashorn/test/script/basic/NASHORN-534.js | 30066 ++++++++++++++++ .../test/script/basic/NASHORN-534.js.EXPECTED | 13 + nashorn/test/script/basic/NASHORN-535.js | 46 + .../test/script/basic/NASHORN-535.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-544.js | 46 + nashorn/test/script/basic/NASHORN-55.js | 37 + nashorn/test/script/basic/NASHORN-554.js | 40 + .../test/script/basic/NASHORN-554.js.EXPECTED | 10 + nashorn/test/script/basic/NASHORN-556.js | 216 + .../test/script/basic/NASHORN-556.js.EXPECTED | 16 + nashorn/test/script/basic/NASHORN-56.js | 41 + .../test/script/basic/NASHORN-56.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-562.js | 38 + nashorn/test/script/basic/NASHORN-565.js | 38 + .../test/script/basic/NASHORN-565.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-575.js | 61 + .../test/script/basic/NASHORN-575.js.EXPECTED | 18 + nashorn/test/script/basic/NASHORN-58.js | 149 + .../test/script/basic/NASHORN-58.js.EXPECTED | 23 + nashorn/test/script/basic/NASHORN-59.js | 41 + .../test/script/basic/NASHORN-59.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-592.js | 120 + .../test/script/basic/NASHORN-592.js.EXPECTED | 44 + nashorn/test/script/basic/NASHORN-597.js | 83 + .../test/script/basic/NASHORN-597.js.EXPECTED | 8 + nashorn/test/script/basic/NASHORN-60.js | 36 + .../test/script/basic/NASHORN-60.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-609.js | 43 + .../test/script/basic/NASHORN-609.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-61.js | 35 + .../test/script/basic/NASHORN-61.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-62.js | 52 + .../test/script/basic/NASHORN-62.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-620.js | 35 + .../test/script/basic/NASHORN-620.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-623.js | 54 + .../test/script/basic/NASHORN-623.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-627.js | 155 + .../test/script/basic/NASHORN-627.js.EXPECTED | 1241 + nashorn/test/script/basic/NASHORN-63.js | 108 + .../test/script/basic/NASHORN-631.js.EXPECTED | 3917 ++ nashorn/test/script/basic/NASHORN-637.js | 49 + .../test/script/basic/NASHORN-637.js.EXPECTED | 8 + nashorn/test/script/basic/NASHORN-638.js | 72 + .../test/script/basic/NASHORN-638.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-639.js | 41 + nashorn/test/script/basic/NASHORN-64.js | 61 + nashorn/test/script/basic/NASHORN-642.js | 41 + .../test/script/basic/NASHORN-642.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-646.js | 31 + nashorn/test/script/basic/NASHORN-653.js | 104 + nashorn/test/script/basic/NASHORN-658.js | 45 + nashorn/test/script/basic/NASHORN-659.js | 39 + nashorn/test/script/basic/NASHORN-66.js | 33 + .../test/script/basic/NASHORN-66.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-664.js | 50 + nashorn/test/script/basic/NASHORN-665.js | 55 + nashorn/test/script/basic/NASHORN-67.js | 44 + .../test/script/basic/NASHORN-67.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-678.js | 50 + nashorn/test/script/basic/NASHORN-68.js | 34 + .../test/script/basic/NASHORN-68.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-689.js | 114 + .../test/script/basic/NASHORN-689.js.EXPECTED | 50 + nashorn/test/script/basic/NASHORN-69.js | 45 + .../test/script/basic/NASHORN-69.js.EXPECTED | 15 + nashorn/test/script/basic/NASHORN-691.js | 57 + .../test/script/basic/NASHORN-691.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-694.js | 39 + .../test/script/basic/NASHORN-694.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-697.js | 59 + nashorn/test/script/basic/NASHORN-703.js | 113 + .../test/script/basic/NASHORN-703.js.EXPECTED | 7 + nashorn/test/script/basic/NASHORN-703a.js | 122 + .../script/basic/NASHORN-703a.js.EXPECTED | 7 + nashorn/test/script/basic/NASHORN-705.js | 35 + nashorn/test/script/basic/NASHORN-71.js | 33 + .../test/script/basic/NASHORN-71.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-710.js | 42 + nashorn/test/script/basic/NASHORN-711.js | 54 + .../test/script/basic/NASHORN-711.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-72.js | 54 + .../test/script/basic/NASHORN-72.js.EXPECTED | 8 + nashorn/test/script/basic/NASHORN-722.js | 42 + nashorn/test/script/basic/NASHORN-73.js | 122 + .../test/script/basic/NASHORN-73.js.EXPECTED | 12 + nashorn/test/script/basic/NASHORN-737.js | 33 + .../test/script/basic/NASHORN-737.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-74.js | 35 + .../test/script/basic/NASHORN-74.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-740.js | 33 + .../test/script/basic/NASHORN-740.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-75.js | 47 + .../test/script/basic/NASHORN-75.js.EXPECTED | 3 + nashorn/test/script/basic/NASHORN-758.js | 40 + nashorn/test/script/basic/NASHORN-759.js | 78 + .../test/script/basic/NASHORN-759.js.EXPECTED | 47 + nashorn/test/script/basic/NASHORN-760.js | 54 + nashorn/test/script/basic/NASHORN-768.js | 93 + nashorn/test/script/basic/NASHORN-778.js | 33 + nashorn/test/script/basic/NASHORN-78.js | 54 + nashorn/test/script/basic/NASHORN-79.js | 40 + .../test/script/basic/NASHORN-79.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-792.js | 72 + .../test/script/basic/NASHORN-792.js.EXPECTED | 7 + nashorn/test/script/basic/NASHORN-80.js | 35 + .../test/script/basic/NASHORN-80.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-81.js | 77 + nashorn/test/script/basic/NASHORN-833.js | 40 + .../test/script/basic/NASHORN-833.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-85.js | 31 + .../test/script/basic/NASHORN-85.js.EXPECTED | 1 + nashorn/test/script/basic/NASHORN-86.js | 67 + nashorn/test/script/basic/NASHORN-87.js | 40 + nashorn/test/script/basic/NASHORN-89.js | 81 + nashorn/test/script/basic/NASHORN-90.js | 34 + .../test/script/basic/NASHORN-90.js.EXPECTED | 5 + nashorn/test/script/basic/NASHORN-91.js | 42 + .../test/script/basic/NASHORN-91.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-92.js | 42 + .../test/script/basic/NASHORN-92.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-93.js | 39 + nashorn/test/script/basic/NASHORN-95.js | 50 + .../test/script/basic/NASHORN-95.js.EXPECTED | 4 + nashorn/test/script/basic/NASHORN-96.js | 35 + .../test/script/basic/NASHORN-96.js.EXPECTED | 2 + nashorn/test/script/basic/NASHORN-97.js | 37 + nashorn/test/script/basic/NASHORN-98.js | 47 + .../test/script/basic/NASHORN-98.js.EXPECTED | 6 + nashorn/test/script/basic/NASHORN-99.js | 54 + nashorn/test/script/basic/addition.js | 84 + .../test/script/basic/addition.js.EXPECTED | 20 + nashorn/test/script/basic/allgettersetters.js | 133 + nashorn/test/script/basic/andor.js | 35 + nashorn/test/script/basic/andor.js.EXPECTED | 4 + nashorn/test/script/basic/anonrecur.js | 34 + .../test/script/basic/anonrecur.js.EXPECTED | 1 + nashorn/test/script/basic/applycall.js | 56 + .../test/script/basic/applycall.js.EXPECTED | 14 + nashorn/test/script/basic/args.js | 47 + nashorn/test/script/basic/args.js.EXPECTED | 3 + nashorn/test/script/basic/arity.js | 91 + nashorn/test/script/basic/arity.js.EXPECTED | 30 + nashorn/test/script/basic/arrayprotoclass.js | 32 + .../script/basic/arrayprotoclass.js.EXPECTED | 1 + nashorn/test/script/basic/arrays.js | 160 + nashorn/test/script/basic/arrays.js.EXPECTED | 51 + nashorn/test/script/basic/arrays2.js | 53 + nashorn/test/script/basic/arrays2.js.EXPECTED | 7 + nashorn/test/script/basic/arraysIntKey.js | 35 + .../script/basic/arraysIntKey.js.EXPECTED | 2 + nashorn/test/script/basic/arrayset.js | 39 + .../test/script/basic/arrayset.js.EXPECTED | 6 + nashorn/test/script/basic/arrayundefined.js | 36 + .../script/basic/arrayundefined.js.EXPECTED | 4 + nashorn/test/script/basic/assign.js | 50 + nashorn/test/script/basic/assign.js.EXPECTED | 13 + nashorn/test/script/basic/bitwise_and.js | 51 + .../test/script/basic/bitwise_and.js.EXPECTED | 18 + nashorn/test/script/basic/booleangetter.js | 43 + .../script/basic/booleangetter.js.EXPECTED | 1 + nashorn/test/script/basic/builtin.js | 73 + nashorn/test/script/basic/builtin.js.EXPECTED | 1 + nashorn/test/script/basic/builtin_assign.js | 36 + .../script/basic/builtin_assign.js.EXPECTED | 3 + nashorn/test/script/basic/builtinchain.js | 55 + .../script/basic/builtinchain.js.EXPECTED | 16 + nashorn/test/script/basic/calllink.js | 81 + .../test/script/basic/calllink.js.EXPECTED | 12 + nashorn/test/script/basic/closure.js | 38 + nashorn/test/script/basic/closure.js.EXPECTED | 8 + nashorn/test/script/basic/commandargs.js | 36 + .../test/script/basic/commandargs.js.EXPECTED | 2 + nashorn/test/script/basic/compile-octane.js | 30 + .../script/basic/compile-octane.js.EXPECTED | 12 + nashorn/test/script/basic/condassign.js | 36 + .../test/script/basic/condassign.js.EXPECTED | 2 + nashorn/test/script/basic/construct.js | 59 + .../test/script/basic/construct.js.EXPECTED | 15 + nashorn/test/script/basic/constructorname.js | 52 + .../script/basic/constructorname.js.EXPECTED | 7 + nashorn/test/script/basic/date.js | 101 + nashorn/test/script/basic/date.js.EXPECTED | 132 + nashorn/test/script/basic/dateparse.js | 55 + .../test/script/basic/dateparse.js.EXPECTED | 10 + nashorn/test/script/basic/decinc.js | 70 + nashorn/test/script/basic/decinc.js.EXPECTED | 12 + nashorn/test/script/basic/delete.js | 63 + nashorn/test/script/basic/delete.js.EXPECTED | 18 + nashorn/test/script/basic/delete2.js | 80 + nashorn/test/script/basic/delete2.js.EXPECTED | 25 + nashorn/test/script/basic/dotpropname.js | 40 + .../test/script/basic/dotpropname.js.EXPECTED | 2 + nashorn/test/script/basic/doublecache.js | 54 + .../test/script/basic/doublecache.js.EXPECTED | 19 + nashorn/test/script/basic/enumeration.js | 55 + .../test/script/basic/enumeration.js.EXPECTED | 16 + nashorn/test/script/basic/errors.js | 95 + nashorn/test/script/basic/errors.js.EXPECTED | 31 + nashorn/test/script/basic/errorstack.js | 51 + .../test/script/basic/errorstack.js.EXPECTED | 4 + nashorn/test/script/basic/eval.js | 73 + nashorn/test/script/basic/eval.js.EXPECTED | 15 + nashorn/test/script/basic/evalreturn.js | 71 + .../test/script/basic/evalreturn.js.EXPECTED | 11 + nashorn/test/script/basic/exprclosure.js | 38 + .../test/script/basic/exprclosure.js.EXPECTED | 4 + nashorn/test/script/basic/extensibility.js | 47 + .../script/basic/extensibility.js.EXPECTED | 6 + nashorn/test/script/basic/fileline.js | 48 + .../test/script/basic/fileline.js.EXPECTED | 4 + .../test/script/basic/finally-catchalls.js | 121 + .../basic/finally-catchalls.js.EXPECTED | 62 + nashorn/test/script/basic/finallyreturn.js | 41 + .../script/basic/finallyreturn.js.EXPECTED | 1 + nashorn/test/script/basic/forin.js | 56 + nashorn/test/script/basic/forin.js.EXPECTED | 37 + nashorn/test/script/basic/forin2.js | 116 + nashorn/test/script/basic/forin2.js.EXPECTED | 4 + nashorn/test/script/basic/funcarray.js | 42 + .../test/script/basic/funcarray.js.EXPECTED | 4 + nashorn/test/script/basic/funcbind.js | 53 + .../test/script/basic/funcbind.js.EXPECTED | 11 + nashorn/test/script/basic/funcconstructor.js | 43 + .../script/basic/funcconstructor.js.EXPECTED | 10 + nashorn/test/script/basic/getclassname.js | 126 + nashorn/test/script/basic/getenv.js | 31 + nashorn/test/script/basic/getenv.js.EXPECTED | 1 + nashorn/test/script/basic/getter_callsite.js | 51 + .../script/basic/getter_callsite.js.EXPECTED | 4 + nashorn/test/script/basic/gettercalls.js | 48 + .../test/script/basic/gettercalls.js.EXPECTED | 21 + nashorn/test/script/basic/getterfunc.js | 69 + .../test/script/basic/getterfunc.js.EXPECTED | 30 + nashorn/test/script/basic/gettersetter.js | 78 + .../script/basic/gettersetter.js.EXPECTED | 13 + nashorn/test/script/basic/globalaccess.js | 40 + .../script/basic/globalaccess.js.EXPECTED | 1 + nashorn/test/script/basic/globals.js | 94 + nashorn/test/script/basic/globals.js.EXPECTED | 32 + nashorn/test/script/basic/globalscope.js | 43 + .../test/script/basic/globalscope.js.EXPECTED | 2 + nashorn/test/script/basic/hello.js | 31 + nashorn/test/script/basic/hello.js.EXPECTED | 1 + nashorn/test/script/basic/herestr_operator.js | 39 + .../script/basic/herestr_operator.js.EXPECTED | 1 + nashorn/test/script/basic/illegaljavaname.js | 37 + .../script/basic/illegaljavaname.js.EXPECTED | 2 + nashorn/test/script/basic/incheck.js | 54 + nashorn/test/script/basic/incheck.js.EXPECTED | 10 + nashorn/test/script/basic/indexedcall.js | 35 + .../test/script/basic/indexedcall.js.EXPECTED | 1 + nashorn/test/script/basic/info.js | 32 + nashorn/test/script/basic/info.js.EXPECTED | 1 + .../script/basic/inherited_nonwritable.js | 40 + nashorn/test/script/basic/instanceof.js | 66 + .../test/script/basic/instanceof.js.EXPECTED | 21 + nashorn/test/script/basic/instanceof2.js | 48 + .../test/script/basic/instanceof2.js.EXPECTED | 8 + nashorn/test/script/basic/interfaces.js | 50 + .../test/script/basic/interfaces.js.EXPECTED | 3 + nashorn/test/script/basic/iterator.js | 42 + .../test/script/basic/iterator.js.EXPECTED | 12 + nashorn/test/script/basic/java.js | 47 + nashorn/test/script/basic/java.js.EXPECTED | 12 + nashorn/test/script/basic/javaarray.js | 71 + .../test/script/basic/javaarray.js.EXPECTED | 16 + .../test/script/basic/javaarrayconversion.js | 221 + .../basic/javaarrayconversion.js.EXPECTED | 1 + nashorn/test/script/basic/javaexceptions.js | 58 + .../script/basic/javaexceptions.js.EXPECTED | 7 + nashorn/test/script/basic/javaimporter.js | 48 + .../script/basic/javaimporter.js.EXPECTED | 4 + nashorn/test/script/basic/javainnerclasses.js | 53 + .../script/basic/javainnerclasses.js.EXPECTED | 9 + nashorn/test/script/basic/javasigcall.js | 46 + .../test/script/basic/javasigcall.js.EXPECTED | 5 + nashorn/test/script/basic/jquery.js | 93 + nashorn/test/script/basic/jquery.js.EXPECTED | 2 + nashorn/test/script/basic/jsadapter.js | 99 + .../test/script/basic/jsadapter.js.EXPECTED | 22 + nashorn/test/script/basic/jsadapterlink.js | 67 + .../script/basic/jsadapterlink.js.EXPECTED | 8 + nashorn/test/script/basic/json.js | 62 + nashorn/test/script/basic/json.js.EXPECTED | 15 + nashorn/test/script/basic/list.js | 68 + nashorn/test/script/basic/list.js.EXPECTED | 17 + nashorn/test/script/basic/literal.js | 38 + nashorn/test/script/basic/literal.js.EXPECTED | 4 + nashorn/test/script/basic/load.js | 31 + nashorn/test/script/basic/load.js.EXPECTED | 1 + nashorn/test/script/basic/loadedfile.js | 36 + nashorn/test/script/basic/localundef.js | 46 + .../test/script/basic/localundef.js.EXPECTED | 3 + nashorn/test/script/basic/map.js | 60 + nashorn/test/script/basic/map.js.EXPECTED | 18 + nashorn/test/script/basic/math.js | 42 + nashorn/test/script/basic/math.js.EXPECTED | 9 + nashorn/test/script/basic/minuszero.js | 41 + .../test/script/basic/minuszero.js.EXPECTED | 6 + nashorn/test/script/basic/module.js | 34 + nashorn/test/script/basic/moduleload.js | 36 + .../test/script/basic/moduleload.js.EXPECTED | 6 + nashorn/test/script/basic/nashorn2.js | 35 + .../test/script/basic/nashorn2.js.EXPECTED | 2 + nashorn/test/script/basic/natives.js | 37 + nashorn/test/script/basic/natives.js.EXPECTED | 3 + nashorn/test/script/basic/new.js | 62 + nashorn/test/script/basic/new.js.EXPECTED | 14 + nashorn/test/script/basic/newexpr.js | 66 + nashorn/test/script/basic/newexpr.js.EXPECTED | 7 + nashorn/test/script/basic/newnew.js | 48 + nashorn/test/script/basic/newnew.js.EXPECTED | 6 + nashorn/test/script/basic/nonconstructors.js | 53 + .../script/basic/nonconstructors.js.EXPECTED | 4 + nashorn/test/script/basic/nosuchmethod.js | 40 + .../script/basic/nosuchmethod.js.EXPECTED | 4 + nashorn/test/script/basic/nosuchproperty.js | 63 + .../script/basic/nosuchproperty.js.EXPECTED | 4 + nashorn/test/script/basic/number.js | 42 + nashorn/test/script/basic/number.js.EXPECTED | 7 + nashorn/test/script/basic/numberstring.js | 43 + .../script/basic/numberstring.js.EXPECTED | 67 + nashorn/test/script/basic/objectprops.js | 64 + .../test/script/basic/objectprops.js.EXPECTED | 8 + nashorn/test/script/basic/objects.js | 72 + nashorn/test/script/basic/objects.js.EXPECTED | 46 + nashorn/test/script/basic/options.js | 34 + nashorn/test/script/basic/options.js.EXPECTED | 3 + nashorn/test/script/basic/propchange.js | 58 + .../test/script/basic/propchange.js.EXPECTED | 5 + nashorn/test/script/basic/propertycheck.js | 37 + .../script/basic/propertycheck.js.EXPECTED | 2 + nashorn/test/script/basic/proto.js.EXPECTED | 2 + nashorn/test/script/basic/prototype.js | 52 + .../test/script/basic/prototype.js.EXPECTED | 1 + nashorn/test/script/basic/pushpull.js | 41 + .../test/script/basic/pushpull.js.EXPECTED | 7 + nashorn/test/script/basic/regex.js | 114 + nashorn/test/script/basic/regex.js.EXPECTED | 49 + nashorn/test/script/basic/regexp_flags.js | 49 + nashorn/test/script/basic/run-octane.js | 222 + nashorn/test/script/basic/runsunspider.js | 191 + .../script/basic/runsunspider.js.EXPECTED | 1 + nashorn/test/script/basic/samfunc.js | 48 + nashorn/test/script/basic/samfunc.js.EXPECTED | 2 + nashorn/test/script/basic/scripting.js | 81 + .../test/script/basic/scripting.js.EXPECTED | 103 + nashorn/test/script/basic/sealfreeze.js | 55 + .../test/script/basic/sealfreeze.js.EXPECTED | 10 + nashorn/test/script/basic/setlength.js | 45 + .../test/script/basic/setlength.js.EXPECTED | 10 + nashorn/test/script/basic/stdin.js | 35 + nashorn/test/script/basic/stdin.js.EXPECTED | 3 + nashorn/test/script/basic/strings.js | 87 + nashorn/test/script/basic/strings.js.EXPECTED | 37 + nashorn/test/script/basic/throws.js | 33 + nashorn/test/script/basic/throws.js.EXPECTED | 1 + nashorn/test/script/basic/tosource.js | 38 + .../test/script/basic/tosource.js.EXPECTED | 4 + nashorn/test/script/basic/tostring.js | 53 + .../test/script/basic/tostring.js.EXPECTED | 8 + nashorn/test/script/basic/try.js | 50 + nashorn/test/script/basic/try.js.EXPECTED | 7 + nashorn/test/script/basic/trybreakcont.js | 39 + .../script/basic/trybreakcont.js.EXPECTED | 2 + nashorn/test/script/basic/trycatch.js | 47 + .../test/script/basic/trycatch.js.EXPECTED | 1 + nashorn/test/script/basic/trycatchfor.js | 37 + .../test/script/basic/trycatchfor.js.EXPECTED | 1 + nashorn/test/script/basic/tryfinallyreturn.js | 44 + .../script/basic/tryfinallyreturn.js.EXPECTED | 2 + nashorn/test/script/basic/tryforbreak.js | 38 + .../test/script/basic/tryforbreak.js.EXPECTED | 1 + nashorn/test/script/basic/typechange.js | 33 + .../test/script/basic/typechange.js.EXPECTED | 1 + nashorn/test/script/basic/typeof.js | 47 + nashorn/test/script/basic/typeof.js.EXPECTED | 7 + nashorn/test/script/basic/typeof2.js | 45 + nashorn/test/script/basic/typeof2.js.EXPECTED | 12 + nashorn/test/script/basic/undefined.js | 94 + .../test/script/basic/undefined.js.EXPECTED | 10 + nashorn/test/script/basic/underscore.js | 37 + .../test/script/basic/underscore.js.EXPECTED | 1 + nashorn/test/script/basic/varargs.js | 56 + nashorn/test/script/basic/varargs.js.EXPECTED | 57 + nashorn/test/script/basic/void.js | 41 + nashorn/test/script/basic/void.js.EXPECTED | 8 + nashorn/test/script/basic/with.js | 64 + nashorn/test/script/basic/with.js.EXPECTED | 13 + nashorn/test/script/basic/withprimitive.js | 38 + .../script/basic/withprimitive.js.EXPECTED | 1 + nashorn/test/script/basic/writable_relink.js | 41 + .../script/basic/writable_relink.js.EXPECTED | 4 + .../test/script/basic/xmlStrings.js.EXPECTED | 23 + nashorn/test/script/basic/xorassign.js | 37 + .../test/script/basic/xorassign.js.EXPECTED | 1 + nashorn/test/script/basic/yui.js | 45 + nashorn/test/script/basic/yui.js.EXPECTED | 2 + nashorn/test/script/error/NASHORN-154/README | 6 + .../function_mult_params_in_strict.js | 38 + ...function_mult_params_in_strict.js.EXPECTED | 3 + .../improper_return_break_continue.js | 40 + ...improper_return_break_continue.js.EXPECTED | 15 + .../error/NASHORN-154/invalid_lvalue.js | 42 + .../NASHORN-154/invalid_lvalue.js.EXPECTED | 15 + .../NASHORN-154/literal_data_and_accessor.js | 38 + .../literal_data_and_accessor.js.EXPECTED | 6 + .../error/NASHORN-154/literal_mult_getters.js | 36 + .../literal_mult_getters.js.EXPECTED | 3 + .../literal_mult_prop_in_strict.js | 37 + .../literal_mult_prop_in_strict.js.EXPECTED | 3 + .../error/NASHORN-154/with_in_strict.js | 38 + .../NASHORN-154/with_in_strict.js.EXPECTED | 9 + nashorn/test/script/error/NASHORN-214.js | 44 + .../test/script/error/NASHORN-214.js.EXPECTED | 3 + nashorn/test/script/error/NASHORN-35.js | 32 + .../test/script/error/NASHORN-35.js.EXPECTED | 3 + nashorn/test/script/error/NASHORN-39.js | 33 + .../test/script/error/NASHORN-39.js.EXPECTED | 3 + nashorn/test/script/error/NASHORN-568.js | 30 + .../test/script/error/NASHORN-568.js.EXPECTED | 3 + nashorn/test/script/error/NASHORN-57.js | 35 + .../test/script/error/NASHORN-57.js.EXPECTED | 3 + nashorn/test/script/error/NASHORN-668.js | 38 + .../test/script/error/NASHORN-668.js.EXPECTED | 11 + nashorn/test/script/error/quotemissing.js | 28 + .../script/error/quotemissing.js.EXPECTED | 3 + nashorn/test/script/error/strictmode.js | 35 + .../test/script/error/strictmode.js.EXPECTED | 1 + .../script/representations/NASHORN-592a.js | 122 + nashorn/test/script/sandbox/NASHORN-525.js | 54 + nashorn/test/script/sandbox/README | 1 + nashorn/test/script/sandbox/classloader.js | 41 + .../script/sandbox/classloader.js.EXPECTED | 1 + nashorn/test/script/sandbox/doprivileged.js | 58 + .../script/sandbox/doprivileged.js.EXPECTED | 2 + nashorn/test/script/sandbox/exit.js | 46 + nashorn/test/script/sandbox/exit.js.EXPECTED | 2 + nashorn/test/script/sandbox/file.js | 55 + nashorn/test/script/sandbox/file.js.EXPECTED | 3 + nashorn/test/script/sandbox/javaextend.js | 102 + .../script/sandbox/javaextend.js.EXPECTED | 19 + nashorn/test/script/sandbox/loadLibrary.js | 43 + nashorn/test/script/sandbox/net.js | 43 + nashorn/test/script/sandbox/net.js.EXPECTED | 1 + nashorn/test/script/sandbox/property.js | 44 + .../test/script/sandbox/property.js.EXPECTED | 1 + nashorn/test/script/sandbox/reflection.js | 45 + .../script/sandbox/reflection.js.EXPECTED | 1 + nashorn/test/script/sandbox/runnable.js | 41 + .../test/script/sandbox/runnable.js.EXPECTED | 2 + nashorn/test/script/sandbox/unsafe.js | 66 + .../test/script/sandbox/unsafe.js.EXPECTED | 4 + nashorn/test/script/test262.js | 39 + nashorn/test/script/test262_single.js | 38 + .../test/src/UnnamedPackageTestCallback.java | 28 + .../api/scripting/MultipleEngineTest.java | 54 + .../api/scripting/ScriptEngineTest.java | 862 + .../src/jdk/nashorn/api/scripting/Window.java | 75 + .../api/scripting/WindowEventHandler.java | 32 + .../internal/access/BooleanAccessTest.java | 206 + .../internal/access/MethodAccessTest.java | 453 + .../internal/access/NumberAccessTest.java | 776 + .../internal/access/NumberBoxingTest.java | 348 + .../internal/access/ObjectAccessTest.java | 152 + .../jdk/nashorn/internal/access/Person.java | 58 + .../nashorn/internal/access/SharedObject.java | 466 + .../internal/access/StringAccessTest.java | 155 + .../internal/codegen/CompilerTest.java | 188 + .../nashorn/internal/parser/ParserTest.java | 187 + .../internal/performance/AuroraWrapper.java | 214 + .../internal/performance/OctaneTest.java | 307 + .../performance/PerformanceWrapper.java | 155 + .../internal/performance/SplayTest.java | 48 + .../nashorn/internal/runtime/ContextTest.java | 111 + .../nashorn/internal/runtime/JSTypeTest.java | 104 + .../runtime/Nashorn401TestSubject.java | 57 + .../framework/AbstractScriptRunnable.java | 297 + .../test/framework/JSJUnitReportReporter.java | 41 + .../test/framework/OrphanTestFinder.java | 67 + .../test/framework/ParallelTestRunner.java | 492 + .../test/framework/ScriptEvaluator.java | 45 + .../test/framework/ScriptRunnable.java | 236 + .../internal/test/framework/ScriptTest.java | 79 + .../framework/SeparateContextEvaluator.java | 40 + .../framework/SharedContextEvaluator.java | 151 + .../internal/test/framework/TestConfig.java | 75 + .../internal/test/framework/TestFinder.java | 362 + .../internal/test/framework/TestHelper.java | 134 + .../framework/TestReorderInterceptor.java | 59 + .../test/models/ConstructorWithArgument.java | 40 + .../internal/test/models/FinalClass.java | 30 + .../models/NoAccessibleConstructorClass.java | 30 + .../internal/test/models/NonPublicClass.java | 30 + .../internal/test/models/OuterClass.java | 65 + .../internal/test/models/OverloadedSam.java | 31 + .../internal/test/models/OverrideObject.java | 44 + 1176 files changed, 188153 insertions(+), 1 deletion(-) create mode 100644 nashorn/ASSEMBLY_EXCEPTION create mode 100644 nashorn/LICENSE create mode 100644 nashorn/README create mode 100644 nashorn/RELEASE_README create mode 100644 nashorn/THIRD_PARTY_README create mode 100644 nashorn/bin/checkintest.sh create mode 100644 nashorn/bin/fixorphantests.sh create mode 100644 nashorn/bin/fixwhitespace.sh create mode 100644 nashorn/bin/jjs create mode 100644 nashorn/bin/jjs.bat create mode 100644 nashorn/bin/jjssecure create mode 100644 nashorn/bin/jjssecure.bat create mode 100644 nashorn/bin/nashorn create mode 100644 nashorn/bin/nashorn.bat create mode 100644 nashorn/bin/rm-non-tracked.sh create mode 100644 nashorn/bin/verbose_octane.bat create mode 100644 nashorn/bin/verbose_octane.sh create mode 100644 nashorn/buildtools/nasgen/README create mode 100644 nashorn/buildtools/nasgen/build.xml create mode 100644 nashorn/buildtools/nasgen/nasgen.iml create mode 100644 nashorn/buildtools/nasgen/project.properties create mode 100644 nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java create mode 100644 nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java create mode 100644 nashorn/docs/DEVELOPER_README create mode 100644 nashorn/docs/genshelldoc.js create mode 100644 nashorn/make/Makefile create mode 100644 nashorn/make/build-benchmark.xml create mode 100644 nashorn/make/build-nasgen.xml create mode 100644 nashorn/make/build.xml create mode 100644 nashorn/make/nbproject/ide-file-targets.xml create mode 100644 nashorn/make/nbproject/ide-targets.xml create mode 100644 nashorn/make/nbproject/jdk.xml create mode 100644 nashorn/make/nbproject/nbjdk.properties create mode 100644 nashorn/make/nbproject/nbjdk.xml create mode 100644 nashorn/make/nbproject/project.xml create mode 100644 nashorn/make/project.properties create mode 100644 nashorn/samples/counters.js create mode 100644 nashorn/samples/letter.js create mode 100644 nashorn/samples/parser.js create mode 100644 nashorn/samples/shell.js create mode 100644 nashorn/samples/test.js create mode 100644 nashorn/samples/uniq.js create mode 100644 nashorn/src/META-INF/MANIFEST.MF create mode 100644 nashorn/src/META-INF/services/javax.script.ScriptEngineFactory create mode 100644 nashorn/src/jdk/nashorn/api/scripting/NashornException.java create mode 100644 nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java create mode 100644 nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java create mode 100644 nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java create mode 100644 nashorn/src/jdk/nashorn/api/scripting/package-info.java create mode 100644 nashorn/src/jdk/nashorn/api/scripting/resources/engine.js create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/AccessSpecializer.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/CompileUnit.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/Compiler.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/ConstantData.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/Emitter.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/Frame.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/Lower.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/Namespace.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/RuntimeCallSite.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/SharedScopeCall.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/Splitter.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/Transform.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/objects/FieldObjectCreator.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/objects/FunctionObjectCreator.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/objects/MapCreator.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/objects/ObjectClassGenerator.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/objects/ObjectCreator.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/objects/ObjectMapCreator.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/ArrayType.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/BitwiseType.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/BooleanType.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeArrayOps.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeBitwiseOps.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeNumericOps.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/BytecodeOps.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/IntType.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/LongType.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/NumberType.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/NumericType.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/ObjectType.java create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/Type.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/AccessNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/Assignment.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/BaseNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/Block.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/BreakNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/BreakableNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/CallNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/CaseNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/CatchNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/ContinueNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/DoWhileNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/EmptyNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/ExecuteNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/ForNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/FunctionCall.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/IdentNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/IfNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/IndexNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/LabelNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/LabeledNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/LineNumberNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/Location.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/Node.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/ObjectNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/PropertyKey.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/PropertyNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/ReferenceNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/ReturnNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/RuntimeNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/SplitNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/SwitchNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/Symbol.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/TernaryNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/TryNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/TypeOverride.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/UnaryNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/VarNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/WhileNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/WithNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/annotations/ChildNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/annotations/Ignore.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/annotations/ParentNode.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/annotations/Reference.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/debug/ASTWriter.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/DateParser.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/Global.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeArray.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeDate.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeError.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeJava.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeMath.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeObject.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeString.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/Attribute.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/Constructor.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/Function.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/Getter.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/Property.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/ScriptClass.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/Setter.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedConstructor.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/annotations/Where.java create mode 100644 nashorn/src/jdk/nashorn/internal/objects/package-info.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/AbstractParser.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/JSONParser.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/Lexer.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/Parser.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/RegExp.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/RegExpScanner.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/Scanner.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/Token.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/TokenKind.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/TokenLookup.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/TokenStream.java create mode 100644 nashorn/src/jdk/nashorn/internal/parser/TokenType.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/BitVector.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ConsString.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/Context.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/Debug.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/DebugLogger.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ECMAException.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ErrorManager.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/JSErrorType.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/JSType.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/Logging.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/NumberToString.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ParserException.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/Property.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/PropertyAccess.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/PropertyDescriptor.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/PropertyHashMap.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/PropertyListener.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/QuotedStringTokenizer.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/RegExpMatch.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/Scope.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ScriptFunction.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/Source.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/SpillProperty.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/URIUtils.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/Undefined.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/Version.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/WithObject.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayFilter.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedArrayFilter.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/DeletedRangeArrayFilter.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/EmptyArrayLikeIterator.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/FrozenArrayFilter.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/IntArrayData.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/InvalidArrayIndexException.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/LongArrayData.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/MapIterator.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/NoTypeArrayData.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/NumberArrayData.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseArrayIterator.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseMapIterator.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/SealedArrayFilter.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/SparseArrayData.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/arrays/UndefinedArrayFilter.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/JavaArgumentConverters.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/Lookup.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/Mangler.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/MethodHandleFactory.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/MethodHandleFunctionality.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuardedInvocation.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/options/KeyValueOption.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/options/Option.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/options/Options.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/options/ValueOption.java create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/resources/parser.js create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/resources/version.properties-template create mode 100644 nashorn/src/jdk/nashorn/internal/scripts/JO$.java create mode 100644 nashorn/src/jdk/nashorn/internal/scripts/JS$.java create mode 100644 nashorn/src/jdk/nashorn/tools/Shell.java create mode 100644 nashorn/src/jdk/nashorn/tools/resources/Shell.properties create mode 100644 nashorn/src/jdk/nashorn/tools/resources/shell.js create mode 100644 nashorn/src/netscape/javascript/JSObject.java create mode 100644 nashorn/src/overview.html create mode 100644 nashorn/test/README create mode 100644 nashorn/test/examples/dual-fields-micro.js create mode 100644 nashorn/test/examples/innerbench.js create mode 100644 nashorn/test/examples/typechain.js create mode 100644 nashorn/test/lib/benchmark.js create mode 100644 nashorn/test/opt/add.js create mode 100644 nashorn/test/opt/add_constant.js create mode 100644 nashorn/test/opt/add_reuse_callsite.js create mode 100644 nashorn/test/opt/add_revert2.js create mode 100644 nashorn/test/opt/cascade_specialize.js create mode 100644 nashorn/test/script/assert.js create mode 100644 nashorn/test/script/basic/NASHORN-100.js create mode 100644 nashorn/test/script/basic/NASHORN-100.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-101.js create mode 100644 nashorn/test/script/basic/NASHORN-101.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-102.js create mode 100644 nashorn/test/script/basic/NASHORN-102.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-103.js create mode 100644 nashorn/test/script/basic/NASHORN-104.js create mode 100644 nashorn/test/script/basic/NASHORN-104.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-105.js create mode 100644 nashorn/test/script/basic/NASHORN-105.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-106.js create mode 100644 nashorn/test/script/basic/NASHORN-106.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-107.js create mode 100644 nashorn/test/script/basic/NASHORN-108.js create mode 100644 nashorn/test/script/basic/NASHORN-108.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-109.js create mode 100644 nashorn/test/script/basic/NASHORN-109.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-11.js create mode 100644 nashorn/test/script/basic/NASHORN-11.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-111.js create mode 100644 nashorn/test/script/basic/NASHORN-111.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-113.js create mode 100644 nashorn/test/script/basic/NASHORN-113.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-114.js create mode 100644 nashorn/test/script/basic/NASHORN-115.js create mode 100644 nashorn/test/script/basic/NASHORN-115.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-117.js create mode 100644 nashorn/test/script/basic/NASHORN-118.js create mode 100644 nashorn/test/script/basic/NASHORN-118.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-119.js create mode 100644 nashorn/test/script/basic/NASHORN-119.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-12.js create mode 100644 nashorn/test/script/basic/NASHORN-120.js create mode 100644 nashorn/test/script/basic/NASHORN-122.js create mode 100644 nashorn/test/script/basic/NASHORN-122.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-126.js create mode 100644 nashorn/test/script/basic/NASHORN-126.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-127.js create mode 100644 nashorn/test/script/basic/NASHORN-127.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-130.js create mode 100644 nashorn/test/script/basic/NASHORN-132.js create mode 100644 nashorn/test/script/basic/NASHORN-132.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-133.js create mode 100644 nashorn/test/script/basic/NASHORN-133.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-135.js create mode 100644 nashorn/test/script/basic/NASHORN-136.js create mode 100644 nashorn/test/script/basic/NASHORN-136.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-14.js create mode 100644 nashorn/test/script/basic/NASHORN-14.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-148.js create mode 100644 nashorn/test/script/basic/NASHORN-148.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-15.js create mode 100644 nashorn/test/script/basic/NASHORN-15.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-153.js create mode 100644 nashorn/test/script/basic/NASHORN-156.js create mode 100644 nashorn/test/script/basic/NASHORN-157.js create mode 100644 nashorn/test/script/basic/NASHORN-163.js create mode 100644 nashorn/test/script/basic/NASHORN-163.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-164.js create mode 100644 nashorn/test/script/basic/NASHORN-165.js create mode 100644 nashorn/test/script/basic/NASHORN-166.js create mode 100644 nashorn/test/script/basic/NASHORN-168.js create mode 100644 nashorn/test/script/basic/NASHORN-168.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-169.js create mode 100644 nashorn/test/script/basic/NASHORN-172.js create mode 100644 nashorn/test/script/basic/NASHORN-173.js create mode 100644 nashorn/test/script/basic/NASHORN-173.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-174.js create mode 100644 nashorn/test/script/basic/NASHORN-175.js create mode 100644 nashorn/test/script/basic/NASHORN-176.js create mode 100644 nashorn/test/script/basic/NASHORN-177.js create mode 100644 nashorn/test/script/basic/NASHORN-177.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-178.js create mode 100644 nashorn/test/script/basic/NASHORN-178.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-179.js create mode 100644 nashorn/test/script/basic/NASHORN-18.js create mode 100644 nashorn/test/script/basic/NASHORN-18.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-181.js create mode 100644 nashorn/test/script/basic/NASHORN-182.js create mode 100644 nashorn/test/script/basic/NASHORN-183.js create mode 100644 nashorn/test/script/basic/NASHORN-184.js create mode 100644 nashorn/test/script/basic/NASHORN-184.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-185.js create mode 100644 nashorn/test/script/basic/NASHORN-185.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-187.js create mode 100644 nashorn/test/script/basic/NASHORN-188.js create mode 100644 nashorn/test/script/basic/NASHORN-188.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-19.js create mode 100644 nashorn/test/script/basic/NASHORN-19.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-190.js create mode 100644 nashorn/test/script/basic/NASHORN-192.js create mode 100644 nashorn/test/script/basic/NASHORN-194.js create mode 100644 nashorn/test/script/basic/NASHORN-196.js create mode 100644 nashorn/test/script/basic/NASHORN-198.js create mode 100644 nashorn/test/script/basic/NASHORN-20.js create mode 100644 nashorn/test/script/basic/NASHORN-20.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-201.js create mode 100644 nashorn/test/script/basic/NASHORN-202.js create mode 100644 nashorn/test/script/basic/NASHORN-203.js create mode 100644 nashorn/test/script/basic/NASHORN-204.js create mode 100644 nashorn/test/script/basic/NASHORN-205.js create mode 100644 nashorn/test/script/basic/NASHORN-206.js create mode 100644 nashorn/test/script/basic/NASHORN-207.js create mode 100644 nashorn/test/script/basic/NASHORN-207_2.js create mode 100644 nashorn/test/script/basic/NASHORN-208.js create mode 100644 nashorn/test/script/basic/NASHORN-208.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-209.js create mode 100644 nashorn/test/script/basic/NASHORN-209.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-21.js create mode 100644 nashorn/test/script/basic/NASHORN-21.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-211.js create mode 100644 nashorn/test/script/basic/NASHORN-212.js create mode 100644 nashorn/test/script/basic/NASHORN-213.js create mode 100644 nashorn/test/script/basic/NASHORN-215.js create mode 100644 nashorn/test/script/basic/NASHORN-215.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-216.js create mode 100644 nashorn/test/script/basic/NASHORN-217.js create mode 100644 nashorn/test/script/basic/NASHORN-217.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-219.js create mode 100644 nashorn/test/script/basic/NASHORN-219.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-22.js create mode 100644 nashorn/test/script/basic/NASHORN-22.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-221.js create mode 100644 nashorn/test/script/basic/NASHORN-222.js create mode 100644 nashorn/test/script/basic/NASHORN-223.js create mode 100644 nashorn/test/script/basic/NASHORN-225.js create mode 100644 nashorn/test/script/basic/NASHORN-226.js create mode 100644 nashorn/test/script/basic/NASHORN-227.js create mode 100644 nashorn/test/script/basic/NASHORN-228.js create mode 100644 nashorn/test/script/basic/NASHORN-229.js create mode 100644 nashorn/test/script/basic/NASHORN-229_subtest.js create mode 100644 nashorn/test/script/basic/NASHORN-23.js create mode 100644 nashorn/test/script/basic/NASHORN-23.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-232.js create mode 100644 nashorn/test/script/basic/NASHORN-234.js create mode 100644 nashorn/test/script/basic/NASHORN-235.js create mode 100644 nashorn/test/script/basic/NASHORN-236.js create mode 100644 nashorn/test/script/basic/NASHORN-237.js create mode 100644 nashorn/test/script/basic/NASHORN-239.js create mode 100644 nashorn/test/script/basic/NASHORN-24.js create mode 100644 nashorn/test/script/basic/NASHORN-24.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-241.js create mode 100644 nashorn/test/script/basic/NASHORN-242.js create mode 100644 nashorn/test/script/basic/NASHORN-245.js create mode 100644 nashorn/test/script/basic/NASHORN-247.js create mode 100644 nashorn/test/script/basic/NASHORN-25.js create mode 100644 nashorn/test/script/basic/NASHORN-25.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-251.js create mode 100644 nashorn/test/script/basic/NASHORN-252.js create mode 100644 nashorn/test/script/basic/NASHORN-253.js create mode 100644 nashorn/test/script/basic/NASHORN-256.js create mode 100644 nashorn/test/script/basic/NASHORN-258.js create mode 100644 nashorn/test/script/basic/NASHORN-258.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-26.js create mode 100644 nashorn/test/script/basic/NASHORN-26.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-260.js create mode 100644 nashorn/test/script/basic/NASHORN-261.js create mode 100644 nashorn/test/script/basic/NASHORN-262.js create mode 100644 nashorn/test/script/basic/NASHORN-263.js create mode 100644 nashorn/test/script/basic/NASHORN-264.js create mode 100644 nashorn/test/script/basic/NASHORN-265.js create mode 100644 nashorn/test/script/basic/NASHORN-265.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-266.js create mode 100644 nashorn/test/script/basic/NASHORN-269.js create mode 100644 nashorn/test/script/basic/NASHORN-27.js create mode 100644 nashorn/test/script/basic/NASHORN-27.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-270.js create mode 100644 nashorn/test/script/basic/NASHORN-271.js create mode 100644 nashorn/test/script/basic/NASHORN-275.js create mode 100644 nashorn/test/script/basic/NASHORN-276.js create mode 100644 nashorn/test/script/basic/NASHORN-277.js create mode 100644 nashorn/test/script/basic/NASHORN-278.js create mode 100644 nashorn/test/script/basic/NASHORN-28.js create mode 100644 nashorn/test/script/basic/NASHORN-28.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-281.js create mode 100644 nashorn/test/script/basic/NASHORN-284.js create mode 100644 nashorn/test/script/basic/NASHORN-284.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-285.js create mode 100644 nashorn/test/script/basic/NASHORN-285.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-288.js create mode 100644 nashorn/test/script/basic/NASHORN-29.js create mode 100644 nashorn/test/script/basic/NASHORN-29.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-293.js create mode 100644 nashorn/test/script/basic/NASHORN-293.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-294.js create mode 100644 nashorn/test/script/basic/NASHORN-296.js create mode 100644 nashorn/test/script/basic/NASHORN-297.js create mode 100644 nashorn/test/script/basic/NASHORN-30.js create mode 100644 nashorn/test/script/basic/NASHORN-30.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-300.js create mode 100644 nashorn/test/script/basic/NASHORN-301.js create mode 100644 nashorn/test/script/basic/NASHORN-301.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-304.js create mode 100644 nashorn/test/script/basic/NASHORN-310.js create mode 100644 nashorn/test/script/basic/NASHORN-310.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-318.js create mode 100644 nashorn/test/script/basic/NASHORN-318.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-32.js create mode 100644 nashorn/test/script/basic/NASHORN-32.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-321.js create mode 100644 nashorn/test/script/basic/NASHORN-321.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-323.js create mode 100644 nashorn/test/script/basic/NASHORN-323.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-324.js create mode 100644 nashorn/test/script/basic/NASHORN-33.js create mode 100644 nashorn/test/script/basic/NASHORN-33.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-331.js create mode 100644 nashorn/test/script/basic/NASHORN-331.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-337.js create mode 100644 nashorn/test/script/basic/NASHORN-337.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-34.js create mode 100644 nashorn/test/script/basic/NASHORN-34.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-340.js create mode 100644 nashorn/test/script/basic/NASHORN-340.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-349.js create mode 100644 nashorn/test/script/basic/NASHORN-354.js create mode 100644 nashorn/test/script/basic/NASHORN-354.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-355.js create mode 100644 nashorn/test/script/basic/NASHORN-355.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-36.js create mode 100644 nashorn/test/script/basic/NASHORN-36.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-365.js create mode 100644 nashorn/test/script/basic/NASHORN-366.js create mode 100644 nashorn/test/script/basic/NASHORN-366.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-368.js create mode 100644 nashorn/test/script/basic/NASHORN-368.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-37.js create mode 100644 nashorn/test/script/basic/NASHORN-37.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-375.js create mode 100644 nashorn/test/script/basic/NASHORN-376.js create mode 100644 nashorn/test/script/basic/NASHORN-377.js create mode 100644 nashorn/test/script/basic/NASHORN-377.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-378.js create mode 100644 nashorn/test/script/basic/NASHORN-38.js create mode 100644 nashorn/test/script/basic/NASHORN-38.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-380.js create mode 100644 nashorn/test/script/basic/NASHORN-380.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-381.js create mode 100644 nashorn/test/script/basic/NASHORN-382.js create mode 100644 nashorn/test/script/basic/NASHORN-383.js create mode 100644 nashorn/test/script/basic/NASHORN-384.js create mode 100644 nashorn/test/script/basic/NASHORN-384.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-385.js create mode 100644 nashorn/test/script/basic/NASHORN-385.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-389.js create mode 100644 nashorn/test/script/basic/NASHORN-389.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-393.js create mode 100644 nashorn/test/script/basic/NASHORN-393.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-394.js create mode 100644 nashorn/test/script/basic/NASHORN-394.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-396.js create mode 100644 nashorn/test/script/basic/NASHORN-397.js create mode 100644 nashorn/test/script/basic/NASHORN-398.js create mode 100644 nashorn/test/script/basic/NASHORN-40.js create mode 100644 nashorn/test/script/basic/NASHORN-40.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-400.js create mode 100644 nashorn/test/script/basic/NASHORN-400.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-401.js create mode 100644 nashorn/test/script/basic/NASHORN-401.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-402.js create mode 100644 nashorn/test/script/basic/NASHORN-402.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-404.js create mode 100644 nashorn/test/script/basic/NASHORN-405.js create mode 100644 nashorn/test/script/basic/NASHORN-405.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-406.js create mode 100644 nashorn/test/script/basic/NASHORN-408.js create mode 100644 nashorn/test/script/basic/NASHORN-408.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-415.js create mode 100644 nashorn/test/script/basic/NASHORN-415.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-416.js create mode 100644 nashorn/test/script/basic/NASHORN-417.js create mode 100644 nashorn/test/script/basic/NASHORN-418.js create mode 100644 nashorn/test/script/basic/NASHORN-420.js create mode 100644 nashorn/test/script/basic/NASHORN-421.js create mode 100644 nashorn/test/script/basic/NASHORN-423.js create mode 100644 nashorn/test/script/basic/NASHORN-423.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-423a.js create mode 100644 nashorn/test/script/basic/NASHORN-424.js create mode 100644 nashorn/test/script/basic/NASHORN-424.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-425.js create mode 100644 nashorn/test/script/basic/NASHORN-425.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-426.js create mode 100644 nashorn/test/script/basic/NASHORN-427.js create mode 100644 nashorn/test/script/basic/NASHORN-428.js create mode 100644 nashorn/test/script/basic/NASHORN-429.js create mode 100644 nashorn/test/script/basic/NASHORN-432.js create mode 100644 nashorn/test/script/basic/NASHORN-433.js create mode 100644 nashorn/test/script/basic/NASHORN-434.js create mode 100644 nashorn/test/script/basic/NASHORN-435.js create mode 100644 nashorn/test/script/basic/NASHORN-437.js create mode 100644 nashorn/test/script/basic/NASHORN-44.js create mode 100644 nashorn/test/script/basic/NASHORN-44.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-441.js create mode 100644 nashorn/test/script/basic/NASHORN-441.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-442.js create mode 100644 nashorn/test/script/basic/NASHORN-443.js create mode 100644 nashorn/test/script/basic/NASHORN-444.js create mode 100644 nashorn/test/script/basic/NASHORN-444.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-445.js create mode 100644 nashorn/test/script/basic/NASHORN-446.js create mode 100644 nashorn/test/script/basic/NASHORN-447.js create mode 100644 nashorn/test/script/basic/NASHORN-448.js create mode 100644 nashorn/test/script/basic/NASHORN-449.js create mode 100644 nashorn/test/script/basic/NASHORN-449.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-45.js create mode 100644 nashorn/test/script/basic/NASHORN-45.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-450.js create mode 100644 nashorn/test/script/basic/NASHORN-452.js create mode 100644 nashorn/test/script/basic/NASHORN-459.js create mode 100644 nashorn/test/script/basic/NASHORN-46.js create mode 100644 nashorn/test/script/basic/NASHORN-46.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-462.js create mode 100644 nashorn/test/script/basic/NASHORN-463.js create mode 100644 nashorn/test/script/basic/NASHORN-468.js create mode 100644 nashorn/test/script/basic/NASHORN-47.js create mode 100644 nashorn/test/script/basic/NASHORN-473.js create mode 100644 nashorn/test/script/basic/NASHORN-473.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-474.js create mode 100644 nashorn/test/script/basic/NASHORN-474.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-478.js create mode 100644 nashorn/test/script/basic/NASHORN-48.js create mode 100644 nashorn/test/script/basic/NASHORN-48.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-481.js create mode 100644 nashorn/test/script/basic/NASHORN-481.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-482.js create mode 100644 nashorn/test/script/basic/NASHORN-484.js create mode 100644 nashorn/test/script/basic/NASHORN-484.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-486.js create mode 100644 nashorn/test/script/basic/NASHORN-487.js create mode 100644 nashorn/test/script/basic/NASHORN-488.js create mode 100644 nashorn/test/script/basic/NASHORN-49.js create mode 100644 nashorn/test/script/basic/NASHORN-49.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-490.js create mode 100644 nashorn/test/script/basic/NASHORN-494.js create mode 100644 nashorn/test/script/basic/NASHORN-497.js create mode 100644 nashorn/test/script/basic/NASHORN-498.js create mode 100644 nashorn/test/script/basic/NASHORN-499.js create mode 100644 nashorn/test/script/basic/NASHORN-50.js create mode 100644 nashorn/test/script/basic/NASHORN-50.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-500.js create mode 100644 nashorn/test/script/basic/NASHORN-503.js create mode 100644 nashorn/test/script/basic/NASHORN-503.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-51.js create mode 100644 nashorn/test/script/basic/NASHORN-51.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-511.js create mode 100644 nashorn/test/script/basic/NASHORN-515.js create mode 100644 nashorn/test/script/basic/NASHORN-515.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-516.js create mode 100644 nashorn/test/script/basic/NASHORN-52.js create mode 100644 nashorn/test/script/basic/NASHORN-534.js create mode 100644 nashorn/test/script/basic/NASHORN-534.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-535.js create mode 100644 nashorn/test/script/basic/NASHORN-535.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-544.js create mode 100644 nashorn/test/script/basic/NASHORN-55.js create mode 100644 nashorn/test/script/basic/NASHORN-554.js create mode 100644 nashorn/test/script/basic/NASHORN-554.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-556.js create mode 100644 nashorn/test/script/basic/NASHORN-556.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-56.js create mode 100644 nashorn/test/script/basic/NASHORN-56.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-562.js create mode 100644 nashorn/test/script/basic/NASHORN-565.js create mode 100644 nashorn/test/script/basic/NASHORN-565.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-575.js create mode 100644 nashorn/test/script/basic/NASHORN-575.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-58.js create mode 100644 nashorn/test/script/basic/NASHORN-58.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-59.js create mode 100644 nashorn/test/script/basic/NASHORN-59.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-592.js create mode 100644 nashorn/test/script/basic/NASHORN-592.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-597.js create mode 100644 nashorn/test/script/basic/NASHORN-597.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-60.js create mode 100644 nashorn/test/script/basic/NASHORN-60.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-609.js create mode 100644 nashorn/test/script/basic/NASHORN-609.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-61.js create mode 100644 nashorn/test/script/basic/NASHORN-61.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-62.js create mode 100644 nashorn/test/script/basic/NASHORN-62.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-620.js create mode 100644 nashorn/test/script/basic/NASHORN-620.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-623.js create mode 100644 nashorn/test/script/basic/NASHORN-623.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-627.js create mode 100644 nashorn/test/script/basic/NASHORN-627.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-63.js create mode 100644 nashorn/test/script/basic/NASHORN-631.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-637.js create mode 100644 nashorn/test/script/basic/NASHORN-637.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-638.js create mode 100644 nashorn/test/script/basic/NASHORN-638.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-639.js create mode 100644 nashorn/test/script/basic/NASHORN-64.js create mode 100644 nashorn/test/script/basic/NASHORN-642.js create mode 100644 nashorn/test/script/basic/NASHORN-642.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-646.js create mode 100644 nashorn/test/script/basic/NASHORN-653.js create mode 100644 nashorn/test/script/basic/NASHORN-658.js create mode 100644 nashorn/test/script/basic/NASHORN-659.js create mode 100644 nashorn/test/script/basic/NASHORN-66.js create mode 100644 nashorn/test/script/basic/NASHORN-66.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-664.js create mode 100644 nashorn/test/script/basic/NASHORN-665.js create mode 100644 nashorn/test/script/basic/NASHORN-67.js create mode 100644 nashorn/test/script/basic/NASHORN-67.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-678.js create mode 100644 nashorn/test/script/basic/NASHORN-68.js create mode 100644 nashorn/test/script/basic/NASHORN-68.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-689.js create mode 100644 nashorn/test/script/basic/NASHORN-689.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-69.js create mode 100644 nashorn/test/script/basic/NASHORN-69.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-691.js create mode 100644 nashorn/test/script/basic/NASHORN-691.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-694.js create mode 100644 nashorn/test/script/basic/NASHORN-694.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-697.js create mode 100644 nashorn/test/script/basic/NASHORN-703.js create mode 100644 nashorn/test/script/basic/NASHORN-703.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-703a.js create mode 100644 nashorn/test/script/basic/NASHORN-703a.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-705.js create mode 100644 nashorn/test/script/basic/NASHORN-71.js create mode 100644 nashorn/test/script/basic/NASHORN-71.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-710.js create mode 100644 nashorn/test/script/basic/NASHORN-711.js create mode 100644 nashorn/test/script/basic/NASHORN-711.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-72.js create mode 100644 nashorn/test/script/basic/NASHORN-72.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-722.js create mode 100644 nashorn/test/script/basic/NASHORN-73.js create mode 100644 nashorn/test/script/basic/NASHORN-73.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-737.js create mode 100644 nashorn/test/script/basic/NASHORN-737.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-74.js create mode 100644 nashorn/test/script/basic/NASHORN-74.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-740.js create mode 100644 nashorn/test/script/basic/NASHORN-740.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-75.js create mode 100644 nashorn/test/script/basic/NASHORN-75.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-758.js create mode 100644 nashorn/test/script/basic/NASHORN-759.js create mode 100644 nashorn/test/script/basic/NASHORN-759.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-760.js create mode 100644 nashorn/test/script/basic/NASHORN-768.js create mode 100644 nashorn/test/script/basic/NASHORN-778.js create mode 100644 nashorn/test/script/basic/NASHORN-78.js create mode 100644 nashorn/test/script/basic/NASHORN-79.js create mode 100644 nashorn/test/script/basic/NASHORN-79.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-792.js create mode 100644 nashorn/test/script/basic/NASHORN-792.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-80.js create mode 100644 nashorn/test/script/basic/NASHORN-80.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-81.js create mode 100644 nashorn/test/script/basic/NASHORN-833.js create mode 100644 nashorn/test/script/basic/NASHORN-833.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-85.js create mode 100644 nashorn/test/script/basic/NASHORN-85.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-86.js create mode 100644 nashorn/test/script/basic/NASHORN-87.js create mode 100644 nashorn/test/script/basic/NASHORN-89.js create mode 100644 nashorn/test/script/basic/NASHORN-90.js create mode 100644 nashorn/test/script/basic/NASHORN-90.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-91.js create mode 100644 nashorn/test/script/basic/NASHORN-91.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-92.js create mode 100644 nashorn/test/script/basic/NASHORN-92.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-93.js create mode 100644 nashorn/test/script/basic/NASHORN-95.js create mode 100644 nashorn/test/script/basic/NASHORN-95.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-96.js create mode 100644 nashorn/test/script/basic/NASHORN-96.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-97.js create mode 100644 nashorn/test/script/basic/NASHORN-98.js create mode 100644 nashorn/test/script/basic/NASHORN-98.js.EXPECTED create mode 100644 nashorn/test/script/basic/NASHORN-99.js create mode 100644 nashorn/test/script/basic/addition.js create mode 100644 nashorn/test/script/basic/addition.js.EXPECTED create mode 100644 nashorn/test/script/basic/allgettersetters.js create mode 100644 nashorn/test/script/basic/andor.js create mode 100644 nashorn/test/script/basic/andor.js.EXPECTED create mode 100644 nashorn/test/script/basic/anonrecur.js create mode 100644 nashorn/test/script/basic/anonrecur.js.EXPECTED create mode 100644 nashorn/test/script/basic/applycall.js create mode 100644 nashorn/test/script/basic/applycall.js.EXPECTED create mode 100644 nashorn/test/script/basic/args.js create mode 100644 nashorn/test/script/basic/args.js.EXPECTED create mode 100644 nashorn/test/script/basic/arity.js create mode 100644 nashorn/test/script/basic/arity.js.EXPECTED create mode 100644 nashorn/test/script/basic/arrayprotoclass.js create mode 100644 nashorn/test/script/basic/arrayprotoclass.js.EXPECTED create mode 100644 nashorn/test/script/basic/arrays.js create mode 100644 nashorn/test/script/basic/arrays.js.EXPECTED create mode 100644 nashorn/test/script/basic/arrays2.js create mode 100644 nashorn/test/script/basic/arrays2.js.EXPECTED create mode 100644 nashorn/test/script/basic/arraysIntKey.js create mode 100644 nashorn/test/script/basic/arraysIntKey.js.EXPECTED create mode 100644 nashorn/test/script/basic/arrayset.js create mode 100644 nashorn/test/script/basic/arrayset.js.EXPECTED create mode 100644 nashorn/test/script/basic/arrayundefined.js create mode 100644 nashorn/test/script/basic/arrayundefined.js.EXPECTED create mode 100644 nashorn/test/script/basic/assign.js create mode 100644 nashorn/test/script/basic/assign.js.EXPECTED create mode 100644 nashorn/test/script/basic/bitwise_and.js create mode 100644 nashorn/test/script/basic/bitwise_and.js.EXPECTED create mode 100644 nashorn/test/script/basic/booleangetter.js create mode 100644 nashorn/test/script/basic/booleangetter.js.EXPECTED create mode 100644 nashorn/test/script/basic/builtin.js create mode 100644 nashorn/test/script/basic/builtin.js.EXPECTED create mode 100644 nashorn/test/script/basic/builtin_assign.js create mode 100644 nashorn/test/script/basic/builtin_assign.js.EXPECTED create mode 100644 nashorn/test/script/basic/builtinchain.js create mode 100644 nashorn/test/script/basic/builtinchain.js.EXPECTED create mode 100644 nashorn/test/script/basic/calllink.js create mode 100644 nashorn/test/script/basic/calllink.js.EXPECTED create mode 100644 nashorn/test/script/basic/closure.js create mode 100644 nashorn/test/script/basic/closure.js.EXPECTED create mode 100644 nashorn/test/script/basic/commandargs.js create mode 100644 nashorn/test/script/basic/commandargs.js.EXPECTED create mode 100644 nashorn/test/script/basic/compile-octane.js create mode 100644 nashorn/test/script/basic/compile-octane.js.EXPECTED create mode 100644 nashorn/test/script/basic/condassign.js create mode 100644 nashorn/test/script/basic/condassign.js.EXPECTED create mode 100644 nashorn/test/script/basic/construct.js create mode 100644 nashorn/test/script/basic/construct.js.EXPECTED create mode 100644 nashorn/test/script/basic/constructorname.js create mode 100644 nashorn/test/script/basic/constructorname.js.EXPECTED create mode 100644 nashorn/test/script/basic/date.js create mode 100644 nashorn/test/script/basic/date.js.EXPECTED create mode 100644 nashorn/test/script/basic/dateparse.js create mode 100644 nashorn/test/script/basic/dateparse.js.EXPECTED create mode 100644 nashorn/test/script/basic/decinc.js create mode 100644 nashorn/test/script/basic/decinc.js.EXPECTED create mode 100644 nashorn/test/script/basic/delete.js create mode 100644 nashorn/test/script/basic/delete.js.EXPECTED create mode 100644 nashorn/test/script/basic/delete2.js create mode 100644 nashorn/test/script/basic/delete2.js.EXPECTED create mode 100644 nashorn/test/script/basic/dotpropname.js create mode 100644 nashorn/test/script/basic/dotpropname.js.EXPECTED create mode 100644 nashorn/test/script/basic/doublecache.js create mode 100644 nashorn/test/script/basic/doublecache.js.EXPECTED create mode 100644 nashorn/test/script/basic/enumeration.js create mode 100644 nashorn/test/script/basic/enumeration.js.EXPECTED create mode 100644 nashorn/test/script/basic/errors.js create mode 100644 nashorn/test/script/basic/errors.js.EXPECTED create mode 100644 nashorn/test/script/basic/errorstack.js create mode 100644 nashorn/test/script/basic/errorstack.js.EXPECTED create mode 100644 nashorn/test/script/basic/eval.js create mode 100644 nashorn/test/script/basic/eval.js.EXPECTED create mode 100644 nashorn/test/script/basic/evalreturn.js create mode 100644 nashorn/test/script/basic/evalreturn.js.EXPECTED create mode 100644 nashorn/test/script/basic/exprclosure.js create mode 100644 nashorn/test/script/basic/exprclosure.js.EXPECTED create mode 100644 nashorn/test/script/basic/extensibility.js create mode 100644 nashorn/test/script/basic/extensibility.js.EXPECTED create mode 100644 nashorn/test/script/basic/fileline.js create mode 100644 nashorn/test/script/basic/fileline.js.EXPECTED create mode 100644 nashorn/test/script/basic/finally-catchalls.js create mode 100644 nashorn/test/script/basic/finally-catchalls.js.EXPECTED create mode 100644 nashorn/test/script/basic/finallyreturn.js create mode 100644 nashorn/test/script/basic/finallyreturn.js.EXPECTED create mode 100644 nashorn/test/script/basic/forin.js create mode 100644 nashorn/test/script/basic/forin.js.EXPECTED create mode 100644 nashorn/test/script/basic/forin2.js create mode 100644 nashorn/test/script/basic/forin2.js.EXPECTED create mode 100644 nashorn/test/script/basic/funcarray.js create mode 100644 nashorn/test/script/basic/funcarray.js.EXPECTED create mode 100644 nashorn/test/script/basic/funcbind.js create mode 100644 nashorn/test/script/basic/funcbind.js.EXPECTED create mode 100644 nashorn/test/script/basic/funcconstructor.js create mode 100644 nashorn/test/script/basic/funcconstructor.js.EXPECTED create mode 100644 nashorn/test/script/basic/getclassname.js create mode 100644 nashorn/test/script/basic/getenv.js create mode 100644 nashorn/test/script/basic/getenv.js.EXPECTED create mode 100644 nashorn/test/script/basic/getter_callsite.js create mode 100644 nashorn/test/script/basic/getter_callsite.js.EXPECTED create mode 100644 nashorn/test/script/basic/gettercalls.js create mode 100644 nashorn/test/script/basic/gettercalls.js.EXPECTED create mode 100644 nashorn/test/script/basic/getterfunc.js create mode 100644 nashorn/test/script/basic/getterfunc.js.EXPECTED create mode 100644 nashorn/test/script/basic/gettersetter.js create mode 100644 nashorn/test/script/basic/gettersetter.js.EXPECTED create mode 100644 nashorn/test/script/basic/globalaccess.js create mode 100644 nashorn/test/script/basic/globalaccess.js.EXPECTED create mode 100644 nashorn/test/script/basic/globals.js create mode 100644 nashorn/test/script/basic/globals.js.EXPECTED create mode 100644 nashorn/test/script/basic/globalscope.js create mode 100644 nashorn/test/script/basic/globalscope.js.EXPECTED create mode 100644 nashorn/test/script/basic/hello.js create mode 100644 nashorn/test/script/basic/hello.js.EXPECTED create mode 100644 nashorn/test/script/basic/herestr_operator.js create mode 100644 nashorn/test/script/basic/herestr_operator.js.EXPECTED create mode 100644 nashorn/test/script/basic/illegaljavaname.js create mode 100644 nashorn/test/script/basic/illegaljavaname.js.EXPECTED create mode 100644 nashorn/test/script/basic/incheck.js create mode 100644 nashorn/test/script/basic/incheck.js.EXPECTED create mode 100644 nashorn/test/script/basic/indexedcall.js create mode 100644 nashorn/test/script/basic/indexedcall.js.EXPECTED create mode 100644 nashorn/test/script/basic/info.js create mode 100644 nashorn/test/script/basic/info.js.EXPECTED create mode 100644 nashorn/test/script/basic/inherited_nonwritable.js create mode 100644 nashorn/test/script/basic/instanceof.js create mode 100644 nashorn/test/script/basic/instanceof.js.EXPECTED create mode 100644 nashorn/test/script/basic/instanceof2.js create mode 100644 nashorn/test/script/basic/instanceof2.js.EXPECTED create mode 100644 nashorn/test/script/basic/interfaces.js create mode 100644 nashorn/test/script/basic/interfaces.js.EXPECTED create mode 100644 nashorn/test/script/basic/iterator.js create mode 100644 nashorn/test/script/basic/iterator.js.EXPECTED create mode 100644 nashorn/test/script/basic/java.js create mode 100644 nashorn/test/script/basic/java.js.EXPECTED create mode 100644 nashorn/test/script/basic/javaarray.js create mode 100644 nashorn/test/script/basic/javaarray.js.EXPECTED create mode 100644 nashorn/test/script/basic/javaarrayconversion.js create mode 100644 nashorn/test/script/basic/javaarrayconversion.js.EXPECTED create mode 100644 nashorn/test/script/basic/javaexceptions.js create mode 100644 nashorn/test/script/basic/javaexceptions.js.EXPECTED create mode 100644 nashorn/test/script/basic/javaimporter.js create mode 100644 nashorn/test/script/basic/javaimporter.js.EXPECTED create mode 100644 nashorn/test/script/basic/javainnerclasses.js create mode 100644 nashorn/test/script/basic/javainnerclasses.js.EXPECTED create mode 100644 nashorn/test/script/basic/javasigcall.js create mode 100644 nashorn/test/script/basic/javasigcall.js.EXPECTED create mode 100644 nashorn/test/script/basic/jquery.js create mode 100644 nashorn/test/script/basic/jquery.js.EXPECTED create mode 100644 nashorn/test/script/basic/jsadapter.js create mode 100644 nashorn/test/script/basic/jsadapter.js.EXPECTED create mode 100644 nashorn/test/script/basic/jsadapterlink.js create mode 100644 nashorn/test/script/basic/jsadapterlink.js.EXPECTED create mode 100644 nashorn/test/script/basic/json.js create mode 100644 nashorn/test/script/basic/json.js.EXPECTED create mode 100644 nashorn/test/script/basic/list.js create mode 100644 nashorn/test/script/basic/list.js.EXPECTED create mode 100644 nashorn/test/script/basic/literal.js create mode 100644 nashorn/test/script/basic/literal.js.EXPECTED create mode 100644 nashorn/test/script/basic/load.js create mode 100644 nashorn/test/script/basic/load.js.EXPECTED create mode 100644 nashorn/test/script/basic/loadedfile.js create mode 100644 nashorn/test/script/basic/localundef.js create mode 100644 nashorn/test/script/basic/localundef.js.EXPECTED create mode 100644 nashorn/test/script/basic/map.js create mode 100644 nashorn/test/script/basic/map.js.EXPECTED create mode 100644 nashorn/test/script/basic/math.js create mode 100644 nashorn/test/script/basic/math.js.EXPECTED create mode 100644 nashorn/test/script/basic/minuszero.js create mode 100644 nashorn/test/script/basic/minuszero.js.EXPECTED create mode 100644 nashorn/test/script/basic/module.js create mode 100644 nashorn/test/script/basic/moduleload.js create mode 100644 nashorn/test/script/basic/moduleload.js.EXPECTED create mode 100644 nashorn/test/script/basic/nashorn2.js create mode 100644 nashorn/test/script/basic/nashorn2.js.EXPECTED create mode 100644 nashorn/test/script/basic/natives.js create mode 100644 nashorn/test/script/basic/natives.js.EXPECTED create mode 100644 nashorn/test/script/basic/new.js create mode 100644 nashorn/test/script/basic/new.js.EXPECTED create mode 100644 nashorn/test/script/basic/newexpr.js create mode 100644 nashorn/test/script/basic/newexpr.js.EXPECTED create mode 100644 nashorn/test/script/basic/newnew.js create mode 100644 nashorn/test/script/basic/newnew.js.EXPECTED create mode 100644 nashorn/test/script/basic/nonconstructors.js create mode 100644 nashorn/test/script/basic/nonconstructors.js.EXPECTED create mode 100644 nashorn/test/script/basic/nosuchmethod.js create mode 100644 nashorn/test/script/basic/nosuchmethod.js.EXPECTED create mode 100644 nashorn/test/script/basic/nosuchproperty.js create mode 100644 nashorn/test/script/basic/nosuchproperty.js.EXPECTED create mode 100644 nashorn/test/script/basic/number.js create mode 100644 nashorn/test/script/basic/number.js.EXPECTED create mode 100644 nashorn/test/script/basic/numberstring.js create mode 100644 nashorn/test/script/basic/numberstring.js.EXPECTED create mode 100644 nashorn/test/script/basic/objectprops.js create mode 100644 nashorn/test/script/basic/objectprops.js.EXPECTED create mode 100644 nashorn/test/script/basic/objects.js create mode 100644 nashorn/test/script/basic/objects.js.EXPECTED create mode 100644 nashorn/test/script/basic/options.js create mode 100644 nashorn/test/script/basic/options.js.EXPECTED create mode 100644 nashorn/test/script/basic/propchange.js create mode 100644 nashorn/test/script/basic/propchange.js.EXPECTED create mode 100644 nashorn/test/script/basic/propertycheck.js create mode 100644 nashorn/test/script/basic/propertycheck.js.EXPECTED create mode 100644 nashorn/test/script/basic/proto.js.EXPECTED create mode 100644 nashorn/test/script/basic/prototype.js create mode 100644 nashorn/test/script/basic/prototype.js.EXPECTED create mode 100644 nashorn/test/script/basic/pushpull.js create mode 100644 nashorn/test/script/basic/pushpull.js.EXPECTED create mode 100644 nashorn/test/script/basic/regex.js create mode 100644 nashorn/test/script/basic/regex.js.EXPECTED create mode 100644 nashorn/test/script/basic/regexp_flags.js create mode 100644 nashorn/test/script/basic/run-octane.js create mode 100644 nashorn/test/script/basic/runsunspider.js create mode 100644 nashorn/test/script/basic/runsunspider.js.EXPECTED create mode 100644 nashorn/test/script/basic/samfunc.js create mode 100644 nashorn/test/script/basic/samfunc.js.EXPECTED create mode 100644 nashorn/test/script/basic/scripting.js create mode 100644 nashorn/test/script/basic/scripting.js.EXPECTED create mode 100644 nashorn/test/script/basic/sealfreeze.js create mode 100644 nashorn/test/script/basic/sealfreeze.js.EXPECTED create mode 100644 nashorn/test/script/basic/setlength.js create mode 100644 nashorn/test/script/basic/setlength.js.EXPECTED create mode 100644 nashorn/test/script/basic/stdin.js create mode 100644 nashorn/test/script/basic/stdin.js.EXPECTED create mode 100644 nashorn/test/script/basic/strings.js create mode 100644 nashorn/test/script/basic/strings.js.EXPECTED create mode 100644 nashorn/test/script/basic/throws.js create mode 100644 nashorn/test/script/basic/throws.js.EXPECTED create mode 100644 nashorn/test/script/basic/tosource.js create mode 100644 nashorn/test/script/basic/tosource.js.EXPECTED create mode 100644 nashorn/test/script/basic/tostring.js create mode 100644 nashorn/test/script/basic/tostring.js.EXPECTED create mode 100644 nashorn/test/script/basic/try.js create mode 100644 nashorn/test/script/basic/try.js.EXPECTED create mode 100644 nashorn/test/script/basic/trybreakcont.js create mode 100644 nashorn/test/script/basic/trybreakcont.js.EXPECTED create mode 100644 nashorn/test/script/basic/trycatch.js create mode 100644 nashorn/test/script/basic/trycatch.js.EXPECTED create mode 100644 nashorn/test/script/basic/trycatchfor.js create mode 100644 nashorn/test/script/basic/trycatchfor.js.EXPECTED create mode 100644 nashorn/test/script/basic/tryfinallyreturn.js create mode 100644 nashorn/test/script/basic/tryfinallyreturn.js.EXPECTED create mode 100644 nashorn/test/script/basic/tryforbreak.js create mode 100644 nashorn/test/script/basic/tryforbreak.js.EXPECTED create mode 100644 nashorn/test/script/basic/typechange.js create mode 100644 nashorn/test/script/basic/typechange.js.EXPECTED create mode 100644 nashorn/test/script/basic/typeof.js create mode 100644 nashorn/test/script/basic/typeof.js.EXPECTED create mode 100644 nashorn/test/script/basic/typeof2.js create mode 100644 nashorn/test/script/basic/typeof2.js.EXPECTED create mode 100644 nashorn/test/script/basic/undefined.js create mode 100644 nashorn/test/script/basic/undefined.js.EXPECTED create mode 100644 nashorn/test/script/basic/underscore.js create mode 100644 nashorn/test/script/basic/underscore.js.EXPECTED create mode 100644 nashorn/test/script/basic/varargs.js create mode 100644 nashorn/test/script/basic/varargs.js.EXPECTED create mode 100644 nashorn/test/script/basic/void.js create mode 100644 nashorn/test/script/basic/void.js.EXPECTED create mode 100644 nashorn/test/script/basic/with.js create mode 100644 nashorn/test/script/basic/with.js.EXPECTED create mode 100644 nashorn/test/script/basic/withprimitive.js create mode 100644 nashorn/test/script/basic/withprimitive.js.EXPECTED create mode 100644 nashorn/test/script/basic/writable_relink.js create mode 100644 nashorn/test/script/basic/writable_relink.js.EXPECTED create mode 100644 nashorn/test/script/basic/xmlStrings.js.EXPECTED create mode 100644 nashorn/test/script/basic/xorassign.js create mode 100644 nashorn/test/script/basic/xorassign.js.EXPECTED create mode 100644 nashorn/test/script/basic/yui.js create mode 100644 nashorn/test/script/basic/yui.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-154/README create mode 100644 nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js create mode 100644 nashorn/test/script/error/NASHORN-154/function_mult_params_in_strict.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js create mode 100644 nashorn/test/script/error/NASHORN-154/improper_return_break_continue.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-154/invalid_lvalue.js create mode 100644 nashorn/test/script/error/NASHORN-154/invalid_lvalue.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js create mode 100644 nashorn/test/script/error/NASHORN-154/literal_data_and_accessor.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-154/literal_mult_getters.js create mode 100644 nashorn/test/script/error/NASHORN-154/literal_mult_getters.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js create mode 100644 nashorn/test/script/error/NASHORN-154/literal_mult_prop_in_strict.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-154/with_in_strict.js create mode 100644 nashorn/test/script/error/NASHORN-154/with_in_strict.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-214.js create mode 100644 nashorn/test/script/error/NASHORN-214.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-35.js create mode 100644 nashorn/test/script/error/NASHORN-35.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-39.js create mode 100644 nashorn/test/script/error/NASHORN-39.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-568.js create mode 100644 nashorn/test/script/error/NASHORN-568.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-57.js create mode 100644 nashorn/test/script/error/NASHORN-57.js.EXPECTED create mode 100644 nashorn/test/script/error/NASHORN-668.js create mode 100644 nashorn/test/script/error/NASHORN-668.js.EXPECTED create mode 100644 nashorn/test/script/error/quotemissing.js create mode 100644 nashorn/test/script/error/quotemissing.js.EXPECTED create mode 100644 nashorn/test/script/error/strictmode.js create mode 100644 nashorn/test/script/error/strictmode.js.EXPECTED create mode 100644 nashorn/test/script/representations/NASHORN-592a.js create mode 100644 nashorn/test/script/sandbox/NASHORN-525.js create mode 100644 nashorn/test/script/sandbox/README create mode 100644 nashorn/test/script/sandbox/classloader.js create mode 100644 nashorn/test/script/sandbox/classloader.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/doprivileged.js create mode 100644 nashorn/test/script/sandbox/doprivileged.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/exit.js create mode 100644 nashorn/test/script/sandbox/exit.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/file.js create mode 100644 nashorn/test/script/sandbox/file.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/javaextend.js create mode 100644 nashorn/test/script/sandbox/javaextend.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/loadLibrary.js create mode 100644 nashorn/test/script/sandbox/net.js create mode 100644 nashorn/test/script/sandbox/net.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/property.js create mode 100644 nashorn/test/script/sandbox/property.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/reflection.js create mode 100644 nashorn/test/script/sandbox/reflection.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/runnable.js create mode 100644 nashorn/test/script/sandbox/runnable.js.EXPECTED create mode 100644 nashorn/test/script/sandbox/unsafe.js create mode 100644 nashorn/test/script/sandbox/unsafe.js.EXPECTED create mode 100644 nashorn/test/script/test262.js create mode 100644 nashorn/test/script/test262_single.js create mode 100644 nashorn/test/src/UnnamedPackageTestCallback.java create mode 100644 nashorn/test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java create mode 100644 nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java create mode 100644 nashorn/test/src/jdk/nashorn/api/scripting/Window.java create mode 100644 nashorn/test/src/jdk/nashorn/api/scripting/WindowEventHandler.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/access/BooleanAccessTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/access/MethodAccessTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/access/NumberAccessTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/access/NumberBoxingTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/access/ObjectAccessTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/access/Person.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/access/SharedObject.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/access/StringAccessTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/performance/AuroraWrapper.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/performance/OctaneTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/performance/SplayTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/runtime/JSTypeTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/runtime/Nashorn401TestSubject.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/AbstractScriptRunnable.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/JSJUnitReportReporter.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/OrphanTestFinder.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/ParallelTestRunner.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptEvaluator.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptRunnable.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/ScriptTest.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/SeparateContextEvaluator.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/TestConfig.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/TestFinder.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/TestHelper.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/framework/TestReorderInterceptor.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/models/ConstructorWithArgument.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/models/FinalClass.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/models/NoAccessibleConstructorClass.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/models/NonPublicClass.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/models/OuterClass.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/models/OverloadedSam.java create mode 100644 nashorn/test/src/jdk/nashorn/internal/test/models/OverrideObject.java diff --git a/nashorn/.hgignore b/nashorn/.hgignore index 83cef213d48..fe2082c8702 100644 --- a/nashorn/.hgignore +++ b/nashorn/.hgignore @@ -1,4 +1,25 @@ +syntax: glob + ^build/ ^dist/ -/nbproject/private/ ^.hgtip +/nbproject/private/ +^webrev/ +webrev.zip +*.class +*.log +*.orig +hotspot.log +private.properties +genfiles.properties +private.xml +.DS_Store* +TEST-*.xml +TESTS-*.xml +report.xml +CC/ +jcov2/ +buildtools/nasgen/nbproject/private/ +buildtools/nasgen/dist/ +buildtools/nasgen/build/ +.idea/* diff --git a/nashorn/ASSEMBLY_EXCEPTION b/nashorn/ASSEMBLY_EXCEPTION new file mode 100644 index 00000000000..8b7ac1d0813 --- /dev/null +++ b/nashorn/ASSEMBLY_EXCEPTION @@ -0,0 +1,27 @@ + +OPENJDK ASSEMBLY EXCEPTION + +The OpenJDK source code made available by Sun at openjdk.java.net and +openjdk.dev.java.net ("OpenJDK Code") is distributed under the terms of the +GNU General Public License version 2 +only ("GPL2"), with the following clarification and special exception. + + Linking this OpenJDK Code statically or dynamically with other code + is making a combined work based on this library. Thus, the terms + and conditions of GPL2 cover the whole combination. + + As a special exception, Sun gives you permission to link this + OpenJDK Code with certain code licensed by Sun as indicated at + http://openjdk.java.net/legal/exception-modules-2007-05-08.html + ("Designated Exception Modules") to produce an executable, + regardless of the license terms of the Designated Exception Modules, + and to copy and distribute the resulting executable under GPL2, + provided that the Designated Exception Modules continue to be + governed by the licenses under which they were offered by Sun. + +As such, it allows licensees and sublicensees of Sun's GPL2 OpenJDK Code to +build an executable that includes those portions of necessary code that Sun +could not provide under GPL2 (or that Sun has provided under GPL2 with the +Classpath exception). If you modify or add to the OpenJDK code, that new +GPL2 code may still be combined with Designated Exception Modules if the +new code is made subject to this exception by its copyright holder. diff --git a/nashorn/LICENSE b/nashorn/LICENSE new file mode 100644 index 00000000000..b40a0f457d7 --- /dev/null +++ b/nashorn/LICENSE @@ -0,0 +1,347 @@ +The GNU General Public License (GPL) + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must +show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program proprietary. +To prevent this, we have made it clear that any patent must be licensed for +everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included +without limitation in the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + + a) You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or + in part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of + this License. + + c) If the modified program normally reads commands interactively when run, + you must cause it, when started running for such interactive use in the + most ordinary way, to print or display an announcement including an + appropriate copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to view a copy + of this License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the Program is + not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and +its terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a +work based on the Program, the distribution of the whole must be on the terms +of this License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on +the Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and +2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 above + on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to + give any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code +distributed need not include anything that is normally distributed (in either +source or binary form) with the major components (compiler, kernel, and so on) +of the operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or +any work based on the Program), you indicate your acceptance of this License to +do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by +third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), conditions +are imposed on you (whether by court order, agreement or otherwise) that +contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In +such case, this License incorporates the limitation as if written in the body +of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later +version", you have the option of following the terms and conditions either of +that version or of any later version published by the Free Software Foundation. +If the Program does not specify a version number of this License, you may +choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER +OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + + Copyright (C) + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 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 General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it +starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes + with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free + software, and you are welcome to redistribute it under certain conditions; + type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + 'Gnomovision' (which makes passes at compilers) written by James Hacker. + + signature of Ty Coon, 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General Public +License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL + +Certain source files distributed by Oracle America and/or its affiliates are +subject to the following clarification and special exception to the GPL, but +only where Oracle has expressly included in the particular source file's header +the words "Oracle designates this particular file as subject to the "Classpath" +exception as provided by Oracle in the LICENSE file that accompanied this code." + + Linking this library statically or dynamically with other modules is making + a combined work based on this library. Thus, the terms and conditions of + the GNU General Public License cover the whole combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules, + and to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent module, + the terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. If + you modify this library, you may extend this exception to your version of + the library, but you are not obligated to do so. If you do not wish to do + so, delete this exception statement from your version. diff --git a/nashorn/README b/nashorn/README new file mode 100644 index 00000000000..52b30919065 --- /dev/null +++ b/nashorn/README @@ -0,0 +1,147 @@ +- What is Nashorn? + +Nashorn is a runtime environment for programs written in ECMAScript 5.1 +that runs on top of JVM. + +- How to find out more about ECMAScript 5.1? + +The specification can be found at + + http://www.ecma-international.org/publications/standards/Ecma-262.htm + +- How to checkout sources of Nashorn project? + +Nashorn project uses Mercurial source code control system. You can +download Mercurial from http://mercurial.selenic.com/wiki/Download + +Information about the forest extension can be found at + + http://mercurial.selenic.com/wiki/ForestExtension + +and downlaoded using + + hg clone https://bitbucket.org/gxti/hgforest + +You can clone Nashorn Mercurial forest using this command: + + hg fclone http://hg.openjdk.java.net/nashorn/jdk8 nashorn~jdk8 + +To update your copy of the forest (fwith the latest code: + + (cd nashorn~jdk8 ; hg fpull) + +Or just the nashorn subdirectory with + + (cd nashorn~jdk8/nashorn ; hg pull -u) + +To learn about Mercurial in detail, please visit http://hgbook.red-bean.com. + +- How to build? + +To build Nashorn, you need to install JDK 8. You may use the Nashorn +forest build (recommended) or down load from java.net. You will need to +set JAVA_HOME environmental variable to point to your JDK installation +directory. + + cd nashorn~jdk8/nashorn/make + ant clean; ant + +- How to run? + +Use the jjs script (see RELESE_README): + + cd nashorn~jdk8/nashorn + sh bin/jjs + +Nashorn supports javax.script API. It is possible to drop nashorn.jar in +class path and request for "nashorn" script engine from +javax.script.ScriptEngineManager. + +Look for samples under the directory test/src/jdk/nashorn/api/scripting/. + +- Documentation + +Comprehensive development documentation is found in the Nashorn JavaDoc. You can +build it using: + + cd nashorn~jdk8/nashorn/make + ant javadoc + +after which you can view the generated documentation at dist/javadoc/index.html. + +- Running tests + +Nashorn tests are TestNG based. Running tests requires downloading the +TestNG library and placing its jar file into the lib subdirectory: + + # download and install TestNG + wget http://testng.org/testng-x.y.z.zip + unzip testng-x.y.z.zip + cp testng-x.y.z/testng-x.y.z.jar test/lib/testng.jar + +After that, you can run the tests using: + cd make + ant test + +You can also run the ECMA-262 test suite with Nashorn. In order to do +that, you will need to get a copy of it and put it in +test/script/external/test262 directory. A convenient way to do it is: + + hg clone http://hg.ecmascript.org/tests/test262/ test/script/external/test262 + +Alternatively, you can check it out elsewhere and make +test/script/external/test262 a symbolic link to that directory. After +you've done this, you can run the ECMA-262 tests using: + + cd nashorn~jdk8/nashorn/make + ant test262 + +These tests take time, so we have a parallelized runner for them that +takes advantage of all processor cores on the computer: + + cd nashorn~jdk8/nashorn/make + ant test262parallel + +- How to write your own test? + +Nashorn uses it's own simple test framework. Any .js file dropped under +nashorn/test directory is considered as a test. A test file can +optionally have .js.EXPECTED (foo.js.EXPECTED for foo.js) associated +with it. The .EXPECTED file, if exists, should contain the output +expected from compiling and/or running the test file. + +The test runner crawls these directories for .js files and looks for +JTReg-style @foo comments to identify tests. + + * @test - A test is tagged with @test. + + * @test/fail - Tests that are supposed to fail (compiling, see @run/fail + for runtime) are tagged with @test/fail. + + * @test/compile-error - Test expects compilation to fail, compares + output. + + * @test/warning - Test expects compiler warnings, compares output. + + * @test/nocompare - Test expects to compile [and/or run?] + successfully(may be warnings), does not compare output. + + * @subtest - denotes necessary file for a main test file; itself is not + a test. + + * @run - A test that should be run is also tagged with @run (otherwise + the test runner only compiles the test). + + * @run/fail - A test that should compile but fail with a runtime error. + + * @run/ignore-std-error - script may produce output on stderr, ignore + this output. + + * @argument - pass an argument to script. + + * @option \ - pass option to engine, sample. + +/** + * @option --dump-ir-graph + * @test + */ diff --git a/nashorn/RELEASE_README b/nashorn/RELEASE_README new file mode 100644 index 00000000000..9984be4ce32 --- /dev/null +++ b/nashorn/RELEASE_README @@ -0,0 +1,20 @@ +The Nashorn repo is in the process of being migrated to OpenJDK and as such is +incomplete in several areas. + +- The build system is not fully integrated. When complete, Nashorn will be +installed in its proper location in the JRE. + +- Once integrated, the correct version of the JDK will be wrapped around +Nashorn. In the meantime, ensure you use JDK8 b68 or later. + +- The jjs tool has not been implemented in binary form yet. Use "sh bin/jjs" +(or bin/jjs.bat on windows) in the interm. + +- The Dynalink component is not fully integrated into Nashorn as yet, but will +be when details are finalized. + +- And, finally Nashorn is still in development. To stay up to date, subscribe +to nashorn-dev@openjdk.java.net at + + http://mail.openjdk.java.net/mailman/listinfo/nashorn-dev. + diff --git a/nashorn/THIRD_PARTY_README b/nashorn/THIRD_PARTY_README new file mode 100644 index 00000000000..44318349aed --- /dev/null +++ b/nashorn/THIRD_PARTY_README @@ -0,0 +1,69 @@ +DO NOT TRANSLATE OR LOCALIZE. +----------------------------- + +%% This notice is provided with respect to ECMAScript Language +Specification ECMA-262 Edition 5.1 which is included with the Nashorn +technology. + +--- begin of LICENSE --- +Copyright notice +Copyright © 2011 Ecma International +Ecma International +Rue du Rhone 114 +CH-1204 Geneva +Tel: +41 22 849 6000 +Fax: +41 22 849 6001 +Web: http://www.ecma-international.org + +This document and possible translations of it may be copied and furnished to +others, and derivative works that comment on or otherwise explain it or assist +in its implementation may be prepared, copied, published, and distributed, in +whole or in part, without restriction of any kind, provided that the above +copyright notice and this section are included on all such copies and derivative +works. However, this document itself may not be modified in any way, including +by removing the copyright notice or references to Ecma International, except as +needed for the purpose of developing any document or deliverable produced by +Ecma International (in which case the rules applied to copyrights must be +followed) or as required to translate it into languages other than English. The +limited permissions granted above are perpetual and will not be revoked by Ecma +International or its successors or assigns. This document and the information +contained herein is provided on an "AS IS" basis and ECMA INTERNATIONAL +DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY +WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP +RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE." Software License + +All Software contained in this document ("Software)" is protected by copyright +and is being made available under the "BSD License", included below. This +Software may be subject to third party rights (rights from parties other than +Ecma International), including patent rights, and no licenses under such third +party rights are granted under this license even if the third party concerned is +a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS +AVAILABLE AT http://www.ecma-international.org/memento/codeofconduct.htm FOR +INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO +IMPLEMENT ECMA INTERNATIONAL STANDARDS*. Redistribution and use in source and +binary forms, with or without modification, are permitted provided that the +following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +3. Neither the name of the authors nor Ecma International may be used to endorse +or promote products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +--- end of LICENSE --- diff --git a/nashorn/bin/checkintest.sh b/nashorn/bin/checkintest.sh new file mode 100644 index 00000000000..a4750d5888e --- /dev/null +++ b/nashorn/bin/checkintest.sh @@ -0,0 +1,266 @@ +#!/bin/bash +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +#best pass rate at test 262 known +TEST262_PASS_AT_LEAST=435 + +RUN_TEST="true" +RUN_TEST262="true" +RUN_NODE="true" +KEEP_OUTPUT="true" +CLEAN_AND_BUILD_NASHORN="true" + +#the stable node version to sync against +NODE_LAST_STABLE=v0.6.18 + +#parse args +for arg in $* +do + if [ $arg = "--no-test" ]; then + RUN_TEST="false" + echo "**** WARNING - you have disabled 'ant test', which is a minimum checkin requirement..." + elif [ $arg = "--no-262" ]; then + RUN_TEST262="false" + elif [ $arg = "--no-node" ]; then + RUN_NODE="false" + elif [ $arg = "--no-build" ]; then + CLEAN_AND_BUILD_NASHORN="false" + elif [ $arg = "--no-logs" ]; then + KEEP_OUTPUT="false" + fi +done + +function lastpart() { + arr=$(echo $1 | tr "/" "\n") + for x in $arr + do + _last=$x + done + echo $_last +} + +function check_installed() { + which $1 >/dev/null + if [ $? -ne 0 ]; then + echo "Error $1 not installed: $?" + exit 2 + fi +} + +check_installed hg +check_installed git +check_installed mv +check_installed git + +PWD=$(pwd); + +while [ -z $NASHORN_ROOT ] +do + if [ -e $PWD/.hg ]; then + NASHORN_ROOT=${PWD} + break + fi + PWD=$(dirname ${PWD}) +done + +echo "Nashorn root detected at ${NASHORN_ROOT}" + +COMMON_ROOT=$(dirname $NASHORN_ROOT) +echo "Common root is ${COMMON_ROOT}" + +echo "Running checkintest..." + +ABSOLUTE_NASHORN_HOME=$COMMON_ROOT/$(lastpart $NASHORN_ROOT) + +if [ $CLEAN_AND_BUILD_NASHORN != "false" ]; then + echo "Cleaning and building nashorn at $ABSOLUTE_NASHORN_HOME/nashorn..." + $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant clean >/dev/null 2>/dev/null) + $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant jar >/dev/null 2>/dev/null) + echo "Done." +fi + +function failure_check() { + while read line + do + LINE=$(echo $line | grep "Tests run") + if [ "${LINE}" != "" ]; then + RESULT=$(echo $line | grep "Failures: 0" | grep "Errors: 0") + if [ "${RESULT}" == "" ]; then + TESTNAME=$2 + echo "There were errors in ${TESTNAME} : ${LINE}" + exit 1 + fi + fi + done < $1 +} + +function test() { + TEST_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX) + echo "Running 'ant test' on nashorn from ${ABSOLUTE_NASHORN_HOME}/nashorn..." + $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant test >$TEST_OUTPUT) + echo "Done." + + failure_check $TEST_OUTPUT + + echo "**** SUCCESS: 'ant test' successful" + + if [ $KEEP_OUTPUT == "true" ]; then + cp $TEST_OUTPUT ./checkintest.test.log + rm -fr $TEST_OUTPUT + fi +} + +if [ $RUN_TEST != "false" ]; then + test; +fi + +function test262() { + + echo "Running 'ant test262parallel' on nashorn from ${ABSOLUTE_NASHORN_HOME}/nashorn..." + TEST262_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX) + + echo "Looking for ${ABSOLUTE_NASHORN_HOME}/test/test262..." + + if [ ! -e $ABSOLUTE_NASHORN_HOME/nashorn/test/test262 ]; then + echo "test262 is missing... looking in $COMMON_ROOT..." + if [ ! -e $COMMON_ROOT/test262 ]; then + echo "... not there either... cloning from repo..." + hg clone http://hg.ecmascript.org/tests/test262 $COMMON_ROOT/test262 >/dev/null 2>/dev/null + echo "Done." + fi + echo "Adding soft link ${COMMON_ROOT}/test262 -> ${ABSOLUTE_NASHORN_HOME}/test/test262..." + ln -s $COMMON_ROOT/test262 $ABSOLUTE_NASHORN_HOME/nashorn/test/test262 + echo "Done." + fi + + echo "Ensuring test262 is up to date..." + $(cd $ABSOLUTE_NASHORN_HOME/nashorn/test/test262; hg pull -u >/dev/null 2>/dev/null) + echo "Done." + + echo "Running test262..." + $(cd $ABSOLUTE_NASHORN_HOME/nashorn; ant test262parallel > $TEST262_OUTPUT) + + FAILED=$(cat $TEST262_OUTPUT|grep "Tests run:"| cut -d ' ' -f 15 |tr -cd '"[[:digit:]]') + if [ $FAILED -gt $TEST262_PASS_AT_LEAST ]; then + echo "FAILURE: There are ${FAILED} failures in test262 and can be no more than ${TEST262_PASS_AT_LEAST}" + cp $TEST262_OUTPUT ./checkintest.test262.log + echo "See ./checkintest.test262.log" + echo "Terminating due to error" + exit 1 + elif [ $FAILED -lt $TEST262_PASS_AT_LEAST ]; then + echo "There seem to have been fixes to 262. ${FAILED} < ${TEST262_PASS_AT_LEAST}. Please update limit in bin/checkintest.sh" + fi + + echo "**** SUCCESS: Test262 passed with no more than ${TEST262_PASS_AT_LEAST} failures." + + if [ $KEEP_OUTPUT == "true" ]; then + cp $TEST262_OUTPUT ./checkintest.test262.log + rm -fr $TEST262_OUTPUT + fi +} + +if [ $RUN_TEST262 != "false" ]; then + test262; +fi; + +function testnode() { + TESTNODEJAR_OUTPUT=$ABSOLUTE_NASHORN_HOME/$(mktemp tmp.XXXXX) + + echo "Running node tests..." +#replace node jar properties nashorn with this nashorn + + NODEJAR_PROPERTIES=~/nodejar.properties + + NODE_HOME=$(cat $NODEJAR_PROPERTIES | grep ^node.home | cut -f2 -d=) + NASHORN_HOME=$(cat $NODEJAR_PROPERTIES | grep ^nashorn.home | cut -f2 -d=) + + ABSOLUTE_NODE_HOME=$COMMON_ROOT/$(lastpart $NODE_HOME) + + echo "Writing nodejar.properties..." + + cat > $NODEJAR_PROPERTIES << EOF +node.home=../node +nashorn.home=../$(lastpart $NASHORN_ROOT) +EOF + echo "Done." + echo "Checking node home ${ABSOLUTE_NODE_HOME}..." + + if [ ! -e $ABSOLUTE_NODE_HOME ]; then + echo "Node base dir not found. Cloning node..." + $(cd $COMMON_ROOT; git clone https://github.com/joyent/node.git $(lastpart $NODE_HOME) >/dev/null 2>/dev/null) + echo "Done." + echo "Updating to last stable version ${NODE_LAST_STABLE}..." + $(cd $ABSOLUTE_NODE_HOME; git checkout $NODE_LAST_STABLE >/dev/null 2>/dev/null) + echo "Done." + echo "Running configure..." + $(cd $ABSOLUTE_NODE_HOME; ./configure >/dev/null 2>/dev/null) + echo "Done." + fi + + echo "Ensuring node is built..." +#make sure node is built + $(cd $ABSOLUTE_NODE_HOME; make >/dev/null 2>/dev/null) + echo "Done." + + NODEJAR_HOME=$COMMON_ROOT/nodejar + + if [ ! -e $NODEJAR_HOME ]; then + echo "No node jar home found. cloning from depot..." + $(cd $COMMON_ROOT; hg clone https://hg.kenai.com/hg/nodejs~source nodejar >/dev/null 2>/dev/null) + $(cd $COMMON_ROOT/nodejar; ant >/dev/null) + echo "Done." + echo "Copying node files..." + $(cd $COMMON_ROOT/nodejar; ant copy-node-files >/dev/null 2>/dev/null) + echo "Patching node files..." + $(cd $COMMON_ROOT/nodejar; ant patch-node-files >/dev/null 2>/dev/null) + echo "Done." + fi + + echo "Ensuring node.jar is up to date from source depot..." + $(cd $COMMON_ROOT/nodejar; hg pull -u >/dev/null 2>/dev/null) + echo "Done." + + echo "Installing nashorn..." + $(cd $COMMON_ROOT/nodejar; ant >/dev/null) + echo "Done." + + echo "Running node.jar test..." + $(cd $COMMON_ROOT/nodejar; mvn clean verify >$TESTNODEJAR_OUTPUT) + echo "Done." + + failure_check $TESTNODEJAR_OUTPUT + + echo "**** SUCCESS: Node test successful." + + if [ $KEEP_OUTPUT == "true" ]; then + rm -fr $TESTNODEJAR_OUTPUT + cp $TESTNODEJAR_OUTPUT ./checkintest.nodejar.log + fi +} + +if [ $RUN_NODE != "false" ]; then + testnode; +fi; + +echo "Finished" diff --git a/nashorn/bin/fixorphantests.sh b/nashorn/bin/fixorphantests.sh new file mode 100644 index 00000000000..d7e5f74b6af --- /dev/null +++ b/nashorn/bin/fixorphantests.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +#ensure that all tests tagged with @test are also tagged with @run + +for f in $(find test/script/basic/*.js); do + grep @test $f >/dev/null + TEST=$? + grep @run $f >/dev/null + RUN=$? + + if [ $TEST -eq 0 ] && [ ! $RUN -eq 0 ]; then + echo "repairing ${f}..." + TEMP=$(mktemp /tmp/scratch.XXXXXX) + + #IFS='', -raw flag to preserve white space + while IFS='' read -r line; do + echo $line | grep @test >/dev/null + TEST=$? + printf "%s\n" "$line" + if [ $TEST -eq 0 ]; then + printf "%s\n" "$line" | sed s/@test/@run/g + fi + done < $f >$TEMP + + cp $TEMP $f + + rm -fr $TEMP + fi + +done diff --git a/nashorn/bin/fixwhitespace.sh b/nashorn/bin/fixwhitespace.sh new file mode 100644 index 00000000000..921a233df21 --- /dev/null +++ b/nashorn/bin/fixwhitespace.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +#convert tabs to spaces +find . -name "*.java" -exec sed -i "" 's/ / /g' {} \; + +#remove trailing whitespace +find . -name "*.java" -exec sed -i "" 's/[ ]*$//' \{} \; + diff --git a/nashorn/bin/jjs b/nashorn/bin/jjs new file mode 100644 index 00000000000..ae436b27ab5 --- /dev/null +++ b/nashorn/bin/jjs @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1; + +$JAVA_HOME/bin/java -server -XX:-TieredCompilation -Xms2G -Xmx2G -esa -ea -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -XX:+HeapDumpOnOutOfMemoryError -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.debug=true jdk.nashorn.tools.Shell $* diff --git a/nashorn/bin/jjs.bat b/nashorn/bin/jjs.bat new file mode 100644 index 00000000000..a7169577bcb --- /dev/null +++ b/nashorn/bin/jjs.bat @@ -0,0 +1,27 @@ +rem +rem Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +rem +rem This code is free software; you can redistribute it and/or modify it +rem under the terms of the GNU General Public License version 2 only, as +rem published by the Free Software Foundation. Oracle designates this +rem particular file as subject to the "Classpath" exception as provided +rem by Oracle in the LICENSE file that accompanied this code. +rem +rem This code is distributed in the hope that it will be useful, but WITHOUT +rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +rem version 2 for more details (a copy is included in the LICENSE file that +rem accompanied this code). +rem +rem You should have received a copy of the GNU General Public License version +rem 2 along with this work; if not, write to the Free Software Foundation, +rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +rem +rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +rem or visit www.oracle.com if you need additional information or have any +rem questions. +rem +@echo off + +java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.ext.dirs=%~dp0\..\dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false jdk.nashorn.tools.Shell diff --git a/nashorn/bin/jjssecure b/nashorn/bin/jjssecure new file mode 100644 index 00000000000..887c421d95c --- /dev/null +++ b/nashorn/bin/jjssecure @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1; + +$JAVA_HOME/bin/java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=true -Dnashorn.home=`dirname $0`/.. -Djava.security.manager jdk.nashorn.tools.Shell $* diff --git a/nashorn/bin/jjssecure.bat b/nashorn/bin/jjssecure.bat new file mode 100644 index 00000000000..662b167ae19 --- /dev/null +++ b/nashorn/bin/jjssecure.bat @@ -0,0 +1,27 @@ +rem +rem Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +rem +rem This code is free software; you can redistribute it and/or modify it +rem under the terms of the GNU General Public License version 2 only, as +rem published by the Free Software Foundation. Oracle designates this +rem particular file as subject to the "Classpath" exception as provided +rem by Oracle in the LICENSE file that accompanied this code. +rem +rem This code is distributed in the hope that it will be useful, but WITHOUT +rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +rem version 2 for more details (a copy is included in the LICENSE file that +rem accompanied this code). +rem +rem You should have received a copy of the GNU General Public License version +rem 2 along with this work; if not, write to the Free Software Foundation, +rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +rem +rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +rem or visit www.oracle.com if you need additional information or have any +rem questions. +rem +@echo off + +java -Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -Djava.ext.dirs=%~dp0\..\dist -XX:+HeapDumpOnOutOfMemoryError -Dnashorn.debug=true -Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -Dnashorn.home=%~dp0\.. -Djava.security.manager jdk.nashorn.tools.Shell diff --git a/nashorn/bin/nashorn b/nashorn/bin/nashorn new file mode 100644 index 00000000000..7720f423cdb --- /dev/null +++ b/nashorn/bin/nashorn @@ -0,0 +1,29 @@ +#!/bin/bash +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +[ -z "$JAVA_HOME" ] && echo "Please set JAVA_HOME" && exit 1; + +$JAVA_HOME/bin/jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:`dirname $0`/../dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -J-Dnashorn.debug=true -l nashorn $* diff --git a/nashorn/bin/nashorn.bat b/nashorn/bin/nashorn.bat new file mode 100644 index 00000000000..86aafc44a8a --- /dev/null +++ b/nashorn/bin/nashorn.bat @@ -0,0 +1,27 @@ +rem +rem Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +rem +rem This code is free software; you can redistribute it and/or modify it +rem under the terms of the GNU General Public License version 2 only, as +rem published by the Free Software Foundation. Oracle designates this +rem particular file as subject to the "Classpath" exception as provided +rem by Oracle in the LICENSE file that accompanied this code. +rem +rem This code is distributed in the hope that it will be useful, but WITHOUT +rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +rem version 2 for more details (a copy is included in the LICENSE file that +rem accompanied this code). +rem +rem You should have received a copy of the GNU General Public License version +rem 2 along with this work; if not, write to the Free Software Foundation, +rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +rem +rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +rem or visit www.oracle.com if you need additional information or have any +rem questions. +rem +@echo off + +jrunscript -J-Xms2G -J-Xmx2G -J-XX:-TieredCompilation -J-server -J-esa -J-ea -J-Djava.ext.dirs=%~dp0\..\dist -J-XX:+HeapDumpOnOutOfMemoryError -J-Dnashorn.debug=true -J-Djava.lang.invoke.MethodHandle.DEBUG_NAMES=false -l nashorn diff --git a/nashorn/bin/rm-non-tracked.sh b/nashorn/bin/rm-non-tracked.sh new file mode 100644 index 00000000000..aaadcf3809c --- /dev/null +++ b/nashorn/bin/rm-non-tracked.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +hg status|grep ^\?|awk '{print $2}'|xargs rm diff --git a/nashorn/bin/verbose_octane.bat b/nashorn/bin/verbose_octane.bat new file mode 100644 index 00000000000..69abbf8b47d --- /dev/null +++ b/nashorn/bin/verbose_octane.bat @@ -0,0 +1,59 @@ +rem +rem Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +rem DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +rem +rem This code is free software; you can redistribute it and/or modify it +rem under the terms of the GNU General Public License version 2 only, as +rem published by the Free Software Foundation. +rem +rem This code is distributed in the hope that it will be useful, but WITHOUT +rem ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +rem FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +rem version 2 for more details (a copy is included in the LICENSE file that +rem accompanied this code). +rem +rem You should have received a copy of the GNU General Public License version +rem 2 along with this work; if not, write to the Free Software Foundation, +rem Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +rem +rem Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +rem or visit www.oracle.com if you need additional information or have any +rem questions. +rem +@echo off + +if "%JAVA_HOME%" neq "" ( + call :run "%JAVA_HOME%/bin/java" +) else ( + call :run java +) +goto :EOF + +:run +setlocal +set NASHORN_JAR=dist/nashorn.jar +set JVM_FLAGS=-Xms2G -Xmx2G -XX:-TieredCompilation -server -esa -ea -jar %NASHORN_JAR% +set JVM_FLAGS7=-Xbootclasspath/p:%NASHORN_JAR% %JVM_FLAGS% +set OCTANE_ARGS=--verbose --iterations 7 + +%1 -fullversion 2>&1 | findstr /L /C:"version ""1.7" +if %errorlevel% equ 0 ( + set CMD=%1 %JVM_FLAGS7% +) else ( + %1 -fullversion + set CMD=%1 %JVM_FLAGS% +) + +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/box2d.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/code-load.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/crypto.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/deltablue.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/gbemu.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/navier-stokes.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/pdfjs.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/raytrace.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/regexp.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/richards.js %OCTANE_ARGS% +%CMD% test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/splay.js %OCTANE_ARGS% +endlocal +goto :EOF diff --git a/nashorn/bin/verbose_octane.sh b/nashorn/bin/verbose_octane.sh new file mode 100644 index 00000000000..6a9b7eb32e1 --- /dev/null +++ b/nashorn/bin/verbose_octane.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +ITERS=$1 +if [ -z $ITERS ]; then + ITERS=7 +fi +NASHORN_JAR=dist/nashorn.jar +JVM_FLAGS="-XX:+UnlockDiagnosticVMOptions -Dnashorn.unstable.relink.threshold=8 -Xms2G -Xmx2G -XX:-TieredCompilation -server -jar ${NASHORN_JAR}" +JVM_FLAGS7="-Xbootclasspath/p:${NASHORN_JAR} ${JVM_FLAGS}" +OCTANE_ARGS="--verbose --iterations ${ITERS}" + +BENCHMARKS=( "box2d.js" "code-load.js" "crypto.js" "deltablue.js" "earley-boyer.js" "gbemu.js" "navier-stokes.js" "raytrace.js" "regexp.js" "richards.js" "splay.js" ) +# TODO mandreel.js has metaspace issues + +if [ ! -z $JAVA7_HOME ]; then + echo "running ${ITERS} iterations with java7 using JAVA_HOME=${JAVA7_HOME}..." + for BENCHMARK in "${BENCHMARKS[@]}" + do + CMD="${JAVA8_HOME}/bin/java ${JVM_FLAGS} test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/${BENCHMARK} ${OCTANE_ARGS}" + $CMD + done +else + echo "no JAVA7_HOME set. skipping java7" +fi + +if [ ! -z $JAVA8_HOME ]; then + echo "running ${ITERS} iterations with java8 using JAVA_HOME=${JAVA8_HOME}..." + for BENCHMARK in "${BENCHMARKS[@]}" + do + CMD="${JAVA8_HOME}/bin/java ${JVM_FLAGS} test/script/basic/run-octane.js -- test/script/external/octane/benchmarks/${BENCHMARK} ${OCTANE_ARGS}" + $CMD + done +else + echo "no JAVA8_HOME set" +fi + +echo "Done" diff --git a/nashorn/buildtools/nasgen/README b/nashorn/buildtools/nasgen/README new file mode 100644 index 00000000000..d4509459691 --- /dev/null +++ b/nashorn/buildtools/nasgen/README @@ -0,0 +1,34 @@ +Nasgen is a tool for processing Java classes that implement native +JavaScript objects. It does so by looking for the +com.oracle.nashorn.objects.annotations.ScriptClass annotation and other +annotations in that package. + +For each class "C", nasgen instruments the original class and generates +two additional classes: a "C$Prototype" class for the JavaScript +prototype object, and a "C$Constructor" class for the JavaScript +constructor function. + +Each class instrumented or generated by nasgen contains a private static +"$nasgenmap$" field of type com.oracle.nashorn.runtime.PropertyMap and +static initializer block to initialize the field to the object's +JavaScript properties. + +Members annotated with @Function, @Property, @Getter, and @Setter are +mapped to the $Constructor, $Prototype, or main class, depending on the +value of the annotation's 'where' field. By default, @Property, @Getter, +and @Setter belong to the main class while @Function methods without +explicit 'where' field belong to the $Prototype class. The @Constructor +annotation marks a method to be invoked as JavaScript constructor. + +Nasgen enforces all @Function/@Getter/@Setter/@Constructor annotated +methods to be declared as static. Static final @Property fields remain +in the main class while other @Property fields are moved to respective +classes depending on the annotation's 'where' value. For functions +mapped to the $Prototype or $Constructor class, nasgen also generates +getters and setters prefixed by G$ and S$, respectively. + +Nasgen-generated classes are hidden from normal ClassLoaders by giving +them a ".clazz" file name extension instead of the standard ".class" +extension. This allows script classes to be loaded independently by each +Nashorn context through the com.oracle.nashorn.runtime.StructureLoader +class loader. diff --git a/nashorn/buildtools/nasgen/build.xml b/nashorn/buildtools/nasgen/build.xml new file mode 100644 index 00000000000..e20793b7d43 --- /dev/null +++ b/nashorn/buildtools/nasgen/build.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nashorn/buildtools/nasgen/nasgen.iml b/nashorn/buildtools/nasgen/nasgen.iml new file mode 100644 index 00000000000..b67d39e96ff --- /dev/null +++ b/nashorn/buildtools/nasgen/nasgen.iml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + diff --git a/nashorn/buildtools/nasgen/project.properties b/nashorn/buildtools/nasgen/project.properties new file mode 100644 index 00000000000..65047d95312 --- /dev/null +++ b/nashorn/buildtools/nasgen/project.properties @@ -0,0 +1,52 @@ +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +application.title=nasgen + +# source and target levels +build.compiler=modern +javac.source=1.7 +javac.target=1.7 + +build.classes.dir=${build.dir}/classes + +# This directory is removed when the project is cleaned: +build.dir=build + +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/nasgen.jar +dist.javadoc.dir=${dist.dir}/javadoc + +nashorn.dir=../../ + +javac.debug=true + +javac.classpath=\ + ${nashorn.dir}/build/classes + +meta.inf.dir=${src.dir}/META-INF +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +run.jvmargs= +src.dir=src diff --git a/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF b/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..b70986369a1 --- /dev/null +++ b/nashorn/buildtools/nasgen/src/META-INF/MANIFEST.MF @@ -0,0 +1,4 @@ +Manifest-Version: 1.0 +Class-Path: lib/ant-1.7.1.jar +Main-Class: jdk.nashorn.internal.tools.nasgen.Main + diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java new file mode 100644 index 00000000000..3a78da413d2 --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.GETTER_PREFIX; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SETTER_PREFIX; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_OBJECT; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.List; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.FieldVisitor; +import jdk.internal.org.objectweb.asm.Handle; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Type; +import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind; + +/** + * Base class for class generator classes. + * + */ +public class ClassGenerator { + /** ASM class writer used to output bytecode for this class */ + protected final ClassWriter cw; + + /** + * Constructor + */ + protected ClassGenerator() { + this.cw = makeClassWriter(); + } + + MethodGenerator makeStaticInitializer() { + return makeStaticInitializer(cw); + } + + MethodGenerator makeConstructor() { + return makeConstructor(cw); + } + + MethodGenerator makeMethod(final int access, final String name, final String desc) { + return makeMethod(cw, access, name, desc); + } + + void addMapField() { + addMapField(cw); + } + + void addField(final String name, final String desc) { + addField(cw, name, desc); + } + + void addFunctionField(final String name) { + addFunctionField(cw, name); + } + + void addGetter(final String owner, final MemberInfo memInfo) { + addGetter(cw, owner, memInfo); + } + + void addSetter(final String owner, final MemberInfo memInfo) { + addSetter(cw, owner, memInfo); + } + + void emitGetClassName(final String name) { + final MethodGenerator mi = makeMethod(ACC_PUBLIC, GET_CLASS_NAME, GET_CLASS_NAME_DESC); + mi.loadLiteral(name); + mi.returnValue(); + mi.computeMaxs(); + mi.visitEnd(); + } + + static ClassWriter makeClassWriter() { + return new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) { + @Override + protected String getCommonSuperClass(final String type1, final String type2) { + try { + return super.getCommonSuperClass(type1, type2); + } catch (final RuntimeException | LinkageError e) { + return StringConstants.OBJECT_TYPE; + } + } + }; + } + + static MethodGenerator makeStaticInitializer(final ClassVisitor cv) { + return makeStaticInitializer(cv, CLINIT); + } + + static MethodGenerator makeStaticInitializer(final ClassVisitor cv, final String name) { + final int access = ACC_PUBLIC | ACC_STATIC; + final String desc = DEFAULT_INIT_DESC; + final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); + return new MethodGenerator(mv, access, name, desc); + } + + static MethodGenerator makeConstructor(final ClassVisitor cv) { + final int access = ACC_PUBLIC; + final String name = INIT; + final String desc = DEFAULT_INIT_DESC; + final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); + return new MethodGenerator(mv, access, name, desc); + } + + static MethodGenerator makeMethod(final ClassVisitor cv, final int access, final String name, final String desc) { + final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); + return new MethodGenerator(mv, access, name, desc); + } + + static void emitStaticInitPrefix(final MethodGenerator mi, final String className) { + mi.visitCode(); + mi.pushNull(); + mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC); + mi.loadClass(className); + mi.invokeStatic(MAP_TYPE, MAP_NEWMAP, MAP_NEWMAP_DESC); + mi.storeLocal(0); + } + + static void emitStaticInitSuffix(final MethodGenerator mi, final String className) { + mi.loadLocal(0); + mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC); + mi.returnVoid(); + mi.computeMaxs(); + mi.visitEnd(); + } + + @SuppressWarnings("fallthrough") + private static Type memInfoType(final MemberInfo memInfo) { + switch (memInfo.getJavaDesc().charAt(0)) { + case 'I': return Type.INT_TYPE; + case 'J': return Type.LONG_TYPE; + case 'D': return Type.DOUBLE_TYPE; + default: assert false : memInfo.getJavaDesc(); + case 'L': return TYPE_OBJECT; + } + } + + private static String getterDesc(final MemberInfo memInfo) { + return Type.getMethodDescriptor(memInfoType(memInfo)); + } + + private static String setterDesc(final MemberInfo memInfo) { + return Type.getMethodDescriptor(Type.VOID_TYPE, memInfoType(memInfo)); + } + + static void addGetter(final ClassVisitor cv, final String owner, final MemberInfo memInfo) { + final int access = ACC_PUBLIC; + final String name = GETTER_PREFIX + memInfo.getJavaName(); + final String desc = getterDesc(memInfo); + final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); + final MethodGenerator mi = new MethodGenerator(mv, access, name, desc); + mi.visitCode(); + if (memInfo.isStatic() && memInfo.getKind() == Kind.PROPERTY) { + mi.getStatic(owner, memInfo.getJavaName(), memInfo.getJavaDesc()); + } else { + mi.loadLocal(0); + mi.getField(owner, memInfo.getJavaName(), memInfo.getJavaDesc()); + } + mi.returnValue(); + mi.computeMaxs(); + mi.visitEnd(); + } + + static void addSetter(final ClassVisitor cv, final String owner, final MemberInfo memInfo) { + final int access = ACC_PUBLIC; + final String name = SETTER_PREFIX + memInfo.getJavaName(); + final String desc = setterDesc(memInfo); + final MethodVisitor mv = cv.visitMethod(access, name, desc, null, null); + final MethodGenerator mi = new MethodGenerator(mv, access, name, desc); + mi.visitCode(); + if (memInfo.isStatic() && memInfo.getKind() == Kind.PROPERTY) { + mi.loadLocal(1); + mi.putStatic(owner, memInfo.getJavaName(), memInfo.getJavaDesc()); + } else { + mi.loadLocal(0); + mi.loadLocal(1); + mi.putField(owner, memInfo.getJavaName(), memInfo.getJavaDesc()); + } + mi.returnVoid(); + mi.computeMaxs(); + mi.visitEnd(); + } + + static void addMapField(final ClassVisitor cv) { + // add a MAP static field + final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC, + MAP_FIELD_NAME, MAP_DESC, null, null); + if (fv != null) { + fv.visitEnd(); + } + } + + static void addField(final ClassVisitor cv, final String name, final String desc) { + final FieldVisitor fv = cv.visitField(ACC_PRIVATE, name, desc, null, null); + if (fv != null) { + fv.visitEnd(); + } + } + + static void addFunctionField(final ClassVisitor cv, final String name) { + addField(cv, name, OBJECT_DESC); + } + + static void newFunction(final MethodGenerator mi, final String className, final MemberInfo memInfo, final List specs) { + final boolean arityFound = (memInfo.getArity() != MemberInfo.DEFAULT_ARITY); + + mi.loadLiteral(memInfo.getName()); + mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, memInfo.getJavaName(), memInfo.getJavaDesc())); + + assert specs != null; + if (!specs.isEmpty()) { + mi.memberInfoArray(className, specs); + mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC); + } else { + mi.invokeStatic(SCRIPTFUNCTIONIMPL_TYPE, SCRIPTFUNCTIONIMPL_MAKEFUNCTION, SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC); + } + + if (arityFound) { + mi.dup(); + mi.push(memInfo.getArity()); + mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, SCRIPTFUNCTION_SETARITY_DESC); + } + + } + + static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) { + final String propertyName = memInfo.getName(); + mi.loadLocal(0); + mi.loadLiteral(propertyName); + // setup flags + mi.push(memInfo.getAttributes()); + // setup getter method handle + String javaName = GETTER_PREFIX + memInfo.getJavaName(); + mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, getterDesc(memInfo))); + // setup setter method handle + if (memInfo.isFinal()) { + mi.pushNull(); + } else { + javaName = SETTER_PREFIX + memInfo.getJavaName(); + mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo))); + } + mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC); + mi.storeLocal(0); + } + + static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) { + final String propertyName = getter.getName(); + mi.loadLocal(0); + mi.loadLiteral(propertyName); + // setup flags + mi.push(getter.getAttributes()); + // setup getter method handle + mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, + getter.getJavaName(), getter.getJavaDesc())); + // setup setter method handle + if (setter == null) { + mi.pushNull(); + } else { + mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, + setter.getJavaName(), setter.getJavaDesc())); + } + mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC); + mi.storeLocal(0); + } + + static ScriptClassInfo getScriptClassInfo(final String fileName) throws IOException { + try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName))) { + return getScriptClassInfo(new ClassReader(bis)); + } + } + + static ScriptClassInfo getScriptClassInfo(final byte[] classBuf) { + return getScriptClassInfo(new ClassReader(classBuf)); + } + + private static ScriptClassInfo getScriptClassInfo(final ClassReader reader) { + final ScriptClassInfoCollector scic = new ScriptClassInfoCollector(); + reader.accept(scic, 0); + return scic.getScriptClassInfo(); + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java new file mode 100644 index 00000000000..2491e630ee7 --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER; +import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC3; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_INIT_DESC4; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_SETARITY_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTION_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import jdk.internal.org.objectweb.asm.Handle; + +/** + * This class generates constructor class for a @ClassInfo annotated class. + * + */ +public class ConstructorGenerator extends ClassGenerator { + private final ScriptClassInfo scriptClassInfo; + private final String className; + private final MemberInfo constructor; + private final int memberCount; + private final List specs; + + ConstructorGenerator(final ScriptClassInfo sci) { + this.scriptClassInfo = sci; + + this.className = scriptClassInfo.getConstructorClassName(); + this.constructor = scriptClassInfo.getConstructor(); + this.memberCount = scriptClassInfo.getConstructorMemberCount(); + this.specs = scriptClassInfo.getSpecializedConstructors(); + } + + byte[] getClassBytes() { + // new class extensing from ScriptObject + final String superClass = (constructor != null)? SCRIPTFUNCTIONIMPL_TYPE : SCRIPTOBJECT_TYPE; + cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClass, null); + if (memberCount > 0) { + // add fields + emitFields(); + // add + emitStaticInitializer(); + } + // add + emitConstructor(); + + if (constructor == null) { + emitGetClassName(scriptClassInfo.getName()); + } + + cw.visitEnd(); + return cw.toByteArray(); + } + + // --Internals only below this point + private void emitFields() { + // Introduce "Function" type instance fields for each + // constructor @Function in script class and introduce instance + // fields for each constructor @Property in the script class. + for (MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (memInfo.isConstructorFunction()) { + addFunctionField(memInfo.getJavaName()); + memInfo = (MemberInfo)memInfo.clone(); + memInfo.setJavaDesc(OBJECT_DESC); + memInfo.setJavaAccess(ACC_PUBLIC); + addGetter(className, memInfo); + addSetter(className, memInfo); + } else if (memInfo.isConstructorProperty()) { + if (memInfo.isStaticFinal()) { + addGetter(scriptClassInfo.getJavaName(), memInfo); + } else { + addField(memInfo.getJavaName(), memInfo.getJavaDesc()); + memInfo = (MemberInfo)memInfo.clone(); + memInfo.setJavaAccess(ACC_PUBLIC); + addGetter(className, memInfo); + addSetter(className, memInfo); + } + } + } + + addMapField(); + } + + private void emitStaticInitializer() { + final MethodGenerator mi = makeStaticInitializer(); + emitStaticInitPrefix(mi, className); + + for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (memInfo.isConstructorFunction() || memInfo.isConstructorProperty()) { + linkerAddGetterSetter(mi, className, memInfo); + } else if (memInfo.isConstructorGetter()) { + final MemberInfo setter = scriptClassInfo.findSetter(memInfo); + linkerAddGetterSetter(mi, className, memInfo, setter); + } + } + emitStaticInitSuffix(mi, className); + } + + private void emitConstructor() { + final MethodGenerator mi = makeConstructor(); + mi.visitCode(); + callSuper(mi); + + if (memberCount > 0) { + // initialize Function type fields + initFunctionFields(mi); + // initialize data fields + initDataFields(mi); + } + + if (constructor != null) { + final int arity = constructor.getArity(); + if (arity != MemberInfo.DEFAULT_ARITY) { + mi.loadThis(); + mi.push(arity); + mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETARITY, + SCRIPTFUNCTION_SETARITY_DESC); + } + } + mi.returnVoid(); + mi.computeMaxs(); + mi.visitEnd(); + } + + private void loadMap(final MethodGenerator mi) { + if (memberCount > 0) { + mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC); + // make sure we use duplicated PropertyMap so that original map + // stays intact and so can be used for many globals in same context + mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC); + } + } + + private void callSuper(final MethodGenerator mi) { + String superClass, superDesc; + mi.loadThis(); + if (constructor == null) { + // call ScriptObject. + superClass = SCRIPTOBJECT_TYPE; + superDesc = (memberCount > 0) ? SCRIPTOBJECT_INIT_DESC : DEFAULT_INIT_DESC; + loadMap(mi); + } else { + // call Function. + superClass = SCRIPTFUNCTIONIMPL_TYPE; + superDesc = (memberCount > 0) ? SCRIPTFUNCTIONIMPL_INIT_DESC4 : SCRIPTFUNCTIONIMPL_INIT_DESC3; + mi.loadLiteral(constructor.getName()); + mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc())); + loadMap(mi); + mi.memberInfoArray(scriptClassInfo.getJavaName(), specs); //pushes null if specs empty + } + + mi.invokeSpecial(superClass, INIT, superDesc); + } + + private void initFunctionFields(final MethodGenerator mi) { + for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (!memInfo.isConstructorFunction()) { + continue; + } + mi.loadThis(); + newFunction(mi, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName())); + mi.putField(className, memInfo.getJavaName(), OBJECT_DESC); + } + } + + private void initDataFields(final MethodGenerator mi) { + for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (!memInfo.isConstructorProperty() || memInfo.isFinal()) { + continue; + } + final Object value = memInfo.getValue(); + if (value != null) { + mi.loadThis(); + mi.loadLiteral(value); + mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc()); + } else if (!memInfo.getInitClass().isEmpty()) { + final String clazz = memInfo.getInitClass(); + mi.loadThis(); + mi.newObject(clazz); + mi.dup(); + mi.invokeSpecial(clazz, INIT, DEFAULT_INIT_DESC); + mi.putField(className, memInfo.getJavaName(), memInfo.getJavaDesc()); + } + } + + if (constructor != null) { + mi.loadThis(); + final String protoName = scriptClassInfo.getPrototypeClassName(); + mi.newObject(protoName); + mi.dup(); + mi.invokeSpecial(protoName, INIT, DEFAULT_INIT_DESC); + mi.dup(); + mi.loadThis(); + mi.invokeStatic(PROTOTYPEOBJECT_TYPE, PROTOTYPEOBJECT_SETCONSTRUCTOR, + PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC); + mi.putField(SCRIPTFUNCTION_TYPE, PROTOTYPE, OBJECT_DESC); + } + } + + /** + * Entry point for ConstructorGenerator run separately as an application. Will display + * usage. Takes one argument, a class name. + * @param args args vector + * @throws IOException if class can't be read + */ + public static void main(final String[] args) throws IOException { + if (args.length != 1) { + System.err.println("Usage: " + ConstructorGenerator.class.getName() + " "); + System.exit(1); + } + + final String className = args[0].replace('.', '/'); + final ScriptClassInfo sci = getScriptClassInfo(className + ".class"); + if (sci == null) { + System.err.println("No @ScriptClass in " + className); + System.exit(2); + throw new IOException(); // get rid of warning for sci.verify() below - may be null + } + + try { + sci.verify(); + } catch (final Exception e) { + System.err.println(e.getMessage()); + System.exit(3); + } + final ConstructorGenerator gen = new ConstructorGenerator(sci); + try (FileOutputStream fos = new FileOutputStream(className + CONSTRUCTOR_SUFFIX + ".class")) { + fos.write(gen.getClassBytes()); + } + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java new file mode 100644 index 00000000000..96e49c1df49 --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/Main.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; + +/** + * Main class for the "nasgen" tool. + * + */ +public class Main { + private static final boolean DEBUG = Boolean.getBoolean("nasgen.debug"); + + private interface ErrorReporter { + public void error(String msg); + } + + /** + * Public entry point for Nasgen if invoked from command line. Nasgen takes three arguments + * in order: input directory, package list, output directory + * + * @param args argument vector + */ + public static void main(final String[] args) { + final ErrorReporter reporter = new ErrorReporter() { + @Override + public void error(final String msg) { + Main.error(msg, 1); + } + }; + if (args.length == 3) { + processAll(args[0], args[1], args[2], reporter); + } else { + error("Usage: nasgen ", 1); + } + } + + private static void processAll(final String in, final String pkgList, final String out, final ErrorReporter reporter) { + final File inDir = new File(in); + if (!inDir.exists() || !inDir.isDirectory()) { + reporter.error(in + " does not exist or not a directory"); + return; + } + + final File outDir = new File(out); + if (!outDir.exists() || !outDir.isDirectory()) { + reporter.error(out + " does not exist or not a directory"); + return; + } + + final String[] packages = pkgList.split(":"); + for (String pkg : packages) { + pkg = pkg.replace('.', File.separatorChar); + final File dir = new File(inDir, pkg); + final File[] classes = dir.listFiles(); + for (final File clazz : classes) { + if (clazz.isFile() && clazz.getName().endsWith(".class")) { + if (! process(clazz, new File(outDir, pkg), reporter)) { + return; + } + } + } + } + } + + private static boolean process(final File inFile, final File outDir, final ErrorReporter reporter) { + try { + byte[] buf = new byte[(int)inFile.length()]; + + try (FileInputStream fin = new FileInputStream(inFile)) { + fin.read(buf); + } + + final ScriptClassInfo sci = ClassGenerator.getScriptClassInfo(buf); + + if (sci != null) { + try { + sci.verify(); + } catch (final Exception e) { + reporter.error(e.getMessage()); + return false; + } + + // create necessary output package dir + outDir.mkdirs(); + + // instrument @ScriptClass + final ClassWriter writer = ClassGenerator.makeClassWriter(); + final ClassReader reader = new ClassReader(buf); + final ScriptClassInstrumentor inst = new ScriptClassInstrumentor(writer, sci); + reader.accept(inst, 0); + //noinspection UnusedAssignment + + // write instrumented class + try (FileOutputStream fos = new FileOutputStream(new File(outDir, inFile.getName()))) { + buf = writer.toByteArray(); + if (DEBUG) { + verify(buf); + } + fos.write(buf); + } + + // simple class name without package prefix + String simpleName = inFile.getName(); + simpleName = simpleName.substring(0, simpleName.indexOf(".class")); + + if (sci.getPrototypeMemberCount() > 0) { + // generate prototype class + final PrototypeGenerator protGen = new PrototypeGenerator(sci); + buf = protGen.getClassBytes(); + if (DEBUG) { + verify(buf); + } + try (FileOutputStream fos = new FileOutputStream(new File(outDir, simpleName + StringConstants.PROTOTYPE_SUFFIX + ".class"))) { + fos.write(buf); + } + } + + if (sci.getConstructorMemberCount() > 0 || sci.getConstructor() != null) { + // generate constructor class + final ConstructorGenerator consGen = new ConstructorGenerator(sci); + buf = consGen.getClassBytes(); + if (DEBUG) { + verify(buf); + } + try (FileOutputStream fos = new FileOutputStream(new File(outDir, simpleName + StringConstants.CONSTRUCTOR_SUFFIX + ".class"))) { + fos.write(buf); + } + } + } + return true; + } catch (final IOException | RuntimeException e) { + if (DEBUG) { + e.printStackTrace(System.err); + } + reporter.error(e.getMessage()); + + return false; + } + } + + private static void verify(final byte[] buf) { + final ClassReader cr = new ClassReader(buf); + CheckClassAdapter.verify(cr, false, new PrintWriter(System.err)); + } + + private static void error(final String msg, final int exitCode) { + System.err.println(msg); + System.exit(exitCode); + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java new file mode 100644 index 00000000000..62e8de2a6bc --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MemberInfo.java @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; + +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.internal.org.objectweb.asm.Type; +import jdk.nashorn.internal.objects.annotations.Where; + +/** + * Details about a Java method or field annotated with any of the field/method + * annotations from the jdk.nashorn.internal.objects.annotations package. + */ +public final class MemberInfo implements Cloneable { + /** + * The different kinds of available class annotations + */ + public static enum Kind { + /** This is a script class */ + SCRIPT_CLASS, + /** This is a constructor */ + CONSTRUCTOR, + /** This is a function */ + FUNCTION, + /** This is a getter */ + GETTER, + /** This is a setter */ + SETTER, + /** This is a property */ + PROPERTY, + /** This is a specialized version of a function */ + SPECIALIZED_FUNCTION, + /** This is a specialized version of a constructor */ + SPECIALIZED_CONSTRUCTOR + } + + // keep in sync with jdk.nashorn.internal.objects.annotations.Attribute + static final int DEFAULT_ATTRIBUTES = 0x0; + + static final int DEFAULT_ARITY = -2; + + // the kind of the script annotation - one of the above constants + private MemberInfo.Kind kind; + // script property name + private String name; + // script property attributes + private int attributes; + // name of the java member + private String javaName; + // type descriptor of the java member + private String javaDesc; + // access bits of the Java field or method + private int javaAccess; + // initial value for static @Property fields + private Object value; + // class whose object is created to fill property value + private String initClass; + // arity of the Function or Constructor + private int arity; + + private Where where; + + /** + * @return the kind + */ + public Kind getKind() { + return kind; + } + + /** + * @param kind the kind to set + */ + public void setKind(final Kind kind) { + this.kind = kind; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(final String name) { + this.name = name; + } + + /** + * @return the attributes + */ + public int getAttributes() { + return attributes; + } + + /** + * @param attributes the attributes to set + */ + public void setAttributes(final int attributes) { + this.attributes = attributes; + } + + /** + * @return the javaName + */ + public String getJavaName() { + return javaName; + } + + /** + * @param javaName the javaName to set + */ + public void setJavaName(final String javaName) { + this.javaName = javaName; + } + + /** + * @return the javaDesc + */ + public String getJavaDesc() { + return javaDesc; + } + + void setJavaDesc(final String javaDesc) { + this.javaDesc = javaDesc; + } + + int getJavaAccess() { + return javaAccess; + } + + void setJavaAccess(final int access) { + this.javaAccess = access; + } + + Object getValue() { + return value; + } + + void setValue(final Object value) { + this.value = value; + } + + Where getWhere() { + return where; + } + + void setWhere(final Where where) { + this.where = where; + } + + boolean isFinal() { + return (javaAccess & Opcodes.ACC_FINAL) != 0; + } + + boolean isStatic() { + return (javaAccess & Opcodes.ACC_STATIC) != 0; + } + + boolean isStaticFinal() { + return isStatic() && isFinal(); + } + + boolean isInstanceGetter() { + return kind == Kind.GETTER && where == Where.INSTANCE; + } + + /** + * Check whether this MemberInfo is a getter that resides in the instance + * @return true if instance setter + */ + boolean isInstanceSetter() { + return kind == Kind.SETTER && where == Where.INSTANCE; + } + + boolean isInstanceProperty() { + return kind == Kind.PROPERTY && where == Where.INSTANCE; + } + + boolean isInstanceFunction() { + return kind == Kind.FUNCTION && where == Where.INSTANCE; + } + + boolean isPrototypeGetter() { + return kind == Kind.GETTER && where == Where.PROTOTYPE; + } + + boolean isPrototypeSetter() { + return kind == Kind.SETTER && where == Where.PROTOTYPE; + } + + boolean isPrototypeProperty() { + return kind == Kind.PROPERTY && where == Where.PROTOTYPE; + } + + boolean isPrototypeFunction() { + return kind == Kind.FUNCTION && where == Where.PROTOTYPE; + } + + boolean isConstructorGetter() { + return kind == Kind.GETTER && where == Where.CONSTRUCTOR; + } + + boolean isConstructorSetter() { + return kind == Kind.SETTER && where == Where.CONSTRUCTOR; + } + + boolean isConstructorProperty() { + return kind == Kind.PROPERTY && where == Where.CONSTRUCTOR; + } + + boolean isConstructorFunction() { + return kind == Kind.FUNCTION && where == Where.CONSTRUCTOR; + } + + boolean isConstructor() { + return kind == Kind.CONSTRUCTOR; + } + + void verify() { + if (kind == Kind.CONSTRUCTOR) { + final Type returnType = Type.getReturnType(javaDesc); + if (! returnType.toString().equals(OBJECT_DESC)) { + error("return value should be of Object type, found" + returnType); + } + final Type[] argTypes = Type.getArgumentTypes(javaDesc); + if (argTypes.length < 2) { + error("constructor methods should have at least 2 args"); + } + if (! argTypes[0].equals(Type.BOOLEAN_TYPE)) { + error("first argument should be of boolean type, found" + argTypes[0]); + } + if (! argTypes[1].toString().equals(OBJECT_DESC)) { + error("second argument should be of Object type, found" + argTypes[0]); + } + + if (argTypes.length > 2) { + for (int i = 2; i < argTypes.length - 1; i++) { + if (! argTypes[i].toString().equals(OBJECT_DESC)) { + error(i + "'th argument should be of Object type, found " + argTypes[i]); + } + } + + final String lastArgType = argTypes[argTypes.length - 1].toString(); + final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC); + if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) { + error("last argument is neither Object nor Object[] type: " + lastArgType); + } + + if (isVarArg && argTypes.length > 3) { + error("vararg constructor has more than 3 arguments"); + } + } + } else if (kind == Kind.FUNCTION) { + final Type returnType = Type.getReturnType(javaDesc); + if (! returnType.toString().equals(OBJECT_DESC)) { + error("return value should be of Object type, found" + returnType); + } + final Type[] argTypes = Type.getArgumentTypes(javaDesc); + if (argTypes.length < 1) { + error("function methods should have at least 1 arg"); + } + if (! argTypes[0].toString().equals(OBJECT_DESC)) { + error("first argument should be of Object type, found" + argTypes[0]); + } + + if (argTypes.length > 1) { + for (int i = 1; i < argTypes.length - 1; i++) { + if (! argTypes[i].toString().equals(OBJECT_DESC)) { + error(i + "'th argument should be of Object type, found " + argTypes[i]); + } + } + + final String lastArgType = argTypes[argTypes.length - 1].toString(); + final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC); + if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) { + error("last argument is neither Object nor Object[] type: " + lastArgType); + } + + if (isVarArg && argTypes.length > 2) { + error("vararg function has more than 2 arguments"); + } + } + } else if (kind == Kind.GETTER) { + final Type[] argTypes = Type.getArgumentTypes(javaDesc); + if (argTypes.length != 1) { + error("getter methods should have one argument"); + } + if (! argTypes[0].toString().equals(OBJECT_DESC)) { + error("first argument of getter should be of Object type, found: " + argTypes[0]); + } + if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) { + error("return type of getter should not be void"); + } + } else if (kind == Kind.SETTER) { + final Type[] argTypes = Type.getArgumentTypes(javaDesc); + if (argTypes.length != 2) { + error("setter methods should have two arguments"); + } + if (! argTypes[0].toString().equals(OBJECT_DESC)) { + error("first argument of setter should be of Object type, found: " + argTypes[0]); + } + if (!Type.getReturnType(javaDesc).toString().equals("V")) { + error("return type of setter should be void, found: " + Type.getReturnType(javaDesc)); + } + } + } + + private void error(final String msg) { + throw new RuntimeException(javaName + javaDesc + " : " + msg); + } + + /** + * @return the initClass + */ + String getInitClass() { + return initClass; + } + + /** + * @param initClass the initClass to set + */ + void setInitClass(final String initClass) { + this.initClass = initClass; + } + + @Override + protected Object clone() { + try { + return super.clone(); + } catch (final CloneNotSupportedException e) { + assert false : "clone not supported " + e; + return null; + } + } + + /** + * @return the arity + */ + int getArity() { + return arity; + } + + /** + * @param arity the arity to set + */ + void setArity(final int arity) { + this.arity = arity; + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java new file mode 100644 index 00000000000..500b8224946 --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import static jdk.internal.org.objectweb.asm.Opcodes.AALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.AASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.ACONST_NULL; +import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.ANEWARRAY; +import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN; +import static jdk.internal.org.objectweb.asm.Opcodes.ASM4; +import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.BALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.BASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.BIPUSH; +import static jdk.internal.org.objectweb.asm.Opcodes.CALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.CASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST; +import static jdk.internal.org.objectweb.asm.Opcodes.DALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.DASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.DCONST_0; +import static jdk.internal.org.objectweb.asm.Opcodes.DRETURN; +import static jdk.internal.org.objectweb.asm.Opcodes.DUP; +import static jdk.internal.org.objectweb.asm.Opcodes.DUP2; +import static jdk.internal.org.objectweb.asm.Opcodes.FALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.FASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.FCONST_0; +import static jdk.internal.org.objectweb.asm.Opcodes.FRETURN; +import static jdk.internal.org.objectweb.asm.Opcodes.GETFIELD; +import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.IALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0; +import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL; +import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL; +import static jdk.internal.org.objectweb.asm.Opcodes.IRETURN; +import static jdk.internal.org.objectweb.asm.Opcodes.ISTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.LALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.LASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0; +import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN; +import static jdk.internal.org.objectweb.asm.Opcodes.NEW; +import static jdk.internal.org.objectweb.asm.Opcodes.POP; +import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD; +import static jdk.internal.org.objectweb.asm.Opcodes.PUTSTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.RETURN; +import static jdk.internal.org.objectweb.asm.Opcodes.SALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.SASTORE; +import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH; +import static jdk.internal.org.objectweb.asm.Opcodes.SWAP; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.METHODHANDLE_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.TYPE_METHODHANDLE; + +import java.util.List; +import jdk.internal.org.objectweb.asm.Handle; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Type; + +/** + * Base class for all method generating classes. + * + */ +public class MethodGenerator extends MethodVisitor { + private final int access; + private final String name; + private final String descriptor; + private final Type returnType; + private final Type[] argumentTypes; + + MethodGenerator(final MethodVisitor mv, final int access, final String name, final String descriptor) { + super(ASM4, mv); + this.access = access; + this.name = name; + this.descriptor = descriptor; + this.returnType = Type.getReturnType(descriptor); + this.argumentTypes = Type.getArgumentTypes(descriptor); + } + + int getAccess() { + return access; + } + + final String getName() { + return name; + } + + final String getDescriptor() { + return descriptor; + } + + final Type getReturnType() { + return returnType; + } + + final Type[] getArgumentTypes() { + return argumentTypes; + } + + /** + * Check whether access for this method is static + * @return true if static + */ + protected final boolean isStatic() { + return (getAccess() & ACC_STATIC) != 0; + } + + /** + * Check whether this method is a constructor + * @return true if constructor + */ + protected final boolean isConstructor() { + return "".equals(name); + } + + void newObject(final String type) { + super.visitTypeInsn(NEW, type); + } + + void newObjectArray(final String type) { + super.visitTypeInsn(ANEWARRAY, type); + } + + void loadThis() { + if ((access & ACC_STATIC) != 0) { + throw new IllegalStateException("no 'this' inside static method"); + } + super.visitVarInsn(ALOAD, 0); + } + + void returnValue() { + super.visitInsn(returnType.getOpcode(IRETURN)); + } + + void returnVoid() { + super.visitInsn(RETURN); + } + + // load, store + void arrayLoad(final Type type) { + super.visitInsn(type.getOpcode(IALOAD)); + } + + void arrayLoad() { + super.visitInsn(AALOAD); + } + + void arrayStore(final Type type) { + super.visitInsn(type.getOpcode(IASTORE)); + } + + void arrayStore() { + super.visitInsn(AASTORE); + } + + void loadLiteral(final Object value) { + super.visitLdcInsn(value); + } + + void classLiteral(final String className) { + super.visitLdcInsn(className); + } + + void loadLocal(final Type type, final int index) { + super.visitVarInsn(type.getOpcode(ILOAD), index); + } + + void loadLocal(final int index) { + super.visitVarInsn(ALOAD, index); + } + + void storeLocal(final Type type, final int index) { + super.visitVarInsn(type.getOpcode(ISTORE), index); + } + + void storeLocal(final int index) { + super.visitVarInsn(ASTORE, index); + } + + void checkcast(final String type) { + super.visitTypeInsn(CHECKCAST, type); + } + + // push constants/literals + void pushNull() { + super.visitInsn(ACONST_NULL); + } + + void push(final int value) { + if (value >= -1 && value <= 5) { + super.visitInsn(ICONST_0 + value); + } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { + super.visitIntInsn(BIPUSH, value); + } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { + super.visitIntInsn(SIPUSH, value); + } else { + super.visitLdcInsn(value); + } + } + + void loadClass(final String className) { + super.visitLdcInsn(Type.getObjectType(className)); + } + + void pop() { + super.visitInsn(POP); + } + + // various "dups" + void dup() { + super.visitInsn(DUP); + } + + void dup2() { + super.visitInsn(DUP2); + } + + void swap() { + super.visitInsn(SWAP); + } + + void dupArrayValue(final int arrayOpcode) { + switch (arrayOpcode) { + case IALOAD: case FALOAD: + case AALOAD: case BALOAD: + case CALOAD: case SALOAD: + case IASTORE: case FASTORE: + case AASTORE: case BASTORE: + case CASTORE: case SASTORE: + dup(); + break; + + case LALOAD: case DALOAD: + case LASTORE: case DASTORE: + dup2(); + break; + default: + throw new AssertionError("invalid dup"); + } + } + + void dupReturnValue(final int returnOpcode) { + switch (returnOpcode) { + case IRETURN: + case FRETURN: + case ARETURN: + super.visitInsn(DUP); + return; + case LRETURN: + case DRETURN: + super.visitInsn(DUP2); + return; + case RETURN: + return; + default: + throw new IllegalArgumentException("not return"); + } + } + + void dupValue(final Type type) { + switch (type.getSize()) { + case 1: + dup(); + break; + case 2: + dup2(); + break; + default: + throw new AssertionError("invalid dup"); + } + } + + void dupValue(final String desc) { + final int typeCode = desc.charAt(0); + switch (typeCode) { + case '[': + case 'L': + case 'Z': + case 'C': + case 'B': + case 'S': + case 'I': + super.visitInsn(DUP); + break; + case 'J': + case 'D': + super.visitInsn(DUP2); + break; + default: + throw new RuntimeException("invalid signature"); + } + } + + // push default value of given type desc + void defaultValue(final String desc) { + final int typeCode = desc.charAt(0); + switch (typeCode) { + case '[': + case 'L': + super.visitInsn(ACONST_NULL); + break; + case 'Z': + case 'C': + case 'B': + case 'S': + case 'I': + super.visitInsn(ICONST_0); + break; + case 'J': + super.visitInsn(LCONST_0); + break; + case 'F': + super.visitInsn(FCONST_0); + break; + case 'D': + super.visitInsn(DCONST_0); + break; + default: + throw new AssertionError("invalid desc " + desc); + } + } + + // invokes, field get/sets + void invokeVirtual(final String owner, final String method, final String desc) { + super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc); + } + + void invokeSpecial(final String owner, final String method, final String desc) { + super.visitMethodInsn(INVOKESPECIAL, owner, method, desc); + } + + void invokeStatic(final String owner, final String method, final String desc) { + super.visitMethodInsn(INVOKESTATIC, owner, method, desc); + } + + void putStatic(final String owner, final String field, final String desc) { + super.visitFieldInsn(PUTSTATIC, owner, field, desc); + } + + void getStatic(final String owner, final String field, final String desc) { + super.visitFieldInsn(GETSTATIC, owner, field, desc); + } + + void putField(final String owner, final String field, final String desc) { + super.visitFieldInsn(PUTFIELD, owner, field, desc); + } + + void getField(final String owner, final String field, final String desc) { + super.visitFieldInsn(GETFIELD, owner, field, desc); + } + + void memberInfoArray(final String className, final List mis) { + if (mis.isEmpty()) { + pushNull(); + return; + } + + int pos = 0; + push(mis.size()); + newObjectArray(METHODHANDLE_TYPE); + for (final MemberInfo mi : mis) { + dup(); + push(pos++); + visitLdcInsn(new Handle(H_INVOKESTATIC, className, mi.getJavaName(), mi.getJavaDesc())); + arrayStore(TYPE_METHODHANDLE); + } + } + + void computeMaxs() { + // These values are ignored as we create class writer + // with ClassWriter.COMPUTE_MAXS flag. + super.visitMaxs(Short.MAX_VALUE, Short.MAX_VALUE); + } + + // debugging support - print calls + void println(final String msg) { + super.visitFieldInsn(GETSTATIC, + "java/lang/System", + "out", + "Ljava/io/PrintStream;"); + super.visitLdcInsn(msg); + super.visitMethodInsn(INVOKEVIRTUAL, + "java/io/PrintStream", + "println", + "(Ljava/lang/String;)V"); + } + + // print the object on the top of the stack + void printObject() { + super.visitFieldInsn(GETSTATIC, + "java/lang/System", + "out", + "Ljava/io/PrintStream;"); + super.visitInsn(SWAP); + super.visitMethodInsn(INVOKEVIRTUAL, + "java/io/PrintStream", + "println", + "(Ljava/lang/Object;)V"); + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java new file mode 100644 index 00000000000..7f585c0392b --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/NullVisitor.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import jdk.internal.org.objectweb.asm.AnnotationVisitor; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.FieldVisitor; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; + +/** + * A visitor that does nothing on visitXXX calls. + * + */ +public class NullVisitor extends ClassVisitor { + NullVisitor() { + super(Opcodes.ASM4); + } + + @Override + public MethodVisitor visitMethod( + final int access, + final String name, + final String desc, + final String signature, + final String[] exceptions) { + return new MethodVisitor(Opcodes.ASM4) { + @Override + public AnnotationVisitor visitAnnotationDefault() { + return new NullAnnotationVisitor(); + } + + @Override + public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { + return new NullAnnotationVisitor(); + } + }; + } + + @Override + public FieldVisitor visitField( + final int access, + final String name, + final String desc, + final String signature, + final Object value) { + return new FieldVisitor(Opcodes.ASM4) { + @Override + public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { + return new NullAnnotationVisitor(); + } + }; + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { + return new NullAnnotationVisitor(); + } + + private static class NullAnnotationVisitor extends AnnotationVisitor { + NullAnnotationVisitor() { + super(Opcodes.ASM4); + } + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java new file mode 100644 index 00000000000..a8b6e639b4e --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER; +import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC; + +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * This class generates prototype class for a @ClassInfo annotated class. + * + */ +public class PrototypeGenerator extends ClassGenerator { + private final ScriptClassInfo scriptClassInfo; + private final String className; + private final int memberCount; + + PrototypeGenerator(final ScriptClassInfo sci) { + this.scriptClassInfo = sci; + this.className = scriptClassInfo.getPrototypeClassName(); + this.memberCount = scriptClassInfo.getPrototypeMemberCount(); + } + + byte[] getClassBytes() { + // new class extensing from ScriptObject + cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, PROTOTYPEOBJECT_TYPE, null); + if (memberCount > 0) { + // add fields + emitFields(); + // add + emitStaticInitializer(); + } + // add + emitConstructor(); + + // add getClassName() + emitGetClassName(scriptClassInfo.getName()); + + cw.visitEnd(); + return cw.toByteArray(); + } + + // --Internals only below this point + private void emitFields() { + // introduce "Function" type instance fields for each + // prototype @Function in script class info + for (MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (memInfo.isPrototypeFunction()) { + addFunctionField(memInfo.getJavaName()); + memInfo = (MemberInfo)memInfo.clone(); + memInfo.setJavaDesc(OBJECT_DESC); + addGetter(className, memInfo); + addSetter(className, memInfo); + } else if (memInfo.isPrototypeProperty()) { + if (memInfo.isStaticFinal()) { + addGetter(scriptClassInfo.getJavaName(), memInfo); + } else { + addField(memInfo.getJavaName(), memInfo.getJavaDesc()); + memInfo = (MemberInfo)memInfo.clone(); + memInfo.setJavaAccess(ACC_PUBLIC); + addGetter(className, memInfo); + addSetter(className, memInfo); + } + } + } + + addMapField(); + } + + private void emitStaticInitializer() { + final MethodGenerator mi = makeStaticInitializer(); + emitStaticInitPrefix(mi, className); + for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (memInfo.isPrototypeFunction() || memInfo.isPrototypeProperty()) { + linkerAddGetterSetter(mi, className, memInfo); + } else if (memInfo.isPrototypeGetter()) { + final MemberInfo setter = scriptClassInfo.findSetter(memInfo); + linkerAddGetterSetter(mi, className, memInfo, setter); + } + } + emitStaticInitSuffix(mi, className); + } + + private void emitConstructor() { + final MethodGenerator mi = makeConstructor(); + mi.visitCode(); + mi.loadThis(); + if (memberCount > 0) { + // call "super(map$)" + mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC); + // make sure we use duplicated PropertyMap so that original map + // stays intact and so can be used for many globals in same context + mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC); + mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC); + // initialize Function type fields + initFunctionFields(mi); + } else { + // call "super()" + mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, DEFAULT_INIT_DESC); + } + mi.returnVoid(); + mi.computeMaxs(); + mi.visitEnd(); + } + + private void initFunctionFields(final MethodGenerator mi) { + for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (! memInfo.isPrototypeFunction()) { + continue; + } + mi.loadThis(); + newFunction(mi, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName())); + mi.putField(className, memInfo.getJavaName(), OBJECT_DESC); + } + } + + /** + * External entry point for PrototypeGenerator if called from the command line + * + * @param args arguments, takes 1 argument which is the class to process + * @throws IOException if class cannot be read + */ + public static void main(final String[] args) throws IOException { + if (args.length != 1) { + System.err.println("Usage: " + ConstructorGenerator.class.getName() + " "); + System.exit(1); + } + + final String className = args[0].replace('.', '/'); + final ScriptClassInfo sci = getScriptClassInfo(className + ".class"); + if (sci == null) { + System.err.println("No @ScriptClass in " + className); + System.exit(2); + throw new AssertionError(); //guard against warning that sci is null below + } + try { + sci.verify(); + } catch (final Exception e) { + System.err.println(e.getMessage()); + System.exit(3); + } + final PrototypeGenerator gen = new PrototypeGenerator(sci); + try (FileOutputStream fos = new FileOutputStream(className + PROTOTYPE_SUFFIX + ".class")) { + fos.write(gen.getClassBytes()); + } + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java new file mode 100644 index 00000000000..b5e285225c5 --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfo.java @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import jdk.internal.org.objectweb.asm.Type; +import jdk.nashorn.internal.objects.annotations.Constructor; +import jdk.nashorn.internal.objects.annotations.Function; +import jdk.nashorn.internal.objects.annotations.Getter; +import jdk.nashorn.internal.objects.annotations.Property; +import jdk.nashorn.internal.objects.annotations.ScriptClass; +import jdk.nashorn.internal.objects.annotations.Setter; +import jdk.nashorn.internal.objects.annotations.SpecializedConstructor; +import jdk.nashorn.internal.objects.annotations.SpecializedFunction; +import jdk.nashorn.internal.objects.annotations.Where; +import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind; + +/** + * All annotation information from a class that is annotated with + * the annotation com.sun.oracle.objects.annotations.ScriptClass. + * + */ +public final class ScriptClassInfo { + // descriptots for various annotations + static final String SCRIPT_CLASS_ANNO_DESC = Type.getDescriptor(ScriptClass.class); + static final String CONSTRUCTOR_ANNO_DESC = Type.getDescriptor(Constructor.class); + static final String FUNCTION_ANNO_DESC = Type.getDescriptor(Function.class); + static final String GETTER_ANNO_DESC = Type.getDescriptor(Getter.class); + static final String SETTER_ANNO_DESC = Type.getDescriptor(Setter.class); + static final String PROPERTY_ANNO_DESC = Type.getDescriptor(Property.class); + static final String WHERE_ENUM_DESC = Type.getDescriptor(Where.class); + static final String SPECIALIZED_FUNCTION = Type.getDescriptor(SpecializedFunction.class); + static final String SPECIALIZED_CONSTRUCTOR = Type.getDescriptor(SpecializedConstructor.class); + + static final Map annotations = new HashMap<>(); + + static { + annotations.put(SCRIPT_CLASS_ANNO_DESC, Kind.SCRIPT_CLASS); + annotations.put(FUNCTION_ANNO_DESC, Kind.FUNCTION); + annotations.put(CONSTRUCTOR_ANNO_DESC, Kind.CONSTRUCTOR); + annotations.put(GETTER_ANNO_DESC, Kind.GETTER); + annotations.put(SETTER_ANNO_DESC, Kind.SETTER); + annotations.put(PROPERTY_ANNO_DESC, Kind.PROPERTY); + annotations.put(SPECIALIZED_FUNCTION, Kind.SPECIALIZED_FUNCTION); + annotations.put(SPECIALIZED_CONSTRUCTOR, Kind.SPECIALIZED_CONSTRUCTOR); + } + + // name of the script class + private String name; + // member info for script properties + private List members = Collections.emptyList(); + // java class name that is annotated with @ScriptClass + private String javaName; + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(final String name) { + this.name = name; + } + + /** + * @return the members + */ + public List getMembers() { + return Collections.unmodifiableList(members); + } + + /** + * @param members the members to set + */ + public void setMembers(final List members) { + this.members = members; + } + + MemberInfo getConstructor() { + for (final MemberInfo memInfo : members) { + if (memInfo.getKind() == Kind.CONSTRUCTOR) { + return memInfo; + } + } + return null; + } + + List getSpecializedConstructors() { + final List res = new LinkedList<>(); + for (final MemberInfo memInfo : members) { + if (memInfo.getKind() == Kind.SPECIALIZED_CONSTRUCTOR) { + res.add(memInfo); + } + } + return res; + } + + int getPrototypeMemberCount() { + int count = 0; + for (final MemberInfo memInfo : members) { + if (memInfo.getWhere() == Where.PROTOTYPE || memInfo.isConstructor()) { + count++; + } + } + return count; + } + + int getConstructorMemberCount() { + int count = 0; + for (final MemberInfo memInfo : members) { + if (memInfo.getWhere() == Where.CONSTRUCTOR) { + count++; + } + } + return count; + } + + int getInstancePropertyCount() { + int count = 0; + for (final MemberInfo memInfo : members) { + if (memInfo.getWhere() == Where.INSTANCE) { + count++; + } + } + return count; + } + + MemberInfo find(final String findJavaName, final String findJavaDesc, final int findAccess) { + for (final MemberInfo memInfo : members) { + if (memInfo.getJavaName().equals(findJavaName) && + memInfo.getJavaDesc().equals(findJavaDesc) && + memInfo.getJavaAccess() == findAccess) { + return memInfo; + } + } + return null; + } + + List findSpecializations(final String methodName) { + final List res = new LinkedList<>(); + for (final MemberInfo memInfo : members) { + if (memInfo.getName().equals(methodName) && + memInfo.getKind() == Kind.SPECIALIZED_FUNCTION) { + res.add(memInfo); + } + } + return res; + } + + MemberInfo findSetter(final MemberInfo getter) { + assert getter.getKind() == Kind.GETTER : "getter expected"; + final String getterName = getter.getName(); + final Where getterWhere = getter.getWhere(); + for (final MemberInfo memInfo : members) { + if (memInfo.getKind() == Kind.SETTER && + getterName.equals(memInfo.getName()) && + getterWhere == memInfo.getWhere()) { + return memInfo; + } + } + return null; + } + + /** + * @return the javaName + */ + public String getJavaName() { + return javaName; + } + + /** + * @param javaName the javaName to set + */ + void setJavaName(final String javaName) { + this.javaName = javaName; + } + + String getConstructorClassName() { + return getJavaName() + StringConstants.CONSTRUCTOR_SUFFIX; + } + + String getPrototypeClassName() { + return getJavaName() + StringConstants.PROTOTYPE_SUFFIX; + } + + void verify() { + boolean constructorSeen = false; + for (final MemberInfo memInfo : getMembers()) { + if (memInfo.isConstructor()) { + if (constructorSeen) { + error("more than @Constructor method"); + } + constructorSeen = true; + } + try { + memInfo.verify(); + } catch (final Exception e) { + error(e.getMessage()); + } + } + } + + private void error(final String msg) throws RuntimeException { + throw new RuntimeException(javaName + " : " + msg); + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java new file mode 100644 index 00000000000..43c2bc6c6ea --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInfoCollector.java @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.SCRIPT_CLASS_ANNO_DESC; +import static jdk.nashorn.internal.tools.nasgen.ScriptClassInfo.WHERE_ENUM_DESC; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import jdk.internal.org.objectweb.asm.AnnotationVisitor; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.FieldVisitor; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.nashorn.internal.objects.annotations.Where; +import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind; + +/** + * This class collects all @ScriptClass and other annotation information from a + * compiled .class file. Enforces that @Function/@Getter/@Setter/@Constructor + * methods are declared to be 'static'. + */ +public class ScriptClassInfoCollector extends ClassVisitor { + private String scriptClassName; + private List scriptMembers; + private String javaClassName; + + ScriptClassInfoCollector(final ClassVisitor visitor) { + super(Opcodes.ASM4, visitor); + } + + ScriptClassInfoCollector() { + this(new NullVisitor()); + } + + private void addScriptMember(final MemberInfo memInfo) { + if (scriptMembers == null) { + scriptMembers = new ArrayList<>(); + } + scriptMembers.add(memInfo); + } + + @Override + public void visit(final int version, final int access, final String name, final String signature, + final String superName, final String[] interfaces) { + super.visit(version, access, name, signature, superName, interfaces); + javaClassName = name; + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { + final AnnotationVisitor delegateAV = super.visitAnnotation(desc, visible); + if (SCRIPT_CLASS_ANNO_DESC.equals(desc)) { + return new AnnotationVisitor(Opcodes.ASM4, delegateAV) { + @Override + public void visit(final String name, final Object value) { + if ("value".equals(name)) { + scriptClassName = (String) value; + } + super.visit(name, value); + } + }; + } + + return delegateAV; + } + + @Override + public FieldVisitor visitField(final int fieldAccess, final String fieldName, final String fieldDesc, final String signature, final Object value) { + final FieldVisitor delegateFV = super.visitField(fieldAccess, fieldName, fieldDesc, signature, value); + + return new FieldVisitor(Opcodes.ASM4, delegateFV) { + @Override + public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { + final AnnotationVisitor delegateAV = super.visitAnnotation(descriptor, visible); + + if (ScriptClassInfo.PROPERTY_ANNO_DESC.equals(descriptor)) { + final MemberInfo memInfo = new MemberInfo(); + + memInfo.setKind(Kind.PROPERTY); + memInfo.setJavaName(fieldName); + memInfo.setJavaDesc(fieldDesc); + memInfo.setJavaAccess(fieldAccess); + + if ((fieldAccess & Opcodes.ACC_STATIC) != 0) { + memInfo.setValue(value); + } + + addScriptMember(memInfo); + + return new AnnotationVisitor(Opcodes.ASM4, delegateAV) { + // These could be "null" if values are not suppiled, + // in which case we have to use the default values. + private String name; + private Integer attributes; + private String clazz = ""; + private Where where; + + @Override + public void visit(final String annotationName, final Object annotationValue) { + switch (annotationName) { + case "name": + this.name = (String) annotationValue; + break; + case "attributes": + this.attributes = (Integer) annotationValue; + break; + case "clazz": + this.clazz = (annotationValue == null) ? "" : annotationValue.toString(); + break; + default: + break; + } + super.visit(annotationName, annotationValue); + } + + @Override + public void visitEnum(final String enumName, final String desc, final String enumValue) { + if ("where".equals(enumName) && WHERE_ENUM_DESC.equals(desc)) { + this.where = Where.valueOf(enumValue); + } + super.visitEnum(enumName, desc, enumValue); + } + + @Override + public void visitEnd() { + super.visitEnd(); + memInfo.setName(name == null ? fieldName : name); + memInfo.setAttributes(attributes == null + ? MemberInfo.DEFAULT_ATTRIBUTES : attributes); + clazz = clazz.replace('.', '/'); + memInfo.setInitClass(clazz); + memInfo.setWhere(where == null? Where.INSTANCE : where); + } + }; + } + + return delegateAV; + } + }; + } + + private void error(final String javaName, final String javaDesc, final String msg) { + throw new RuntimeException(scriptClassName + "." + javaName + javaDesc + " : " + msg); + } + + @Override + public MethodVisitor visitMethod(final int methodAccess, final String methodName, + final String methodDesc, final String signature, final String[] exceptions) { + + final MethodVisitor delegateMV = super.visitMethod(methodAccess, methodName, methodDesc, + signature, exceptions); + + return new MethodVisitor(Opcodes.ASM4, delegateMV) { + + @Override + public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) { + final AnnotationVisitor delegateAV = super.visitAnnotation(descriptor, visible); + final Kind annoKind = ScriptClassInfo.annotations.get(descriptor); + + if (annoKind != null) { + if ((methodAccess & Opcodes.ACC_STATIC) == 0) { + error(methodName, methodDesc, "nasgen method annotations cannot be on instance methods"); + } + + final MemberInfo memInfo = new MemberInfo(); + + memInfo.setKind(annoKind); + memInfo.setJavaName(methodName); + memInfo.setJavaDesc(methodDesc); + memInfo.setJavaAccess(methodAccess); + + addScriptMember(memInfo); + + return new AnnotationVisitor(Opcodes.ASM4, delegateAV) { + // These could be "null" if values are not suppiled, + // in which case we have to use the default values. + private String name; + private Integer attributes; + private Integer arity; + private Where where; + + @Override + public void visit(final String annotationName, final Object annotationValue) { + switch (annotationName) { + case "name": + this.name = (String)annotationValue; + break; + case "attributes": + this.attributes = (Integer)annotationValue; + break; + case "arity": + this.arity = (Integer)annotationValue; + break; + default: + break; + } + + super.visit(annotationName, annotationValue); + } + + @Override + public void visitEnum(final String enumName, final String desc, final String enumValue) { + if ("where".equals(enumName) && WHERE_ENUM_DESC.equals(desc)) { + this.where = Where.valueOf(enumValue); + } + super.visitEnum(enumName, desc, enumValue); + } + + @Override + public void visitEnd() { + super.visitEnd(); + + if (memInfo.getKind() == Kind.CONSTRUCTOR) { + memInfo.setName(name == null ? scriptClassName : name); + } else { + memInfo.setName(name == null ? methodName : name); + } + memInfo.setAttributes(attributes == null ? MemberInfo.DEFAULT_ATTRIBUTES : attributes); + + memInfo.setArity((arity == null)? MemberInfo.DEFAULT_ARITY : arity); + if (where == null) { + // by default @Getter/@Setter belongs to INSTANCE + // @Function belong to PROTOTYPE. + switch (memInfo.getKind()) { + case GETTER: + case SETTER: + where = Where.INSTANCE; + break; + case SPECIALIZED_CONSTRUCTOR: + case CONSTRUCTOR: + where = Where.CONSTRUCTOR; + break; + case FUNCTION: + where = Where.PROTOTYPE; + break; + case SPECIALIZED_FUNCTION: + //TODO is this correct + default: + break; + } + } + memInfo.setWhere(where); + } + }; + } + + return delegateAV; + } + }; + } + + ScriptClassInfo getScriptClassInfo() { + ScriptClassInfo sci = null; + if (scriptClassName != null) { + sci = new ScriptClassInfo(); + sci.setName(scriptClassName); + if (scriptMembers == null) { + scriptMembers = Collections.emptyList(); + } + sci.setMembers(scriptMembers); + sci.setJavaName(javaClassName); + } + return sci; + } + + /** + * External entry point for ScriptClassInfoCollector if invoked from the command line + * @param args argument vector, args contains a class for which to collect info + * @throws IOException if there were problems parsing args or class + */ + public static void main(final String[] args) throws IOException { + if (args.length != 1) { + System.err.println("Usage: " + ScriptClassInfoCollector.class.getName() + " "); + System.exit(1); + } + + args[0] = args[0].replace('.', '/'); + final ScriptClassInfoCollector scic = new ScriptClassInfoCollector(); + try (final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(args[0] + ".class"))) { + final ClassReader reader = new ClassReader(bis); + reader.accept(scic, 0); + } + final ScriptClassInfo sci = scic.getScriptClassInfo(); + final PrintStream out = System.out; + if (sci != null) { + out.println("script class: " + sci.getName()); + out.println("==================================="); + for (final MemberInfo memInfo : sci.getMembers()) { + out.println("kind : " + memInfo.getKind()); + out.println("name : " + memInfo.getName()); + out.println("attributes: " + memInfo.getAttributes()); + out.println("javaName: " + memInfo.getJavaName()); + out.println("javaDesc: " + memInfo.getJavaDesc()); + out.println("where: " + memInfo.getWhere()); + out.println("====================================="); + } + } else { + out.println(args[0] + " is not a @ScriptClass"); + } + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java new file mode 100644 index 00000000000..c8e97370737 --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.DUP; +import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL; +import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.NEW; +import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD; +import static jdk.internal.org.objectweb.asm.Opcodes.RETURN; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.$CLINIT$; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import jdk.internal.org.objectweb.asm.AnnotationVisitor; +import jdk.internal.org.objectweb.asm.Attribute; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.FieldVisitor; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; +import jdk.nashorn.internal.objects.annotations.Where; +import jdk.nashorn.internal.tools.nasgen.MemberInfo.Kind; + +/** + * This class instruments the java class annotated with @ScriptClass. + * + * Changes done are: + * + * 1) remove all jdk.nashorn.internal.objects.annotations.* annotations. + * 2) static final @Property fields stay here. Other @Property fields moved to + * respective classes depending on 'where' value of annotation. + * 2) add "Map" type static field named "$map". + * 3) add static initializer block to initialize map. + */ + +public class ScriptClassInstrumentor extends ClassVisitor { + private final ScriptClassInfo scriptClassInfo; + private final int memberCount; + private boolean staticInitFound; + + ScriptClassInstrumentor(final ClassVisitor visitor, final ScriptClassInfo sci) { + super(Opcodes.ASM4, visitor); + if (sci == null) { + throw new IllegalArgumentException("Null ScriptClassInfo, is the class annotated?"); + } + this.scriptClassInfo = sci; + this.memberCount = scriptClassInfo.getInstancePropertyCount(); + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { + if (ScriptClassInfo.annotations.containsKey(desc)) { + // ignore @ScriptClass + return null; + } + + return super.visitAnnotation(desc, visible); + } + + @Override + public FieldVisitor visitField(final int fieldAccess, final String fieldName, + final String fieldDesc, final String signature, final Object value) { + final MemberInfo memInfo = scriptClassInfo.find(fieldName, fieldDesc, fieldAccess); + if (memInfo != null && memInfo.getKind() == Kind.PROPERTY && + memInfo.getWhere() != Where.INSTANCE && !memInfo.isStaticFinal()) { + // non-instance @Property fields - these have to go elsewhere unless 'static final' + return null; + } + + final FieldVisitor delegateFV = super.visitField(fieldAccess, fieldName, fieldDesc, + signature, value); + return new FieldVisitor(Opcodes.ASM4, delegateFV) { + @Override + public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { + if (ScriptClassInfo.annotations.containsKey(desc)) { + // ignore script field annotations + return null; + } + + return fv.visitAnnotation(desc, visible); + } + + @Override + public void visitAttribute(final Attribute attr) { + fv.visitAttribute(attr); + } + + @Override + public void visitEnd() { + fv.visitEnd(); + } + }; + } + + @Override + public MethodVisitor visitMethod(final int methodAccess, final String methodName, + final String methodDesc, final String signature, final String[] exceptions) { + + final boolean isConstructor = INIT.equals(methodName); + final boolean isStaticInit = CLINIT.equals(methodName); + + if (isStaticInit) { + staticInitFound = true; + } + + final MethodGenerator delegateMV = new MethodGenerator(super.visitMethod(methodAccess, methodName, methodDesc, + signature, exceptions), methodAccess, methodName, methodDesc); + + return new MethodVisitor(Opcodes.ASM4, delegateMV) { + @Override + public void visitInsn(final int opcode) { + // call $clinit$ just before return from + if (isStaticInit && opcode == RETURN) { + super.visitMethodInsn(INVOKESTATIC, scriptClassInfo.getJavaName(), + $CLINIT$, DEFAULT_INIT_DESC); + } + super.visitInsn(opcode); + } + + @Override + public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { + if (isConstructor && opcode == INVOKESPECIAL && + INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) { + super.visitFieldInsn(GETSTATIC, scriptClassInfo.getJavaName(), + MAP_FIELD_NAME, MAP_DESC); + super.visitMethodInsn(INVOKESPECIAL, SCRIPTOBJECT_TYPE, INIT, + SCRIPTOBJECT_INIT_DESC); + + if (memberCount > 0) { + // initialize @Property fields if needed + for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (memInfo.isInstanceProperty() && !memInfo.getInitClass().isEmpty()) { + final String clazz = memInfo.getInitClass(); + super.visitVarInsn(ALOAD, 0); + super.visitTypeInsn(NEW, clazz); + super.visitInsn(DUP); + super.visitMethodInsn(INVOKESPECIAL, clazz, + INIT, DEFAULT_INIT_DESC); + super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(), + memInfo.getJavaName(), memInfo.getJavaDesc()); + } + + if (memInfo.isInstanceFunction()) { + super.visitVarInsn(ALOAD, 0); + ClassGenerator.newFunction(delegateMV, scriptClassInfo.getJavaName(), memInfo, scriptClassInfo.findSpecializations(memInfo.getJavaName())); + super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(), + memInfo.getJavaName(), OBJECT_DESC); + } + } + } + } else { + super.visitMethodInsn(opcode, owner, name, desc); + } + } + + @Override + public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { + if (ScriptClassInfo.annotations.containsKey(desc)) { + // ignore script method annotations + return null; + } + return super.visitAnnotation(desc, visible); + } + }; + } + + @Override + public void visitEnd() { + emitFields(); + emitStaticInitializer(); + emitGettersSetters(); + super.visitEnd(); + } + + private void emitFields() { + // introduce "Function" type instance fields for each + // instance @Function in script class info + final String className = scriptClassInfo.getJavaName(); + for (MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (memInfo.isInstanceFunction()) { + ClassGenerator.addFunctionField(cv, memInfo.getJavaName()); + memInfo = (MemberInfo)memInfo.clone(); + memInfo.setJavaDesc(OBJECT_DESC); + ClassGenerator.addGetter(cv, className, memInfo); + ClassGenerator.addSetter(cv, className, memInfo); + } + } + ClassGenerator.addMapField(this); + } + + void emitGettersSetters() { + if (memberCount > 0) { + for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { + final String className = scriptClassInfo.getJavaName(); + if (memInfo.isInstanceProperty()) { + ClassGenerator.addGetter(cv, className, memInfo); + if (! memInfo.isFinal()) { + ClassGenerator.addSetter(cv, className, memInfo); + } + } + } + } + } + + private void emitStaticInitializer() { + final String className = scriptClassInfo.getJavaName(); + if (! staticInitFound) { + // no user written and so create one + final MethodVisitor mv = ClassGenerator.makeStaticInitializer(this); + mv.visitCode(); + mv.visitInsn(RETURN); + mv.visitMaxs(Short.MAX_VALUE, 0); + mv.visitEnd(); + } + // Now generate $clinit$ + final MethodGenerator mi = ClassGenerator.makeStaticInitializer(this, $CLINIT$); + ClassGenerator.emitStaticInitPrefix(mi, className); + if (memberCount > 0) { + for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { + if (memInfo.isInstanceProperty() || memInfo.isInstanceFunction()) { + ClassGenerator.linkerAddGetterSetter(mi, className, memInfo); + } else if (memInfo.isInstanceGetter()) { + final MemberInfo setter = scriptClassInfo.findSetter(memInfo); + ClassGenerator.linkerAddGetterSetter(mi, className, memInfo, setter); + } + } + } + ClassGenerator.emitStaticInitSuffix(mi, className); + } + + /** + * External entry point for ScriptClassInfoCollector if run from the command line + * + * @param args arguments - one argument is needed, the name of the class to collect info from + * + * @throws IOException if there are problems reading class + */ + public static void main(final String[] args) throws IOException { + if (args.length != 1) { + System.err.println("Usage: " + ScriptClassInfoCollector.class.getName() + " "); + System.exit(1); + } + + final String fileName = args[0].replace('.', '/') + ".class"; + final ScriptClassInfo sci = ClassGenerator.getScriptClassInfo(fileName); + if (sci == null) { + System.err.println("No @ScriptClass in " + fileName); + System.exit(2); + throw new AssertionError(); //guard against warning that sci is null below + } + + try { + sci.verify(); + } catch (final Exception e) { + System.err.println(e.getMessage()); + System.exit(3); + } + + final ClassWriter writer = ClassGenerator.makeClassWriter(); + try (final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName))) { + final ClassReader reader = new ClassReader(bis); + final CheckClassAdapter checker = new CheckClassAdapter(writer); + final ScriptClassInstrumentor instr = new ScriptClassInstrumentor(checker, sci); + reader.accept(instr, 0); + } + + try (FileOutputStream fos = new FileOutputStream(fileName)) { + fos.write(writer.toByteArray()); + } + } +} diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java new file mode 100644 index 00000000000..06032733e92 --- /dev/null +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.tools.nasgen; + +import java.lang.invoke.MethodHandle; +import java.lang.reflect.Method; +import jdk.internal.org.objectweb.asm.Type; +import jdk.nashorn.internal.objects.PrototypeObject; +import jdk.nashorn.internal.objects.ScriptFunctionImpl; +import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.ScriptFunction; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.linker.Lookup; + +/** + * String constants used for code generation/instrumentation. + */ +@SuppressWarnings("javadoc") +public interface StringConstants { + static final Type TYPE_METHOD = Type.getType(Method.class); + static final Type TYPE_METHODHANDLE = Type.getType(MethodHandle.class); + static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class); + static final Type TYPE_OBJECT = Type.getType(Object.class); + static final Type TYPE_CLASS = Type.getType(Class.class); + static final Type TYPE_STRING = Type.getType(String.class); + + // Nashorn types + static final Type TYPE_LOOKUP = Type.getType(Lookup.class); + static final Type TYPE_PROPERTYMAP = Type.getType(PropertyMap.class); + static final Type TYPE_PROTOTYPEOBJECT = Type.getType(PrototypeObject.class); + static final Type TYPE_SCRIPTFUNCTION = Type.getType(ScriptFunction.class); + static final Type TYPE_SCRIPTFUNCTIONIMPL = Type.getType(ScriptFunctionImpl.class); + static final Type TYPE_SCRIPTOBJECT = Type.getType(ScriptObject.class); + + static final String PROTOTYPE = "prototype"; + static final String PROTOTYPE_SUFFIX = "$Prototype"; + static final String CONSTRUCTOR_SUFFIX = "$Constructor"; + // This field name is known to Nashorn runtime (Context). + // Synchronize the name change, if needed at all. + static final String MAP_FIELD_NAME = "$nasgenmap$"; + static final String $CLINIT$ = "$clinit$"; + static final String CLINIT = ""; + static final String INIT = ""; + static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE); + + static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP); + + static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName(); + + static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName(); + static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor(); + static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class); + + static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName(); + static final String SCRIPTFUNCTIONIMPL_TYPE = TYPE_SCRIPTFUNCTIONIMPL.getInternalName(); + static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION = "makeFunction"; + static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC = + Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE); + static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC = + Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY); + + static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 = + Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY); + static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 = + Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_METHODHANDLE_ARRAY); + static final String SCRIPTFUNCTION_SETARITY = "setArity"; + static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE); + static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName(); + static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor"; + static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT); + static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName(); + static final String MAP_TYPE = TYPE_PROPERTYMAP.getInternalName(); + static final String MAP_DESC = TYPE_PROPERTYMAP.getDescriptor(); + static final String MAP_NEWMAP = "newMap"; + static final String MAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_CLASS); + static final String MAP_DUPLICATE = "duplicate"; + static final String MAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP); + static final String MAP_SETFLAGS = "setFlags"; + static final String LOOKUP_TYPE = TYPE_LOOKUP.getInternalName(); + static final String LOOKUP_GETMETHOD = "getMethod"; + static final String LOOKUP_NEWPROPERTY = "newProperty"; + static final String LOOKUP_NEWPROPERTY_DESC = + Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_PROPERTYMAP, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE); + static final String GETTER_PREFIX = "G$"; + static final String SETTER_PREFIX = "S$"; + + // ScriptObject.getClassName() method. + static final String GET_CLASS_NAME = "getClassName"; + static final String GET_CLASS_NAME_DESC = Type.getMethodDescriptor(TYPE_STRING); +} diff --git a/nashorn/docs/DEVELOPER_README b/nashorn/docs/DEVELOPER_README new file mode 100644 index 00000000000..747379bc87b --- /dev/null +++ b/nashorn/docs/DEVELOPER_README @@ -0,0 +1,445 @@ +This document describes system properties that are used for internal +debugging and instrumentation purposes, along with the system loggers, +which are used for the same thing. + +This document is intended as a developer resource, and it is not +needed as Nashorn documentation for normal usage. Flags and system +properties described herein are subject to change without notice. + +===================================== +1. System properties used internally +===================================== + +This documentation of the system property flags assume that the +default value of the flag is false, unless otherwise specified. + + +SYSTEM PROPERTY: -Dnashorn.callsiteaccess.debug + +See the description of the access logger below. This flag is +equivalent to enabling the access logger with "info" level. + + +SYSTEM PROPERTY: -Dnashorn.compiler.ints.disable + +This flag prevents ints and longs (non double values) from being used +for any primitive representation in the lowered IR. This is default +false, i.e Lower will attempt to use integer variables as long as it +can. For example, var x = 17 would try to use x as an integer, unless +other operations occur later that require coercion to wider type, for +example x *= 17.1; + + +SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic + +Arithmetic operations in Nashorn (except bitwise ones) typically +coerce the operands to doubles (as per the JavaScript spec). To switch +this off and remain in integer mode, for example for "var x = a&b; var +y = c&d; var z = x*y;", use this flag. This will force the +multiplication of variables that are ints to be done with the IMUL +bytecode and the result "z" to become an int. + +WARNING: Note that is is experimental only to ensure that type support +exists for all primitive types. The generated code is unsound. This +will be the case until we do optimizations based on it. There is a CR +in Nashorn to do better range analysis, and ensure that this is only +done where the operation can't overflow into a wider type. Currently +no overflow checking is done, so at the moment, until range analysis +has been completed, this option is turned off. + +We've experimented by using int arithmetic for everything and putting +overflow checks afterwards, which would recompute the operation with +the correct precision, but have yet to find a configuration where this +is faster than just using doubles directly, even if the int operation +does not overflow. Getting access to a JVM intrinsic that does branch +on overflow would probably alleviate this. + +There is also a problem with this optimistic approach if the symbol +happens to reside in a local variable slot in the bytecode, as those +are strongly typed. Then we would need to split large sections of +control flow, so this is probably not the right way to go, while range +analysis is. There is a large difference between integer bytecode +without overflow checks and double bytecode. The former is +significantly faster. + + +SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace= + +See the description of the codegen logger below. + + +SYSTEM_PROPERTY: -Dnashorn.fields.debug + +See the description on the fields logger below. + + +SYSTEM PROPERTY: -Dnashorn.fields.dual + +When this property is true, Nashorn will attempt to use primitive +fields for AccessorProperties (currently just AccessorProperties, not +spill properties). Memory footprint for script objects will increase, +as we need to maintain both a primitive field (a long) as well as an +Object field for the property value. Ints are represented as the 32 +low bits of the long fields. Doubles are represented as the +doubleToLongBits of their value. This way a single field can be used +for all primitive types. Packing and unpacking doubles to their bit +representation is intrinsified by the JVM and extremely fast. + +While dual fields in theory runs significantly faster than Object +fields due to reduction of boxing and memory allocation overhead, +there is still work to be done to make this a general purpose +solution. Research is ongoing. + +In the future, this might complement or be replaced by experimental +feature sun.misc.TaggedArray, which has been discussed on the mlvm +mailing list. TaggedArrays are basically a way to share data space +between primitives and references, and have the GC understand this. + +As long as only primitive values are written to the fields and enough +type information exists to make sure that any reads don't have to be +uselessly boxed and unboxed, this is significantly faster than the +standard "Objects only" approach that currently is the default. See +test/examples/dual-fields-micro.js for an example that runs twice as +fast with dual fields as without them. Here, the compiler, can +determine that we are dealing with numbers only throughout the entire +property life span of the properties involved. + +If a "real" object (not a boxed primitive) is written to a field that +has a primitive representation, its callsite is relinked and an Object +field is used forevermore for that particular field in that +PropertyMap and its children, even if primitives are later assigned to +it. + +As the amount of compile time type information is very small in a +dynamic language like JavaScript, it is frequently the case that +something has to be treated as an object, because we don't know any +better. In reality though, it is often a boxed primitive is stored to +an AccessorProperty. The fastest way to handle this soundly is to use +a callsite typecheck and avoid blowing the field up to an Object. We +never revert object fields to primitives. Ping-pong:ing back and forth +between primitive representation and Object representation would cause +fatal performance overhead, so this is not an option. + +For a general application the dual fields approach is still slower +than objects only fields in some places, about the same in most cases, +and significantly faster in very few. This is due the program using +primitives, but we still can't prove it. For example "local_var a = +call(); field = a;" may very well write a double to the field, but the +compiler dare not guess a double type if field is a local variable, +due to bytecode variables being strongly typed and later non +interchangeable. To get around this, the entire method would have to +be replaced and a continuation retained to restart from. We believe +that the next steps we should go through are instead: + +1) Implement method specialization based on callsite, as it's quite +frequently the case that numbers are passed around, but currently our +function nodes just have object types visible to the compiler. For +example "var b = 17; func(a,b,17)" is an example where two parameters +can be specialized, but the main version of func might also be called +from another callsite with func(x,y,"string"). + +2) This requires lazy jitting as the functions have to be specialized +per callsite. + +Even though "function square(x) { return x*x }" might look like a +trivial function that can always only take doubles, this is not +true. Someone might have overridden the valueOf for x so that the +toNumber coercion has side effects. To fulfil JavaScript semantics, +the coercion has to run twice for both terms of the multiplication +even if they are the same object. This means that call site +specialization is necessary, not parameter specialization on the form +"function square(x) { var xd = (double)x; return xd*xd; }", as one +might first think. + +Generating a method specialization for any variant of a function that +we can determine by types at compile time is a combinatorial explosion +of byte code (try it e.g. on all the variants of am3 in the Octane +benchmark crypto.js). Thus, this needs to be lazy + +3) Possibly optimistic callsite writes, something on the form + +x = y; //x is a field known to be a primitive. y is only an object as +far as we can tell + +turns into + +try { + x = (int)y; +} catch (X is not an integer field right now | ClassCastException e) { + x = y; +} + +Mini POC shows that this is the key to a lot of dual field performance +in seemingly trivial micros where one unknown object, in reality +actually a primitive, foils it for us. Very common pattern. Once we +are "all primitives", dual fields runs a lot faster than Object fields +only. + +We still have to deal with objects vs primitives for local bytecode +slots, possibly through code copying and versioning. + + +SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace= + +When this property is set, creation and manipulation of any symbol +named "x" will show information about when the compiler changes its +type assumption, bytecode local variable slot assignment and other +data. This is useful if, for example, a symbol shows up as an Object, +when you believe it should be a primitive. Usually there is an +explanation for this, for example that it exists in the global scope +and type analysis has to be more conservative. In that case, the stack +trace upon type change to object will usually tell us why. + + +SYSTEM PROPERTY: nashorn.lexer.xmlliterals + +If this property it set, it means that the Lexer should attempt to +parse XML literals, which would otherwise generate syntax +errors. Warning: there are currently no unit tests for this +functionality. + +XML literals, when this is enabled, end up as standard LiteralNodes in +the IR. + + +SYSTEM_PROPERTY: nashorn.debug + +If this property is set to true, Nashorn runs in Debug mode. Debug +mode is slightly slower, as for example statistics counters are enabled +during the run. Debug mode makes available a NativeDebug instance +called "Debug" in the global space that can be used to print property +maps and layout for script objects, as well as a "dumpCounters" method +that will print the current values of the previously mentioned stats +counters. + +These functions currently exists for Debug: + +"map" - print(Debug.map(x)) will dump the PropertyMap for object x to +stdout (currently there also exist functions called "embedX", where X +is a value from 0 to 3, that will dump the contents of the embed pool +for the first spill properties in any script object and "spill", that +will dump the contents of the growing spill pool of spill properties +in any script object. This is of course subject to change without +notice, should we change the script object layout. + +"methodHandle" - this method returns the method handle that is used +for invoking a particular script function. + +"identical" - this method compares two script objects for reference +equality. It is a == Java comparison + +"dumpCounters" - will dump the debug counters' current values to +stdout. + +Currently we count number of ScriptObjects in the system, number of +Scope objects in the system, number of ScriptObject listeners added, +removed and dead (without references). + +We also count number of ScriptFunctions, ScriptFunction invocations +and ScriptFunction allocations. + +Furthermore we count PropertyMap statistics: how many property maps +exist, how many times were property maps cloned, how many times did +the property map history cache hit, prevent new allocations, how many +prototype invalidations were done, how many time the property map +proto cache hit. + +Finally we count callsite misses on a per callsite bases, which occur +when a callsite has to be relinked, due to a previous assumption of +object layout being invalidated. + + +SYSTEM PROPERTY: nashorn.methodhandles.debug, +nashorn.methodhandles.debug=create + +If this property is enabled, each MethodHandle related call that uses +the java.lang.invoke package gets its MethodHandle intercepted and an +instrumentation printout of arguments and return value appended to +it. This shows exactly which method handles are executed and from +where. (Also MethodTypes and SwitchPoints). This can be augmented with +more information, for example, instance count, by subclassing or +further extending the TraceMethodHandleFactory implementation in +MethodHandleFactory.java. + +If the property is specialized with "=create" as its option, +instrumentation will be shown for method handles upon creation time +rather than at runtime usage. + + +SYSTEM PROPERTY: nashorn.methodhandles.debug.stacktrace + +This does the same as nashorn.methodhandles.debug, but when enabled +also dumps the stack trace for every instrumented method handle +operation. Warning: This is enormously verbose, but provides a pretty +decent "grep:able" picture of where the calls are coming from. + +See the description of the codegen logger below for a more verbose +description of this option + + +SYSTEM PROPERTY: nashorn.scriptfunction.specialization.disable + +There are several "fast path" implementations of constructors and +functions in the NativeObject classes that, in their original form, +take a variable amount of arguments. Said functions are also declared +to take Object parameters in their original form, as this is what the +JavaScript specification mandates. + +However, we often know quite a lot more at a callsite of one of these +functions. For example, Math.min is called with a fixed number (2) of +integer arguments. The overhead of boxing these ints to Objects and +folding them into an Object array for the generic varargs Math.min +function is an order of magnitude slower than calling a specialized +implementation of Math.min that takes two integers. Specialized +functions and constructors are identified by the tag +@SpecializedFunction and @SpecializedConstructor in the Nashorn +code. The linker will link in the most appropriate (narrowest types, +right number of types and least number of arguments) specialization if +specializations are available. + +Every ScriptFunction may carry specializations that the linker can +choose from. This framework will likely be extended for user defined +functions. The compiler can often infer enough parameter type info +from callsites for in order to generate simpler versions with less +generic Object types. This feature depends on future lazy jitting, as +there tend to be many calls to user defined functions, some where the +callsite can be specialized, some where we mostly see object +parameters even at the callsite. + +If this system property is set to true, the linker will not attempt to +use any specialized function or constructor for native objects, but +just call the generic one. + + +SYSTEM PROPERTY: nashorn.tcs.miss.samplePercent= + +When running with the trace callsite option (-tcs), Nashorn will count +and instrument any callsite misses that require relinking. As the +number of relinks is large and usually produces a lot of output, this +system property can be used to constrain the percentage of misses that +should be logged. Typically this is set to 1 or 5 (percent). 1% is the +default value. + + +SYSTEM_PROPERTY: nashorn.profilefile= + +When running with the profile callsite options (-pcs), Nashorn will +dump profiling data for all callsites to stderr as a shutdown hook. To +instead redirect this to a file, specify the path to the file using +this system property. + + +=============== +2. The loggers. +=============== + +The Nashorn loggers can be used to print per-module or per-subsystem +debug information with different levels of verbosity. The loggers for +a given subsystem are available are enabled by using + +--log=[:] + +on the command line. + +Here identifies the name of the subsystem to be logged +and the optional colon and level argument is a standard +java.util.logging.Level name (severe, warning, info, config, fine, +finer, finest). If the level is left out for a particular subsystem, +it defaults to "info". Any log message logged as the level or a level +that is more important will be output to stderr by the logger. + +Several loggers can be enabled by a single command line option, by +putting a comma after each subsystem/level tuple (or each subsystem if +level is unspecified). The --log option can also be given multiple +times on the same command line, with the same effect. + +For example: --log=codegen,fields:finest is equivalent to +--log=codegen:info --log=fields:finest + +The subsystems that currently support logging are: + + +* compiler + +The compiler is in charge of turning source code and function nodes +into byte code, and installs the classes into a class loader +controlled from the Context. Log messages are, for example, about +things like new compile units being allocated. The compiler has global +settings that all the tiers of codegen (e.g. Lower and CodeGenerator) +use. + + +* codegen + +The code generator is the emitter stage of the code pipeline, and +turns the lowest tier of a FunctionNode into bytecode. Codegen logging +shows byte codes as they are being emitted, line number information +and jumps. It also shows the contents of the bytecode stack prior to +each instruction being emitted. This is a good debugging aid. For +example: + +[codegen] #41 line:2 (f)_afc824e +[codegen] #42 load symbol x slot=2 +[codegen] #43 {1:O} load int 0 +[codegen] #44 {2:I O} dynamic_runtime_call GT:ZOI_I args=2 returnType=boolean +[codegen] #45 signature (Ljava/lang/Object;I)Z +[codegen] #46 {1:Z} ifeq ternary_false_5402fe28 +[codegen] #47 load symbol x slot=2 +[codegen] #48 {1:O} goto ternary_exit_107c1f2f +[codegen] #49 ternary_false_5402fe28 +[codegen] #50 load symbol x slot=2 +[codegen] #51 {1:O} convert object -> double +[codegen] #52 {1:D} neg +[codegen] #53 {1:D} convert double -> object +[codegen] #54 {1:O} ternary_exit_107c1f2f +[codegen] #55 {1:O} return object + +shows a ternary node being generated for the sequence "return x > 0 ? +x : -x" + +The first number on the log line is a unique monotonically increasing +emission id per bytecode. There is no guarantee this is the same id +between runs. depending on non deterministic code +execution/compilation, but for small applications it usually is. If +the system variable -Dnashorn.codegen.debug.trace= is set, where x +is a bytecode emission id, a stack trace will be shown as the +particular bytecode is about to be emitted. This can be a quick way to +determine where it comes from without attaching the debugger. "Who +generated that neg?" + +The --log=codegen option is equivalent to setting the system variable +"nashorn.codegen.debug" to true. + + +* lower + +The lowering annotates a FunctionNode with symbols for each identifier +and transforms high level constructs into lower level ones, that the +CodeGenerator consumes. + +Lower logging typically outputs things like post pass actions, +insertions of casts because symbol types have been changed and type +specialization information. Currently very little info is generated by +this logger. This will probably change. + + +* access + +The --log=access option is equivalent to setting the system variable +"nashorn.callsiteaccess.debug" to true. There are several levels of +the access logger, usually the default level "info" is enough + +It is very simple to create your own logger. Use the DebugLogger class +and give the subsystem name as a constructor argument. + + +* fields + +The --log=fields option (at info level) is equivalent to setting the +system variable "nashorn.fields.debug" to true. At the info level it +will only show info about type assumptions that were invalidated. If +the level is set to finest, it will also trace every AccessorProperty +getter and setter in the program, show arguments, return values +etc. It will also show the internal representation of respective field +(Object in the normal case, unless running with the dual field +representation) \ No newline at end of file diff --git a/nashorn/docs/genshelldoc.js b/nashorn/docs/genshelldoc.js new file mode 100644 index 00000000000..c3cf5c305e6 --- /dev/null +++ b/nashorn/docs/genshelldoc.js @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Generate HTML documentation for shell tool. Re-run this tool to regenerate + * html doc when you change options. + * + * Usage: + * + * jjs -scripting genshelldoc.js > shell.html + */ + +var Options = Packages.jdk.nashorn.internal.runtime.options.Options; +var title = "Nashorn command line shell tool"; + +print(< + + +${title} + + + +

Usage

+

+ +jjs <options> <script-files> [ -- <script-arguments> ] + +

+ +

${title} options

+ + + + + + + + +PREFIX); + +for each (opt in Options.validOptions) { + +var isTimezone = (opt.type == "timezone"); +var defValue = opt.defaultValue; +if (defValue == null) { + defValue = "<none>"; +} + +if (isTimezone) { + // don't output current user's timezone + defValue = "<default-timezone>" +} + +print(< + + + + + +ROW); + +} + +print(< + + +SUFFIX); diff --git a/nashorn/make/Makefile b/nashorn/make/Makefile new file mode 100644 index 00000000000..7d768708853 --- /dev/null +++ b/nashorn/make/Makefile @@ -0,0 +1,224 @@ +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# Makefile for nashorn: wrapper around Ant build.xml file + +# +# On Solaris, the standard 'make' utility will not work with these makefiles. +# This little rule is only understood by Solaris make, and is harmless +# when seen by the GNU make tool. If using Solaris make, this causes the +# make command to fail. +# +SUN_MAKE_TEST:sh = @echo "ERROR: PLEASE USE GNU VERSION OF MAKE"; exit 33 + +# +# Minimal platform defs +# Need FullPath because we can't rely on gnumake abspath, until we use v3.81 +# + +SYSTEM_UNAME := $(shell uname) + +# Where is unwanted output to be delivered? +# On Windows, MKS uses the special file "NUL", cygwin uses the customary unix file. +ifeq ($(SYSTEM_UNAME), Windows_NT) +DEV_NULL = NUL +else +DEV_NULL = /dev/null +endif + +ifneq (,$(findstring CYGWIN,$(SYSTEM_UNAME))) +USING_CYGWIN = true +endif + +ifdef USING_CYGWIN +define FullPath +$(shell cygpath -a -s -m $1 2> $(DEV_NULL)) +endef +else +define FullPath +$(shell cd $1 2> $(DEV_NULL) && pwd) +endef +endif + +# +# Makefile args +# + +ifdef QUIET + ANT_OPTIONS += -quiet +endif + +ifdef VERBOSE + ANT_OPTIONS += -verbose -debug +endif + +ifdef JDK_VERSION + ANT_OPTIONS += -Djdk.version=$(JDK_VERSION) +endif + +ifdef FULL_VERSION + ANT_OPTIONS += -Dfull.version='$(FULL_VERSION)' # will contain spaces +endif + +ifdef MILESTONE +ifneq ($(MILESTONE),fcs) + ANT_OPTIONS += -Dmilestone=$(MILESTONE) +else + ANT_OPTIONS += -Drelease=$(JDK_VERSION) +endif +endif + +ifdef BUILD_NUMBER + ANT_OPTIONS += -Dbuild.number=$(BUILD_NUMBER) +else + ifdef JDK_BUILD_NUMBER + ANT_OPTIONS += -Dbuild.number=$(JDK_BUILD_NUMBER) + endif +endif + +ifeq ($(VARIANT), DBG) + ANT_OPTIONS += -Djavac.debug=true +else + ifeq ($(VARIANT), OPT) + ANT_OPTIONS += -Djavac.debug=false + endif +endif + +ifeq ($(DEBUG_CLASSFILES), true) + ANT_OPTIONS += -Djavac.debug=true + ANT_OPTIONS += -Ddebug.classfiles=true +endif + +# Note: jdk/make/common/Defs.gmk uses LANGUAGE_VERSION (-source NN) +# and the somewhat misnamed CLASS_VERSION (-target NN) +ifdef TARGET_CLASS_VERSION + ANT_OPTIONS += -Djavac.target=$(TARGET_CLASS_VERSION) +else + ifdef JAVAC_TARGET_ARG + ANT_OPTIONS += -Djavac.target=$(JAVAC_TARGET_ARG) + endif +endif + +ifdef SOURCE_LANGUAGE_VERSION + ANT_OPTIONS += -Djavac.source=$(SOURCE_LANGUAGE_VERSION) +else + ifdef JAVAC_SOURCE_ARG + ANT_OPTIONS += -Djavac.source=$(JAVAC_SOURCE_ARG) + endif +endif + +ifdef ALT_BOOTDIR + ANT_OPTIONS += -Dboot.java.home=$(ALT_BOOTDIR) + ANT_JAVA_HOME = JAVA_HOME=$(ALT_BOOTDIR) +endif + +# To facilitate bootstrapping, much of langtools can be compiled with (just) +# a boot JDK. However, some source files need to be compiled against +# new JDK API. In a bootstrap build, an import JDK may not be available, +# so build.xml can also build against the source files in a jdk repo, +# in which case it will automatically generate stub files for the new JDK API. +ifdef JDK_TOPDIR + ANT_OPTIONS += -Dimport.jdk=$(JDK_TOPDIR) +else + ifdef ALT_JDK_TOPDIR + ANT_OPTIONS += -Dimport.jdk=$(ALT_JDK_TOPDIR) + else + ifdef ALT_JDK_IMPORT_PATH + ANT_OPTIONS += -Dimport.jdk=$(ALT_JDK_IMPORT_PATH) + endif + endif +endif + +ifdef ALT_OUTPUTDIR + OUTPUTDIR = $(ALT_OUTPUTDIR) + ANT_OPTIONS += -Dbuild.dir=$(ALT_OUTPUTDIR)/build + ANT_OPTIONS += -Ddist.dir=$(ALT_OUTPUTDIR)/dist +else + OUTPUTDIR = .. +endif +#ABS_OUTPUTDIR = $(abspath $(OUTPUTDIR)) +ABS_OUTPUTDIR = $(call FullPath,$(OUTPUTDIR)) + +ANT_TMPDIR = $(ABS_OUTPUTDIR)/build/ant-tmp +ANT_OPTS = ANT_OPTS=-Djava.io.tmpdir='$(ANT_TMPDIR)' + +ifdef FINDBUGS_HOME + ANT_OPTIONS += -Dfindbugs.home=$(FINDBUGS_HOME) +endif + +ifdef ANT_HOME + ANT = $(ANT_HOME)/bin/ant + ifneq ($(shell test -x $(ANT) && echo OK), OK) + $(error $(ANT) not found -- please update ANT_HOME) + endif +else + ANT = ant + ifneq ($(shell test -x "`which $(ANT)`" && echo OK), OK) + $(error 'ant' not found -- please set ANT_HOME or put 'ant' on your PATH) + endif +endif + +# Default target and expected 'do everything' target +# comments docs to avoid too many ASM warnings +# all: test docs + +all: test + +# Standard make clobber target +clobber: clean + +# All ant targets of interest +ANT_TARGETS = clean jar javadoc shelldoc docs test test262 test262parallel # for now + +# Create diagnostics log (careful, ant 1.8.0 -diagnostics always does an exit 1) +$(OUTPUTDIR)/build/ant-diagnostics.log: + @mkdir -p $(OUTPUTDIR)/build $(ANT_TMPDIR) + @$(RM) $@ + $(ANT_JAVA_HOME) $(ANT_OPTS) $(ANT) -diagnostics > $@ ; \ + $(ANT_JAVA_HOME) $(ANT_OPTS) $(ANT) -version >> $@ + +# Create a make target for each +$(ANT_TARGETS): $(OUTPUTDIR)/build/ant-diagnostics.log + @ mkdir -p $(OUTPUTDIR)/build $(ANT_TMPDIR) + $(ANT_JAVA_HOME) $(ANT_OPTS) $(ANT) $(ANT_OPTIONS) $@ + +#------------------------------------------------------------------- +# +# Targets for Oracle's internal JPRT build system + +CD = cd +ZIP = zip + +JPRT_ARCHIVE_BUNDLE=$(ABS_OUTPUTDIR)/$(JPRT_BUILD_FLAVOR)-bundle.zip + +jprt_build_product jprt_build_debug jprt_build_fastdebug: all + ( $(CD) $(OUTPUTDIR) && \ + $(ZIP) -q -r $(JPRT_ARCHIVE_BUNDLE) build dist ) + +#------------------------------------------------------------------- + +# Declare these phony (not filenames) +.PHONY: $(ANT_TARGETS) all clobber \ + jprt_build_product jprt_build_debug jprt_build_fastdebug diff --git a/nashorn/make/build-benchmark.xml b/nashorn/make/build-benchmark.xml new file mode 100644 index 00000000000..b6dce19565e --- /dev/null +++ b/nashorn/make/build-benchmark.xml @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nashorn/make/build-nasgen.xml b/nashorn/make/build-nasgen.xml new file mode 100644 index 00000000000..fe5a67820bb --- /dev/null +++ b/nashorn/make/build-nasgen.xml @@ -0,0 +1,86 @@ + + + + Builds and runs nasgen. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml new file mode 100644 index 00000000000..79669a8020d --- /dev/null +++ b/nashorn/make/build.xml @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${line.separator} + + + + + + + + + + + + +
+ + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \/ + /// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Representation test failed - output differs! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/nashorn/make/nbproject/ide-file-targets.xml b/nashorn/make/nbproject/ide-file-targets.xml new file mode 100644 index 00000000000..3a957ccd8a2 --- /dev/null +++ b/nashorn/make/nbproject/ide-file-targets.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + Must set property 'debug.class' + + + + + + + + + + + + + + + + + Must set property 'run.class' + + + + + + + + + diff --git a/nashorn/make/nbproject/ide-targets.xml b/nashorn/make/nbproject/ide-targets.xml new file mode 100644 index 00000000000..281672d8b5a --- /dev/null +++ b/nashorn/make/nbproject/ide-targets.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/nashorn/make/nbproject/jdk.xml b/nashorn/make/nbproject/jdk.xml new file mode 100644 index 00000000000..b6fa7ebba63 --- /dev/null +++ b/nashorn/make/nbproject/jdk.xml @@ -0,0 +1,179 @@ + + + + + + Permits selection of a JDK to use when building and running project. + See: http://www.netbeans.org/issues/show_bug.cgi?id=64160 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nbjdk.active=${nbjdk.active} nbjdk.home=${nbjdk.home} nbjdk.java=${nbjdk.java} nbjdk.javac=${nbjdk.javac} nbjdk.javadoc=${nbjdk.javadoc} nbjdk.bootclasspath=${nbjdk.bootclasspath} nbjdk.valid=${nbjdk.valid} have-jdk-1.4=${have-jdk-1.4} have-jdk-1.5=${have-jdk-1.5} + + + + + Warning: nbjdk.active=${nbjdk.active} or nbjdk.home=${nbjdk.home} is an invalid Java platform; ignoring and using ${jdkhome.presumed} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/nashorn/make/nbproject/nbjdk.properties b/nashorn/make/nbproject/nbjdk.properties new file mode 100644 index 00000000000..6260c35a3d8 --- /dev/null +++ b/nashorn/make/nbproject/nbjdk.properties @@ -0,0 +1,24 @@ +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +nbjdk.active=JDK_1.8 + diff --git a/nashorn/make/nbproject/nbjdk.xml b/nashorn/make/nbproject/nbjdk.xml new file mode 100644 index 00000000000..cbd7af38a5f --- /dev/null +++ b/nashorn/make/nbproject/nbjdk.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nashorn/make/nbproject/project.xml b/nashorn/make/nbproject/project.xml new file mode 100644 index 00000000000..ee88965a853 --- /dev/null +++ b/nashorn/make/nbproject/project.xml @@ -0,0 +1,177 @@ + + + + org.netbeans.modules.ant.freeform + + + nashorn + + + + nashorn + + + + + . + UTF-8 + + + + ../src + + + + ../test/src + + + + ../buildtools/nasgen/src + + + + java + ../test/src + UTF-8 + + + + java + ../src + UTF-8 + + + + java + ../buildtools/nasgen/src + UTF-8 + + + + + + jar + + + + clean + + + + javadoc + + + + test + + + + clean + jar + + + + run + + + + debug-nb + + + + debug-selected-file-in-src + + debug.class + test/src + \.java$ + java-name + + + + + + + + run-selected-file-in-src + + run.class + test/src + \.java$ + java-name + + + + + + + + + + + ../test/src + + + + ../src + + + + ../buildtools/nasgen/src + + + build.xml + + + + + + + + + + + + + + + + + ../test/src + + ../test/lib/testng.jar:../build/classes:../src + 1.7 + + + ../src + ../build/dynalink/dynalink.jar + 1.7 + + + ../buildtools/nasgen/src + ../build/classes:../src + 1.7 + + + + diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties new file mode 100644 index 00000000000..64ec4083406 --- /dev/null +++ b/nashorn/make/project.properties @@ -0,0 +1,223 @@ +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +application.title=nashorn + +# source and target levels +build.compiler=modern +javac.source=1.7 +javac.target=1.7 + +# nashorn version information +nashorn.version=0.1 +nashorn.fullversion=0.1 +nashorn.product.name=Oracle Nashorn + +# This directory is removed when the project is cleaned: +build.dir=build +build.classes.dir=${build.dir}/classes +build.zip=${build.dir}/nashorn.zip +build.gzip=${build.dir}/nashorn.tar.gz + +# nashorn Shell tool +nashorn.shell.tool=jdk.nashorn.tools.Shell + +# nasgen tool +nasgen.tool=jdk.nashorn.internal.tools.nasgen.Main + +# parallel test runner tool +parallel.test.runner=jdk.nashorn.internal.test.framework.ParallelTestRunner + +# test classes directory +build.test.classes.dir=${build.dir}/test/classes +# test results directory +build.test.results.dir=${build.dir}/test/reports + +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/nashorn.jar +dist.javadoc.dir=${dist.dir}/javadoc + +# directory where asm project lives +asm.dir=../asm +asm.src.dir=${asm.dir}/src + +# jars refererred +file.reference.testng.jar=test/lib/testng.jar + +# Set testng verbose level +# From TestNG docs: "the verbosity level (0 to 10 where 10 is most detailed) +# Actually, this is a lie: you can specify -1 and this will put TestNG in +# debug mode (no longer slicing off stack traces and all)." + +testng.verbose=2 + +# TestNG listeners - we want to replace TestNG's own JUnit +# reporter, but want everything else provided by default +# Unfortunately, we've to clone the other default reporters here. + +testng.listeners=\ + org.testng.reporters.SuiteHTMLReporter, \ + org.testng.reporters.jq.Main, \ + org.testng.reporters.FailedReporter, \ + org.testng.reporters.XMLReporter \ + org.testng.reporters.EmailableReporter, \ + jdk.nashorn.internal.test.framework.JSJUnitReportReporter + +# Define the version of Dynalink that is used. Version types are either +# 'snapshot' or 'release'. When it is 'snapshot', the version must have +# "-SNAPSHOT" suffix and the jar version will have a timestamp in it. When +# it's 'release', the version has no suffix, and the jar version is +# identical to version - fun with Maven central. +dynalink.version=0.5-SNAPSHOT +dynalink.version.type=snapshot +dynalink.jar.version=0.5-20121218.140128-11 +dynalink.dir.name=dynalink +dynalink.dir=build/${dynalink.dir.name} +dynalink.jar=${dynalink.dir}/dynalink.jar + +javac.debug=true +javac.encoding=ascii +javac.classpath=\ + ${build.classes.dir}:\ + ${dynalink.jar} +javac.test.classpath=\ + ${build.classes.dir}:\ + ${build.test.classes.dir}:\ + ${file.reference.testng.jar} + +meta.inf.dir=${src.dir}/META-INF + +run.classpath=\ + ${build.classes.dir} + +# test scripts to run +test.dir=test +test.script.dir=test/script +test.basic.dir=test/script/basic +test.error.dir=test/script/error +test.sandbox.dir=test/script/sandbox +test.external.dir=test/script/external +test262.dir=${test.external.dir}/test262 +test262.suite.dir=${test262.dir}/test/suite + +test-sys-prop.test.dir=${test.dir} +test-sys-prop.test.js.roots=${test.basic.dir} ${test.error.dir} ${test.sandbox.dir} +test-sys-prop.test262.suite.dir=${test262.suite.dir} +test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases +test-sys-prop.test.basic.dir=${test.basic.dir} + +# framework root for our script tests +test-sys-prop.test.js.framework=${test.script.dir}/assert.js + +# Control the verbosity of ParserTest +test-sys-prop.parsertest.verbose=false + +# turn on/off scripting mode for parser tests +test-sys-prop.parsertest.scripting=true + +# turn on/off test262 scripts for parser tests +test-sys-prop.parsertest.test262=false + +# Control the verbosity of the CompilerTest +test-sys-prop.compilertest.verbose=false + +# turn on/off scripting mode for compiler tests +test-sys-prop.compilertest.scripting=true + +# turn on/off test262 scripts for compiler tests +test-sys-prop.compilertest.test262=false + +# test directory to be excluded. +test-sys-prop.test.js.exclude.dir=${test.script.dir}/currently-failing ${test.external.dir} + +# run everything that's js in here, without checking file headers for test annotations +test-sys-prop.test.js.unchecked.dir=${test262.dir} + +# test root for octane +octane-test-sys-prop.test.js.roots=${test.external.dir}/octane/benchmarks + +# framework root for octane +octane-test-sys-prop.test.js.framework=${test.basic.dir}/run-octane.js + +# list of tests to be excluded +octane-test-sys-prop.test.js.exclude.list=base.js + +# test root for sunspider +sunspider-test-sys-prop.test.js.roots=${test.external.dir}/sunspider/ + +# framework root for sunspider +sunspider-test-sys-prop.test.js.framework=${test.basic.dir}/runsunspider.js + +# list of tests to be excluded +sunspider-test-sys-prop.test.js.exclude.list= + +# execute our script tests in shared nashorn context or not? +test-sys-prop.test.js.shared.context=false + +# execute test262 tests in shared nashorn context or not? +test262-test-sys-prop.test.js.shared.context=true + +# test262 test root +test262-test-sys-prop.test.js.roots=${test262.suite.dir} +# test262 enable/disable strict mode tests +test262-test-sys-prop.test.js.enable.strict.mode=true + +# file containing test262 tests to be excluded +# test262-test-sys-prop.test.js.excludes.file=${test262.dir}/test/config/excludelist.xml + +# list of test262 test dirs to be excluded +test262-test-sys-prop.test.js.exclude.dir=\ + ${test262.suite.dir}/intl402/ + +# test262 test frameworks +test262-test-sys-prop.test.js.framework=\ + -timezone=PST \ + ${test.script.dir}/test262.js \ + ${test262.dir}/test/harness/framework.js \ + ${test262.dir}/test/harness/sta.js + +run.test.classpath=\ + ${file.reference.testng.jar}:\ + ${build.test.classes.dir} +src.dir=src +test.src.dir=test/src + +# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods +# add '-Dtest.js.outofprocess' to run each test in a new sub-process +run.test.jvmargs=-server -Xmx3G -XX:-TieredCompilation -esa -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8 +#-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M +run.test.jvmargs.octane=-Xms2G -Xmx2G ${run.test.jvmargs} + +run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy + +# path of rhino.jar for benchmarks +rhino.jar= + +v8.shell=d8 + +#path to rhino jar file +octaneperf-sys-prop.rhino.jar=${rhino.jar} + +#timeout for performance tests in minutes +octaneperf-sys-prop.timeout.value=10 diff --git a/nashorn/samples/counters.js b/nashorn/samples/counters.js new file mode 100644 index 00000000000..eb55d2870cf --- /dev/null +++ b/nashorn/samples/counters.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * This file can be run along with any script you want to run + * to print aggregate stat counters from nashorn. + * + * Usage: jjs counters.js + */ + +Debug.dumpCounters(); diff --git a/nashorn/samples/letter.js b/nashorn/samples/letter.js new file mode 100644 index 00000000000..d45bd086b45 --- /dev/null +++ b/nashorn/samples/letter.js @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Demonstrates "heredoc" feature with "scripting" mode. + * + * Usage: jjs -scripting letter.js -- + */ + +# This is shell-style line comment +var obj = { sender: $ARG[0], recipient: $ARG[1] }; + +// JavaScript style line comment is ok too. +print(<"); +} + +with (imports) { + var reader = new BufferedReader(new InputStreamReader(System["in"])); + var line = null; + prompt(); + while ((line = reader.readLine()) != null) { + if (line != "") { + var args = line.split(" "); + try { + if (args[0] == "eval") { + var code = line.substring("eval".length); + var res = eval(code); + if (res != undefined) { + print(res); + } + } else { + var argList = new ArrayList(); + for (i in args) { argList.add(args[i]); } + var procBuilder = new ProcessBuilder(argList); + procBuilder.redirectErrorStream(); + var proc = procBuilder.start(); + var out = new BufferedReader(new InputStreamReader(proc.getInputStream())); + var line = null; + while ((line = out.readLine()) != null) { + System.out.println(line); + } + proc.waitFor(); + } + } catch (e) { + print(e); + } + } + prompt(); + } +} diff --git a/nashorn/samples/test.js b/nashorn/samples/test.js new file mode 100644 index 00000000000..e1d30b0ac51 --- /dev/null +++ b/nashorn/samples/test.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +print("Hello World"); diff --git a/nashorn/samples/uniq.js b/nashorn/samples/uniq.js new file mode 100644 index 00000000000..157c4f59451 --- /dev/null +++ b/nashorn/samples/uniq.js @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Prints unique lines from a given file. + */ + +if (arguments.length != 1) { + print("Usage: jjs uniq.js -- "); + java.lang.System.exit(1); +} + +var imports = new JavaImporter(java.io); + +var uniqueLines = {}; +with (imports) { + var reader = new BufferedReader(new FileReader(arguments[0])); + while ((line = reader.readLine()) != null) { + // using a JS object as a map... + uniqueLines[line] = true; + } +} + +// now print the collected lines +for (i in uniqueLines) { + print(i); +} diff --git a/nashorn/src/META-INF/MANIFEST.MF b/nashorn/src/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..b61190e5ba9 --- /dev/null +++ b/nashorn/src/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Main-Class: jdk.nashorn.tools.Shell + +Name: jdk/nashorn/ +Implementation-Vendor: Oracle Corporation diff --git a/nashorn/src/META-INF/services/javax.script.ScriptEngineFactory b/nashorn/src/META-INF/services/javax.script.ScriptEngineFactory new file mode 100644 index 00000000000..ec7da013a99 --- /dev/null +++ b/nashorn/src/META-INF/services/javax.script.ScriptEngineFactory @@ -0,0 +1,25 @@ +# +# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +jdk.nashorn.api.scripting.NashornScriptEngineFactory diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java new file mode 100644 index 00000000000..f1a42648b7e --- /dev/null +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting; + +/** + * This is base exception for all Nashorn exceptions. These originate from user's + * ECMAScript code. Example: script parse errors, exceptions thrown from scripts. + * Note that ScriptEngine methods like "eval", "invokeMethod", "invokeFunction" + * will wrap this as ScriptException and throw it. But, there are cases where user + * may need to access this exception (or implementation defined subtype of this). + * For example, if java interface is implemented by a script object or Java access + * to script object properties via java.util.Map interface. In these cases, user + * code will get an instance of this or implementation defined subclass. + */ +@SuppressWarnings("serial") +public class NashornException extends RuntimeException { + // script file name + private String fileName; + // script line number + private int line; + // script column number + private int column; + + /** + * Constructor + * + * @param msg exception message + */ + protected NashornException(final String msg) { + super(msg); + } + + /** + * Constructor + * @param msg exception message + * @param cause exception cause + */ + protected NashornException(final String msg, final Throwable cause) { + super(msg, cause); + } + + /** + * Constructor + * + * @param cause exception cause + */ + protected NashornException(final Throwable cause) { + super(cause); + } + + /** + * Get the source file name for this {@code NashornException} + * @return the file name + */ + public final String getFileName() { + return fileName; + } + + /** + * Set the source file name for this {@code NashornException} + * @param fileName file name + */ + protected final void setFileName(final String fileName) { + this.fileName = fileName; + } + + /** + * Get the line number for this {@code NashornException} + * @return the line number + */ + public final int getLineNumber() { + return line; + } + + /** + * Set the line number for this {@code NashornException} + * @param line line number + */ + protected final void setLineNumber(final int line) { + this.line = line; + } + + /** + * Get the column for this {@code NashornException} + * @return the column + */ + public final int getColumnNumber() { + return column; + } + + /** + * Set the column number for this {@code NashornException} + * @param column the column + */ + public final void setColumnNumber(final int column) { + this.column = column; + } +} diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java new file mode 100644 index 00000000000..3fde40aae94 --- /dev/null +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -0,0 +1,521 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting; + +import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError; +import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; +import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; +import static jdk.nashorn.internal.runtime.linker.Lookup.MH; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.lang.invoke.MethodHandle; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import javax.script.AbstractScriptEngine; +import javax.script.Bindings; +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.Invocable; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptException; +import javax.script.SimpleBindings; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ErrorManager; +import jdk.nashorn.internal.runtime.GlobalObject; +import jdk.nashorn.internal.runtime.Property; +import jdk.nashorn.internal.runtime.ScriptFunction; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.Source; +import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; +import jdk.nashorn.internal.runtime.options.Options; + +/** + * JSR-223 compliant script engine for Nashorn. Instances are not created directly, but rather returned through + * {@link NashornScriptEngineFactory#getScriptEngine()}. Note that this engine implements the {@link Compilable} and + * {@link Invocable} interfaces, allowing for efficient precompilation and repeated execution of scripts. + * @see NashornScriptEngineFactory + */ + +public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable, Invocable { + + private final ScriptEngineFactory factory; + private final Context nashornContext; + private final ScriptObject global; + + // default options passed to Nashorn Options object + private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-af", "-doe" }; + + NashornScriptEngine(final NashornScriptEngineFactory factory) { + this(factory, DEFAULT_OPTIONS); + } + + @SuppressWarnings("LeakingThisInConstructor") + NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args) { + this.factory = factory; + final Options options = new Options("nashorn"); + options.process(args); + + // throw ParseException on first error from script + final ErrorManager errors = new Context.ThrowErrorManager(); + // create new Nashorn Context and get global object + this.nashornContext = AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Context run() { + try { + return new Context(options, errors); + } catch (final RuntimeException e) { + if (Context.DEBUG) { + e.printStackTrace(); + } + throw e; + } + } + }); + + // create new global object + this.global = nashornContext.createGlobal(); + + // current ScriptContext exposed as "context" + global.addOwnProperty("context", Property.NOT_ENUMERABLE, context); + // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as + // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property + // in the Global of a Context we just created - both the Context and the Global were just created and can not be + // seen from another thread outside of this constructor. + global.addOwnProperty("engine", Property.NOT_ENUMERABLE, this); + // global script arguments + global.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED); + + // evaluate engine initial script + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + @Override + public Void run() throws ScriptException { + evalEngineScript(); + return null; + } + }); + } catch (final PrivilegedActionException e) { + if (Context.DEBUG) { + e.printStackTrace(); + } + throw new RuntimeException(e); + } + } + + @Override + public Object eval(final Reader reader, final ScriptContext ctxt) throws ScriptException { + try { + return evalImpl(Source.readFully(reader), ctxt); + } catch (final IOException e) { + throw new ScriptException(e); + } + } + + @Override + public Object eval(final String script, final ScriptContext ctxt) throws ScriptException { + return evalImpl(script.toCharArray(), ctxt); + } + + /* + * FIXME: This is not exactly right. Script execution should actually + * put the variables in ENGINE_SCOPE bindings. But, it is difficult + * (not possible?) with the way ScriptObject is implemented. So, for now + * giving access to script variables by accessing it from "globals". This + * way at least engine.get("foo") will work whenever "foo" is a global var + * defined by eval'ed scripts. + */ + @Override + public Object get(final String key) { + Object value = super.get(key); + if (value == null) { + value = ScriptObjectMirror.wrap(global.get(key), global); + } + return (value == UNDEFINED) ? null : value; + } + + @Override + public ScriptEngineFactory getFactory() { + return factory; + } + + @Override + public Bindings createBindings() { + return new SimpleBindings(); + } + + // Compilable methods + + @Override + public CompiledScript compile(final Reader reader) throws ScriptException { + try { + return asCompiledScript(compileImpl(Source.readFully(reader), context)); + } catch (final IOException e) { + throw new ScriptException(e); + } + } + + @Override + public CompiledScript compile(final String str) throws ScriptException { + return asCompiledScript(compileImpl(str.toCharArray(), context)); + } + + // Invocable methods + + @Override + public Object invokeFunction(final String name, final Object... args) + throws ScriptException, NoSuchMethodException { + return invokeImpl(null, name, args); + } + + @Override + public Object invokeMethod(final Object self, final String name, final Object... args) + throws ScriptException, NoSuchMethodException { + if (self == null) { + throw new IllegalArgumentException("script object can not be null"); + } + return invokeImpl(self, name, args); + } + + private T getInterfaceInner(final Object self, final Class clazz) { + final Object realSelf; + if(self == null) { + realSelf = global; + } else if (!(self instanceof ScriptObject)) { + realSelf = ScriptObjectMirror.unwrap(self, global); + } else { + realSelf = self; + } + try { + final ScriptObject oldGlobal = Context.getGlobal(); + try { + if(oldGlobal != global) { + setNashornGlobal(global); + } + return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz).invoke(realSelf)); + } finally { + if(oldGlobal != global) { + setNashornGlobal(oldGlobal); + } + } + } catch(final RuntimeException|Error e) { + throw e; + } catch(final Throwable t) { + throw new RuntimeException(t); + } + } + + @Override + public T getInterface(final Class clazz) { + return getInterfaceInner(null, clazz); + } + + @Override + public T getInterface(final Object self, final Class clazz) { + if (self == null) { + throw new IllegalArgumentException("script object can not be null"); + } + return getInterfaceInner(self, clazz); + } + + // These are called from the "engine.js" script + + /** + * This hook is used to search js global variables exposed from Java code. + * + * @param self 'this' passed from the script + * @param ctxt current ScriptContext in which name is searched + * @param name name of the variable searched + * @return the value of the named variable + */ + public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) { + final int scope = ctxt.getAttributesScope(name); + if (scope != -1) { + return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), global); + } + + if (self == UNDEFINED) { + // scope access and so throw ReferenceError + referenceError(global, "not.defined", name); + } + + return UNDEFINED; + } + + /** + * This hook is used to call js global functions exposed from Java code. + * + * @param self 'this' passed from the script + * @param ctxt current ScriptContext in which method is searched + * @param name name of the method + * @param args arguments to be passed to the method + * @return return value of the called method + */ + public Object __noSuchMethod__(final Object self, final ScriptContext ctxt, final String name, final Object args) { + final int scope = ctxt.getAttributesScope(name); + Object value; + + if (scope != -1) { + value = ctxt.getAttribute(name, scope); + } else { + if (self == UNDEFINED) { + referenceError(global, "not.defined", name); + } else { + typeError(global, "no.such.function", name, ScriptRuntime.safeToString(global)); + } + return UNDEFINED; + } + + value = ScriptObjectMirror.unwrap(value, global); + + if (value instanceof Method) { + final Method method = (Method) value; + final int mods = method.getModifiers(); + if (Modifier.isStatic(mods) && Modifier.isPublic(mods)) { + value = MH.find((Method)value); + } + } + + if (value instanceof MethodHandle) { + value = ((GlobalObject)global).newScriptFunction(name, (MethodHandle)value, null, false); + } + + if (!(value instanceof ScriptFunction)) { + typeError(global, "not.a.function", name); + } + + if (value instanceof ScriptFunction) { + return ScriptObjectMirror.unwrap(ScriptRuntime.apply((ScriptFunction)value, global, args), global); + } + + typeError(global, "not.a.function", ScriptRuntime.safeToString(name)); + + return UNDEFINED; + } + + private void evalEngineScript() throws ScriptException { + final URL url = NashornScriptEngine.class.getResource("resources/engine.js"); + try { + final InputStream is = url.openStream(); + put(ScriptEngine.FILENAME, url); + try (final InputStreamReader isr = new InputStreamReader(is)) { + eval(isr); + } + } catch (final IOException e) { + throw new ScriptException(e); + } finally { + put(ScriptEngine.FILENAME, null); + } + } + + // scripts should see "context" and "engine" as variables + private void setContextVariables(final ScriptContext ctxt) { + ctxt.setAttribute("context", ctxt, ScriptContext.ENGINE_SCOPE); + // current ScriptContext exposed as "context" + global.set("context", ctxt, false); + Object args = ctxt.getAttribute("arguments"); + // if no arguments passed, make it empty array + if (args == null) { + args = ScriptRuntime.EMPTY_ARRAY; + } + args = ((GlobalObject)global).wrapAsObject(args); + global.set("arguments", args, false); + } + + private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException { + final ScriptObject oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + + Object self = selfObject; + + try { + if (globalChanged) { + setNashornGlobal(global); + } + + ScriptObject sobj; + Object value; + + self = ScriptObjectMirror.unwrap(self, global); + + // FIXME: should convert when self is not ScriptObject + if (self instanceof ScriptObject) { + sobj = (ScriptObject)self; + value = sobj.get(name); + } else if (self == null) { + self = global; + sobj = global; + value = sobj.get(name); + } else { + // Find the java method and make a ScriptFunction of it. + final Method[] methods = self.getClass().getMethods(); + Method target = null; + + for (final Method mth : methods) { + // choose the right overload by number of arguments -- don't + // care overload resolution for now.. + if (mth.getName().equals(name) && + mth.getParameterTypes().length == args.length) { + target = mth; + break; + } + } + if (target == null) { + throw new NoSuchMethodException(name); + } + final GlobalObject gobj = (GlobalObject) global; + value = gobj.newScriptFunction(name, MH.find(target), null, false); + } + + if (value instanceof ScriptFunction) { + final Object res; + try { + res = ScriptRuntime.apply((ScriptFunction)value, self, ScriptObjectMirror.unwrapArray(args, global)); + } catch (final Exception e) { + throwAsScriptException(e); + throw new AssertionError("should not reach here"); + } + return ScriptObjectMirror.wrap(res, global); + } + + throw new NoSuchMethodException(name); + } finally { + if (globalChanged) { + setNashornGlobal(oldGlobal); + } + } + } + + private Object evalImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException { + return evalImpl(compileImpl(buf, ctxt), ctxt); + } + + private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException { + if (script == null) { + return null; + } + final ScriptObject oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + try { + if (globalChanged) { + setNashornGlobal(global); + } + + setContextVariables(ctxt); + Object res = ScriptRuntime.apply(script, global); + res = ScriptObjectMirror.wrap(res, global); + return (res == UNDEFINED) ? null : res; + } catch (final Exception e) { + throwAsScriptException(e); + throw new AssertionError("should not reach here"); + } finally { + if (globalChanged) { + setNashornGlobal(oldGlobal); + } + } + } + + private static void throwAsScriptException(final Exception e) throws ScriptException { + if (e instanceof ScriptException) { + throw (ScriptException)e; + } else if (e instanceof NashornException) { + final NashornException ne = (NashornException)e; + final ScriptException se = new ScriptException( + ne.getMessage(), ne.getFileName(), + ne.getLineNumber(), ne.getColumnNumber()); + se.initCause(e); + throw se; + } else if (e instanceof RuntimeException) { + throw (RuntimeException)e; + } else { + // wrap any other exception as ScriptException + throw new ScriptException(e); + } + } + + private CompiledScript asCompiledScript(final ScriptFunction script) { + return new CompiledScript() { + @Override + public Object eval(final ScriptContext ctxt) throws ScriptException { + return evalImpl(script, ctxt); + } + @Override + public ScriptEngine getEngine() { + return NashornScriptEngine.this; + } + }; + } + + private ScriptFunction compileImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException { + final ScriptObject oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + try { + final Object val = ctxt.getAttribute(ScriptEngine.FILENAME); + final String fileName = (val != null) ? val.toString() : ""; + + // !!HACK!! do not evaluate "init.js" from jrunscript tool!! + if ("".equals(fileName)) { + return null; + } + + final Source source = new Source(fileName, buf); + if (globalChanged) { + setNashornGlobal(global); + } + + setContextVariables(ctxt); + return nashornContext.compileScript(source, global, nashornContext._strict); + } catch (final Exception e) { + throwAsScriptException(e); + throw new AssertionError("should not reach here"); + } finally { + if (globalChanged) { + setNashornGlobal(oldGlobal); + } + } + } + + // don't make this public!! + static void setNashornGlobal(final ScriptObject global) { + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { + Context.setGlobal(global); + return null; + } + }); + } +} diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java new file mode 100644 index 00000000000..2bb6a3484d7 --- /dev/null +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import jdk.nashorn.internal.runtime.Version; + +/** + * JSR-223 compliant script engine factory for Nashorn. The engine answers for: + *
    + *
  • names {@code "nashorn"}, {@code "Nashorn"}, {@code "js"}, {@code "JS"}, {@code "JavaScript"}, + * {@code "javascript"}, {@code "ECMAScript"}, and {@code "ecmascript"};
  • + *
  • MIME types {@code "application/javascript"}, {@code "application/ecmascript"}, {@code "text/javascript"}, and + * {@code "text/ecmascript"};
  • + *
  • as well as for the extension {@code "js"}.
  • + *
+ * Programs executing in engines created using {@link #getScriptEngine(String[])} will have the passed arguments + * accessible as a global variable named {@code "arguments"}. + */ +public final class NashornScriptEngineFactory implements ScriptEngineFactory { + @Override + public String getEngineName() { + return (String) getParameter(ScriptEngine.ENGINE); + } + + @Override + public String getEngineVersion() { + return (String) getParameter(ScriptEngine.ENGINE_VERSION); + } + + @Override + public List getExtensions() { + return Collections.unmodifiableList(extensions); + } + + @Override + public String getLanguageName() { + return (String) getParameter(ScriptEngine.LANGUAGE); + } + + @Override + public String getLanguageVersion() { + return (String) getParameter(ScriptEngine.LANGUAGE_VERSION); + } + + @Override + public String getMethodCallSyntax(final String obj, final String method, final String... args) { + final StringBuilder sb = new StringBuilder().append(obj).append('.').append(method).append('('); + final int len = args.length; + + if (len > 0) { + sb.append(args[0]); + } + for (int i = 1; i < len; i++) { + sb.append(',').append(args[i]); + } + sb.append(')'); + + return sb.toString(); + } + + @Override + public List getMimeTypes() { + return Collections.unmodifiableList(mimeTypes); + } + + @Override + public List getNames() { + return Collections.unmodifiableList(names); + } + + @Override + public String getOutputStatement(final String toDisplay) { + return "print(" + toDisplay + ")"; + } + + @Override + public Object getParameter(final String key) { + switch (key) { + case ScriptEngine.NAME: + return "javascript"; + case ScriptEngine.ENGINE: + return "Oracle Nashorn"; + case ScriptEngine.ENGINE_VERSION: + return Version.version(); + case ScriptEngine.LANGUAGE: + return "ECMAScript"; + case ScriptEngine.LANGUAGE_VERSION: + return "ECMA - 262 Edition 5.1"; + case "THREADING": + // The engine implementation is not thread-safe. Can't be + // used to execute scripts concurrently on multiple threads. + return null; + default: + throw new IllegalArgumentException("Invalid key"); + } + } + + @Override + public String getProgram(final String... statements) { + final StringBuilder sb = new StringBuilder(); + + for (final String statement : statements) { + sb.append(statement).append(';'); + } + + return sb.toString(); + } + + @Override + public ScriptEngine getScriptEngine() { + return new NashornScriptEngine(this); + } + + /** + * Create a new Script engine initialized by given arguments. + * + * @param args arguments array passed to script engine. + * @return newly created script engine. + */ + public ScriptEngine getScriptEngine(final String[] args) { + return new NashornScriptEngine(this, args); + } + + // -- Internals only below this point + + private static final List names; + private static final List mimeTypes; + private static final List extensions; + + static { + names = immutableList( + "nashorn", "Nashorn", + "js", "JS", + "JavaScript", "javascript", + "ECMAScript", "ecmascript" + ); + + mimeTypes = immutableList( + "application/javascript", + "application/ecmascript", + "text/javascript", + "text/ecmascript" + ); + + extensions = immutableList("js"); + } + + private static List immutableList(final String... elements) { + return Collections.unmodifiableList(Arrays.asList(elements)); + } +} diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java new file mode 100644 index 00000000000..44021fada90 --- /dev/null +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Callable; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ScriptFunction; +import jdk.nashorn.internal.runtime.ScriptObject; +import netscape.javascript.JSObject; + +/** + * Mirror object that wraps a given ScriptObject instance. User can + * access ScriptObject via the java.util.Map interface. + */ +final class ScriptObjectMirror extends JSObject implements Map { + private final ScriptObject sobj; + private final ScriptObject global; + + ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) { + this.sobj = sobj; + this.global = global; + } + + @Override + public boolean equals(final Object other) { + if (other instanceof ScriptObjectMirror) { + return sobj.equals(((ScriptObjectMirror)other).sobj); + } + + return false; + } + + @Override + public int hashCode() { + return sobj.hashCode(); + } + + private V inGlobal(final Callable callable) { + final ScriptObject oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + if (globalChanged) { + NashornScriptEngine.setNashornGlobal(global); + } + try { + return callable.call(); + } catch (final RuntimeException e) { + throw e; + } catch (final Exception e) { + throw new AssertionError("Cannot happen", e); + } finally { + if (globalChanged) { + NashornScriptEngine.setNashornGlobal(oldGlobal); + } + } + } + + // JSObject methods + @Override + public Object call(final String methodName, final Object args[]) { + final Object val = sobj.get(methodName); + final ScriptObject oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + + if (val instanceof ScriptFunction) { + final Object[] modifiedArgs = unwrapArray(args, global); + if (modifiedArgs != null) { + for (int i = 0; i < modifiedArgs.length; i++) { + final Object arg = modifiedArgs[i]; + if (arg instanceof ScriptObject) { + modifiedArgs[i] = wrap(arg, oldGlobal); + } + } + } + + try { + if (globalChanged) { + NashornScriptEngine.setNashornGlobal(global); + } + return wrap(((ScriptFunction)val).invoke(sobj, modifiedArgs), global); + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } finally { + if (globalChanged) { + NashornScriptEngine.setNashornGlobal(oldGlobal); + } + } + } + + throw new RuntimeException("No such method: " + methodName); + } + + @Override + public Object eval(final String s) { + return inGlobal(new Callable() { + @Override + public Object call() { + return wrap(global.getContext().eval(global, s, null, null, false), global); + } + }); + } + + @Override + public Object getMember(final String name) { + return get(name); + } + + @Override + public Object getSlot(final int index) { + return get(Integer.valueOf(index)); + } + + @Override + public void removeMember(final String name) { + remove(name); + } + + @Override + public void setMember(final String name, final Object value) { + put(name, wrap(value, Context.getGlobal())); + } + + @Override + public void setSlot(final int index, final Object value) { + put(Integer.valueOf(index), wrap(value, Context.getGlobal())); + } + + @Override + public void clear() { + inGlobal(new Callable() { + @Override public Object call() { + sobj.clear(); + return null; + }}); + } + + @Override + public boolean containsKey(final Object key) { + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.containsKey(unwrap(key, global)); + }}); + } + + @Override + public boolean containsValue(final Object value) { + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.containsValue(unwrap(value, global)); + }}); + } + + @Override + public Set> entrySet() { + return inGlobal(new Callable>>() { + @Override public Set> call() { + final Iterator iter = sobj.propertyIterator(); + final Set> entries = new HashSet<>(); + + while (iter.hasNext()) { + final Object key = wrap(iter.next(), global); + final Object value = wrap(sobj.get(key), global); + entries.add(new AbstractMap.SimpleImmutableEntry<>(key, value)); + } + + return Collections.unmodifiableSet(entries); + } + }); + } + + @Override + public Object get(final Object key) { + return inGlobal(new Callable() { @Override public Object call() { + return wrap(sobj.get(key), global); + }}); + } + + @Override + public boolean isEmpty() { + return inGlobal(new Callable() { @Override public Boolean call() { + return sobj.isEmpty(); + }}); + } + + @Override + public Set keySet() { + return inGlobal(new Callable>() { @Override public Set call() { + final Iterator iter = sobj.propertyIterator(); + final Set keySet = new HashSet<>(); + + while (iter.hasNext()) { + keySet.add(wrap(iter.next(), global)); + } + + return Collections.unmodifiableSet(keySet); + }}); + } + + @Override + public Object put(final Object key, final Object value) { + return inGlobal(new Callable() { + @Override public Object call() { + return sobj.put(unwrap(key, global), unwrap(value, global)); + }}); + } + + @Override + public void putAll(final Map map) { + final boolean strict = sobj.getContext()._strict; + inGlobal(new Callable() { @Override public Object call() { + for (final Map.Entry entry : map.entrySet()) { + sobj.set(unwrap(entry.getKey(), global), unwrap(entry.getValue(), global), strict); + } + return null; + }}); + } + + @Override + public Object remove(final Object key) { + return inGlobal(new Callable() { + @Override public Object call() { + return wrap(sobj.remove(unwrap(key, global)), global); + } + }); + } + + @Override + public int size() { + return inGlobal(new Callable() { + @Override public Integer call() { + return sobj.size(); + } + }); + } + + @Override + public Collection values() { + return inGlobal(new Callable>() { @Override public Collection call() { + final List values = new ArrayList<>(size()); + final Iterator iter = sobj.valueIterator(); + + while (iter.hasNext()) { + values.add(wrap(iter.next(), global)); + } + + return Collections.unmodifiableList(values); + }}); + } + + static Object wrap(final Object obj, final ScriptObject homeGlobal) { + return (obj instanceof ScriptObject) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj; + } + + static Object unwrap(final Object obj, final ScriptObject homeGlobal) { + if (obj instanceof ScriptObjectMirror) { + final ScriptObjectMirror mirror = (ScriptObjectMirror)obj; + return (mirror.global == homeGlobal)? mirror.sobj : obj; + } + + return obj; + } + + static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) { + if (args == null || args.length == 0) { + return args; + } + + final Object[] newArgs = new Object[args.length]; + int index = 0; + for (final Object obj : args) { + newArgs[index] = wrap(obj, homeGlobal); + index++; + } + return newArgs; + } + + static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) { + if (args == null || args.length == 0) { + return args; + } + + final Object[] newArgs = new Object[args.length]; + int index = 0; + for (final Object obj : args) { + newArgs[index] = unwrap(obj, homeGlobal); + index++; + } + return newArgs; + } +} diff --git a/nashorn/src/jdk/nashorn/api/scripting/package-info.java b/nashorn/src/jdk/nashorn/api/scripting/package-info.java new file mode 100644 index 00000000000..32472901236 --- /dev/null +++ b/nashorn/src/jdk/nashorn/api/scripting/package-info.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * This package provides the {@code javax.script} integration, which is the preferred way to use Nashorn. + * You will ordinarily do this to obtain an instance of a Nashorn script engine: + *
+ * import javax.script.*;
+ * ...
+ * ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("Nashorn");
+ * 
+ *

Nashorn script engines implement the optional {@link javax.script.Invocable} and {@link javax.script.Compilable} + * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. See + * {@link jdk.nashorn.api.scripting.NashornScriptEngineFactory} for further details. + */ +package jdk.nashorn.api.scripting; diff --git a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js new file mode 100644 index 00000000000..49e8d45b853 --- /dev/null +++ b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * This script file is executed by script engine at the construction + * of the engine. The functions here assume global variables "context" + * of type javax.script.ScriptContext and "engine" of the type + * jdk.nashorn.api.scripting.NashornScriptEngine. + * + **/ + +Object.defineProperty(this, "__noSuchProperty__", { + configurable: true, + enumerable: false, + writable: true, + value: function (name) { + 'use strict'; + return engine.__noSuchProperty__(this, context, name); + } +}); + +Object.defineProperty(this, "__noSuchMethod__", { + configurable: true, + enumerable: false, + writable: true, + value: function (name, args) { + 'use strict'; + return engine.__noSuchMethod__(this, context, name, args); + } +}); + +function print(str) { + var writer = context.getWriter(); + if (! (writer instanceof java.io.PrintWriter)) { + writer = new java.io.PrintWriter(writer); + } + writer.println(String(str)); +} diff --git a/nashorn/src/jdk/nashorn/internal/codegen/AccessSpecializer.java b/nashorn/src/jdk/nashorn/internal/codegen/AccessSpecializer.java new file mode 100644 index 00000000000..56a3e7ecc45 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/codegen/AccessSpecializer.java @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.codegen; + +import java.util.HashSet; +import jdk.nashorn.internal.codegen.types.Type; +import jdk.nashorn.internal.ir.AccessNode; +import jdk.nashorn.internal.ir.Assignment; +import jdk.nashorn.internal.ir.BinaryNode; +import jdk.nashorn.internal.ir.CallNode; +import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.IdentNode; +import jdk.nashorn.internal.ir.IndexNode; +import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.ReferenceNode; +import jdk.nashorn.internal.ir.Symbol; +import jdk.nashorn.internal.ir.TypeOverride; +import jdk.nashorn.internal.ir.UnaryNode; +import jdk.nashorn.internal.ir.VarNode; +import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; +import jdk.nashorn.internal.ir.visitor.NodeVisitor; +import jdk.nashorn.internal.parser.Token; +import jdk.nashorn.internal.parser.TokenType; +import jdk.nashorn.internal.runtime.Debug; +import jdk.nashorn.internal.runtime.DebugLogger; + +/** + * This is a post pass for Lower, that removes casts for accessors to objects in + * Scope, and replaces the accessor type with a narrower one with possible. + * + * Any node that implements TypeOverride will be subject to access specialization. + * + * TypeOverride basically means "type inference has determined that the field x + * is an object, but if you do x & 17, it can be read as an int, which we hope + * coincides with its internal representation. In that case there is no boxing + * that may or may not be removed by the JVM and less data bandwidth. + * + * Ideally this should not be a post pass, but it requires slot AND scope info, and has + * to be run where it is, which is called from {@link CodeGenerator}. + * + * @see TypeOverride + */ + +final class AccessSpecializer extends NodeOperatorVisitor implements Transform { + /** Debug logger for access specialization. Enable it with --log=access:level + or -Dnashorn.specializations.debug */ + private static final DebugLogger LOG = new DebugLogger("access", "nashorn.callsiteaccess.debug"); + private static final boolean DEBUG = LOG.isEnabled(); + + @Override + public Node enter(final FunctionNode node) { + if (node.isTransformApplied(AccessSpecializer.class)) { + return null; + } + + return node; + } + + @Override + public Node leave(final FunctionNode node) { + node.registerTransform(AccessSpecializer.class); + return node; + } + + @Override + public Node leave(final VarNode varNode) { + if (varNode.isAssignment()) { + return leaveAssign(varNode); + } + + return varNode; + } + + @Override + public Node leave(final CallNode callNode) { + final Node function = callNode.getFunction(); + if (function instanceof ReferenceNode) { + changeType(callNode, ((ReferenceNode)function).getReference().getType()); + } + return callNode; + } + + @Override + public Node leaveASSIGN(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_ADD(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_BIT_AND(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_BIT_OR(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_BIT_XOR(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_DIV(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_MOD(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_MUL(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_SAR(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_SHL(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_SHR(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveASSIGN_SUB(final BinaryNode binaryNode) { + return leaveAssign(binaryNode); + } + + @Override + public Node leaveCOMMALEFT(final BinaryNode binaryNode) { + return propagateResultType(binaryNode, binaryNode.lhs().getType()); + } + + @Override + public Node leaveCOMMARIGHT(final BinaryNode binaryNode) { + return propagateResultType(binaryNode, binaryNode.rhs().getType()); + } + + @Override + public Node leaveCONVERT(final UnaryNode unaryNode) { + final Type castTo = unaryNode.getType(); + + Node rhs = unaryNode.rhs(); + + // Go through all conversions until we find the first non-convert node. + while (rhs.tokenType() == TokenType.CONVERT) { + rhs = ((UnaryNode)rhs).rhs(); + } + + // If this node can be type changed + if (canHaveCallSiteType(rhs) && isSupportedCallSiteType(castTo)) { + /* + * Just add a callsite type and throw away the cast, appropriate + * getter/setter is selected, which will do the conversion for us + */ + changeType(rhs, castTo); + fine("*** cast: converting " + debugNode(unaryNode) + " to " + debugNode(rhs)); + + return rhs; + } + + // Micro optimization for node hygiene and pattern detection - remove unnecessary same type cast + if (unaryNode.getType().isEquivalentTo(rhs.getType())) { + return rhs; + } + + return unaryNode; + } + + @Override + public Node leaveDECINC(final UnaryNode unaryNode) { + assert unaryNode.isAssignment(); + + final Node dest = unaryNode.getAssignmentDest(); + if (canHaveCallSiteType(dest) && isSupportedCallSiteType(unaryNode.getType())) { + changeTypeInAssignment(dest, unaryNode.getType()); + } + + return unaryNode; + } + + /** + * Is this a node that can have its type overridden. This is true for + * AccessNodes, IndexNodes and IdentNodes + * + * @param node the node to check + * @return true if node can have a callsite type + */ + private static boolean canHaveCallSiteType(final Node node) { + return node instanceof TypeOverride && ((TypeOverride)node).canHaveCallSiteType(); + } + + /** + * Is the specialization type supported. Currently we treat booleans as objects + * and have no special boolean type accessor, thus booleans are ignored. + * TODO - support booleans? NASHORN-590 + * + * @param castTo the type to check + * @return true if call site type is supported + */ + private static boolean isSupportedCallSiteType(final Type castTo) { + return castTo.isNumeric(); // don't specializable for boolean + } + + /** + * Turn a node into a covert node + * + * @param node the node + * @return the node as a convert node + */ + private static Node convert(final Node node) { + return new UnaryNode(node.getSource(), + Token.recast(node.getToken(), TokenType.CONVERT), + node); + } + + private static Node leaveAssign(final Node node) { + assert node.isAssignment() : node + " is not an assignment"; + + + final Node lhs = ((Assignment)node).getAssignmentDest(); + Node rhs = ((Assignment)node).getAssignmentSource(); + + /** + * Nodes with local variable slots are assumed to be of their optimal type + * already and aren't affected here. This is not strictly true, for instance + * with doubles instead of in a bounded loop. TODO - range check: NASHORN-363 + * + * This is also not strictly true for var y = x = 55; where y has no other uses + * Then y can be an int, but lower conservatively does an object of the assign to + * scope + */ + final Symbol lhsSymbol = lhs.getSymbol(); + + if (lhsSymbol.hasSlot() && !lhsSymbol.isScope()) { + finest(lhs.getSymbol() + " has slot!"); + if (!lhs.getType().isEquivalentTo(rhs.getType())) { + finest("\tslot assignment: " +lhs.getType()+ " " +rhs.getType() + " " + debugNode(node)); + + final Node c = convert(rhs); + c.setSymbol(lhsSymbol); + ((Assignment)node).setAssignmentSource(c); + + fine("*** slot assignment turned to : " + debugNode(node)); + } else { + finest("aborted - type equivalence between lhs and rhs"); + } + + return node; + } + + // e.g. __DIR__, __LINE__, __FILE__ - don't try to change these + if (lhs instanceof IdentNode && ((IdentNode)lhs).isSpecialIdentity()) { + return node; + } + + /** + * Try to cast to the type of the right hand side, now pruned. E.g. an (object)17 should + * now be just 17, an int. + */ + Type castTo = rhs.getType(); + + // If LHS can't get a new type, neither can rhs - retain the convert + if (!canHaveCallSiteType(lhs)) { + return node; + } + + // Take the narrowest type of the entire cast sequence + while (rhs.tokenType() == TokenType.CONVERT) { + rhs = ((UnaryNode)rhs).rhs(); + castTo = Type.narrowest(rhs.getType(), castTo); //e.g. (object)(int) -> int even though object is outermost + } + + // If castTo is wider than widestOperationType, castTo can be further slowed down + final Type widestOperationType = node.getWidestOperationType(); + finest("node wants to be " + castTo + " and its widest operation is " + widestOperationType); + + if (widestOperationType != castTo && Type.widest(castTo, widestOperationType) == castTo) { + info("###" + node + " castTo was " + castTo + " but could be downgraded to " + node.getWidestOperationType()); + castTo = node.getWidestOperationType(); + if (rhs instanceof TypeOverride) { + changeType(rhs, castTo); + } + } + + /* + * If this is a self modifying op, we can't be narrower than the widest optype + * or e.g. x = x + 12 and x += 12 will turn into different things + */ + if (node.isSelfModifying()) { + castTo = Type.widest(widestOperationType, castTo); + } + + // We only specialize for numerics, not for booleans. + if (isSupportedCallSiteType(castTo)) { + if (rhs.getType() != castTo) { + finest("cast was necessary, abort: " + node + " " + rhs.getType() + " != " + castTo); + return node; + } + + finest("assign: " + debugNode(node)); + + changeTypeInAssignment(lhs, castTo); + ((Assignment)node).setAssignmentSource(rhs); + + info("### modified to " + debugNode(node) + " (given type override " + castTo + ")"); + + propagateResultType(node, castTo); + } + + return node; + } + + private static Node propagateResultType(final Node node, final Type type) { + //warning! this CANNOT be done for non temporaries as they are used in other computations + if (isSupportedCallSiteType(type)) { + if (node.getSymbol().isTemp()) { + finest("changing temporary type: " + debugNode(node) + " to " + type); + node.getSymbol().setTypeOverride(type); + info("### node modified to " + debugNode(node) + " (given type override " + type + ")"); + } + } + return node; + } + + private static void changeTypeInAssignment(final Node dest, final Type newType) { + if (changeType(dest, newType)) { + finest("changed assignment " + dest + " " + dest.getSymbol()); + assert !newType.isObject(); + + final HashSet exclude = new HashSet<>(); + + dest.accept(new NodeVisitor() { + + private void setCanBePrimitive(final Symbol symbol) { + fine("*** can be primitive symbol " + symbol + " " + Debug.id(symbol)); + symbol.setCanBePrimitive(newType); + } + + @Override + public Node enter(final IdentNode identNode) { + if (!exclude.contains(identNode)) { + setCanBePrimitive(identNode.getSymbol()); + } + return null; + } + + @Override + public Node enter(final AccessNode accessNode) { + setCanBePrimitive(accessNode.getProperty().getSymbol()); + return null; + } + + @Override + public Node enter(final IndexNode indexNode) { + exclude.add(indexNode.getBase()); //prevent array base node to be flagged as primitive, but k in a[k++] is fine + return indexNode; + } + + }); + } + } + + private static boolean changeType(final Node node, final Type newType) { + if (!node.getType().equals(newType)) { + ((TypeOverride)node).setType(newType); + return true; + } + return false; + } + + private static String debugNode(final Node node) { + if (DEBUG) { + return node.toString(); + } + return ""; + } + + private static void info(final String str) { + LOG.info(str); + } + + private static void fine(final String str) { + LOG.fine(str); + } + + private static void finest(final String str) { + LOG.finest(str); + } + +} diff --git a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java new file mode 100644 index 00000000000..e15633f801e --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.codegen; + +import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.EQ; +import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.GE; +import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.GT; +import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.LE; +import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.LT; +import static jdk.nashorn.internal.codegen.MethodEmitter.Condition.NE; + +import jdk.nashorn.internal.codegen.MethodEmitter.Label; +import jdk.nashorn.internal.codegen.types.Type; +import jdk.nashorn.internal.ir.BinaryNode; +import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.TernaryNode; +import jdk.nashorn.internal.ir.UnaryNode; + +/** + * Branch optimizer for CodeGenerator. Given a jump condition this helper + * class attempts to simplify the control flow + */ +final class BranchOptimizer { + + private final CodeGenerator codegen; + private final MethodEmitter method; + + BranchOptimizer(final CodeGenerator codegen, final MethodEmitter method) { + this.codegen = codegen; + this.method = method; + } + + void execute(final Node node, final Label label, final boolean state) { + branchOptimizer(node, label, state); + } + + private void load(final Node node) { + codegen.load(node); + } + + private void branchOptimizer(final UnaryNode unaryNode, final Label label, final boolean state) { + final Node rhs = unaryNode.rhs(); + + switch (unaryNode.tokenType()) { + case NOT: + branchOptimizer(rhs, label, !state); + return; + case CONVERT: + if (unaryNode.getType().isBoolean()) { + branchOptimizer(rhs, label, state); + return; + } + break; + default: + break; + } + + // convert to boolean + load(unaryNode); + method.convert(Type.BOOLEAN); + if (state) { + method.ifne(label); + } else { + method.ifeq(label); + } + } + + private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) { + final Node lhs = binaryNode.lhs(); + final Node rhs = binaryNode.rhs(); + + switch (binaryNode.tokenType()) { + case AND: + if (state) { + final Label skip = new Label("skip"); + branchOptimizer(lhs, skip, false); + branchOptimizer(rhs, label, true); + method.label(skip); + } else { + branchOptimizer(lhs, label, false); + branchOptimizer(rhs, label, false); + } + return; + + case OR: + if (state) { + branchOptimizer(lhs, label, true); + branchOptimizer(rhs, label, true); + } else { + final Label skip = new Label("skip"); + branchOptimizer(lhs, skip, true); + branchOptimizer(rhs, label, false); + method.label(skip); + } + return; + + case EQ: + case EQ_STRICT: + assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); + load(lhs); + load(rhs); + method.conditionalJump(state ? EQ : NE, true, label); + return; + + case NE: + case NE_STRICT: + assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); + load(lhs); + load(rhs); + method.conditionalJump(state ? NE : EQ, true, label); + return; + + case GE: + assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); + load(lhs); + load(rhs); + method.conditionalJump(state ? GE : LT, !state, label); + return; + + case GT: + assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); + load(lhs); + load(rhs); + method.conditionalJump(state ? GT : LE, !state, label); + return; + + case LE: + assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol(); + load(lhs); + load(rhs); + method.conditionalJump(state ? LE : GT, state, label); + return; + + case LT: + assert rhs.getType().isEquivalentTo(lhs.getType()) : "type mismatch: " + lhs.getSymbol() + " to " + rhs.getSymbol() + " in " + binaryNode; + load(lhs); + load(rhs); + method.conditionalJump(state ? LT : GE, state, label); + return; + + default: + break; + } + + load(binaryNode); + method.convert(Type.BOOLEAN); + if (state) { + method.ifne(label); + } else { + method.ifeq(label); + } + } + + private void branchOptimizer(final Node node, final Label label, final boolean state) { + if (!(node instanceof TernaryNode)) { + + if (node instanceof BinaryNode) { + branchOptimizer((BinaryNode)node, label, state); + return; + } + + if (node instanceof UnaryNode) { + branchOptimizer((UnaryNode)node, label, state); + return; + } + } + + load(node); + method.convert(Type.BOOLEAN); + if (state) { + method.ifne(label); + } else { + method.ifeq(label); + } + } +} diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java new file mode 100644 index 00000000000..9b95cf836f9 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/codegen/ClassEmitter.java @@ -0,0 +1,620 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.codegen; + +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_VARARGS; +import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEINTERFACE; +import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESPECIAL; +import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC; +import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEVIRTUAL; +import static jdk.internal.org.objectweb.asm.Opcodes.H_NEWINVOKESPECIAL; +import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; +import static jdk.nashorn.internal.codegen.CompilerConstants.CLINIT; +import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS; +import static jdk.nashorn.internal.codegen.CompilerConstants.GET_ARRAY_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.GET_ARRAY_SUFFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP; +import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING; +import static jdk.nashorn.internal.codegen.CompilerConstants.INIT; +import static jdk.nashorn.internal.codegen.CompilerConstants.SET_MAP; +import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE; +import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE; +import static jdk.nashorn.internal.codegen.CompilerConstants.className; +import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor; +import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; +import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.util.TraceClassVisitor; +import jdk.nashorn.internal.codegen.types.Type; +import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.Source; + +/** + * The interface responsible for speaking to ASM, emitting classes, + * fields and methods. + *

+ * This file contains the ClassEmitter, which is the master object + * responsible for writing byte codes. It utilizes a MethodEmitter + * for method generation, which also the NodeVisitors own, to keep + * track of the current code generator and what it is doing. + *

+ * There is, however, nothing stopping you from using this in a + * completely self contained environment, for example in ObjectGenerator + * where there are no visitors or external hooks. + *

+ * MethodEmitter makes it simple to generate code for methods without + * having to do arduous type checking. It maintains a type stack + * and will pick the appropriate operation for all operations sent to it + * We also allow chained called to a MethodEmitter for brevity, e.g. + * it is legal to write _new(className).dup() or + * load(slot).load(slot2).xor().store(slot3); + *

+ * If running with assertions enabled, any type conflict, such as different + * bytecode stack sizes or operating on the wrong type will be detected + * and an error thrown. + *

+ * There is also a very nice debug interface that can emit formatted + * bytecodes that have been written. This is enabled by setting the + * environment "nashorn.codegen.debug" to true, or --log=codegen: + *

+ * A ClassEmitter implements an Emitter - i.e. it needs to have + * well defined start and end calls for whatever it is generating. Assertions + * detect if this is not true + * + * @see Compiler + * @see CodeGenerator + */ +public class ClassEmitter implements Emitter { + + /** Sanity check flag - have we started on a class? */ + private boolean classStarted; + + /** Sanity check flag - have we ended this emission? */ + private boolean classEnded; + + /** + * Sanity checks - which methods have we currently + * started for generation in this class? + */ + private final HashSet methodsStarted; + + /** The ASM classwriter that we use for all bytecode operations */ + protected final ClassWriter cw; + + /** The context */ + protected final Context context; + + /** Default flags for class generation - oublic class */ + private static final EnumSet DEFAULT_METHOD_FLAGS = EnumSet.of(Flag.PUBLIC); + + /** Compile unit class name. */ + private String unitClassName; + + /** Set of constants access methods required. */ + private Set> constantMethodNeeded; + + /** + * Constructor - only used internally in this class as it breaks + * abstraction towards ASM or other code generator below + * + * @param context context + * @param cw ASM classwriter + */ + private ClassEmitter(final Context context, final ClassWriter cw) { + assert context != null; + + this.context = context; + this.cw = cw; + this.methodsStarted = new HashSet<>(); + } + + /** + * Constructor + * + * @param context context + * @param className name of class to weave + * @param superClassName super class name for class + * @param interfaceNames names of interfaces implemented by this class, or null if none + */ + public ClassEmitter(final Context context, final String className, final String superClassName, final String... interfaceNames) { + this(context, new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS)); + cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, className, null, superClassName, interfaceNames); + } + + /** + * Constructor from the compiler + * + * @param compiler Compiler + * @param unitClassName Compile unit class name. + * @param strictMode Should we generate this method in strict mode + */ + ClassEmitter(final Compiler compiler, final String unitClassName, final boolean strictMode) { + this(compiler.getContext(), + new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) { + private static final String OBJECT_CLASS = "java/lang/Object"; + + @Override + protected String getCommonSuperClass(final String type1, final String type2) { + try { + return super.getCommonSuperClass(type1, type2); + } catch (final RuntimeException e) { + if (isScriptObject(Compiler.SCRIPTS_PACKAGE, type1) && isScriptObject(Compiler.SCRIPTS_PACKAGE, type2)) { + return className(ScriptObject.class); + } + return OBJECT_CLASS; + } + } + }); + + this.unitClassName = unitClassName; + this.constantMethodNeeded = new HashSet<>(); + + cw.visit(V1_7, ACC_PUBLIC | ACC_SUPER, unitClassName, null, Compiler.pathName(jdk.nashorn.internal.scripts.JS$.class.getName()), null); + cw.visitSource(compiler.getSource().getName(), null); + + defineCommonStatics(strictMode); + } + + /** + * Define the static fields common in all scripts. + * @param strictMode Should we generate this method in strict mode + */ + private void defineCommonStatics(final boolean strictMode) { + // source - used to store the source data (text) for this script. Shared across + // compile units. Set externally by the compiler. + field(EnumSet.of(Flag.PUBLIC, Flag.STATIC), SOURCE.tag(), Source.class); + + // constants - used to the constants array for this script. Shared across + // compile units. Set externally by the compiler. + field(EnumSet.of(Flag.PUBLIC, Flag.STATIC), CONSTANTS.tag(), Object[].class); + + // strictMode - was this script compiled in strict mode. Set externally by the compiler. + field(EnumSet.of(Flag.PUBLIC, Flag.STATIC, Flag.FINAL), STRICT_MODE.tag(), boolean.class, strictMode); + } + + /** + * Define static utilities common needed in scripts. These are per compile unit + * and therefore have to be defined here and not in code gen. + */ + private void defineCommonUtilities() { + assert unitClassName != null; + + if (constantMethodNeeded.contains(String.class)) { + // $getString - get the ith entry from the constants table and cast to String. + final MethodEmitter getStringMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), GET_STRING.tag(), String.class, int.class); + getStringMethod.begin(); + getStringMethod.getStatic(unitClassName, CONSTANTS.tag(), CONSTANTS.descriptor()) + .load(Type.INT, 0) + .arrayload() + .checkcast(String.class) + ._return(); + getStringMethod.end(); + } + + if (constantMethodNeeded.contains(PropertyMap.class)) { + // $getMap - get the ith entry from the constants table and cast to PropertyMap. + final MethodEmitter getMapMethod = method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), GET_MAP.tag(), PropertyMap.class, int.class); + getMapMethod.begin(); + getMapMethod.loadConstants(unitClassName) + .load(Type.INT, 0) + .arrayload() + .checkcast(PropertyMap.class) + ._return(); + getMapMethod.end(); + + // $setMap - overwrite an existing map. + final MethodEmitter setMapMethod = method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), SET_MAP.tag(), void.class, int.class, PropertyMap.class); + setMapMethod.begin(); + setMapMethod.loadConstants(unitClassName) + .load(Type.INT, 0) + .load(Type.OBJECT, 1) + .arraystore(); + setMapMethod.returnVoid(); + setMapMethod.end(); + } + + // $getXXXX$array - get the ith entry from the constants table and cast to XXXX[]. + for (final Class cls : constantMethodNeeded) { + if (cls.isArray()) { + defineGetArrayMethod(cls); + } + } + } + + /** + * Constructs a primitive specific method for getting the ith entry from the constants table and cast. + * @param cls Array class. + */ + private void defineGetArrayMethod(final Class cls) { + assert unitClassName != null; + + final String methodName = getArrayMethodName(cls); + final MethodEmitter getArrayMethod = method(EnumSet.of(Flag.PRIVATE, Flag.STATIC), methodName, cls, int.class); + + getArrayMethod.begin(); + getArrayMethod.getStatic(unitClassName, CONSTANTS.tag(), CONSTANTS.descriptor()) + .load(Type.INT, 0) + .arrayload() + .checkcast(cls) + .dup() + .arraylength() + .invoke(staticCallNoLookup(Arrays.class, "copyOf", cls, cls, int.class)) + ._return(); + getArrayMethod.end(); + } + + /** + * Generate the name of a get array from constant pool method. + * @param cls Name of array class. + * @return Method name. + */ + static String getArrayMethodName(final Class cls) { + assert cls.isArray(); + return GET_ARRAY_PREFIX.tag() + cls.getComponentType().getSimpleName() + GET_ARRAY_SUFFIX.tag(); + } + + /** + * Ensure a get constant method is issued for the class. + * @param cls Class of constant. + */ + public void needGetConstantMethod(final Class cls) { + constantMethodNeeded.add(cls); + } + + /** + * Inspect class name and decide whether we are generating a ScriptObject class + * + * @param scriptPrefix the script class prefix for the current script + * @param type the type to check + * + * @return true if type is ScriptObject + */ + private static boolean isScriptObject(final String scriptPrefix, final String type) { + if (type.startsWith(scriptPrefix)) { + return true; + } else if (type.equals(CompilerConstants.className(ScriptObject.class))) { + return true; + } else if (type.startsWith(Compiler.OBJECTS_PACKAGE)) { + return true; + } + + return false; + } + + /** + * Call at beginning of class emission + * @see Emitter + */ + @Override + public void begin() { + classStarted = true; + } + + /** + * Call at end of class emission + * @see Emitter + */ + @Override + public void end() { + assert classStarted; + + if (unitClassName != null) { + defineCommonUtilities(); + } + + cw.visitEnd(); + classStarted = false; + classEnded = true; + assert methodsStarted.isEmpty() : "methodsStarted not empty " + methodsStarted; + } + + /** + * Disassemble an array of byte code. + * + * @param context the context + * @param bytecode byte array representing bytecode + */ + public static void disassemble(final Context context, final byte[] bytecode) { + new ClassReader(bytecode).accept(new TraceClassVisitor(context.getErr()), 0); + } + + /** + * Verify an array of byte code as a valid Java class + * + * @param context the context + * @param bytecode the bytecode array + */ + public static void verify(final Context context, final byte[] bytecode) { + context.verify(bytecode); + } + + /** + * @return context used for class emission + */ + Context getContext() { + return context; + } + + /** + * Call back from MethodEmitter for method start + * + * @see MethodEmitter + * + * @param method method emitter. + */ + void beginMethod(final MethodEmitter method) { + assert !methodsStarted.contains(method); + methodsStarted.add(method); + } + + /** + * Call back from MethodEmitter for method end + * + * @see MethodEmitter + * + * @param method + */ + void endMethod(final MethodEmitter method) { + assert methodsStarted.contains(method); + methodsStarted.remove(method); + } + + /** + * Add a new method to the class - defaults to public method + * + * @param methodName name of method + * @param rtype return type of the method + * @param ptypes parameter types the method + * + * @return method emitter to use for weaving this method + */ + public MethodEmitter method(final String methodName, final Class rtype, final Class... ptypes) { + return method(DEFAULT_METHOD_FLAGS, methodName, rtype, ptypes); //TODO why public default ? + } + + /** + * Add a new method to the class - defaults to public method + * + * @param methodFlags access flags for the method + * @param methodName name of method + * @param rtype return type of the method + * @param ptypes parameter types the method + * + * @return method emitter to use for weaving this method + */ + public MethodEmitter method(final EnumSet methodFlags, final String methodName, final Class rtype, final Class... ptypes) { + return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, methodDescriptor(rtype, ptypes), null, null)); + } + + /** + * Add a new method to the class - defaults to public method + * + * @param methodName name of method + * @param descriptor descriptor of method + * + * @return method emitter to use for weaving this method + */ + public MethodEmitter method(final String methodName, final String descriptor) { + return method(DEFAULT_METHOD_FLAGS, methodName, descriptor); + } + + /** + * Add a new method to the class - defaults to public method + * + * @param methodFlags access flags for the method + * @param methodName name of method + * @param descriptor descriptor of method + * + * @return method emitter to use for weaving this method + */ + public MethodEmitter method(final EnumSet methodFlags, final String methodName, final String descriptor) { + return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, descriptor, null, null)); + } + + /** + * Add a new method to the class, representing a function node + * + * @param functionNode the function node to generate a method for + * @return method emitter to use for weaving this method + */ + public MethodEmitter method(final FunctionNode functionNode) { + final MethodVisitor mv = cw.visitMethod( + ACC_PUBLIC | ACC_STATIC | (functionNode.isVarArg() ? ACC_VARARGS : 0), + functionNode.getName(), + FunctionSignature.functionSignature(functionNode), + null, + null); + + return new MethodEmitter(this, mv, functionNode); + } + + /** + * Start generating the method in the class + * + * @return method emitter to use for weaving + */ + public MethodEmitter clinit() { + return method(EnumSet.of(Flag.STATIC), CLINIT.tag(), void.class); + } + + /** + * Start generating an ()V method in the class + * + * @return method emitter to use for weaving ()V + */ + public MethodEmitter init() { + return method(INIT.tag(), void.class); + } + + /** + * Start generating an ()V method in the class + * + * @param ptypes parameter types for constructor + * @return method emitter to use for weaving ()V + */ + public MethodEmitter init(final Class... ptypes) { + return method(INIT.tag(), void.class, ptypes); + } + + /** + * Start generating an (...)V method in the class + * + * @param flags access flags for the constructor + * @param ptypes parameter types for the constructor + * + * @return method emitter to use for weaving (...)V + */ + public MethodEmitter init(final EnumSet flags, final Class... ptypes) { + return method(flags, INIT.tag(), void.class, ptypes); + } + + /** + * Add a field to the class, initialized to a value + * + * @param fieldFlags flags, e.g. should it be static or public etc + * @param fieldName name of field + * @param fieldType the type of the field + * @param value the value + * + * @see ClassEmitter.Flag + */ + public final void field(final EnumSet fieldFlags, final String fieldName, final Class fieldType, final Object value) { + cw.visitField(Flag.getValue(fieldFlags), fieldName, typeDescriptor(fieldType), null, value).visitEnd(); + } + + /** + * Add a field to the class + * + * @param fieldFlags access flags for the field + * @param fieldName name of field + * @param fieldType type of the field + * + * @see ClassEmitter.Flag + */ + public final void field(final EnumSet fieldFlags, final String fieldName, final Class fieldType) { + field(fieldFlags, fieldName, fieldType, null); + } + + /** + * Add a field to the class - defaults to public + * + * @param fieldName name of field + * @param fieldType type of field + */ + public final void field(final String fieldName, final Class fieldType) { + field(EnumSet.of(Flag.PUBLIC), fieldName, fieldType, null); + } + + /** + * Return a bytecode array from this ClassEmitter. The ClassEmitter must + * have been ended (having its end function called) for this to work. + * + * @return byte code array for generated class, null if class generation hasn't been ended with {@link ClassEmitter#end()} + */ + public byte[] toByteArray() { + assert classEnded; + if (!classEnded) { + return null; + } + + return cw.toByteArray(); + } + + /** + * Abstraction for flags used in class emission + * + * We provide abstraction separating these from the underlying bytecode + * emitter. + * + * Flags are provided for method handles, protection levels, static/virtual + * fields/methods. + */ + public static enum Flag { + /** method handle with static access */ + HANDLE_STATIC(H_INVOKESTATIC), + /** method handle with new invoke special access */ + HANDLE_NEWSPECIAL(H_NEWINVOKESPECIAL), + /** method handle with invoke special access */ + HANDLE_SPECIAL(H_INVOKESPECIAL), + /** method handle with invoke virtual access */ + HANDLE_VIRTUAL(H_INVOKEVIRTUAL), + /** method handle with invoke interface access */ + HANDLE_INTERFACE(H_INVOKEINTERFACE), + + /** final access */ + FINAL(ACC_FINAL), + /** static access */ + STATIC(ACC_STATIC), + /** public access */ + PUBLIC(ACC_PUBLIC), + /** private access */ + PRIVATE(ACC_PRIVATE); + + private int value; + + private Flag(final int value) { + this.value = value; + } + + /** + * Get the value of this flag + * @return the int value + */ + public int getValue() { + return value; + } + + /** + * Return the corresponding ASM flag value for an enum set of flags + * + * @param flags enum set of flags + * @return an integer value representing the flags intrinsic values or:ed together + */ + public static int getValue(final EnumSet flags) { + int v = 0; + for (final Flag flag : flags) { + v |= flag.getValue(); + } + return v; + } + } + +} diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java new file mode 100644 index 00000000000..71dc3a7bcb4 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -0,0 +1,3266 @@ +/* + * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.codegen; + +import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.PRIVATE; +import static jdk.nashorn.internal.codegen.ClassEmitter.Flag.STATIC; +import static jdk.nashorn.internal.codegen.CompilerConstants.GET_MAP; +import static jdk.nashorn.internal.codegen.CompilerConstants.GET_STRING; +import static jdk.nashorn.internal.codegen.CompilerConstants.LEAF; +import static jdk.nashorn.internal.codegen.CompilerConstants.QUICK_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.REGEX_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE; +import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_ARRAY_ARG; +import static jdk.nashorn.internal.codegen.CompilerConstants.SPLIT_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.interfaceCallNoLookup; +import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor; +import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; +import static jdk.nashorn.internal.codegen.CompilerConstants.staticField; +import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; +import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; +import static jdk.nashorn.internal.ir.Symbol.IS_TEMP; +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE; +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FUNCTION_DECLARATION; +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_SCOPE; +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import jdk.nashorn.internal.codegen.ClassEmitter.Flag; +import jdk.nashorn.internal.codegen.CompilerConstants.Call; +import jdk.nashorn.internal.codegen.MethodEmitter.Condition; +import jdk.nashorn.internal.codegen.MethodEmitter.Label; +import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode; +import jdk.nashorn.internal.codegen.objects.FieldObjectCreator; +import jdk.nashorn.internal.codegen.objects.FunctionObjectCreator; +import jdk.nashorn.internal.codegen.objects.MapCreator; +import jdk.nashorn.internal.codegen.objects.ObjectMapCreator; +import jdk.nashorn.internal.codegen.types.ArrayType; +import jdk.nashorn.internal.codegen.types.Type; +import jdk.nashorn.internal.ir.AccessNode; +import jdk.nashorn.internal.ir.BaseNode; +import jdk.nashorn.internal.ir.BinaryNode; +import jdk.nashorn.internal.ir.Block; +import jdk.nashorn.internal.ir.BreakNode; +import jdk.nashorn.internal.ir.CallNode; +import jdk.nashorn.internal.ir.CaseNode; +import jdk.nashorn.internal.ir.CatchNode; +import jdk.nashorn.internal.ir.ContinueNode; +import jdk.nashorn.internal.ir.DoWhileNode; +import jdk.nashorn.internal.ir.EmptyNode; +import jdk.nashorn.internal.ir.ExecuteNode; +import jdk.nashorn.internal.ir.ForNode; +import jdk.nashorn.internal.ir.FunctionNode; +import jdk.nashorn.internal.ir.IdentNode; +import jdk.nashorn.internal.ir.IfNode; +import jdk.nashorn.internal.ir.IndexNode; +import jdk.nashorn.internal.ir.LineNumberNode; +import jdk.nashorn.internal.ir.LiteralNode; +import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; +import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; +import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.ObjectNode; +import jdk.nashorn.internal.ir.PropertyNode; +import jdk.nashorn.internal.ir.ReferenceNode; +import jdk.nashorn.internal.ir.ReturnNode; +import jdk.nashorn.internal.ir.RuntimeNode; +import jdk.nashorn.internal.ir.RuntimeNode.Request; +import jdk.nashorn.internal.ir.SplitNode; +import jdk.nashorn.internal.ir.SwitchNode; +import jdk.nashorn.internal.ir.Symbol; +import jdk.nashorn.internal.ir.TernaryNode; +import jdk.nashorn.internal.ir.ThrowNode; +import jdk.nashorn.internal.ir.TryNode; +import jdk.nashorn.internal.ir.UnaryNode; +import jdk.nashorn.internal.ir.VarNode; +import jdk.nashorn.internal.ir.WhileNode; +import jdk.nashorn.internal.ir.WithNode; +import jdk.nashorn.internal.ir.debug.ASTWriter; +import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; +import jdk.nashorn.internal.ir.visitor.NodeVisitor; +import jdk.nashorn.internal.parser.Lexer.RegexToken; +import jdk.nashorn.internal.parser.TokenType; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ECMAException; +import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.Scope; +import jdk.nashorn.internal.runtime.ScriptFunction; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.Source; +import jdk.nashorn.internal.runtime.Undefined; +import jdk.nashorn.internal.runtime.linker.LinkerCallSite; + +/** + * This is the lowest tier of the code generator. It takes lowered ASTs emitted + * from Lower and emits Java byte code. The byte code emission logic is broken + * out into MethodEmitter. MethodEmitter works internally with a type stack, and + * keeps track of the contents of the byte code stack. This way we avoid a large + * number of special cases on the form + *

+ * {@code
+ * if (type == INT) {
+ *     visitInsn(ILOAD, slot);
+ * } else if (type == DOUBLE) {
+ *     visitInsn(DOUBLE, slot);
+ * }
+ * }
+ * 
+ * This quickly became apparent when the code generator was generalized to work + * with all types, and not just numbers or objects. + *

+ * The CodeGenerator visits nodes only once, tags them as resolved and emits + * bytecode for them. + */ +public final class CodeGenerator extends NodeOperatorVisitor { + + /** Current compiler */ + private final Compiler compiler; + + /** Compiler context */ + private final Context context; + + /** Call site flags given to the code generator to be used for all generated call sites */ + private final int callSiteFlags; + + /** How many regexp fields have been emitted */ + private int regexFieldCount; + + /** Map of shared scope call sites */ + private final Map scopeCalls = new HashMap<>(); + + /** When should we stop caching regexp expressions in fields to limit bytecode size? */ + private static final int MAX_REGEX_FIELDS = 2 * 1024; + + /** + * Constructor. + * + * @param compiler + */ + CodeGenerator(final Compiler compiler) { + this.compiler = compiler; + this.context = compiler.getContext(); + this.callSiteFlags = context._callsite_flags; + } + + /** + * Get the compiler + * + * @return the compiler used + */ + public Compiler getCompiler() { + return compiler; + } + + /** + * Gets the call site flags, adding the strict flag if the current function + * being generated is in strict mode + * + * @return the correct flags for a call site in the current function + */ + public int getCallSiteFlags() { + return getCurrentFunctionNode().isStrictMode() ? callSiteFlags | CALLSITE_STRICT : callSiteFlags; + } + + /** + * Load an identity node + * + * @param identNode an identity node to load + * @return the method generator used + */ + private MethodEmitter loadIdent(final IdentNode identNode) { + final Symbol symbol = identNode.getSymbol(); + + if (!symbol.isScope()) { + assert symbol.hasSlot() && symbol.getSlot() != 0 || symbol.isThis(); + return method.load(symbol); + } + + final String name = symbol.getName(); + + if (CompilerConstants.__FILE__.name().equals(name)) { + return method.load(identNode.getSource().getName()); + } else if (CompilerConstants.__DIR__.name().equals(name)) { + return method.load(identNode.getSource().getBase()); + } else if (CompilerConstants.__LINE__.name().equals(name)) { + return method.load(identNode.getSource().getLine(identNode.position())).convert(Type.OBJECT); + } else { + assert identNode.getSymbol().isScope() : identNode + " is not in scope!"; + + final int flags = CALLSITE_SCOPE | getCallSiteFlags(); + method.loadScope(); + + if (symbol.isFastScope(getCurrentFunctionNode())) { + // Only generate shared scope getter for fast-scope symbols so we know we can dial in correct scope. + if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD) { + return loadSharedScopeVar(identNode.getType(), symbol, flags); + } + return loadFastScopeVar(identNode.getType(), symbol, flags, identNode.isFunction()); + } + return method.dynamicGet(identNode.getType(), identNode.getName(), flags, identNode.isFunction()); + } + } + + private MethodEmitter loadSharedScopeVar(final Type valueType, final Symbol symbol, final int flags) { + method.load(symbol.isFastScope(getCurrentFunctionNode()) ? getScopeProtoDepth(getCurrentBlock(), symbol) : -1); + final SharedScopeCall scopeCall = getScopeGet(valueType, symbol, flags | CALLSITE_FAST_SCOPE); + scopeCall.generateInvoke(method); + return method; + } + + private MethodEmitter loadFastScopeVar(final Type valueType, final Symbol symbol, final int flags, final boolean isMethod) { + loadFastScopeProto(symbol, false); + method.dynamicGet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE, isMethod); + return method; + } + + private MethodEmitter storeFastScopeVar(final Type valueType, final Symbol symbol, final int flags) { + loadFastScopeProto(symbol, true); + method.dynamicSet(valueType, symbol.getName(), flags | CALLSITE_FAST_SCOPE); + return method; + } + + private static int getScopeProtoDepth(final Block currentBlock, final Symbol symbol) { + if (currentBlock == symbol.getBlock()) { + return 0; + } + + final int delta = currentBlock.needsScope() ? 1 : 0; + final Block parentBlock = currentBlock.getParent(); + + if (parentBlock != null) { + final int result = getScopeProtoDepth(parentBlock, symbol); + if (result != -1) { + return delta + result; + } + } + + if (currentBlock instanceof FunctionNode) { + for (final Block lookupBlock : ((FunctionNode)currentBlock).getReferencingParentBlocks()) { + final int result = getScopeProtoDepth(lookupBlock, symbol); + if (result != -1) { + return delta + result; + } + } + } + + return -1; + } + + private void loadFastScopeProto(final Symbol symbol, final boolean swap) { + final int depth = getScopeProtoDepth(getCurrentBlock(), symbol); + assert depth != -1; + if(depth > 0) { + if (swap) { + method.swap(); + } + for (int i = 0; i < depth; i++) { + method.invoke(ScriptObject.GET_PROTO); + } + if (swap) { + method.swap(); + } + } + } + + /** + * Generate code that loads this node to the stack. This method is only + * public to be accessible from the maps sub package. Do not call externally + * + * @param node node to load + * + * @return the method emitter used + */ + public MethodEmitter load(final Node node) { + return load(node, false); + } + + private MethodEmitter load(final Node node, final boolean baseAlreadyOnStack) { + final Symbol symbol = node.getSymbol(); + + // If we lack symbols, we just generate what we see. + if (symbol == null) { + node.accept(this); + return method; + } + + /* + * The load may be of type IdentNode, e.g. "x", AccessNode, e.g. "x.y" + * or IndexNode e.g. "x[y]". Both AccessNodes and IndexNodes are + * BaseNodes and the logic for loading the base object is reused + */ + final CodeGenerator codegen = this; + + node.accept(new NodeVisitor(compileUnit, method) { + @Override + public Node enter(final IdentNode identNode) { + loadIdent(identNode); + return null; + } + + @Override + public Node enter(final AccessNode accessNode) { + if (!baseAlreadyOnStack) { + load(accessNode.getBase()).convert(Type.OBJECT); + } + assert method.peekType().isObject(); + method.dynamicGet(node.getType(), accessNode.getProperty().getName(), getCallSiteFlags(), accessNode.isFunction()); + return null; + } + + @Override + public Node enter(final IndexNode indexNode) { + if (!baseAlreadyOnStack) { + load(indexNode.getBase()); + load(indexNode.getIndex()); + } + method.dynamicGetIndex(node.getType(), getCallSiteFlags(), indexNode.isFunction()); + return null; + } + + @Override + public Node enterDefault(final Node otherNode) { + otherNode.accept(codegen); // generate code for whatever we are looking at. + method.load(symbol); // load the final symbol to the stack (or nop if no slot, then result is already there) + return null; + } + }); + + return method; + } + + @Override + public Node enter(final AccessNode accessNode) { + if (accessNode.testResolved()) { + return null; + } + + load(accessNode); + + return null; + } + + /** + * Initialize a specific set of vars to undefined. This has to be done at + * the start of each method for local variables that aren't passed as + * parameters. + * + * @param symbols list of symbols. + */ + private void initSymbols(final Iterable symbols) { + final LinkedList numbers = new LinkedList<>(); + final LinkedList objects = new LinkedList<>(); + + for (final Symbol symbol : symbols) { + /* + * The following symbols are guaranteed to be defined and thus safe + * from having unsigned written to them: parameters internals this + * + * Otherwise we must, unless we perform control/escape analysis, + * assign them undefined. + */ + final boolean isInternal = symbol.isParam() || symbol.isInternal() || symbol.isThis() || !symbol.canBeUndefined(); + + if (symbol.hasSlot() && !isInternal) { + assert symbol.getSymbolType().isNumber() || symbol.getSymbolType().isObject() : "no potentially undefined narrower local vars than doubles are allowed: " + symbol + " in " + getCurrentFunctionNode(); + if (symbol.getSymbolType().isNumber()) { + numbers.add(symbol); + } else if (symbol.getSymbolType().isObject()) { + objects.add(symbol); + } + } + } + + initSymbols(numbers, Type.NUMBER); + initSymbols(objects, Type.OBJECT); + } + + private void initSymbols(final LinkedList symbols, final Type type) { + if (symbols.isEmpty()) { + return; + } + + method.loadUndefined(type); + while (!symbols.isEmpty()) { + final Symbol symbol = symbols.removeFirst(); + if (!symbols.isEmpty()) { + method.dup(); + } + method.store(symbol); + } + } + + /** + * Create symbol debug information. + * + * @param block block containing symbols. + */ + private void symbolInfo(final Block block) { + for (final Symbol symbol : block.getFrame().getSymbols()) { + method.localVariable(symbol, block.getEntryLabel(), block.getBreakLabel()); + } + } + + @Override + public Node enter(final Block block) { + if (block.testResolved()) { + return null; + } + + method.label(block.getEntryLabel()); + initLocals(block); + + return block; + } + + @Override + public Node leave(final Block block) { + method.label(block.getBreakLabel()); + symbolInfo(block); + + if (block.needsScope()) { + popBlockScope(block); + } + + return block; + } + + private void popBlockScope(final Block block) { + final Label exitLabel = new Label("block_exit"); + final Label recoveryLabel = new Label("block_catch"); + final Label skipLabel = new Label("skip_catch"); + + /* pop scope a la try-finally */ + method.loadScope(); + method.invoke(ScriptObject.GET_PROTO); + method.storeScope(); + method._goto(skipLabel); + method.label(exitLabel); + + method._catch(recoveryLabel); + method.loadScope(); + method.invoke(ScriptObject.GET_PROTO); + method.storeScope(); + method.athrow(); + method.label(skipLabel); + method._try(block.getEntryLabel(), exitLabel, recoveryLabel, Throwable.class); + } + + @Override + public Node enter(final BreakNode breakNode) { + if (breakNode.testResolved()) { + return null; + } + + for (int i = 0; i < breakNode.getScopeNestingLevel(); i++) { + closeWith(); + } + + method.splitAwareGoto(breakNode.getTargetLabel()); + + return null; + } + + private MethodEmitter loadArgs(final List args) { + return loadArgs(args, null, false, args.size()); + } + + private MethodEmitter loadArgs(final List args, final String signature, final boolean isVarArg, final int argCount) { + // arg have already been converted to objects here. + if (isVarArg || argCount > LinkerCallSite.ARGLIMIT) { + loadArgsArray(args); + return method; + } + + // pad with undefined if size is too short. argCount is the real number of args + int n = 0; + final Type[] params = signature == null ? null : Type.getMethodArguments(signature); + for (final Node arg : args) { + assert arg != null; + load(arg); + if (params != null) { + method.convert(params[n]); + } + n++; + if (n >= argCount) { + break; + } + } + + while (n < argCount) { + method.loadUndefined(Type.OBJECT); + n++; + } + + return method; + } + + /** + * Create a new function object, including generating its stub code. + * + * @param functionNode FunctionNode to utilize. + */ + private void newFunctionObject(final FunctionNode functionNode) { + // Turn thisProperties into keys and symbols for the FunctionAnalyzer + final Map thisProperties = functionNode.getThisProperties(); + + final List keys = new ArrayList<>(); + final List symbols = new ArrayList<>(); + + for (final Entry entry : thisProperties.entrySet()) { + keys.add(entry.getKey()); + symbols.add(entry.getValue().getSymbol()); + } + + new FunctionObjectCreator(this, functionNode, keys, symbols).makeObject(method); + } + + @Override + public Node enter(final CallNode callNode) { + if (callNode.testResolved()) { + return null; + } + + final List args = callNode.getArgs(); + final Node function = callNode.getFunction(); + final FunctionNode currentFunction = getCurrentFunctionNode(); + final Block currentBlock = getCurrentBlock(); + + function.accept(new NodeVisitor(compileUnit, method) { + + private void sharedScopeCall(final IdentNode identNode, final int flags) { + final Symbol symbol = identNode.getSymbol(); + int scopeCallFlags = flags; + method.loadScope(); + if (symbol.isFastScope(currentFunction)) { + method.load(getScopeProtoDepth(currentBlock, symbol)); + scopeCallFlags |= CALLSITE_FAST_SCOPE; + } else { + method.load(-1); // Bypass fast-scope code in shared callsite + } + loadArgs(args); + final Type[] paramTypes = method.getTypesFromStack(args.size()); + final SharedScopeCall scopeCall = getScopeCall(symbol, identNode.getType(), callNode.getType(), paramTypes, scopeCallFlags); + scopeCall.generateInvoke(method); + } + + private void scopeCall(final IdentNode node, final int flags) { + load(node); + method.convert(Type.OBJECT); // foo() makes no sense if foo == 3 + // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly. + method.loadNull(); + loadArgs(args); + method.dynamicCall(callNode.getType(), args.size(), flags); + } + + private void evalCall(final IdentNode node, final int flags) { + load(node); + method.convert(Type.OBJECT); // foo() makes no sense if foo == 3 + + final Label not_eval = new Label("not_eval"); + final Label eval_done = new Label("eval_done"); + + // check if this is the real built-in eval + method.dup(); + globalIsEval(); + + method.ifeq(not_eval); + // We don't need ScriptFunction object for 'eval' + method.pop(); + + method.loadScope(); // Load up self (scope). + + final CallNode.EvalArgs evalArgs = callNode.getEvalArgs(); + // load evaluated code + load(evalArgs.code); + method.convert(Type.OBJECT); + // special/extra 'eval' arguments + load(evalArgs.evalThis); + method.load(evalArgs.location); + method.load(evalArgs.strictMode); + method.convert(Type.OBJECT); + + // direct call to Global.directEval + globalDirectEval(); + method.convert(callNode.getType()); + method._goto(eval_done); + + method.label(not_eval); + // This is some scope 'eval' or global eval replaced by user + // but not the built-in ECMAScript 'eval' function call + method.loadNull(); + loadArgs(args); + method.dynamicCall(callNode.getType(), args.size(), flags); + + method.label(eval_done); + } + + @Override + public Node enter(final IdentNode node) { + final Symbol symbol = node.getSymbol(); + + if (symbol.isScope()) { + final int flags = getCallSiteFlags() | CALLSITE_SCOPE; + final int useCount = symbol.getUseCount(); + + // Threshold for generating shared scope callsite is lower for fast scope symbols because we know + // we can dial in the correct scope. However, we als need to enable it for non-fast scopes to + // support huge scripts like mandreel.js. + if (callNode.isEval()) { + evalCall(node, flags); + } else if (useCount <= SharedScopeCall.FAST_SCOPE_CALL_THRESHOLD + || (!symbol.isFastScope(currentFunction) && useCount <= SharedScopeCall.SLOW_SCOPE_CALL_THRESHOLD) + || callNode.inWithBlock()) { + scopeCall(node, flags); + } else { + sharedScopeCall(node, flags); + } + assert method.peekType().equals(callNode.getType()); + } else { + enterDefault(node); + } + + return null; + } + + @Override + public Node enter(final AccessNode node) { + load(node.getBase()); + method.convert(Type.OBJECT); + method.dup(); + method.dynamicGet(node.getType(), node.getProperty().getName(), getCallSiteFlags(), true); + method.swap(); + loadArgs(args); + method.dynamicCall(callNode.getType(), args.size(), getCallSiteFlags()); + assert method.peekType().equals(callNode.getType()); + + return null; + } + + @Override + public Node enter(final ReferenceNode node) { + final FunctionNode callee = node.getReference(); + final boolean isVarArg = callee.isVarArg(); + final int argCount = isVarArg ? -1 : callee.getParameters().size(); + + final String signature = new FunctionSignature(true, callee.needsCallee(), callee.getReturnType(), isVarArg ? null : callee.getParameters()).toString(); + + if (callee.isStrictMode()) { // self is undefined + method.loadUndefined(Type.OBJECT); + } else { // get global from scope (which is the self) + globalInstance(); + } + + if (callee.needsCallee()) { // TODO: always true + newFunctionObject(callee); // TODO: if callee not needed, function object is used only to pass scope (could be optimized). if neither the scope nor the function object is needed by the callee, we can pass null instead. + } + + loadArgs(args, signature, isVarArg, argCount); + method.invokeStatic(callee.getCompileUnit().getUnitClassName(), callee.getName(), signature); + assert method.peekType().equals(callee.getReturnType()) : method.peekType() + " != " + callee.getReturnType(); + + return null; + } + + @Override + public Node enter(final IndexNode node) { + load(node.getBase()); + method.convert(Type.OBJECT); + method.dup(); + load(node.getIndex()); + final Type indexType = node.getIndex().getType(); + if (indexType.isObject() || indexType.isBoolean()) { + method.convert(Type.OBJECT); //TODO + } + method.dynamicGetIndex(node.getType(), getCallSiteFlags(), true); + method.swap(); + loadArgs(args); + method.dynamicCall(callNode.getType(), args.size(), getCallSiteFlags()); + assert method.peekType().equals(callNode.getType()); + + return null; + } + + @Override + protected Node enterDefault(final Node node) { + // Load up function. + load(function); + method.convert(Type.OBJECT); //TODO, e.g. booleans can be used as functions + method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE + + loadArgs(args); + method.dynamicCall(callNode.getType(), args.size(), getCallSiteFlags() | CALLSITE_SCOPE); + assert method.peekType().equals(callNode.getType()); + + return null; + } + }); + + method.store(callNode.getSymbol()); + + return null; + } + + @Override + public Node enter(final ContinueNode continueNode) { + if (continueNode.testResolved()) { + return null; + } + + for (int i = 0; i < continueNode.getScopeNestingLevel(); i++) { + closeWith(); + } + + method.splitAwareGoto(continueNode.getTargetLabel()); + + return null; + } + + @Override + public Node enter(final DoWhileNode doWhileNode) { + return enter((WhileNode)doWhileNode); + } + + @Override + public Node enter(final EmptyNode emptyNode) { + return null; + } + + @Override + public Node enter(final ExecuteNode executeNode) { + if (executeNode.testResolved()) { + return null; + } + + final Node expression = executeNode.getExpression(); + expression.accept(this); + + return null; + } + + @Override + public Node enter(final ForNode forNode) { + if (forNode.testResolved()) { + return null; + } + + final Node test = forNode.getTest(); + final Block body = forNode.getBody(); + final Node modify = forNode.getModify(); + + final Label breakLabel = forNode.getBreakLabel(); + final Label continueLabel = forNode.getContinueLabel(); + final Label loopLabel = new Label("loop"); + + Node init = forNode.getInit(); + + if (forNode.isForIn()) { + final Symbol iter = forNode.getIterator(); + + // We have to evaluate the optional initializer expression + // of the iterator variable of the for-in statement. + if (init instanceof VarNode) { + init.accept(this); + init = ((VarNode)init).getName(); + } + + load(modify); + assert modify.getType().isObject(); + method.invoke(forNode.isForEach() ? ScriptRuntime.TO_VALUE_ITERATOR : ScriptRuntime.TO_PROPERTY_ITERATOR); + method.store(iter); + method._goto(continueLabel); + method.label(loopLabel); + + new Store(init) { + @Override + protected void evaluate() { + method.load(iter); + method.invoke(interfaceCallNoLookup(Iterator.class, "next", Object.class)); + } + }.store(); + + body.accept(this); + + method.label(continueLabel); + method.load(iter); + method.invoke(interfaceCallNoLookup(Iterator.class, "hasNext", boolean.class)); + method.ifne(loopLabel); + method.label(breakLabel); + } else { + if (init != null) { + init.accept(this); + } + + final Label testLabel = new Label("test"); + + method._goto(testLabel); + method.label(loopLabel); + body.accept(this); + method.label(continueLabel); + + if (!body.isTerminal() && modify != null) { + load(modify); + } + + method.label(testLabel); + if (test != null) { + new BranchOptimizer(this, method).execute(test, loopLabel, true); + } else { + method._goto(loopLabel); + } + + method.label(breakLabel); + } + + return null; + } + + private void initLocals(final Block block) { + initLocals(block, null); + } + + /** + * Initialize the slots in a frame to undefined. + * + * @param block block with local vars. + */ + private void initLocals(final Block block, final AccessSpecializer accessSpecializer) { + final FunctionNode function = block.getFunction(); + final boolean isFunctionNode = block == function; + + /* + * Get the symbols from the frame and realign the frame so that all + * slots get correct numbers. The slot numbering is not fixed until + * after initLocals has been run + */ + final Frame frame = block.getFrame(); + final List symbols = frame.getSymbols(); + + /* Fix the predefined slots so they have numbers >= 0, like varargs. */ + frame.realign(); + + /* + * Determine if block needs scope, if not, just do initSymbols for this block. + */ + if (block.needsScope()) { + /* + * Determine if function is varargs and consequently variables have to + * be in the scope. + */ + final boolean isVarArg = function.isVarArg(); + final boolean varsInScope = function.varsInScope(); + + // TODO for LET we can do better: if *block* does not contain any eval/with, we don't need its vars in scope. + + final List nameList = new ArrayList<>(); + final List locals = new ArrayList<>(); + + // note that in the case of a varargs vector the arguments in the vector should NOT have local slots + // this was a bug: see NASHORN-21 + if (isVarArg) { + for (final IdentNode param : function.getParameters()) { + param.getSymbol().setNeedsSlot(false); + } + } + + // If there are variable arguments, we need to load them (functions only). + if (isFunctionNode && isVarArg) { + method.loadVarArgs(); + method.loadCallee(); + method.load(function.getParameters().size()); + globalAllocateArguments(); + method.storeArguments(); + } + + // Initalize symbols and values + final List newSymbols = new ArrayList<>(); + final List values = new ArrayList<>(); + + for (final Symbol symbol : symbols) { + if (symbol.isInternal() || symbol.isThis()) { + continue; + } + + if (symbol.isVar() && (varsInScope || symbol.isScope())) { + nameList.add(symbol.getName()); + newSymbols.add(symbol); + values.add(null); + symbol.setIsScope(); + symbol.setNeedsSlot(false); + } else if (symbol.isVar()) { + assert symbol.hasSlot() : symbol + " should have a slot only, no scope"; + locals.add(symbol); + } else if (symbol.isParam() && (varsInScope || isVarArg || symbol.isScope())) { + nameList.add(symbol.getName()); + newSymbols.add(symbol); + values.add(isVarArg ? null : symbol); + symbol.setIsScope(); + if (isVarArg) { + symbol.setNeedsSlot(false); + } + } + } + + /* Correct slot numbering again */ + frame.realign(); + + // we may have locals that need to be initialized + initSymbols(locals); + + if (isFunctionNode) { + initScope(); + } + + if (accessSpecializer != null) { + ((FunctionNode)block).accept(accessSpecializer); + } + + /* + * Create a new object based on the symbols and values, generate + * bootstrap code for object + */ + final FieldObjectCreator foc = new FieldObjectCreator(this, nameList, newSymbols, values, true, isVarArg) { + @Override + protected Type getValueType(final Symbol value) { + return value.getSymbolType(); + } + + @Override + protected void loadValue(final Symbol value) { + method.load(value); + } + }; + foc.makeObject(method); + + // runScript(): merge scope into global + if (isFunctionNode && function.isScript()) { + method.invoke(ScriptRuntime.MERGE_SCOPE); + } + + method.storeScope(); + } else { + initSymbols(symbols); + + if (isFunctionNode) { + initScope(); + } + } + + // Debugging: print symbols? @see --print-symbols flag + printSymbols(block, (isFunctionNode ? "Function " : "Block in ") + (function.getIdent() == null ? "" : function.getIdent().getName())); + } + + private void initScope() { + method.loadCallee(); + method.invoke(ScriptFunction.GET_SCOPE); + method.storeScope(); + } + + @Override + public Node enter(final FunctionNode functionNode) { + if (functionNode.testResolved()) { + return null; + } + + compileUnit = functionNode.getCompileUnit(); + assert compileUnit != null; + + method = compileUnit.getClassEmitter().method(functionNode); + functionNode.setMethodEmitter(method); + // Mark end for variable tables. + method.begin(); + method.label(functionNode.getEntryLabel()); + + initLocals(functionNode, new AccessSpecializer()); + + return functionNode; + } + + @Override + public Node leave(final FunctionNode functionNode) { + // Mark end for variable tables. + method.label(functionNode.getBreakLabel()); + + if (!functionNode.needsScope()) { + method.markerVariable(LEAF.tag(), functionNode.getEntryLabel(), functionNode.getBreakLabel()); + } + + symbolInfo(functionNode); + try { + method.end(); // wrap up this method + } catch (final Throwable t) { + Context.printStackTrace(t); + final VerifyError e = new VerifyError("Code generation bug in \"" + functionNode.getName() + "\": likely stack misaligned: " + t + " " + functionNode.getSource().getName()); + e.initCause(t); + throw e; + } + + return functionNode; + } + + @Override + public Node enter(final IdentNode identNode) { + return null; + } + + @Override + public Node enter(final IfNode ifNode) { + if (ifNode.testResolved()) { + return null; + } + + final Node test = ifNode.getTest(); + final Block pass = ifNode.getPass(); + final Block fail = ifNode.getFail(); + + final Label failLabel = new Label("if_fail"); + final Label afterLabel = fail == null ? failLabel : new Label("if_done"); + + new BranchOptimizer(this, method).execute(test, failLabel, false); + + boolean passTerminal = false; + boolean failTerminal = false; + + pass.accept(this); + if (!pass.hasTerminalFlags()) { + method._goto(afterLabel); //don't fallthru to fail block + } else { + passTerminal = pass.isTerminal(); + } + + if (fail != null) { + method.label(failLabel); + fail.accept(this); + failTerminal = fail.isTerminal(); + } + + //if if terminates, put the after label there + if (!passTerminal || !failTerminal) { + method.label(afterLabel); + } + + return null; + } + + @Override + public Node enter(final IndexNode indexNode) { + if (indexNode.testResolved()) { + return null; + } + + load(indexNode); + + return null; + } + + @Override + public Node enter(final LineNumberNode lineNumberNode) { + if (lineNumberNode.testResolved()) { + return null; + } + + final Label label = new Label("line:" + lineNumberNode.getLineNumber() + " (" + getCurrentFunctionNode().getName() + ")"); + method.label(label); + method.lineNumber(lineNumberNode.getLineNumber(), label); + + return null; + } + + /** + * Load a list of nodes as an array of a specific type + * The array will contain the visited nodes. + * + * @param arrayLiteralNode the array of contents + * @param arrayType the type of the array, e.g. ARRAY_NUMBER or ARRAY_OBJECT + * + * @return the method generator that was used + */ + private MethodEmitter loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) { + assert arrayType == Type.INT_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY; + + final Node[] nodes = arrayLiteralNode.getValue(); + final Object presets = arrayLiteralNode.getPresets(); + final int[] postsets = arrayLiteralNode.getPostsets(); + final Class type = arrayType.getTypeClass(); + final List units = arrayLiteralNode.getUnits(); + + loadConstant(presets); + + final Type elementType = arrayType.getElementType(); + + if (units != null) { + final CompileUnit savedCompileUnit = compileUnit; + final MethodEmitter savedMethod = method; + + try { + for (final ArrayUnit unit : units) { + compileUnit = unit.getCompileUnit(); + + final String className = compileUnit.getUnitClassName(); + final String name = compiler.uniqueName(SPLIT_PREFIX.tag()); + final String signature = methodDescriptor(type, Object.class, ScriptFunction.class, ScriptObject.class, type); + + method = compileUnit.getClassEmitter().method(EnumSet.of(Flag.PUBLIC, Flag.STATIC), name, signature); + method.setFunctionNode(getCurrentFunctionNode()); + method.begin(); + + fixScopeSlot(); + + method.load(arrayType, SPLIT_ARRAY_ARG.slot()); + + for (int i = unit.getLo(); i < unit.getHi(); i++) { + storeElement(nodes, elementType, postsets[i]); + } + + method._return(); + method.end(); + + savedMethod.loadThis(); + savedMethod.swap(); + savedMethod.loadCallee(); + savedMethod.swap(); + savedMethod.loadScope(); + savedMethod.swap(); + savedMethod.invokeStatic(className, name, signature); + } + } finally { + compileUnit = savedCompileUnit; + method = savedMethod; + } + + return method; + } + + for (final int postset : postsets) { + storeElement(nodes, elementType, postset); + } + + return method; + } + + private void storeElement(final Node[] nodes, final Type elementType, final int index) { + method.dup(); + method.load(index); + + final Node element = nodes[index]; + + if (element == null) { + method.loadEmpty(elementType); + } else { + assert elementType.isEquivalentTo(element.getType()) : "array element type doesn't match array type"; + load(element); + } + + method.arraystore(); + } + + private MethodEmitter loadArgsArray(final List args) { + final Object[] array = new Object[args.size()]; + loadConstant(array); + + for (int i = 0; i < args.size(); i++) { + method.dup(); + method.load(i); + load(args.get(i)).convert(Type.OBJECT); //has to be upcast to object or we fail + method.arraystore(); + } + + return method; + } + + /** + * Load a constant from the constant array. This is only public to be callable from the objects + * subpackage. Do not call directly. + * + * @param string string to load + */ + public void loadConstant(final String string) { + final String unitClassName = compileUnit.getUnitClassName(); + final ClassEmitter classEmitter = compileUnit.getClassEmitter(); + final int index = compiler.getConstantData().add(string); + + method.load(index); + method.invokeStatic(unitClassName, GET_STRING.tag(), methodDescriptor(String.class, int.class)); + classEmitter.needGetConstantMethod(String.class); + } + + /** + * Load a constant from the constant array. This is only public to be callable from the objects + * subpackage. Do not call directly. + * + * @param object object to load + */ + public void loadConstant(final Object object) { + final String unitClassName = compileUnit.getUnitClassName(); + final ClassEmitter classEmitter = compileUnit.getClassEmitter(); + final int index = compiler.getConstantData().add(object); + final Class cls = object.getClass(); + + if (cls == PropertyMap.class) { + method.load(index); + method.invokeStatic(unitClassName, GET_MAP.tag(), methodDescriptor(PropertyMap.class, int.class)); + classEmitter.needGetConstantMethod(PropertyMap.class); + } else if (cls.isArray()) { + method.load(index); + final String methodName = ClassEmitter.getArrayMethodName(cls); + method.invokeStatic(unitClassName, methodName, methodDescriptor(cls, int.class)); + classEmitter.needGetConstantMethod(cls); + } else { + method.loadConstants(unitClassName).load(index).arrayload(); + if (cls != Object.class) { + method.checkcast(cls); + } + } + } + + // literal values + private MethodEmitter load(final LiteralNode node) { + final Object value = node.getValue(); + + if (value == null) { + method.loadNull(); + } else if (value instanceof Undefined) { + method.loadUndefined(Type.OBJECT); + } else if (value instanceof String) { + final String string = (String)value; + + if (string.length() > (MethodEmitter.LARGE_STRING_THRESHOLD / 3)) { // 3 == max bytes per encoded char + loadConstant(string); + } else { + method.load(string); + } + } else if (value instanceof RegexToken) { + loadRegex((RegexToken)value); + } else if (value instanceof Boolean) { + method.load((Boolean)value); + } else if (value instanceof Integer) { + method.load((Integer)value); + } else if (value instanceof Long) { + method.load((Long)value); + } else if (value instanceof Double) { + method.load((Double)value); + } else if (node instanceof ArrayLiteralNode) { + final ArrayType type = (ArrayType)node.getType(); + loadArray((ArrayLiteralNode)node, type); + globalAllocateArray(type); + } else { + assert false : "Unknown literal for " + node.getClass() + " " + value.getClass() + " " + value; + } + + return method; + } + + private MethodEmitter loadRegexToken(final RegexToken value) { + method.load(value.getExpression()); + method.load(value.getOptions()); + return globalNewRegExp(); + } + + private MethodEmitter loadRegex(final RegexToken regexToken) { + if (regexFieldCount > MAX_REGEX_FIELDS) { + return loadRegexToken(regexToken); + } + // emit field + final String regexName = compiler.uniqueName(REGEX_PREFIX.tag()); + final ClassEmitter classEmitter = compileUnit.getClassEmitter(); + + classEmitter.field(EnumSet.of(PRIVATE, STATIC), regexName, Object.class); + regexFieldCount++; + + // get field, if null create new regex, finally clone regex object + method.getStatic(compileUnit.getUnitClassName(), regexName, typeDescriptor(Object.class)); + method.dup(); + final Label cachedLabel = new Label("cached"); + method.ifnonnull(cachedLabel); + + method.pop(); + loadRegexToken(regexToken); + method.dup(); + method.putStatic(compileUnit.getUnitClassName(), regexName, typeDescriptor(Object.class)); + + method.label(cachedLabel); + globalRegExpCopy(); + + return method; + } + + @SuppressWarnings("rawtypes") + @Override + public Node enter(final LiteralNode literalNode) { + load(literalNode).store(literalNode.getSymbol()); + return null; + } + + @Override + public Node enter(final ObjectNode objectNode) { + if (objectNode.testResolved()) { + return null; + } + + final List elements = objectNode.getElements(); + final int size = elements.size(); + + final List keys = new ArrayList<>(); + final List symbols = new ArrayList<>(); + final List values = new ArrayList<>(); + + boolean hasGettersSetters = false; + + for (int i = 0; i < size; i++) { + final PropertyNode propertyNode = (PropertyNode)elements.get(i); + final Node value = propertyNode.getValue(); + final String key = propertyNode.getKeyName(); + final Symbol symbol = value == null ? null : propertyNode.getSymbol(); + + if (value == null) { + hasGettersSetters = true; + } + + keys.add(key); + symbols.add(symbol); + values.add(value); + } + + new FieldObjectCreator(this, keys, symbols, values) { + @Override + protected Type getValueType(final Node node) { + return node.getType(); + } + + @Override + protected void loadValue(final Node node) { + load(node); + } + + /** + * Ensure that the properties start out as object types so that + * we can do putfield initializations instead of dynamicSetIndex + * which would be the case to determine initial property type + * otherwise. + * + * Use case, it's very expensive to do a million var x = {a:obj, b:obj} + * just to have to invalidate them immediately on initialization + * + * see NASHORN-594 + */ + @Override + protected MapCreator newMapCreator(final Class fieldObjectClass) { + return new ObjectMapCreator(fieldObjectClass, keys, symbols); + } + + }.makeObject(method); + + method.dup(); + globalObjectPrototype(); + method.invoke(ScriptObject.SET_PROTO); + + if (!hasGettersSetters) { + method.store(objectNode.getSymbol()); + return null; + } + + for (final Node element : elements) { + final PropertyNode propertyNode = (PropertyNode)element; + final Object key = propertyNode.getKey(); + final ReferenceNode getter = (ReferenceNode)propertyNode.getGetter(); + final ReferenceNode setter = (ReferenceNode)propertyNode.getSetter(); + + if (getter == null && setter == null) { + continue; + } + + method.dup().loadKey(key); + + if (getter == null) { + method.loadNull(); + } else { + getter.accept(this); + } + + if (setter == null) { + method.loadNull(); + } else { + setter.accept(this); + } + + method.invoke(ScriptObject.SET_USER_ACCESSORS); + } + + method.store(objectNode.getSymbol()); + + return null; + } + + @Override + public Node enter(final ReferenceNode referenceNode) { + if (referenceNode.testResolved()) { + return null; + } + + newFunctionObject(referenceNode.getReference()); + + return null; + } + + @Override + public Node enter(final ReturnNode returnNode) { + if (returnNode.testResolved()) { + return null; + } + + // Set the split return flag in the scope if this is a split method fragment. + if (method.getSplitNode() != null) { + assert method.getSplitNode().hasReturn() : "unexpected return in split node"; + + method.loadScope(); + method.checkcast(Scope.class); + method.load(0); + method.invoke(Scope.SET_SPLIT_STATE); + } + + final Node expression = returnNode.getExpression(); + if (expression != null) { + load(expression); + } else { + method.loadUndefined(getCurrentFunctionNode().getReturnType()); + } + + method._return(getCurrentFunctionNode().getReturnType()); + + return null; + } + + private static boolean isNullLiteral(final Node node) { + return node instanceof LiteralNode && ((LiteralNode) node).isNull(); + } + + private boolean nullCheck(final RuntimeNode runtimeNode, final List args, final String signature) { + final Request request = runtimeNode.getRequest(); + + if (!Request.isEQ(request) && !Request.isNE(request)) { + return false; + } + + assert args.size() == 2 : "EQ or NE or TYPEOF need two args"; + + Node lhs = args.get(0); + Node rhs = args.get(1); + + if (isNullLiteral(lhs)) { + final Node tmp = lhs; + lhs = rhs; + rhs = tmp; + } + + if (isNullLiteral(rhs)) { + final Label trueLabel = new Label("trueLabel"); + final Label falseLabel = new Label("falseLabel"); + final Label endLabel = new Label("end"); + + load(lhs); + method.dup(); + if (Request.isEQ(request)) { + method.ifnull(trueLabel); + } else if (Request.isNE(request)) { + method.ifnonnull(trueLabel); + } else { + assert false : "Invalid request " + request; + } + + method.label(falseLabel); + load(rhs); + method.invokeStatic(CompilerConstants.className(ScriptRuntime.class), request.toString(), signature); + method._goto(endLabel); + + method.label(trueLabel); + // if NE (not strict) this can be "undefined != null" which is supposed to be false + if (request == Request.NE) { + method.loadUndefined(Type.OBJECT); + final Label isUndefined = new Label("isUndefined"); + final Label afterUndefinedCheck = new Label("afterUndefinedCheck"); + method.if_acmpeq(isUndefined); + // not undefined + method.load(true); + method._goto(afterUndefinedCheck); + method.label(isUndefined); + method.load(false); + method.label(afterUndefinedCheck); + } else { + method.pop(); + method.load(true); + } + method.label(endLabel); + method.convert(runtimeNode.getType()); + method.store(runtimeNode.getSymbol()); + + return true; + } + + return false; + } + + private boolean specializationCheck(final RuntimeNode.Request request, final Node node, final List args) { + if (!request.canSpecialize()) { + return false; + } + + assert args.size() == 2; + final Node lhs = args.get(0); + final Node rhs = args.get(1); + + final Type returnType = node.getType(); + load(lhs); + load(rhs); + + Request finalRequest = request; + + final Request reverse = Request.reverse(request); + if (method.peekType().isObject() && reverse != null) { + if (!method.peekType(1).isObject()) { + method.swap(); + finalRequest = reverse; + } + } + + method.dynamicRuntimeCall( + new SpecializedRuntimeNode( + finalRequest, + new Type[] { + method.peekType(1), + method.peekType() + }, + returnType).getInitialName(), + returnType, + finalRequest); + + method.convert(node.getType()); + method.store(node.getSymbol()); + + return true; + } + + @Override + public Node enter(final RuntimeNode runtimeNode) { + if (runtimeNode.testResolved()) { + return null; + } + + /* + * First check if this should be something other than a runtime node + * AccessSpecializer might have changed the type + */ + if (runtimeNode.isPrimitive()) { + + final Node lhs = runtimeNode.getArgs().get(0); + Node rhs = null; + + if (runtimeNode.getArgs().size() > 1) { + rhs = runtimeNode.getArgs().get(1); + } + + final Type type = runtimeNode.getType(); + final Symbol symbol = runtimeNode.getSymbol(); + + switch (runtimeNode.getRequest()) { + case EQ: + case EQ_STRICT: + return enterCmp(lhs, rhs, Condition.EQ, type, symbol); + case NE: + case NE_STRICT: + return enterCmp(lhs, rhs, Condition.NE, type, symbol); + case LE: + return enterCmp(lhs, rhs, Condition.LE, type, symbol); + case LT: + return enterCmp(lhs, rhs, Condition.LT, type, symbol); + case GE: + return enterCmp(lhs, rhs, Condition.GE, type, symbol); + case GT: + return enterCmp(lhs, rhs, Condition.GT, type, symbol); + case ADD: + return enterNumericAdd(lhs, rhs, type, symbol); + default: + // it's ok to send this one on with only primitive arguments, maybe INSTANCEOF(true, true) or similar + // assert false : runtimeNode + " has all primitive arguments. This is an inconsistent state"; + break; + } + } + + // Get the request arguments. + final List args = runtimeNode.getArgs(); + + if (nullCheck(runtimeNode, args, new FunctionSignature(false, runtimeNode.getType(), args).toString())) { + return null; + } + + if (specializationCheck(runtimeNode.getRequest(), runtimeNode, args)) { + return null; + } + + for (final Node arg : runtimeNode.getArgs()) { + load(arg).convert(Type.OBJECT); //TODO this should not be necessary below Lower + } + + method.invokeStatic( + CompilerConstants.className(ScriptRuntime.class), + runtimeNode.getRequest().toString(), + new FunctionSignature( + false, + runtimeNode.getType(), + runtimeNode.getArgs().size()).toString()); + method.convert(runtimeNode.getType()); + method.store(runtimeNode.getSymbol()); + + return null; + } + + @Override + public Node enter(final SplitNode splitNode) { + if (splitNode.testResolved()) { + return null; + } + + final CompileUnit splitCompileUnit = splitNode.getCompileUnit(); + + final FunctionNode fn = getCurrentFunctionNode(); + final String className = splitCompileUnit.getUnitClassName(); + final String name = splitNode.getName(); + + final Class rtype = fn.getReturnType().getTypeClass(); + final Class[] ptypes = fn.isVarArg() ? + new Class[] {Object.class, ScriptFunction.class, ScriptObject.class, Object.class} : + new Class[] {Object.class, ScriptFunction.class, ScriptObject.class}; + + setCurrentCompileUnit(splitCompileUnit); + splitNode.setCompileUnit(splitCompileUnit); + + final Call splitCall = staticCallNoLookup( + className, + name, + methodDescriptor(rtype, ptypes)); + + setCurrentMethodEmitter( + splitCompileUnit.getClassEmitter().method( + EnumSet.of(Flag.PUBLIC, Flag.STATIC), + name, + rtype, + ptypes)); + + method.setFunctionNode(fn); + method.setSplitNode(splitNode); + splitNode.setMethodEmitter(method); + + final MethodEmitter caller = splitNode.getCaller(); + caller.loadThis(); + caller.loadCallee(); + caller.loadScope(); + if (fn.isVarArg()) { + caller.loadArguments(); + } + caller.invoke(splitCall); + caller.storeResult(); + + method.begin(); + + method.loadUndefined(fn.getReturnType()); + method.storeResult(); + + fixScopeSlot(); + + return splitNode; + } + + private void fixScopeSlot() { + if (getCurrentFunctionNode().getScopeNode().getSymbol().getSlot() != SCOPE.slot()) { + // TODO hack to move the scope to the expected slot (that's needed because split methods reuse the same slots as the root method) + method.load(Type.typeFor(ScriptObject.class), SCOPE.slot()); + method.storeScope(); + } + } + + @Override + public Node leave(final SplitNode splitNode) { + try { + // Wrap up this method. + method.loadResult(); + method._return(getCurrentFunctionNode().getReturnType()); + method.end(); + } catch (final Throwable t) { + Context.printStackTrace(t); + final VerifyError e = new VerifyError("Code generation bug in \"" + splitNode.getName() + "\": likely stack misaligned: " + t + " " + compiler.getSource().getName()); + e.initCause(t); + throw e; + } + + // Handle return from split method if there was one. + final MethodEmitter caller = splitNode.getCaller(); + final List

nametypedefaultdescription
${opt.name} ${opt.shortName == null? "" : opt.shortName}${opt.type}${defValue}${opt.description}